Moodleform is_submit always returns null.

Moodleform is_submit always returns null.

by Anthony De Vellis -
Number of replies: 0
I am trying to create a custom form but is_submit() always returns null, as does get_data(). I cannot seem to figure out why. In the MoodleQuickForm member of the Moodleform sub-object, the _flagSubmitted field is correctly being set to true in MoodleQuickForm::updateSubmission(), which is called by MoodleForm::_process_submission(). This my approximately my class:


class company_email_resend_form extends moodleform {

    public function __construct($pageURL) {

        global $CFG;

        //var_dump("constructor");

        $this->companyId = iomad::get_my_companyid(context_system::instance());

        $this->urlreturn = $CFG->wwwroot."/blocks/iomad_company_admin/company_email_resend_form.php";

        $this->urlcancel = new moodle_url($CFG->wwwroot."/local/iomad_dashboard/index.php");

        $this->email_template_list = array_keys( local_email::get_templates() );

        array_unshift($this->email_template_list, 'Select Template');

        var_dump(__FUNCTION__ .':'. __LINE__);

        parent::__construct($pageURL);

    }


    public function definition() {

        global $USER, $CFG, $OUTPUT;

        var_dump(__FUNCTION__ .':'. __LINE__);


        // log user info

        $message = "user logged in. \nTime: " . date("Y-m-d h:i:sa") . "\nSessionKey: " . sesskey() . "\nUserid: $USER->id \n";

        $this->logger("%file% %level% %message%", ["level" => "warning", "message" => $message, "file" => self::LOG_FILE_PATH]);


        var_dump("========= ".$this->_form->flagSubmitted. " =========");

        if (!$this->is_submitted()) {

            $this->workflowState = _STEP_1;

            var_dump("no submission");

        } else {

            var_dump("submission exists");

        }


        var_dump("state: ". $this->workflowState);


        switch ($this->workflowState ) {

            case _STEP_1:


                break;

            case _STEP_2:


                break;

            case _STEP_3:

           

                break;

            default:

                //throw new Exception("Error: invalid form state");

        }


        //$this->_resetForm();

        $this->_add_form_page_elements();

        echo $OUTPUT->header();

        parent::display();

        echo $OUTPUT->footer();

    }

    private function _add_form_page_elements() {

        // display current workflow page -- this is a dummy method that only adds action buttons for now

         /* code omitted for brevity */ 

        }

    }

}


// iomad checks

/* code omitted for brevity */ 


// Set up PAGE

/* code omitted for brevity */ 


//Instantiate simplehtml_form

$mform = new company_email_resend_form( $pageURL );


//Form processing and displaying is done here

if ( $mform->is_cancelled() ) {

    //Handle form cancel operation, if cancel button is present on form

    var_dump("cancelled");

    die;

} else if ( $mform->is_submitted() ) {

    //In this case you process validated data. $mform->get_data() returns data posted in form.

    var_dump("got data");

} else {

    // this branch is executed if the form is submitted but the data doesn't validate and the form should be redisplayed

    // or on the first display of the form.

    var_dump("default");

}


I do have a possible fix, which I reported in MDL 64929 before being advised that this probably isn't a bug. I subclassed Moodleform to override _process_submission() so that the sesskey "trick" (as described in comments) is nested in the _GET conditional as follows:

function _process_submission($method) {

        var_dump(__FUNCTION__ .':'. __LINE__);

        $submission = array();

        if (!empty($this->_ajaxformdata)) {

            $submission = $this->_ajaxformdata;

        } else if ($method == 'post') {

            if (!empty($_POST)) {

                $submission = $_POST;

                var_dump("post is populated");

            }

        } else {

            $submission = $_GET;

            merge_query_params($submission, $_POST); // Emulate handling of parameters in xxxx_param().


            // following trick is needed to enable proper sesskey checks when using GET forms

            // the _qf__.$this->_formname serves as a marker that form was actually submitted

            if (array_key_exists('_qf__'.$this->_formname, $submission) and $submission['_qf__'.$this->_formname] == 1) {

                if (!confirm_sesskey()) {

                    print_error('invalidsesskey');

                }

                $files = $_FILES;

            } else {

                $submission = array();

                $files = array();

            }

        }


        $this->detectMissingSetType();

        $this->_form->updateSubmission($submission, $files);

    }

This is what the same function looks like in Moodleform:

function _process_submission($method) {

        var_dump(__FUNCTION__ .':'. __LINE__);

        $submission = array();

        if (!empty($this->_ajaxformdata)) {

            $submission = $this->_ajaxformdata;

        } else if ($method == 'post') {

            if (!empty($_POST)) {

                $submission = $_POST;

                var_dump("post is populated");

            }

        } else {

            $submission = $_GET;

            merge_query_params($submission, $_POST); // Emulate handling of parameters in xxxx_param();

        }

// following trick is needed to enable proper sesskey checks when using GET forms

            // the _qf__.$this->_formname serves as a marker that form was actually submitted

            if (array_key_exists('_qf__'.$this->_formname, $submission) and $submission['_qf__'.$this->_formname] == 1) {

                if (!confirm_sesskey()) {

                    print_error('invalidsesskey');

                }

                $files = $_FILES;

            } else {

                $submission = array();

                $files = array();

            }



        $this->detectMissingSetType();

        $this->_form->updateSubmission($submission, $files);

    }


As you can see, the comment says the sesskey 'trick' is for $method == _GET, so I figured it was probably intended to be in the branch of the preceding conditional that handles get. This does indeed fix it, however I am not sure if this actually is a bug or I am doing something wrong. Again you can see MDL 64929 where I tried to report it as a bug, but I was advised this is not a bug and to post here instead. Even though _process_submission should be using _POST in my case, it still sets $submission and $files to empty arrays when the sesskey trick (which seems designed for get method) fails.

Average of ratings: -