function pieform_element_userlist_rule_required(Pieform $form, $value, $element) { if (is_array($value) && count($value)) { return null; } return $form->i18n('rule', 'required', 'required', $element); }
/** * Returns whether the given field matches the specified regex. * * @param Pieform $form The form the rule is being applied to * @param string $value The value to check * @param array $element The element to check * @param string $regex The regular expression to use for the check * @return string The error message, if there is something wrong with * the value. */ function pieform_rule_regex(Pieform $form, $value, $element, $regex) { /*{{{*/ if (!preg_match($regex, $value)) { return $form->i18n('rule', 'regex', 'regex', $element); } }
/** * Checks whether the given value is shorter than the allowed length. * * @param PieForm $form The form the rule is being applied to * @param string $value The value to check * @param array $element The element to check * @param int $minlength The length to check for * @return string The error message, if the value is invalid. */ function pieform_rule_minlength(Pieform $form, $value, $element, $minlength) { /*{{{*/ if (strlen($value) < $minlength) { return sprintf($form->i18n('rule', 'minlength', 'minlength', $element), $minlength); } }
/** * Checks whether the given value is at most a certain size. * * @param Pieform $form The form the rule is being applied to * @param string $value The value to check * @param array $element The element to check * @param int $maxvalue The value to check for * @return string The error message, if the value is invalid. */ function pieform_rule_maxvalue(Pieform $form, $value, $element, $maxvalue) { /*{{{*/ if ($value !== '' && doubleval($value) > $maxvalue) { return sprintf($form->i18n('rule', 'maxvalue', 'maxvalue', $element), $maxvalue); } }
/** * Checks whether the field has been specified. * * @param Pieform $form The form the rule is being applied to * @param string $value The value of the field * @param array $element The element to check * @param string $check Whether to check the element * @return string The error message, if the value is invalid. */ function pieform_rule_required(Pieform $form, $value, $element, $check) { /*{{{*/ if ($check && ($value == '' || $value == array())) { return $form->i18n('rule', 'required', 'required', $element); } }
/** * Returns whether the given field is an integer * * @param Pieform $form The form the rule is being applied to * @param string $value The value to check * @param array $element The element to check * @return string The error message, if there is something wrong with * the address. */ function pieform_rule_integer(Pieform $form, $value, $element) { /*{{{*/ if (!is_numeric($value) || floor($value) != $value) { return $form->i18n('rule', 'integer', 'integer', $element); } }
/** * Returns whether the given field is a valid e-mail address. * * Currently, the check is [anything]@[anything]. Someone is welcome to write * something better, this was made just for testing. * * @param Pieform $form The form the rule is being applied to * @param string $value The e-mail address to check * @param array $element The element to check * @return string The error message, if there is something wrong with * the address. */ function pieform_rule_email(Pieform $form, $value, $element) { /*{{{*/ if (!preg_match('/^[A-Za-z0-9\\._%-]+@(?:[A-Za-z0-9-]+\\.)+[a-z]{2,4}$/', $value)) { return $form->i18n('rule', 'email', 'email', $element); } }
/** * Checks whether the given value is at least a certain size. * * @param Pieform $form The form the rule is being applied to * @param string $value The value to check * @param array $element The element to check * @param int $maxlength The value to check for * @return string The error message, if the value is invalid. */ function pieform_rule_minvalue(Pieform $form, $value, $element, $minvalue) { /*{{{*/ if ($value != '' && intval($value) < $minvalue) { return sprintf($form->i18n('rule', 'minvalue', 'minvalue', $element), $minvalue); } }
/** * Provides a duration chooser, with a text box for a number and a * select box to choose the units, in days, weeks, months, years, or 'no end date'. * * @param Pieform $form The form to render the element for * @param array $element The element to render * @return string The HTML for the element */ function pieform_element_expiry(Pieform $form, $element) { /*{{{*/ $formname = $form->get_name(); $result = ''; $name = $element['name']; if (!isset($element['defaultvalue'])) { $element['defaultvalue'] = null; } $global = $form->get_property('method') == 'get' ? $_GET : $_POST; // Get the value of the element for rendering. if (isset($element['value'])) { $seconds = $element['value']; $values = pieform_element_expiry_get_expiry_from_seconds($element['value']); } else { if (isset($global[$element['name']]) && isset($global[$element['name'] . '_units'])) { $values = array('number' => $global[$element['name']], 'units' => $global[$element['name'] . '_units']); $seconds = $values['number'] * pieform_element_expiry_seconds_in($values['units']); } else { if (isset($element['defaultvalue'])) { $seconds = $element['defaultvalue']; $values = pieform_element_expiry_get_expiry_from_seconds($seconds); } else { $values = array('number' => '', 'units' => 'noenddate'); $seconds = null; } } } // @todo probably create with an actual input element, as tabindex doesn't work here for one thing // Same with the select. And do the events using mochikit signal instead of dom events $numberinput = '<input'; $numberinput .= $values['units'] == 'noenddate' && empty($element['rules']['required']) ? ' disabled="disabled"' : ''; $numberinput .= ' type="text" size="4" name="' . $name . '"'; $numberinput .= ' id="' . $formname . '_' . $name . '" value="' . $values['number'] . '" tabindex="' . $element['tabindex'] . '"'; $numberinput .= (isset($element['error']) ? ' class="error"' : '') . ">\n"; $uselect = '<select onchange="' . $name . '_change()" '; $uselect .= 'name="' . $name . '_units" id="' . $formname . '_' . $name . '_units"' . ' tabindex="' . $element['tabindex'] . "\">\n"; foreach (pieform_element_expire_get_expiry_units() as $u) { // Don't allow 'no end date' if the element is required if ($u == 'noenddate' && !empty($element['rules']['required'])) { continue; } $uselect .= "\t<option value=\"{$u}\"" . ($values['units'] == $u ? ' selected="selected"' : '') . '>' . $form->i18n('element', 'expiry', $u, $element) . "</option>\n"; } $uselect .= "</select>\n"; // Make sure the input is disabled if "no end date" is selected $script = <<<EOJS <script type="text/javascript" language="javascript"> function {$name}_change() { if (\$('{$formname}_{$name}_units').value == 'noenddate') { \$('{$formname}_{$name}').disabled = true; } else { \$('{$formname}_{$name}').disabled = false; } } </script> EOJS; return $numberinput . $uselect . $script; }
/** * Checks whether the given element's value is less than another element. * * Typically useful for dates. * * @param Pieform $form The form the rule is being applied to * @param string $value The value to check * @param array $element The element to check * @param string $otherelement The other element to check for * @return string The error message, if the value is invalid. */ function pieform_rule_before(Pieform $form, $value, $element, $otherelement) { /*{{{*/ $otherelement = $form->get_element($otherelement); $othervalue = $form->get_value($otherelement); if ($value != '' && $othervalue != '' && intval($value) > intval($othervalue)) { return sprintf($form->i18n('rule', 'before', 'before', $element), $otherelement['title']); } }
/** * Makes sure that the submitted value is specified in the 'options' index of * the element. This prevents malicious people from doing things like * submitting values that aren't in a select box. * * @param Pieform $form The form the rule is being applied to * @param string $field The field to check * @param string $element The element being checked * @return string The error message, if the value is invalid. */ function pieform_rule_validateoptions(Pieform $form, $field, $element) { /*{{{*/ // Get the value into an array as a key if it's a scalar, since // the actual check involves array keys $field = (array) $field; $allowedvalues = array_keys($element['options']); foreach ($field as $key) { if (!in_array($key, $allowedvalues)) { return sprintf($form->i18n('rule', 'validateoptions', 'validateoptions', $element), $key); } } }
/** * Multiple file elements * * @param array $element The element to render * @param Pieform $form The form to render the element for * @return string The HTML for the element */ function pieform_element_files(Pieform $form, $element) { $smarty = smarty_core(); $smarty->left_delimiter = '{{'; $smarty->right_delimiter = '}}'; $value = $form->get_value($element); if (!is_array($value) && isset($element['defaultvalue']) && is_array($element['defaultvalue'])) { $value = $element['defaultvalue']; } $smarty->assign('name', $form->get_name() . '_' . $element['name']); $smarty->assign('title', $element['title']); $smarty->assign('addattachment', $form->i18n('element', 'files', 'addattachment', $element)); if (isset($element['maxfilesize']) && is_int($element['maxfilesize'])) { $smarty->assign('maxfilesize', $element['maxfilesize']); } return $smarty->fetch('form/files.tpl'); }
/** * Provides a javascript color selector for inputting a hex color value. * * General documentation about the JavaScript Color Picker (Chooser) is available at * http://jscolor.com/ * * @param Pieform $form The form to render the element for * @param array $element The element to render * @return string The HTML for the element */ function pieform_element_color(Pieform $form, $element) { $result = ''; $name = Pieform::hsc($element['name']); $baseid = Pieform::hsc($form->get_name() . '_' . $element['name']); $value = Pieform::hsc($element['defaultvalue']); $transparent = !empty($element['options']['transparent']) && $element['options']['transparent'] == true; // Transparency optional control if ($transparent) { $optional = <<<EOF <script type="application/javascript"> var {$baseid}_oldval = ''; function {$baseid}_toggle(x) { if ( x.checked ) { {$baseid}_oldval = \$('{$baseid}').value; \$('{$baseid}').value = ''; \$('{$baseid}').disabled = true; } else { \$('{$baseid}').value = {$baseid}_oldval; \$('{$baseid}').disabled = false; } } </script> EOF; $title = ''; if (!empty($element['title'])) { $title = '<span class="accessible-hidden sr-only">' . $element['title'] . ':</span>'; } $optional .= ' <input type="checkbox" ' . (isset($element['defaultvalue']) && $element['defaultvalue'] == 'transparent' ? 'checked="checked" ' : '') . 'name="' . $name . '_optional" id="' . $baseid . '_optional" onchange="' . $baseid . '_toggle(this)" ' . 'tabindex="' . Pieform::hsc($element['tabindex']) . '">'; $optional .= ' <label for="' . $baseid . '_optional">' . $title . $form->i18n('element', 'color', 'transparent', $element) . '</label> '; $result .= $optional; } // Color Picker (Chooser) $result .= '<input type="text" name="' . $name . '_color" id="' . $baseid . '"' . ($transparent && (!isset($element['defaultvalue']) || $element['defaultvalue'] == 'transparent') ? ' disabled="disabled"' : '') . ($transparent ? ' class="color {hash:true,required:false}"' : ' class="color {hash:true}"') . ' value="' . ($value == 'transparent' ? '' : $value) . '">'; return $result; }
/** * @todo add note: because the form select thing will eventually enforce * that the result for $values['institution'] was in the original lot, * and because that only allows authmethods that use 'internal' auth, we * can guarantee that the auth method is internal */ function auth_register_validate(Pieform $form, $values) { global $SESSION; $registerterms = get_config('registerterms'); $spamtrap = new_spam_trap(array(array('type' => 'name', 'value' => $values['firstname']), array('type' => 'name', 'value' => $values['lastname']), array('type' => 'email', 'value' => $values['email']))); if ($form->spam_error() || $spamtrap->is_spam()) { $msg = get_string('formerror'); $emailcontact = get_config('emailcontact'); if (!empty($emailcontact)) { $msg .= ' ' . get_string('formerroremail', 'mahara', $emailcontact, $emailcontact); } $form->set_error(null, $msg); return; } $institution = $values['institution']; safe_require('auth', 'internal'); // First name and last name must contain at least one non whitespace // character, so that there's something to read if (!$form->get_error('firstname') && !preg_match('/\\S/', $values['firstname'])) { $form->set_error('firstname', $form->i18n('required')); } if (!$form->get_error('lastname') && !preg_match('/\\S/', $values['lastname'])) { $form->set_error('lastname', $form->i18n('required')); } // The e-mail address cannot already be in the system if (!$form->get_error('email') && (record_exists('usr', 'email', $values['email']) || record_exists('artefact_internal_profile_email', 'email', $values['email']))) { $form->set_error('email', get_string('emailalreadytaken', 'auth.internal')); } // If the user hasn't agreed to the terms and conditions, don't bother if ($registerterms && $values['tandc'] != 'yes') { $form->set_error('tandc', get_string('youmaynotregisterwithouttandc', 'auth.internal'), false); } $institution = get_record_sql(' SELECT i.name, i.maxuseraccounts, i.registerallowed, COUNT(u.id) AS count FROM {institution} i LEFT OUTER JOIN {usr_institution} ui ON ui.institution = i.name LEFT OUTER JOIN {usr} u ON (ui.usr = u.id AND u.deleted = 0) WHERE i.name = ? GROUP BY i.name, i.maxuseraccounts, i.registerallowed', array($institution)); if (!empty($institution->maxuseraccounts) && $institution->count >= $institution->maxuseraccounts) { // the institution is full so we need to alert the admins of the institution to this fact so // they can either increase the maxusers or turn off the public registration. require_once get_config('docroot') . 'lib/institution.php'; $institutionobj = new Institution($institution->name); $institutionobj->send_admin_institution_is_full_message(); $form->set_error('institution', get_string('institutionfull')); } if (!$institution || !$institution->registerallowed) { $form->set_error('institution', get_string('registrationnotallowed')); } }
/** * Gets the value of the expiry element and converts it to a time in seconds. * * @param Pieform $form The form the element is attached to * @param array $element The element to get the value for * @return int The number of seconds until expiry */ function pieform_element_bytes_get_value(Pieform $form, $element) { /*{{{*/ $name = $element['name']; $global = $form->get_property('method') == 'get' ? $_GET : $_POST; $unit = $global[$name . '_units']; $allunits = pieform_element_bytes_get_bytes_units(); $number = $global[$name]; if (!is_numeric($number)) { $form->set_error($name, $form->i18n('element', 'bytes', 'invalidvalue', $element)); } if (!in_array($unit, $allunits) || $number < 0) { return null; } return $number * pieform_element_bytes_in($unit); }
/** * The CSV file is parsed here so validation errors can be returned to the * user. The data from a successful parsing is stored in the <var>$CVSDATA</var> * array so it can be accessed by the submit function * * @param Pieform $form The form to validate * @param array $values The values submitted */ function uploadcsv_validate(Pieform $form, $values) { global $CSVDATA, $ALLOWEDKEYS, $MANDATORYFIELDS, $FORMAT, $USER, $UPDATES, $MEMBERS, $GROUPS; // Don't even start attempting to parse if there are previous errors if ($form->has_errors()) { return; } if ($values['file']['size'] == 0) { $form->set_error('file', $form->i18n('rule', 'required', 'required', array())); return; } $institution = $values['institution']; if (!$USER->can_edit_institution($institution)) { $form->set_error('institution', get_string('notadminforinstitution', 'admin')); return; } require_once 'csvfile.php'; $csvgroups = new CsvFile($values['file']['tmp_name']); $csvgroups->set('allowedkeys', $ALLOWEDKEYS); $csvgroups->set('mandatoryfields', $MANDATORYFIELDS); $csvdata = $csvgroups->get_data(); if (!empty($csvdata->errors['file'])) { $form->set_error('file', $csvdata->errors['file']); return; } $csverrors = new CSVErrors(); $formatkeylookup = array_flip($csvdata->format); $shortnames = array(); $hadadmin = array(); $num_lines = count($csvdata->data); foreach ($csvdata->data as $key => $line) { // If headers exists, increment i = key + 2 for actual line number $i = $csvgroups->get('headerExists') ? $key + 2 : $key + 1; // In adding 5000 groups, this part was approx 8% of the wall time. if (!($key % 25)) { set_progress_info('uploadgroupmemberscsv', $key, $num_lines * 10, get_string('validating', 'admin')); } // Trim non-breaking spaces -- they get left in place by File_CSV foreach ($line as &$field) { $field = preg_replace('/^(\\s|\\xc2\\xa0)*(.*?)(\\s|\\xc2\\xa0)*$/', '$2', $field); } $shortname = $line[$formatkeylookup['shortname']]; $username = $line[$formatkeylookup['username']]; $role = $line[$formatkeylookup['role']]; $gid = get_field('group', 'id', 'shortname', $shortname, 'institution', $institution); if (!$gid) { $csverrors->add($i, get_string('uploadgroupmemberscsverrornosuchshortname', 'admin', $i, $shortname, $institution)); continue; } $uid = get_field_sql('SELECT id FROM {usr} WHERE LOWER(username) = ?', array(strtolower($username))); if (!$uid) { $csverrors->add($i, get_string('uploadgroupmemberscsverrornosuchusername', 'admin', $i, $username)); continue; } if ($institution != 'mahara' && !record_exists('usr_institution', 'usr', $uid, 'institution', $institution)) { $csverrors->add($i, get_string('uploadgroupmemberscsverrorusernotininstitution', 'admin', $i, $username, $institution)); continue; } if (!in_array($role, array_keys(group_get_role_info($gid)))) { $csverrors->add($i, get_string('uploadgroupmemberscsverrorinvalidrole', 'admin', $i, $role)); continue; } if (!isset($MEMBERS[$gid])) { $MEMBERS[$gid] = array(); } if (isset($MEMBERS[$gid][$uid])) { $csverrors->add($i, get_string('uploadgroupmemberscsverrorduplicateusername', 'admin', $i, $shortname, $username)); continue; } $MEMBERS[$gid][$uid] = $role; $GROUPS[$gid] = $shortname; if ($role == 'admin') { $hasadmin[$shortname] = 1; } } foreach ($GROUPS as $shortname) { if (!isset($hasadmin[$shortname])) { $csverrors->add($i, get_string('uploadgroupmemberscsverrornoadminlisted', 'admin', $i, $shortname)); } } if ($errors = $csverrors->process()) { $form->set_error('file', clean_html($errors)); return; } $FORMAT = $csvdata->format; $CSVDATA = $csvdata->data; }
function adduser_validate(Pieform $form, $values) { global $USER, $TRANSPORTER; $authobj = AuthFactory::create($values['authinstance']); $institution = $authobj->institution; // Institutional admins can only set their own institutions' authinstances if (!$USER->get('admin') && !$USER->is_institutional_admin($authobj->institution)) { $form->set_error('authinstance', get_string('notadminforinstitution', 'admin')); return; } $institution = new Institution($authobj->institution); // Don't exceed max user accounts for the institution if ($institution->isFull()) { $institution->send_admin_institution_is_full_message(); $form->set_error('authinstance', get_string('institutionmaxusersexceeded', 'admin')); return; } $username = $values['username']; $firstname = sanitize_firstname($values['firstname']); $lastname = sanitize_lastname($values['lastname']); $email = sanitize_email($values['email']); $password = $values['password']; if ($USER->get('admin') || get_config_plugin('artefact', 'file', 'institutionaloverride')) { $maxquotaenabled = get_config_plugin('artefact', 'file', 'maxquotaenabled'); $maxquota = get_config_plugin('artefact', 'file', 'maxquota'); if ($maxquotaenabled && $values['quota'] > $maxquota) { $form->set_error('quota', get_string('maxquotaexceededform', 'artefact.file', display_size($maxquota))); } } if (method_exists($authobj, 'is_username_valid_admin')) { if (!$authobj->is_username_valid_admin($username)) { $form->set_error('username', get_string('usernameinvalidadminform', 'auth.internal')); } } else { if (method_exists($authobj, 'is_username_valid')) { if (!$authobj->is_username_valid($username)) { $form->set_error('username', get_string('usernameinvalidform', 'auth.internal')); } } } if (!$form->get_error('username') && record_exists_select('usr', 'LOWER(username) = ?', array(strtolower($username)))) { $form->set_error('username', get_string('usernamealreadytaken', 'auth.internal')); } if (method_exists($authobj, 'is_password_valid') && !$authobj->is_password_valid($password)) { $form->set_error('password', get_string('passwordinvalidform', 'auth.' . $authobj->type)); } if (isset($_POST['createmethod']) && $_POST['createmethod'] == 'leap2a') { $form->set_error('firstname', null); $form->set_error('lastname', null); $form->set_error('email', null); if (!$values['leap2afile'] && ($_FILES['leap2afile']['error'] == UPLOAD_ERR_INI_SIZE || $_FILES['leap2afile']['error'] == UPLOAD_ERR_FORM_SIZE)) { $form->reply(PIEFORM_ERR, array('message' => get_string('uploadedfiletoobig'), 'goto' => '/admin/users/add.php')); $form->set_error('leap2afile', get_string('uploadedfiletoobig')); return; } else { if (!$values['leap2afile']) { $form->set_error('leap2afile', $form->i18n('rule', 'required', 'required')); return; } } if ($values['leap2afile']['type'] == 'application/octet-stream') { require_once 'file.php'; $mimetype = file_mime_type($values['leap2afile']['tmp_name']); } else { $mimetype = trim($values['leap2afile']['type'], '"'); } $date = time(); $niceuser = preg_replace('/[^a-zA-Z0-9_-]/', '-', $values['username']); safe_require('import', 'leap'); $fakeimportrecord = (object) array('data' => array('importfile' => $values['leap2afile']['tmp_name'], 'importfilename' => $values['leap2afile']['name'], 'importid' => $niceuser . '-' . $date, 'mimetype' => $mimetype)); $TRANSPORTER = new LocalImporterTransport($fakeimportrecord); try { $TRANSPORTER->extract_file(); PluginImportLeap::validate_transported_data($TRANSPORTER); } catch (Exception $e) { $form->set_error('leap2afile', $e->getMessage()); } } else { if (!$form->get_error('firstname') && empty($firstname)) { $form->set_error('firstname', $form->i18n('rule', 'required', 'required')); } if (!$form->get_error('lastname') && empty($lastname)) { $form->set_error('lastname', $form->i18n('rule', 'required', 'required')); } if (!$form->get_error('email')) { if (!$form->get_error('email') && empty($email)) { $form->set_error('email', get_string('invalidemailaddress', 'artefact.internal')); } if (record_exists('usr', 'email', $email) || record_exists('artefact_internal_profile_email', 'email', $email)) { $form->set_error('email', get_string('emailalreadytaken', 'auth.internal')); } } } }
function adduser_validate(Pieform $form, $values) { global $USER, $TRANSPORTER; $authobj = AuthFactory::create($values['authinstance']); $institution = $authobj->institution; // Institutional admins can only set their own institutions' authinstances if (!$USER->get('admin') && !$USER->is_institutional_admin($authobj->institution)) { $form->set_error('authinstance', get_string('notadminforinstitution', 'admin')); return; } $institution = new Institution($authobj->institution); // Don't exceed max user accounts for the institution if ($institution->isFull()) { $form->set_error('authinstance', get_string('institutionmaxusersexceeded', 'admin')); return; } $username = $values['username']; $firstname = $values['firstname']; $lastname = $values['lastname']; $email = $values['email']; $password = $values['password']; if (method_exists($authobj, 'is_username_valid') && !$authobj->is_username_valid($username)) { $form->set_error('username', get_string('usernameinvalidform', 'auth.internal')); } if (!$form->get_error('username') && record_exists_select('usr', 'LOWER(username) = ?', strtolower($username))) { $form->set_error('username', get_string('usernamealreadytaken', 'auth.internal')); } if (method_exists($authobj, 'is_password_valid') && !$authobj->is_password_valid($password)) { $form->set_error('password', get_string('passwordinvalidform', 'auth.' . $authobj->type)); } if (isset($_POST['createmethod']) && $_POST['createmethod'] == 'leap2a') { $form->set_error('firstname', null); $form->set_error('lastname', null); $form->set_error('email', null); if (!$values['leap2afile']) { $form->set_error('leap2afile', $form->i18n('rule', 'required', 'required')); return; } if ($values['leap2afile']['type'] == 'application/octet-stream') { require_once 'file.php'; $mimetype = file_mime_type($values['leap2afile']['tmp_name']); } else { $mimetype = $values['leap2afile']['type']; } $date = time(); $niceuser = preg_replace('/[^a-zA-Z0-9_-]/', '-', $values['username']); safe_require('import', 'leap'); $fakeimportrecord = (object) array('data' => array('importfile' => $values['leap2afile']['tmp_name'], 'importfilename' => $values['leap2afile']['name'], 'importid' => $niceuser . '-' . $date, 'mimetype' => $mimetype)); $TRANSPORTER = new LocalImporterTransport($fakeimportrecord); try { $TRANSPORTER->extract_file(); PluginImportLeap::validate_transported_data($TRANSPORTER); } catch (Exception $e) { $form->set_error('leap2afile', $e->getMessage()); } } else { if (!$form->get_error('firstname') && !preg_match('/\\S/', $firstname)) { $form->set_error('firstname', $form->i18n('rule', 'required', 'required')); } if (!$form->get_error('lastname') && !preg_match('/\\S/', $lastname)) { $form->set_error('lastname', $form->i18n('rule', 'required', 'required')); } if (!$form->get_error('email')) { require_once 'phpmailer/class.phpmailer.php'; if (!$form->get_error('email') && !PHPMailer::ValidateAddress($email)) { $form->set_error('email', get_string('invalidemailaddress', 'artefact.internal')); } if (record_exists('usr', 'email', $email) || record_exists('artefact_internal_profile_email', 'email', $email)) { $form->set_error('email', get_string('emailalreadytaken', 'auth.internal')); } } } }
/** * The CSV file is parsed here so validation errors can be returned to the * user. The data from a successful parsing is stored in the <var>$CVSDATA</var> * array so it can be accessed by the submit function * * @param Pieform $form The form to validate * @param array $values The values submitted */ function uploadcsv_validate(Pieform $form, $values) { global $CSVDATA, $ALLOWEDKEYS, $FORMAT, $USER; // Don't even start attempting to parse if there are previous errors if ($form->has_errors()) { return; } if ($values['file']['size'] == 0) { $form->set_error('file', $form->i18n('rule', 'required', 'required', array())); return; } require_once 'pear/File.php'; require_once 'pear/File/CSV.php'; // Don't be tempted to use 'explode' here. There may be > 1 underscore. $break = strpos($values['authinstance'], '_'); $authinstance = substr($values['authinstance'], 0, $break); $institution = substr($values['authinstance'], $break + 1); if (!$USER->can_edit_institution($institution)) { $form->set_error('authinstance', get_string('notadminforinstitution', 'admin')); return; } $usernames = array(); $emails = array(); $conf = File_CSV::discoverFormat($values['file']['tmp_name']); $i = 0; while ($line = File_CSV::readQuoted($values['file']['tmp_name'], $conf)) { $i++; if (!is_array($line)) { // Note: the CSV parser returns true on some errors and false on // others! Yes that's retarded. No I didn't write it :( $form->set_error('file', get_string('uploadcsverrorincorrectnumberoffields', 'admin', $i)); return; } // Get the format of the file if ($i == 1) { foreach ($line as &$potentialkey) { $potentialkey = trim($potentialkey); if (!in_array($potentialkey, $ALLOWEDKEYS)) { $form->set_error('file', get_string('uploadcsverrorinvalidfieldname', 'admin', $potentialkey)); return; } } // Now we know all of the field names are valid, we need to make // sure that the required fields are included $mandatoryfields = array('username', 'password'); $mandatoryfields = array_merge($mandatoryfields, array_keys(ArtefactTypeProfile::get_mandatory_fields())); if ($lockedprofilefields = get_column('institution_locked_profile_field', 'profilefield', 'name', $institution)) { $mandatoryfields = array_merge($mandatoryfields, $lockedprofilefields); } // Add in the locked profile fields for this institution foreach ($mandatoryfields as $field) { if (!in_array($field, $line)) { $form->set_error('file', get_string('uploadcsverrorrequiredfieldnotspecified', 'admin', $field)); return; } } // The format line is valid $FORMAT = $line; log_info('FORMAT:'); log_info($FORMAT); } else { // Trim non-breaking spaces -- they get left in place by File_CSV foreach ($line as &$field) { $field = preg_replace('/^(\\s|\\xc2\\xa0)*(.*?)(\\s|\\xc2\\xa0)*$/', '$2', $field); } // We have a line with the correct number of fields, but should validate these fields // Note: This validation should really be methods on each profile class, that way // it can be used in the profile screen as well. $formatkeylookup = array_flip($FORMAT); $username = $line[$formatkeylookup['username']]; $password = $line[$formatkeylookup['password']]; $email = $line[$formatkeylookup['email']]; $authobj = AuthFactory::create($authinstance); if (method_exists($authobj, 'is_username_valid') && !$authobj->is_username_valid($username)) { $form->set_error('file', get_string('uploadcsverrorinvalidusername', 'admin', $i)); return; } if (record_exists_select('usr', 'LOWER(username) = ?', strtolower($username)) || isset($usernames[strtolower($username)])) { $form->set_error('file', get_string('uploadcsverroruseralreadyexists', 'admin', $i, $username)); return; } if (record_exists('usr', 'email', $email) || isset($emails[$email])) { $form->set_error('file', get_string('uploadcsverroremailaddresstaken', 'admin', $i, $email)); } // Note: only checks for valid form are done here, none of the checks // like whether the password is too easy. The user is going to have to // change their password on first login anyway. if (method_exists($authobj, 'is_password_valid') && !$authobj->is_password_valid($password)) { $form->set_error('file', get_string('uploadcsverrorinvalidpassword', 'admin', $i)); return; } $usernames[strtolower($username)] = 1; $emails[$email] = 1; // All OK! $CSVDATA[] = $line; } } if ($i == 1) { // There was only the title row :( $form->set_error('file', get_string('uploadcsverrornorecords', 'admin')); return; } if ($CSVDATA === null) { // Oops! Couldn't get CSV data for some reason $form->set_error('file', get_string('uploadcsverrorunspecifiedproblem', 'admin')); } }
/** * The CSV file is parsed here so validation errors can be returned to the * user. The data from a successful parsing is stored in the <var>$CVSDATA</var> * array so it can be accessed by the submit function * * @param Pieform $form The form to validate * @param array $values The values submitted */ function uploadcsv_validate(Pieform $form, $values) { global $CSVDATA, $ALLOWEDKEYS, $FORMAT, $USER, $INSTITUTIONNAME, $UPDATES; // Don't even start attempting to parse if there are previous errors if ($form->has_errors()) { return; } $steps_done = 0; $steps_total = $values['updateusers'] ? 5 : 4; if ($values['file']['size'] == 0) { $form->set_error('file', $form->i18n('rule', 'required', 'required', array())); return; } if ($USER->get('admin') || get_config_plugin('artefact', 'file', 'institutionaloverride')) { $maxquotaenabled = get_config_plugin('artefact', 'file', 'maxquotaenabled'); $maxquota = get_config_plugin('artefact', 'file', 'maxquota'); if ($maxquotaenabled && $values['quota'] > $maxquota) { $form->set_error('quota', get_string('maxquotaexceededform', 'artefact.file', display_size($maxquota))); } } require_once 'csvfile.php'; $authinstance = (int) $values['authinstance']; $institution = get_field('auth_instance', 'institution', 'id', $authinstance); if (!$USER->can_edit_institution($institution)) { $form->set_error('authinstance', get_string('notadminforinstitution', 'admin')); return; } $authobj = AuthFactory::create($authinstance); $csvusers = new CsvFile($values['file']['tmp_name']); $csvusers->set('allowedkeys', $ALLOWEDKEYS); // Now we know all of the field names are valid, we need to make // sure that the required fields are included $mandatoryfields = array('username', 'email', 'firstname', 'lastname'); if (!$values['updateusers']) { $mandatoryfields[] = 'password'; } $csvusers->set('mandatoryfields', $mandatoryfields); $csvdata = $csvusers->get_data(); if (!empty($csvdata->errors['file'])) { $form->set_error('file', $csvdata->errors['file']); return; } $csverrors = new CSVErrors(); $formatkeylookup = array_flip($csvdata->format); // First pass validates usernames & passwords in the file, and builds // up a list indexed by username. $emails = array(); if (isset($formatkeylookup['remoteuser'])) { $remoteusers = array(); } $num_lines = count($csvdata->data); $maxcsvlines = get_config('maxusercsvlines'); if ($maxcsvlines && $maxcsvlines < $num_lines) { $form->set_error('file', get_string('uploadcsverrortoomanyusers', 'admin', get_string('nusers', 'mahara', $maxcsvlines))); return; } $existing_usernames = get_records_menu('usr', '', NULL, '', 'LOWER(username) AS username, 1 AS key2'); $existing_usr_email_addresses = get_records_menu('usr', '', NULL, '', 'email, 1 AS key2'); $existing_internal_email_addresses = get_records_menu('artefact_internal_profile_email', 'verified', 1, '', 'email, 1 AS key2'); foreach ($csvdata->data as $key => $line) { // If headers exists, increment i = key + 2 for actual line number $i = $csvusers->get('headerExists') ? $key + 2 : $key + 1; if (!($key % 25)) { set_progress_info('uploaduserscsv', $key, $num_lines * $steps_total, get_string('validating', 'admin')); } // Trim non-breaking spaces -- they get left in place by File_CSV foreach ($line as &$field) { $field = preg_replace('/^(\\s|\\xc2\\xa0)*(.*?)(\\s|\\xc2\\xa0)*$/', '$2', $field); } if (count($line) != count($csvdata->format)) { $csverrors->add($i, get_string('uploadcsverrorwrongnumberoffields', 'admin', $i)); continue; } // We have a line with the correct number of fields, but should validate these fields // Note: This validation should really be methods on each profile class, that way // it can be used in the profile screen as well. $username = $line[$formatkeylookup['username']]; $password = isset($formatkeylookup['password']) ? $line[$formatkeylookup['password']] : null; $email = $line[$formatkeylookup['email']]; if (isset($remoteusers)) { $remoteuser = strlen($line[$formatkeylookup['remoteuser']]) ? $line[$formatkeylookup['remoteuser']] : null; } if (method_exists($authobj, 'is_username_valid_admin')) { if (!$authobj->is_username_valid_admin($username)) { $csverrors->add($i, get_string('uploadcsverrorinvalidusername', 'admin', $i)); } } else { if (method_exists($authobj, 'is_username_valid')) { if (!$authobj->is_username_valid($username)) { $csverrors->add($i, get_string('uploadcsverrorinvalidusername', 'admin', $i)); } } } if (!$values['updateusers']) { // Note: only checks for valid form are done here, none of the checks // like whether the password is too easy. The user is going to have to // change their password on first login anyway. if (method_exists($authobj, 'is_password_valid') && !$authobj->is_password_valid($password)) { $csverrors->add($i, get_string('uploadcsverrorinvalidpassword', 'admin', $i)); } } if (isset($emails[$email])) { // Duplicate email within this file. $csverrors->add($i, get_string('uploadcsverroremailaddresstaken', 'admin', $i, $email)); } else { if (!PHPMailer::ValidateAddress($email)) { $csverrors->add($i, get_string('uploadcsverrorinvalidemail', 'admin', $i, $email)); } else { if (!$values['updateusers']) { // The email address must be new if (array_key_exists($email, $existing_usr_email_addresses) || array_key_exists($email, $existing_internal_email_addresses)) { $csverrors->add($i, get_string('uploadcsverroremailaddresstaken', 'admin', $i, $email)); } } } } $emails[$email] = 1; if (isset($remoteusers) && $remoteuser) { if (isset($remoteusers[$remoteuser])) { $csverrors->add($i, get_string('uploadcsverrorduplicateremoteuser', 'admin', $i, $remoteuser)); } else { if (!$values['updateusers']) { if ($remoteuserowner = get_record_sql(' SELECT u.username FROM {auth_remote_user} aru JOIN {usr} u ON aru.localusr = u.id WHERE aru.remoteusername = ? AND aru.authinstance = ?', array($remoteuser, $authinstance))) { $csverrors->add($i, get_string('uploadcsverrorremoteusertaken', 'admin', $i, $remoteuser, $remoteuserowner->username)); } } } $remoteusers[$remoteuser] = true; } // If we didn't even get a username, we can't check for duplicates, so move on. if (strlen($username) < 1) { continue; } if (isset($usernames[strtolower($username)])) { // Duplicate username within this file. $csverrors->add($i, get_string('uploadcsverroruseralreadyexists', 'admin', $i, $username)); } else { if (!$values['updateusers'] && array_key_exists(strtolower($username), $existing_usernames)) { $csverrors->add($i, get_string('uploadcsverroruseralreadyexists', 'admin', $i, $username)); } $usernames[strtolower($username)] = array('username' => $username, 'password' => $password, 'email' => $email, 'lineno' => $i, 'raw' => $line); if (!empty($remoteuser) && !empty($remoteusers[$remoteuser])) { $usernames[strtolower($username)]['remoteuser'] = $remoteuser; } } } // If the admin is trying to overwrite existing users, identified by username, // this second pass performs some additional checks if ($values['updateusers']) { $key = 0; foreach ($usernames as $lowerusername => $data) { if (!($key % 25)) { set_progress_info('uploaduserscsv', $num_lines + $key, $num_lines * $steps_total, get_string('checkingupdates', 'admin')); } $key++; $line = $data['lineno']; $username = $data['username']; $password = $data['password']; $email = $data['email']; // If the user already exists, they must already be in this institution. $userinstitutions = get_records_sql_assoc("\n SELECT COALESCE(ui.institution, 'mahara') AS institution, u.id\n FROM {usr} u LEFT JOIN {usr_institution} ui ON u.id = ui.usr\n WHERE LOWER(u.username) = ?", array($lowerusername)); if ($userinstitutions) { if (!isset($userinstitutions[$institution])) { if ($institution == 'mahara') { $institutiondisplay = array(); foreach ($userinstitutions as $i) { $institutiondisplay[] = $INSTITUTIONNAME[$i->institution]; } $institutiondisplay = join(', ', $institutiondisplay); $message = get_string('uploadcsverroruserinaninstitution', 'admin', $line, $username, $institutiondisplay); } else { $message = get_string('uploadcsverrorusernotininstitution', 'admin', $line, $username, $INSTITUTIONNAME[$institution]); } $csverrors->add($line, $message); } else { // Remember that this user is being updated $UPDATES[$username] = 1; } } else { // New user, check the password if (method_exists($authobj, 'is_password_valid') && !$authobj->is_password_valid($password)) { $csverrors->add($line, get_string('uploadcsverrorinvalidpassword', 'admin', $line)); } } // Check if the email already exists and if it's owned by this user. This query can return more // than one row when there are duplicate emails already on the site. If that happens, things are // already a bit out of hand, and we'll just allow an update if this user is one of the users who // owns the email. $emailowned = get_records_sql_assoc(' SELECT LOWER(u.username) AS lowerusername, ae.principal FROM {usr} u LEFT JOIN {artefact_internal_profile_email} ae ON u.id = ae.owner AND ae.verified = 1 AND ae.email = ? WHERE ae.owner IS NOT NULL OR u.email = ?', array($email, $email)); // If the email is owned by someone else, it could still be okay provided // that other user's email is also being changed in this csv file. if ($emailowned && !isset($emailowned[$lowerusername])) { foreach ($emailowned as $e) { // Only primary emails can be set in uploadcsv, so it's an error when someone else // owns the email as a secondary. if (!$e->principal) { $csverrors->add($line, get_string('uploadcsverroremailaddresstaken', 'admin', $line, $email)); break; } // It's also an error if the email owner is not being updated in this file if (!isset($usernames[$e->lowerusername])) { $csverrors->add($line, get_string('uploadcsverroremailaddresstaken', 'admin', $line, $email)); break; } // If the other user is being updated in this file, but isn't changing their // email address, it's ok, we've already notified duplicate emails within the file. } } if (isset($remoteusers) && !empty($data['remoteuser'])) { $remoteuser = $data['remoteuser']; $remoteuserowner = get_field_sql(' SELECT LOWER(u.username) FROM {usr} u JOIN {auth_remote_user} aru ON u.id = aru.localusr WHERE aru.remoteusername = ? AND aru.authinstance = ?', array($remoteuser, $authinstance)); if ($remoteuserowner && $remoteuserowner != $lowerusername && !isset($usernames[$remoteuserowner])) { // The remote username is owned by some other user who is not being updated in this file $csverrors->add($line, get_string('uploadcsverrorremoteusertaken', 'admin', $line, $remoteuser, $remoteuserowner)); } } } } if ($errors = $csverrors->process()) { $form->set_error('file', clean_html($errors), false); return; } $FORMAT = $csvdata->format; $CSVDATA = $csvdata->data; }
/** * Provides a date picker, in the form of three dropdowns. * * @param Pieform $form The form to render the element for * @param array $element The element to render * @return string The HTML for the element */ function pieform_element_date(Pieform $form, $element) { /*{{{*/ $result = ''; $name = Pieform::hsc($element['name']); $element['minyear'] = isset($element['minyear']) ? intval($element['minyear']) : 1950; $element['maxyear'] = isset($element['maxyear']) ? intval($element['maxyear']) : 2050; $showtime = isset($element['time']) ? $element['time'] : false; $required = !empty($element['rules']['required']); if ($required && !isset($element['defaultvalue'])) { $element['defaultvalue'] = time(); } $global = $form->get_property('method') == 'get' ? $_GET : $_POST; $dateisset = isset($element['defaultvalue']); // Optional control if (!$required) { $optional = <<<EOF <script type="application/javascript"> function {$name}_toggle(x) { var elements = [ \$('{$name}_hour'), \$('{$name}_minute'), \$('{$name}_day'), \$('{$name}_month'), \$('{$name}_year') ]; for (var i in elements) { if (elements[i]) elements[i].disabled = !x.checked; } } </script> EOF; $dateisset = $dateisset || (isset($element['value']['year']) || isset($global[$element['name'] . '_year'])) && (isset($element['value']['month']) || isset($global[$element['name'] . '_month'])) && (isset($element['value']['day']) || isset($global[$element['name'] . '_day'])); $optional .= ' <input type="checkbox" ' . ($dateisset ? 'checked="checked"' : '') . 'name="' . $name . '_optional" id="' . $name . '_optional" onchange="' . $name . '_toggle(this)" ' . 'tabindex="' . Pieform::hsc($element['tabindex']) . '">'; $optional .= ' <label for="' . $name . '_optional">' . $form->i18n('element', 'date', 'specify', $element) . ': ' . Pieform::hsc($element['title']) . '</label> '; $result .= $optional; } // Year $value = pieform_element_date_get_timeperiod_value('year', $element['minyear'], $element['maxyear'], $element, $form); $year = '<label for="' . $name . '_year" class="accessible-hidden sr-only">' . get_string('year') . '</label>'; $year .= '<span class="picker first"><select class="form-control select" name="' . $name . '_year" id="' . $name . '_year"' . (!$required && !$dateisset ? ' disabled="disabled"' : '') . ' tabindex="' . Pieform::hsc($element['tabindex']) . '"'; if (isset($element['description'])) { $year .= ' aria-describedby="' . $form->element_descriptors($element) . '"'; } $year .= ">\n"; for ($i = $element['minyear']; $i <= $element['maxyear']; $i++) { $year .= "\t<option value=\"{$i}\"" . ($value == $i ? ' selected="selected"' : '') . ">{$i}</option>\n"; } $year .= "</select></span>\n"; // Month $value = pieform_element_date_get_timeperiod_value('month', 1, 12, $element, $form); $month = '<label for="' . $name . '_month" class="accessible-hidden sr-only">' . get_string('month') . '</label>'; $month .= '<span class="picker"><select class="form-control select" name="' . $name . '_month" id="' . $name . '_month"' . (!$required && !$dateisset ? ' disabled="disabled"' : '') . ' tabindex="' . Pieform::hsc($element['tabindex']) . '"'; if (isset($element['description'])) { $month .= ' aria-describedby="' . $form->element_descriptors($element) . '"'; } $month .= ">\n"; $monthnames = explode(',', $form->i18n('element', 'date', 'monthnames', $element)); for ($i = 1; $i <= 12; $i++) { $month .= "\t<option value=\"{$i}\"" . ($value == $i ? ' selected="selected"' : '') . '>' . $monthnames[$i - 1] . "</option>\n"; } $month .= "</select></span>\n"; // Day $value = pieform_element_date_get_timeperiod_value('day', 1, 31, $element, $form); $day = '<label for="' . $name . '_day" class="accessible-hidden sr-only">' . get_string('day') . '</label>'; $day .= '<span class="picker"><select class="form-control select" name="' . $name . '_day" id="' . $name . '_day"' . (!$required && !$dateisset ? ' disabled="disabled"' : '') . ' tabindex="' . Pieform::hsc($element['tabindex']) . '"'; if (isset($element['description'])) { $day .= ' aria-describedby="' . $form->element_descriptors($element) . '"'; } $day .= ">\n"; for ($i = 1; $i <= 31; $i++) { $day .= "\t<option value=\"{$i}\"" . ($value == $i ? ' selected="selected"' : '') . ">{$i}</option>\n"; } $day .= '</select></span>'; if ($showtime) { // Hour $value = pieform_element_date_get_timeperiod_value('hour', 0, 23, $element, $form); $label = get_string('datepicker_hourText'); $hour = '<label for="' . $name . '_hour" class="accessible-hidden sr-only">' . $label . '</label>'; $hour .= '<span class="picker"><select class="form-control select" name="' . $name . '_hour" id="' . $name . '_hour"' . (!$required && !$dateisset ? ' disabled="disabled"' : '') . ' tabindex="' . Pieform::hsc($element['tabindex']) . '"'; if (isset($element['description'])) { $hour .= ' aria-describedby="' . $form->element_descriptors($element) . '"'; } $hour .= ">\n"; for ($i = 0; $i <= 23; $i++) { $hour .= "\t<option value=\"{$i}\"" . ($value == $i ? ' selected="selected"' : '') . ">" . sprintf('%02d', $i) . "</option>\n"; } $hour .= '</select></span>'; // Minute $value = pieform_element_date_get_timeperiod_value('minute', 0, 59, $element, $form); $label = get_string('datepicker_minuteText'); $minute = '<label for="' . $name . '_minute" class="accessible-hidden sr-only">' . $label . '</label>'; $minute .= '<span class="picker date"><select class="form-control select" name="' . $name . '_minute" id="' . $name . '_minute"' . (!$required && !$dateisset ? ' disabled="disabled"' : '') . ' tabindex="' . Pieform::hsc($element['tabindex']) . '"'; if (isset($element['description'])) { $minute .= ' aria-describedby="' . $form->element_descriptors($element) . '"'; } $minute .= ">\n"; for ($i = 0; $i <= 59; $i++) { $minute .= "\t<option value=\"{$i}\"" . ($value == $i ? ' selected="selected"' : '') . ">" . sprintf('%02d', $i) . "</option>\n"; } $minute .= '</select></span>'; $at = ' ' . $form->i18n('element', 'date', 'at', $element) . ' '; $result .= $year . $month . $day . $at . $hour . $minute; } else { $result .= $year . $month . $day; } return $result; }
function pieform_element_wysiwyg_rule_required(Pieform $form, $value, $element, $check) { return $check && strip_tags($value, '<img><iframe><object><embed>') === '' ? $form->i18n('rule', 'required', 'required', $element) : ''; }
/** * The CSV file is parsed here so validation errors can be returned to the * user. The data from a successful parsing is stored in the <var>$CVSDATA</var> * array so it can be accessed by the submit function * * @param Pieform $form The form to validate * @param array $values The values submitted */ function uploadcsv_validate(Pieform $form, $values) { global $CSVDATA, $ALLOWEDKEYS, $MANDATORYFIELDS, $GROUPTYPES, $FORMAT, $USER, $UPDATES, $EDITROLES; // Don't even start attempting to parse if there are previous errors if ($form->has_errors()) { return; } if ($values['file']['size'] == 0) { $form->set_error('file', $form->i18n('rule', 'required', 'required', array())); return; } $institution = $values['institution']; if (!$USER->can_edit_institution($institution)) { $form->set_error('institution', get_string('notadminforinstitution', 'admin')); return; } require_once 'csvfile.php'; $csvgroups = new CsvFile($values['file']['tmp_name']); $csvgroups->set('allowedkeys', $ALLOWEDKEYS); $csvgroups->set('mandatoryfields', $MANDATORYFIELDS); $csvdata = $csvgroups->get_data(); if (!empty($csvdata->errors['file'])) { $form->set_error('file', $csvdata->errors['file']); return; } $csverrors = new CSVErrors(); $formatkeylookup = array_flip($csvdata->format); $shortnames = array(); $displaynames = array(); foreach ($csvdata->data as $key => $line) { // If headers exists, increment i = key + 2 for actual line number $i = $csvgroups->get('headerExists') ? $key + 2 : $key + 1; // Trim non-breaking spaces -- they get left in place by File_CSV foreach ($line as &$field) { $field = preg_replace('/^(\\s|\\xc2\\xa0)*(.*?)(\\s|\\xc2\\xa0)*$/', '$2', $field); } if (count($line) != count($csvdata->format)) { $csverrors->add($i, get_string('uploadcsverrorwrongnumberoffields', 'admin', $i)); continue; } $shortname = $line[$formatkeylookup['shortname']]; $displayname = $line[$formatkeylookup['displayname']]; $grouptype = $line[$formatkeylookup['roles']]; $open = isset($formatkeylookup['open']) && !empty($line[$formatkeylookup['open']]); $controlled = isset($formatkeylookup['controlled']) && !empty($line[$formatkeylookup['controlled']]); $request = isset($formatkeylookup['request']) && !empty($line[$formatkeylookup['request']]); $submitpages = isset($formatkeylookup['submitpages']) && !empty($line[$formatkeylookup['submitpages']]); if (isset($formatkeylookup['editroles'])) { $editroles = $line[$formatkeylookup['editroles']]; } if (!preg_match('/^[a-zA-Z0-9_.-]{2,255}$/', $shortname)) { $csverrors->add($i, get_string('uploadgroupcsverrorinvalidshortname', 'admin', $i, $shortname)); } if (isset($shortnames[$shortname])) { // Duplicate shortname within this file. $csverrors->add($i, get_string('uploadgroupcsverrorshortnamealreadytaken', 'admin', $i, $shortname)); } else { if (!$values['updategroups']) { // The groupname must be new if (record_exists('group', 'shortname', $shortname, 'institution', $institution)) { $csverrors->add($i, get_string('uploadgroupcsverrorshortnamealreadytaken', 'admin', $i, $shortname)); } } else { if ($values['updategroups']) { // The groupname needs to exist if (!record_exists('group', 'shortname', $shortname, 'institution', $institution)) { $csverrors->add($i, get_string('uploadgroupcsverrorshortnamemissing', 'admin', $i, $shortname)); } } } } $shortnames[$shortname] = array('shortname' => $shortname, 'displayname' => $displayname, 'roles' => $grouptype, 'lineno' => $i, 'raw' => $line); if (isset($displaynames[strtolower($displayname)])) { // Duplicate displayname within this file $csverrors->add($i, get_string('uploadgroupcsverrorsgroupnamealreadyexists', 'admin', $i, $displayname)); } else { if (!$values['updategroups']) { // The displayname must be new if (get_records_sql_array('SELECT id FROM {group} WHERE LOWER(TRIM(name)) = ?', array(strtolower(trim($displayname))))) { $csverrors->add($i, get_string('uploadgroupcsverrorgroupnamealreadyexists', 'admin', $i, $displayname)); } } else { // This displayname must be new if not our shortname/institution if (get_records_sql_array(' SELECT id FROM {group} WHERE LOWER(TRIM(name)) = ? AND NOT (shortname = ? AND institution = ?)', array(strtolower(trim($displayname)), $shortname, $institution))) { $csverrors->add($i, get_string('uploadgroupcsverrorgroupnamealreadyexists', 'admin', $i, $displayname)); } } } $displaynames[strtolower($displayname)] = 1; if (!isset($GROUPTYPES[$grouptype])) { $csverrors->add($i, get_string('uploadgroupcsverrorinvalidgrouptype', 'admin', $i, $grouptype)); } if (isset($editroles) && !isset($EDITROLES[$editroles])) { $csverrors->add($i, get_string('uploadgroupcsverrorinvalideditroles', 'admin', $i, $editroles)); } if ($open && $controlled) { $csverrors->add($i, get_string('uploadgroupcsverroropencontrolled', 'admin', $i)); } if ($open && $request) { $csverrors->add($i, get_string('uploadgroupcsverroropenrequest', 'admin', $i)); } if ($values['updategroups']) { foreach ($shortnames as $shortname => $data) { // TODO: Any other checks we have to do for updated groups $UPDATES[$shortname] = 1; } } } if ($errors = $csverrors->process()) { $form->set_error('file', clean_html($errors)); return; } $FORMAT = $csvdata->format; $CSVDATA = $csvdata->data; }
/** * Retrieves the value of the calendar as a unix timestamp * * @param Pieform $form The form the element is attached to * @param array $element The element to get the value for * @return int The unix timestamp represented by the calendar */ function pieform_element_calendar_get_value(Pieform $form, $element) { /*{{{*/ $name = $element['name']; $global = $form->get_property('method') == 'get' ? $_GET : $_POST; if (isset($element['value'])) { return $element['value']; } if ($form->is_submitted() && isset($global[$name])) { if (trim($global[$name]) == '') { return null; } $value = strtotime($global[$name]); if ($value === false) { $form->set_error($name, $form->i18n('element', 'calendar', 'invalidvalue', $element)); return null; } return $value; } if (isset($element['defaultvalue'])) { return $element['defaultvalue']; } return null; }
function import_validate(Pieform $form, $values) { global $USER, $TRANSPORTER; if (!isset($values['leap2afile'])) { $form->set_error('leap2afile', $form->i18n('rule', 'required', 'required')); return; } if ($values['leap2afile']['type'] == 'application/octet-stream') { require_once 'file.php'; $mimetype = file_mime_type($values['leap2afile']['tmp_name']); } else { $mimetype = trim($values['leap2afile']['type'], '"'); } $date = time(); $niceuser = preg_replace('/[^a-zA-Z0-9_-]/', '-', $USER->get('username')); safe_require('import', 'leap'); $fakeimportrecord = (object) array('data' => array('importfile' => $values['leap2afile']['tmp_name'], 'importfilename' => $values['leap2afile']['name'], 'importid' => $niceuser . '-' . $date, 'mimetype' => $mimetype)); $TRANSPORTER = new LocalImporterTransport($fakeimportrecord); try { $TRANSPORTER->extract_file(); PluginImportLeap::validate_transported_data($TRANSPORTER); } catch (Exception $e) { $form->set_error('leap2afile', $e->getMessage()); $TRANSPORTER->cleanup(); } // Check if import data may exceed the user's file quota $importdata = $TRANSPORTER->files_info(); require_once 'function.dirsize.php'; $importdatasize = dirsize($importdata['tempdir'] . 'extract/files'); if ($USER->get('quotaused') + $importdatasize > $USER->get('quota')) { $form->set_error('leap2afile', get_string('importexceedquota', 'import')); $TRANSPORTER->cleanup(); } }
function adduser_validate(Pieform $form, $values) { global $USER; $authobj = AuthFactory::create($values['authinstance']); $institution = $authobj->institution; // Institutional admins can only set their own institutions' authinstances if (!$USER->get('admin') && !$USER->is_institutional_admin($authobj->institution)) { $form->set_error('authinstance', get_string('notadminforinstitution', 'admin')); return; } $institution = new Institution($authobj->institution); // Don't exceed max user accounts for the institution if ($institution->isFull()) { $SESSION->add_error_msg(get_string('institutionmaxusersexceeded', 'admin')); redirect('/admin/users/add.php'); } $username = $values['username']; $firstname = $values['firstname']; $lastname = $values['lastname']; $email = $values['email']; $password = $values['password']; if (method_exists($authobj, 'is_username_valid') && !$authobj->is_username_valid($username)) { $form->set_error('username', get_string('addusererrorinvalidusername', 'admin')); return; } if (!$form->get_error('username') && record_exists_select('usr', 'LOWER(username) = ?', strtolower($username))) { $form->set_error('username', get_string('usernamealreadytaken', 'auth.internal')); return; } if (!$form->get_error('firstname') && !preg_match('/\\S/', $firstname)) { $form->set_error('firstname', $form->i18n('required')); } if (!$form->get_error('lastname') && !preg_match('/\\S/', $lastname)) { $form->set_error('lastname', $form->i18n('required')); } if (record_exists('usr', 'email', $email) || record_exists('artefact_internal_profile_email', 'email', $email)) { $form->set_error('email', get_string('emailalreadytaken', 'auth.internal')); } if (method_exists($authobj, 'is_password_valid') && !$authobj->is_password_valid($password)) { $form->set_error('password', get_string('passwordinvalidform', 'auth.' . $authobj->type)); return; } }
/** * The CSV file is parsed here so validation errors can be returned to the * user. The data from a successful parsing is stored in the <var>$CVSDATA</var> * array so it can be accessed by the submit function * * @param Pieform $form The form to validate * @param array $values The values submitted */ function uploadcsv_validate(Pieform $form, $values) { global $CSVDATA, $ALLOWEDKEYS, $FORMAT, $USER, $CSVERRORS; // Don't even start attempting to parse if there are previous errors if ($form->has_errors()) { return; } if ($values['file']['size'] == 0) { $form->set_error('file', $form->i18n('rule', 'required', 'required', array())); return; } require_once 'csvfile.php'; $authinstance = (int) $values['authinstance']; $institution = get_field('auth_instance', 'institution', 'id', $authinstance); if (!$USER->can_edit_institution($institution)) { $form->set_error('authinstance', get_string('notadminforinstitution', 'admin')); return; } $usernames = array(); $emails = array(); $csvusers = new CsvFile($values['file']['tmp_name']); $csvusers->set('allowedkeys', $ALLOWEDKEYS); // Now we know all of the field names are valid, we need to make // sure that the required fields are included $mandatoryfields = array('username', 'password'); $mandatoryfields = array_merge($mandatoryfields, array_keys(ArtefactTypeProfile::get_mandatory_fields())); if ($lockedprofilefields = get_column('institution_locked_profile_field', 'profilefield', 'name', $institution)) { $mandatoryfields = array_merge($mandatoryfields, $lockedprofilefields); } $csvusers->set('mandatoryfields', $mandatoryfields); $csvdata = $csvusers->get_data(); if (!empty($csvdata->errors['file'])) { $form->set_error('file', $csvdata->errors['file']); return; } foreach ($csvdata->data as $key => $line) { // If headers exists, increment i = key + 2 for actual line number $i = $csvusers->get('headerExists') ? $key + 2 : $key + 1; // Trim non-breaking spaces -- they get left in place by File_CSV foreach ($line as &$field) { $field = preg_replace('/^(\\s|\\xc2\\xa0)*(.*?)(\\s|\\xc2\\xa0)*$/', '$2', $field); } // We have a line with the correct number of fields, but should validate these fields // Note: This validation should really be methods on each profile class, that way // it can be used in the profile screen as well. $formatkeylookup = array_flip($csvdata->format); $username = $line[$formatkeylookup['username']]; $password = $line[$formatkeylookup['password']]; $email = $line[$formatkeylookup['email']]; $authobj = AuthFactory::create($authinstance); if (method_exists($authobj, 'is_username_valid') && !$authobj->is_username_valid($username)) { $CSVERRORS[] = get_string('uploadcsverrorinvalidusername', 'admin', $i); } if (record_exists_select('usr', 'LOWER(username) = ?', strtolower($username)) || isset($usernames[strtolower($username)])) { $CSVERRORS[] = get_string('uploadcsverroruseralreadyexists', 'admin', $i, $username); } if (record_exists('usr', 'email', $email) || record_exists('artefact_internal_profile_email', 'email', $email) || isset($emails[$email])) { $CSVERRORS[] = get_string('uploadcsverroremailaddresstaken', 'admin', $i, $email); } // Note: only checks for valid form are done here, none of the checks // like whether the password is too easy. The user is going to have to // change their password on first login anyway. if (method_exists($authobj, 'is_password_valid') && !$authobj->is_password_valid($password)) { $CSVERRORS[] = get_string('uploadcsverrorinvalidpassword', 'admin', $i); } $usernames[strtolower($username)] = 1; $emails[$email] = 1; } if (!empty($CSVERRORS)) { $form->set_error('file', implode("<br />\n", $CSVERRORS)); return; } $FORMAT = $csvdata->format; $CSVDATA = $csvdata->data; }
function pieform_element_wysiwyg_rule_required(Pieform $form, $value, $element, $check) { return $check && strip_tags($value) === '' ? $form->i18n('rule', 'required', 'required', $element) : ''; }