Skip to content

PHP 8.0 changes to count() seem to break questionnaire_check_page_breaks() funtion (Version 3.11.2 (Build - 2023030700)) #473

@NJahreis

Description

@NJahreis

Hi all,

the changes of the behaviour of the count function in PHP 8 seem to cause issues in the questionnaire_check_page_breaks() function in some cases.

I get the following error in my case thenever editing any existing instance of mod_questionnaire with PHP8:

Got error 'PHP message: PHP Warning: Undefined array key 73 in MYPATH/mod/questionnaire/locallib.php on line 756
PHP message: PHP Warning: Trying to access array offset on value of type null in MYPATH/mod/questionnaire/locallib.php on line 758
PHP message: PHP Warning: Trying to access array offset on value of type null in MYPATH/mod/questionnaire/locallib.php on line 785
PHP message: PHP Warning: Undefined array key 72 in MYPATH/mod/questionnaire/locallib.php on line 788
PHP message: PHP Warning: Trying to access array offset on value of type null in MYPATH/mod/questionnaire/locallib.php on line 788
PHP message: PHP Warning: Undefined array key 72 in MYPATH/mod/questionnaire/locallib.php on line 789
PHP message: PHP Warning: Trying to access array offset on value of type null in MYPATH/mod/questionnaire/locallib.php on line 789
PHP message: PHP Warning: Trying to access array offset on value of type null in MYPATH/mod/questionnaire/locallib.php on line 791
PHP message: Default exception handler: Fehler: count(): Argument #1 ($value) must be of type Countable|array, null given Debug: \nError code: generalexceptionmessage\n* line 791 of /mod/questionnaire/locallib.php: TypeError thrown\n* line 288 of /mod/questionnaire/questions.php: call to questionnaire_check_page_breaks()\n', referer: https://MYMOODLE/mod/questionnaire/questions.php

The code in question can be found here:

// Add pagebreak between question child and not dependent question that follows.
if ($qu['type_id'] != QUESPAGEBREAK) {
$j = $i - 1;
if ($j != 0) {
$prevtypeid = $positions[$j]['type_id'];
$prevdependencies = $positions[$j]['dependencies'];
$outerdependencies = count($qu['dependencies']) >= count($prevdependencies) ?
$qu['dependencies'] : $prevdependencies;
$innerdependencies = count($qu['dependencies']) < count($prevdependencies) ?
$qu['dependencies'] : $prevdependencies;
foreach ($outerdependencies as $okey => $outerdependency) {
foreach ($innerdependencies as $ikey => $innerdependency) {
if ($outerdependency->dependquestionid === $innerdependency->dependquestionid &&
$outerdependency->dependchoiceid === $innerdependency->dependchoiceid &&
$outerdependency->dependlogic === $innerdependency->dependlogic) {
unset($outerdependencies[$okey]);
unset($innerdependencies[$ikey]);
}
}
}
$diffdependencies = count($outerdependencies) + count($innerdependencies);

For testing I changed it so it emulates the old behaviour of the count() function:

        // Add pagebreak between question child and not dependent question that follows.
        if ($qu['type_id'] != QUESPAGEBREAK) {
            $j = $i - 1;
            if ($j != 0) {
                $prevtypeid = $positions[$j]['type_id'];
                $prevdependencies = $positions[$j]['dependencies'];


                $qudepcount = $qu['dependencies'] == null ? 0 : count($qu['dependencies']);
                $prevdepcount = $prevdependencies == null ? 0 : count($prevdependencies);


                $outerdependencies =  $qudepcount >= $prevdepcount ?
                    $qu['dependencies'] : $prevdependencies;
                $innerdependencies =  $qudepcount < $prevdepcount ?
                    $qu['dependencies'] : $prevdependencies;

                foreach ($outerdependencies as $okey => $outerdependency) {
                    foreach ($innerdependencies as $ikey => $innerdependency) {
                        if ($outerdependency->dependquestionid === $innerdependency->dependquestionid &&
                            $outerdependency->dependchoiceid === $innerdependency->dependchoiceid &&
                            $outerdependency->dependlogic === $innerdependency->dependlogic) {
                            unset($outerdependencies[$okey]);
                            unset($innerdependencies[$ikey]);
                        }
                    }
                }


                $outerdepcount = $outerdependencies == null ? 0 : count($outerdependencies);
                $innerdepcount = $innerdependencies == null ? 0 : count($innerdependencies);

                $diffdependencies = $outerdepcount + $innerdepcount;

This seems to resolve the issue but is not a very pretty solution to the problem and I am not sure if it acually fixes the underlying problem or just works around it.

Edit: I have just noticed that the function code has changed in the MOODLE_400_STABLE branch. Maybe the changes just need to be applied to the MOODLE_311_STABLE branch to resolve the issue?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions