Reputation: 63
I am using Moodle version 3.8.4+ and PHP version 7.2.33 . Today I noticed a strange issue when I was trying to send a message to students, the message was:
Coding error detected, it must be fixed by a programmer: Url parameters values can not be arrays! More information about this error
I purge all caches as the suggestion was on "more information" section but it did not work. I run the same Moodle version and PHP version on non production environment with the debugging mode and then I got this error message:
Coding error detected, it must be fixed by a programmer: Url parameters values can not be arrays! More information about this error Debug info: Error code: codingerror Stack trace:
line 405 of /lib/weblib.php: coding_exception thrown
line 460 of /lib/weblib.php: call to moodle_url->params()
line 49 of /mod/reservation/messageselect.php: call to moodle_url->param()
Output buffer:
Invalid array parameter detected in required_param(): messagebody
line 655 of /lib/moodlelib.php: call to debugging()
line 30 of /mod/reservation/messageselect.php: call to optional_param()
The messageselect.php file is this but I am not able to see any issues here:
require_once('../../config.php');
require_once($CFG->dirroot.'/message/lib.php');
$id = required_param('id', PARAM_INT);
$messagebody = optional_param('messagebody', '', PARAM_CLEANHTML);
$send = optional_param('send', '', PARAM_BOOL);
$preview = optional_param('preview', '', PARAM_BOOL);
$edit = optional_param('edit', '', PARAM_BOOL);
$returnto = optional_param('returnto', new moodle_url('/mod/reservation/view.php', array('id' => $id)), PARAM_LOCALURL);
$format = optional_param('format', FORMAT_MOODLE, PARAM_INT);
$deluser = optional_param('deluser', 0, PARAM_INT);
if (isset($id)) {
if (! $cm = get_coursemodule_from_id('reservation', $id)) {
error('Course Module ID was incorrect');
}
if (! $course = $DB->get_record('course', array('id' => $cm->course))) {
error('Course is misconfigured');
}
}
$url = new moodle_url('/mod/reservation/messageselect.php', array('id' => $id));
if ($messagebody !== '') {
$url->param('messagebody', $messagebody);
}
if ($send !== '') {
$url->param('send', $send);
}
if ($preview !== '') {
$url->param('preview', $preview);
}
if ($edit !== '') {
$url->param('edit', $edit);
}
if ($returnto !== '') {
$url->param('returnto', $returnto);
}
if ($format !== FORMAT_MOODLE) {
$url->param('format', $format);
}
if ($deluser !== 0) {
$url->param('deluser', $deluser);
}
$modulecontext = context_module::instance($cm->id);
$PAGE->set_url($url);
$PAGE->set_context($modulecontext);
require_login($course->id, false, $cm);
$coursecontext = context_course::instance($course->id);
$systemcontext = context_system::instance();
require_capability('moodle/course:bulkmessaging', $coursecontext);
if (empty($SESSION->reservation_messageto)) {
$SESSION->reservation_messageto = array();
}
if (!array_key_exists($id, $SESSION->reservation_messageto)) {
$SESSION->reservation_messageto[$id] = array();
}
if ($deluser) {
$idinmessageto = array_key_exists($id, $SESSION->reservation_messageto);
if ($idinmessageto && array_key_exists($deluser, $SESSION->reservation_messageto[$id])) {
unset($SESSION->reservation_messageto[$id][$deluser]);
}
}
if (empty($SESSION->reservation_messageselect[$id]) || $messagebody) {
$SESSION->reservation_messageselect[$id] = array('messagebody' => $messagebody);
}
$messagebody = $SESSION->reservation_messageselect[$id]['messagebody'];
$count = 0;
if ($data = data_submitted()) {
require_sesskey();
foreach ($data as $k => $v) {
if (preg_match('/^(user|teacher)(\d+)$/', $k, $m)) {
if (!array_key_exists($m[2], $SESSION->reservation_messageto[$id])) {
$returnfields = 'id,firstname,lastname,idnumber,email,mailformat,lastaccess, lang, maildisplay';
if ($user = $DB->get_record_select('user', "id = ?", array($m[2]), $returnfields)) {
$SESSION->reservation_messageto[$id][$m[2]] = $user;
$count++;
}
}
}
}
}
$strtitle = get_string('message', 'reservation');
$PAGE->navbar->add($strtitle);
$PAGE->set_title($strtitle);
$PAGE->set_heading($strtitle);
echo $OUTPUT->header();
// If messaging is disabled on site, we can still allow users with capabilities to send emails instead.
if (empty($CFG->messaging)) {
echo $OUTPUT->notification(get_string('messagingdisabled', 'message'));
}
if ($count) {
if ($count == 1) {
$heading = get_string('addedrecip', 'moodle', $count);
} else {
$heading = get_string('addedrecips', 'moodle', $count);
}
echo $OUTPUT->heading($heading);
}
if (!empty($messagebody) && !$edit && !$deluser && ($preview || $send)) {
require_sesskey();
if (count($SESSION->reservation_messageto[$id])) {
if (!empty($preview)) {
echo '<form method="post" action="messageselect.php" style="margin: 0 20px;">
<input type="hidden" name="returnto" value="'.s($returnto).'" />
<input type="hidden" name="id" value="'.$id.'" />
<input type="hidden" name="format" value="'.$format.'" />
<input type="hidden" name="sesskey" value="' . sesskey() . '" />
';
echo "<h3>".get_string('previewhtml')."</h3>";
echo "<div class=\"messagepreview\">\n".format_text($messagebody, $format)."\n</div>\n";
echo '<p align="center"><input type="submit" name="send" value="'.get_string('sendmessage', 'message').'" />'."\n";
echo '<input type="submit" name="edit" value="'.get_string('update').'" /></p>';
echo "\n</form>";
} else if (!empty($send)) {
$fails = array();
foreach ($SESSION->reservation_messageto[$id] as $user) {
if (!message_post_message($USER, $user, $messagebody, $format)) {
$user->fullname = fullname($user);
$fails[] = get_string('messagedselecteduserfailed', 'moodle', $user);
};
}
if (empty($fails)) {
echo $OUTPUT->heading(get_string('messagedselectedusers'));
unset($SESSION->reservation_messageto[$id]);
unset($SESSION->reservation_messageselect[$id]);
} else {
echo $OUTPUT->heading(get_string('messagedselectedcountusersfailed', 'moodle', count($fails)));
echo '<ul>';
foreach ($fails as $f) {
echo '<li>', $f, '</li>';
}
echo '</ul>';
}
echo '<p align="center"><a href="view.php?id='.$id.'">'.get_string('backtoparticipants').'</a></p>';
}
echo $OUTPUT->footer();
exit;
} else {
echo $OUTPUT->notification(get_string('nousersyet'));
}
}
echo '<p align="center"><a href="'.$returnto.'">'.get_string("keepsearching").'</a>'.
((count($SESSION->reservation_messageto[$id])) ? ', '.get_string('usemessageform') : '').'</p>';
if ((!empty($send) || !empty($preview) || !empty($edit)) && (empty($messagebody))) {
echo $OUTPUT->notification(get_string('allfieldsrequired'));
}
if (count($SESSION->reservation_messageto[$id])) {
require_sesskey();
require("message.html");
}
$PAGE->requires->yui_module('moodle-core-formchangechecker',
'M.core_formchangechecker.init',
array(array(
'formid' => 'theform'
))
);
$PAGE->requires->string_for_js('changesmadereallygoaway', 'moodle');
echo $OUTPUT->footer();
```php
Upvotes: 2
Views: 1086
Reputation: 3707
It looks like the massagebody
param in the request that initiates this process is using array syntax, like ?messagebody[]=foo
instead of ?messagebody=foo
, so the error is in whatever page the request originated from. You can either try to figure out why that is and change it, or make a change to this messageselect.php file to flatten the parameter. To do that you would change this:
<?php
if ($messagebody !== '') {
$url->param('messagebody', $messagebody);
}
to this:
<?php
if ($messagebody !== '') {
if(is_array($messagebody))
{
$messagebody = array_shift($messagebody);
}
$url->param('messagebody', $messagebody);
}
However be aware that if the page is sending this parameter as an array, it is quite likely that others will be sent that way as well. Usually you would send parameters using array syntax so that multiple records can be processed in one request, so that messagebody[1] would correlate to format[1], messagebody[2] would correlate to format[2], and so on. The code in messageselect.php is clearly not expecting this. I would be interested to find out what the story is for the page that sends requests here.
Upvotes: 1