phpcodeigniter

CI4: Passing variable to custom validation rule comes through as string not int


I'm trying to rewrite a page from CI3 to CI4.  In CI3, the validation rule took a parameter from the controller. But now that I've rewritten the code, that parameter (projectid) is coming through as the text 'projectid'.  How do I pass a variable from the controller to a custom validation rule in CI4?

in app\Config\Validation.php:

    public array $manageProjectInfo = array (
        'fldPublish' => array (
            'label' => 'Make project public',
            'rules' => 'trim|check_publish_datasets[projectid]'
        )
    );

The following is writing pid: projectid into the logs:

   // check that there are no unpublished datasets if unpublishing project
    public function check_publish_datasets($fldPublish, $pid) { 
        $valid = TRUE;
        $project_model = model('Project_model');
        if (!$fldPublish) {
            log_message('debug','pid: '.$pid);
            $nDatasets = $project_model->get_projectdataavail($pid,$published=TRUE);

            if (count($nDatasets) > 0) {
                $valid = FALSE;
                $error = "This project cannot be unpublished because it contains published datasets.";
            }
        }   
        return $valid;
    }

in app\Controllers\Manage\Project.php

    public function info($projectid = -1) {
            $basics['pagetitle'] = "Manage Project Information";
            if ($this->request->getPost()) {
                $project['fldPublish'] = $this->request->getPost('fldPublish');
            }
            //Define form attributes
            $data['formattribs'] = array(
                'class' => 'basicForm',
                'id' => 'manage-project-info-form'
            );
            //Create array of input options, setting default values to either what they were in the database or what was entered in post data for form repopulation on error
            $data['fldPublish_publish'] = array(
                'name' => 'fldPublish',
                'id' => 'fldPublish',
                'type' => 'radio',
                'value' => '1',
                'checked' => ($project['fldPublish'] == "1" ? TRUE : FALSE)
            );
            $data['fldPublish_notpublish'] = array(
                'name' => 'fldPublish',
                'id' => 'fldPublish',
                'type' => 'radio',
                'value' => '0',
                'checked' => ($project['fldPublish'] == "0" ? TRUE : FALSE)
            );
            //Check if form validation has already been run and passed   
            //Form validation rules set in form_validation config file
            if (!$this->request->is('post') || !$this->validateData($this->request->getPost(), 'manageProjectInfo')) {
                $this->common->render_page($basics, 'manage/project/info', $data);
            }
            //If successful form validation...
            else {
                //Collect post data for insert
                $project = array(
                    'fldPublish' => $this->request->getPost('fldPublish')
                );
                $validData = $this->validator->getValidated();
                foreach ($validData as $key=>$valid) {
                    $project[$key] = $valid;
                }
                //Check flag-type columns to see if they're set to one, if they aren't set values to zero.
                if ($project['fldPublish'] != 1)
                    $project['fldPublish'] = 0;
                //Convert null dates
                $builder = $this->db->table('tblProject');
                $builder->where('pkProjectID', $projectid);
                $updateattempt = $builder->update($info_changes);
                if ($updateattempt) {
                    //update the projectUpdated date and log a tblProjectChanges record
                    $this->project_model->logProjectUpdated($projectid, "project", "info");
                    $this->session->setFlashdata('successmessage', "Your changes were successfully submitted");
                    return redirect()->to('manage/project/' . $projectid . '/info');
                } else {
                    $data['errormessage'] = "There was a problem writing your changes to the database. Please try again";
                    //Load the views with render_pages, passing either name of main view to load or array of main pages to load
                    $this->common->render_page($basics, 'manage/project/info', $data);
                }
            }
        }
    }

In the CI4 documentation, there is an example sending one of the other form inputs as a parameter (https://codeigniter.com/user_guide/libraries/validation.html#setting-multiple-rules). So I tried making a hidden input and passing that, but it also just printed the text name of the variable into the logs.


Solution

  • I ended up having to do two things to fix this. First, I found in the CI4 documentation that,

    "If your method needs to work with parameters, the function will need a minimum of three parameters:

    1. the value to validate ($value)
    2. the parameter string ($params)
    3. an array with all of the data that was submitted the form ($data)
    4. (optional) a custom error string (&$error), just as described above.

    https://codeigniter.com/user_guide/libraries/validation.html#setting-multiple-rules

    However, even passing my variable through the $params parameter, it was still coming through as the text name of the variable.

    So, I added a hidden input to my form with the variable I needed and accessed it through the $data parameter.

        public function check_publish_datasets($fldPublish, string $args, array $data, ?string &$error = null):bool { 
    
            $pid=$data['projectID'];
            $valid = TRUE;
            $project_model = model('Project_model');
            if (!$fldPublish) {
    
                $nDatasets = $project_model->get_projectdataavail($pid,$published=TRUE);
                if (count($nDatasets) > 0) {
                    $valid = FALSE;
                    $error = "This project cannot be unpublished because it contains published datasets.";
                }
            }    
            return $valid;
        }