Fatal error: Call to a member function val() on a non-object in Editor.php after Editor Update

Fatal error: Call to a member function val() on a non-object in Editor.php after Editor Update

pansengtatpansengtat Posts: 66Questions: 26Answers: 1
edited August 2014 in Editor

Fatal error: Call to a member function val() on a non-object in C:\xampp\htdocs\myProgram\php\lib\Editor\Editor.php on line 1026

JSFiddle Link: http://jsfiddle.net/pansengtat/pfgrxhtq/

Encountered this error specifically for the linked sample.

Fatal error: Call to a member function val() on a non-object in Editor.php

Did not encounter this error when writing for similar pages.

Need help urgently to resolve this, as I already updated my copy of Editor/DataTables to most recent version.

I have asked this question before, but now it is coming back again. What is causing this error from recurring over and over again?

Backend code:

<?php
    include 'constants.php';
    include 'mysql_settings.php';
    include 'utility.php';
    
    session_start();
    if(isset($_COOKIE["rememberme"])){
        $rm = $_COOKIE["rememberme"];
    }elseif(isset($_SESSION["rememberme"])){
        $rm = $_SESSION["rememberme"];
    }
    
    if(isset($rm)){
        try{
            $connection = new PDO("mysql:host=$mysql_host;port=$mysql_port;dbname=$mysql_DB", $mysql_user, $mysql_password);
            $connection-> setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        }
        catch (PDOException $err){
            echo '<div class="errorCanvas"><p id="errorMsg">Could not connect to server. Please try again in a few minutes.</p></div>';
            return 0;
        }
        //--- Group ---//
        $current_groupID = getAssignedGroupIDUsingUsername($rm);
        //--- Rank ---//
        $current_rankID = getUserRankID($rm);
        if(session_status() != PHP_SESSION_NONE){
            $_SESSION["rank"] = $current_rankID;
        }
    }

    // DataTables PHP library
    include( "lib/DataTables.php" );
    
    // Alias Editor classes so they are easy to use
    use
        DataTables\Editor,
        DataTables\Editor\Field,
        DataTables\Editor\Format,
        DataTables\Editor\Join,
        DataTables\Editor\Validate;

    //--- Outsource version of Editor ---//
    if ( $current_rankID >= $CONST_RANK_OUTSOURCE ) { //--- Outsource user with his/her assigned group ---//
        $data = Editor::inst($db, 'TestRequestActualSchedule', 'TestRequestNo')
            ->where('TestRequestMain.AssignedGroupID', $current_groupID)
            ->field(
                Field::inst('TestRequestActualSchedule.TestRequestNo')->set(false),
                Field::inst('TestRequestMain.POnumber')->set(false),
                Field::inst('TestRequestMain.ProjectName')->set(false),

                    Field::inst('TestEnvironment.Name')->set(false),
                Field::inst('TestRequestActualSchedule.ActualDate'),
                Field::inst('TestRequestActualSchedule.ManHrsNM')->validator('Validate::numeric'),
                Field::inst('TestRequestActualSchedule.ManHrsOT')->validator('Validate::numeric'),
                Field::inst('TestRequestActualSchedule.ManHrsOTSunPH')->validator('Validate::numeric'),
                Field::inst('TestRequestPlannedSchedule.ScheduledManHrsNM')->set(false),
                Field::inst('TestRequestPlannedSchedule.ScheduledManHrsOT')->set(false),
                Field::inst('TestRequestPlannedSchedule.ScheduledManHrsOTSunPH')->set(false),
                Field::inst('TestRequestMain.Status'),
                    Field::inst('StatusMirror.String')->set(false),
                Field::inst('TestRequestActualSchedule.RazerApproval')->set(false), 
                    Field::inst('ConfirmationMirror.String')->set(false),
                Field::inst('TestRequestAdv.RemarksRazer')->set(false),
                Field::inst('TestRequestMain.AssignedGroupID')->set(false),
                    Field::inst('AssignedGroup.Name')->set(false),
                Field::inst('TestRequestMain.SWQAEngineerID')->set(false)
            )
        ->leftJoin('TestRequestPlannedSchedule', 'TestRequestPlannedSchedule.TestRequestNo', '=', 'TestRequestActualSchedule.TestRequestNo')
        ->leftJoin('TestRequestAdv', 'TestRequestActualSchedule.TestRequestNo', '=', 'TestRequestAdv.TestRequestNo')
        ->leftJoin('TestRequestMain', 'TestRequestActualSchedule.TestRequestNo', '=', 'TestRequestMain.TestRequestNo')
        ->leftJoin('RazerConfirmationMirror', 'TestRequestActualSchedule.RazerApproval', '=', 'ConfirmationMirror.ID')
        ->leftJoin('StatusMirror', 'TestRequestMain.Status', '=', 'StatusMirror.ID')
        ->leftJoin('AssignedGroup', 'TestRequestMain.AssignedGroupID', '=', 'AssignedGroup.ID')
        ->leftJoin('TestEnvironment', 'TestEnvironment.ID', '=', 'TestRequestAdv.TestEnvironmentID')
        ->process($_POST)
        ->data();

        //--- Initialization of dropdown: Outsource  ---//
        if ( !isset($_POST['action']) ) {
            $data['StatusMirror'] = $db
                ->selectDistinct('StatusMirror', 'ID as value, String as label')
                ->fetchAll();
        }
    }
    //--- Outsource version of Internal Staff ---//
    else {
        $data = Editor::inst($db, 'TestRequestActualSchedule', 'TestRequestNo')
            ->field(
                Field::inst('TestRequestActualSchedule.TestRequestNo')->set(false),
                Field::inst('TestRequestMain.POnumber')->set(false),
                Field::inst('TestRequestMain.ProjectName')->set(false),

                    Field::inst('TestEnvironment.Name')->set(false),
                Field::inst('TestRequestActualSchedule.ActualDate'),
                Field::inst('TestRequestActualSchedule.ManHrsNM')->validator('Validate::numeric'),
                Field::inst('TestRequestActualSchedule.ManHrsOT')->validator('Validate::numeric'),
                Field::inst('TestRequestActualSchedule.ManHrsOTSunPH')->validator('Validate::numeric'),
                Field::inst('TestRequestPlannedSchedule.ScheduledManHrsNM')->set(false),
                Field::inst('TestRequestPlannedSchedule.ScheduledManHrsOT')->set(false),
                Field::inst('TestRequestPlannedSchedule.ScheduledManHrsOTSunPH')->set(false),
                Field::inst('TestRequestMain.Status'),
                    Field::inst('StatusMirror.String')->set(false),
                Field::inst('TestRequestActualSchedule.RazerApproval'),
                    Field::inst('ConfirmationMirror.String')->set(false),
                Field::inst('TestRequestAdv.RemarksRazer'),
                Field::inst('TestRequestMain.AssignedGroupID')->set(false),
                    Field::inst('AssignedGroup.Name')->set(false),
                Field::inst('TestRequestMain.SWQAEngineerID')->set(false)
            )
        ->leftJoin('TestRequestPlannedSchedule', 'TestRequestPlannedSchedule.TestRequestNo', '=', 'TestRequestActualSchedule.TestRequestNo')
        ->leftJoin('TestRequestAdv', 'TestRequestActualSchedule.TestRequestNo', '=', 'TestRequestAdv.TestRequestNo')
        ->leftJoin('TestRequestMain', 'TestRequestActualSchedule.TestRequestNo', '=', 'TestRequestMain.TestRequestNo')
        ->leftJoin('RazerConfirmationMirror', 'TestRequestActualSchedule.RazerApproval', '=', 'ConfirmationMirror.ID')
        ->leftJoin('StatusMirror', 'TestRequestMain.Status', '=', 'StatusMirror.ID')
        ->leftJoin('AssignedGroup', 'TestRequestMain.AssignedGroupID', '=', 'AssignedGroup.ID')
        ->leftJoin('TestEnvironment', 'TestEnvironment.ID', '=', 'TestRequestAdv.TestEnvironmentID')
        ->process($_POST)
        ->data();

        //--- Initialization of dropdown: Internal staff ---//
        if ( !isset($_POST['action']) ) {
            $data['ConfirmationMirror'] = $db
                ->selectDistinct('ConfirmationMirror', 'ID as value, String as label')
                ->fetchAll();
            $data['StatusMirror'] = $db
                ->selectDistinct('StatusMirror', 'ID as value, String as label')
                ->fetchAll();
        }
    }

    // Send it back to the client
    echo json_encode($data);

EDIT: I have also used the DataTables Debug Bookmarklet to debug but after a super-duper long waiting session, I got this URL: http://debug.datatables.net/ilowup

I have also enabled Xdebug in PHP.ini, and got this:

Notice: Undefined index: TestEnvironmentID in C:\xampp\htdocs\myProgram\php\lib\Editor\Field.php on line 578

Call Stack

Time Memory Function Location

1 0.0024 190672 {main}( ) ..\TRRecordManHrsEditor.php:0

2 0.0515 679768 DataTables\Editor->process( ) ..\TRRecordManHrsEditor.php:125

3 0.0642 768824 DataTables\Editor->_update( ) ..\Editor.php:419

4 0.0643 769032 DataTables\Editor->_insert_or_update( ) ..\Editor.php:644

5 0.1769 783528 DataTables\Editor\Field->val( ) ..\Editor.php:1026

6 0.1772 783608 DataTables\Editor\Field->_readProp( ) ..\Field.php:400

This question has an accepted answers - jump to answer

Answers

  • allanallan Posts: 63,523Questions: 1Answers: 10,473 Site admin

    Looking at the code, I think that this line is causing the problem:

    ->leftJoin('RazerConfirmationMirror', 'TestRequestActualSchedule.RazerApproval', '=', 'ConfirmationMirror.ID')
    

    Specifically the conflict between RazerConfirmationMirror and ConfirmationMirror.

    It occurs in both code blocks. I'm not sure which one is causing the specific error you are seeing, but both should probably be fixed.

    Allan

  • pansengtatpansengtat Posts: 66Questions: 26Answers: 1
    edited August 2014

    Specifically the conflict between RazerConfirmationMirror and ConfirmationMirror.

    Made the change. Also debugged via Xdebug on Chrome. No dice.

  • allanallan Posts: 63,523Questions: 1Answers: 10,473 Site admin

    Are you able to e-mail me a dump of the SQL schema and data so I can try to recreate the problem here please? allan@{this domain}.net.

    Allan

  • pansengtatpansengtat Posts: 66Questions: 26Answers: 1

    File sent. I suspect that there is an issue with the variable 'TestEnvironmentID'.

    That variable was not meant to be saved, thus it is set(False) in the server-side fileEditor.php script.

  • allanallan Posts: 63,523Questions: 1Answers: 10,473 Site admin
    Answer ✓

    Great - thanks for this! You are correct, the issue with with the TestEnvironmentID option. Basically what is happening is that because it is included in the left join condition, but not in the fields used in the list, Editor is getting a bit confused!

    In Editor.php you will find the following around line 1030:

    if ( $parentLink === $this->_pkey ) {
        $where = array( $childLink => $id );
    }
    else {
        $field = $this->_find_field( $parentLink, 'db' );
        $where = array( $childLink => $field->val('set', $this->_formData) );
    }
    

    Change it to be:

    if ( $parentLink === $this->_pkey ) {
        $where = array( $childLink => $id );
    }
    else {
        $field = $this->_find_field( $parentLink, 'db' );
        if ( ! $field ) {
            continue;
        }
        $where = array( $childLink => $field->val('set', $this->_formData) );
    }
    

    and that will resolve the error in the short term. Longer term, I'm going to sit down when I get back into the office on Monday and see if I can add some useful error information to help resolve this easier in future.

    Allan

  • allanallan Posts: 63,523Questions: 1Answers: 10,473 Site admin

    One other thing - in the core above I had to change all instances of confirmationmirror to be RazerConfirmationMirror to get it to work.

    Allan

This discussion has been closed.