示例#1
0
文件: div.php 项目: Br3nda/mahara
/**
 * Renders form elements inside <div>s.
 *
 * @param Pieform $form    The form the element is being rendered for
 * @param array   $element The element to be rendered
 * @return string          The element rendered inside an appropriate container
 */
function pieform_renderer_div(Pieform $form, $element)
{
    /*{{{*/
    $formname = $form->get_name();
    // Set the class of the enclosing <div> to match that of the element
    $result = '<div';
    if (isset($element['name'])) {
        $result .= ' id="' . $formname . '_' . $element['name'] . '_container"';
    }
    if (!empty($element['class'])) {
        $result .= ' class="' . $element['class'] . '"';
    }
    $result .= '>';
    if (isset($element['labelhtml'])) {
        $result .= $element['labelhtml'];
    }
    //$result .= $builtelement;
    $result .= $element['html'];
    if (isset($element['helphtml'])) {
        $result .= ' ' . $element['helphtml'];
    }
    // Description - optional description of the element, or other note that should be visible
    // on the form itself (without the user having to hover over contextual help
    if ((!$form->has_errors() || $form->get_property('showdescriptiononerror')) && !empty($element['description'])) {
        $result .= '<div class="description"> ' . Pieform::hsc($element['description']) . "</div>";
    }
    if (!empty($element['error'])) {
        $result .= '<div class="errmsg">' . Pieform::hsc($element['error']) . '</div>';
    }
    $result .= "</div>\n";
    return $result;
}
示例#2
0
文件: table.php 项目: Br3nda/mahara
/**
 * Renders form elements inside a <table>.
 *
 * @param Pieform $form    The form the element is being rendered for
 * @param array   $element The element to be rendered
 * @return string          The element rendered inside an appropriate container
 */
function pieform_renderer_table(Pieform $form, $element)
{
    /*{{{*/
    $formname = $form->get_name();
    if ($element['type'] == 'fieldset') {
        // Add table tags to the build element, to preserve HTML compliance
        $builtelement = $element['html'];
        if (0 === strpos($builtelement, "\n<fieldset")) {
            $closelegendpos = strpos($builtelement, '</legend>');
            if ($closelegendpos !== false) {
                $closelegendpos += 9;
                $builtelement = substr($builtelement, 0, $closelegendpos) . '<table><tbody>' . substr($builtelement, $closelegendpos);
            } else {
                $pos = strpos($builtelement, '>') + 1;
                $builtelement = substr($builtelement, 0, $pos) . '<table><tbody>' . substr($builtelement, $pos);
            }
        } else {
            $builtelement = substr($builtelement, 0, 11) . '<table><tbody>' . substr($builtelement, 11);
        }
        $builtelement = substr($builtelement, 0, -12) . '</tbody></table></fieldset>';
        $result = "\t<tr>\n\t\t<td colspan=\"2\">";
        $result .= $builtelement;
        $result .= "</td>\n\t</tr>";
        return $result;
    }
    $result = "\t<tr";
    $result .= ' id="' . $formname . '_' . $element['name'] . '_container"';
    // Set the class of the enclosing <tr> to match that of the element
    if (!empty($element['class'])) {
        $result .= ' class="' . $element['class'] . '"';
    }
    $result .= ">\n\t\t";
    $result .= '<th>';
    if (isset($element['labelhtml'])) {
        $result .= $element['labelhtml'];
    }
    $result .= "</th>\n\t\t<td>";
    $result .= $element['html'];
    if (isset($element['helphtml'])) {
        $result .= ' ' . $element['helphtml'];
    }
    $result .= "</td>\n\t</tr>\n";
    // Description - optional description of the element, or other note that should be visible
    // on the form itself (without the user having to hover over contextual help
    if ((!$form->has_errors() || $form->get_property('showdescriptiononerror')) && !empty($element['description'])) {
        if ($form->get_property('descriptionintwocells')) {
            $result .= "\t<tr>\n\t\t<td></td><td class=\"description\">";
        } else {
            $result .= "\t<tr>\n\t\t<td colspan=\"2\" class=\"description\">";
        }
        $result .= $element['description'];
        $result .= "</td>\n\t</tr>\n";
    }
    if (!empty($element['error'])) {
        $result .= "\t<tr>\n\t\t<td colspan=\"2\" class=\"errmsg\">";
        $result .= $element['error'];
        $result .= "</td>\n\t</tr>\n";
    }
    return $result;
}
/**
 * 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>$LEAP2AFILES</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 bulkimport_validate(Pieform $form, $values)
{
    global $LEAP2AFILES, $USER;
    // Don't even start attempting to parse if there are previous errors
    if ($form->has_errors()) {
        return;
    }
    require_once 'csvfile.php';
    $zipfile = $values['file'];
    if (!is_file($zipfile)) {
        $form->set_error('file', get_string('importfilenotafile', 'admin'));
        return;
    }
    if (!is_readable($zipfile)) {
        $form->set_error('file', get_string('importfilenotreadable', 'admin'));
        return;
    }
    // Create temporary directory
    $importdir = get_config('dataroot') . 'import/' . $USER->get('id') . '/' . time() . '/';
    if (!check_dir_exists($importdir)) {
        throw new SystemException("Couldn't create the temporary export directory {$importdir}");
    }
    $command = sprintf('%s %s %s', escapeshellcmd(get_config('pathtounzip')), escapeshellarg($zipfile), '-d ' . escapeshellarg($importdir));
    $output = array();
    exec($command, $output, $returnvar);
    if ($returnvar != 0) {
        log_debug("unzip command failed with return value {$returnvar}");
        // Let's make it obvious if the cause is obvious :)
        if ($returnvar == 127) {
            log_debug("This means that 'unzip' isn't installed, or the config var \$cfg->pathtounzip is not" . " pointing at unzip (see Mahara's file lib/config-defaults.php)");
        }
        throw new SystemException(get_string('unzipfailed', 'admin', hsc($zipfile)));
    } else {
        log_debug("Unzipped {$zipfile} into {$importdir}");
    }
    $csvfilename = $importdir . '/usernames.csv';
    if (!is_readable($csvfilename)) {
        $form->set_error('file', get_string('importfilemissinglisting', 'admin'));
        return;
    }
    $csvusers = new CsvFile($csvfilename);
    $csvusers->set('headerExists', false);
    $csvusers->set('format', array('username', 'filename'));
    $csvdata = $csvusers->get_data();
    if (!empty($csvdata->errors['file'])) {
        $form->set_error('file', get_string('invalidlistingfile', 'admin'));
        return;
    }
    foreach ($csvdata->data as $user) {
        $username = $user[0];
        $filename = $user[1];
        $LEAP2AFILES[$username] = "{$importdir}/users/{$filename}";
    }
}
示例#4
0
/**
 * 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>$LEAP2AFILES</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 bulkimport_validate(Pieform $form, $values)
{
    global $LEAP2AFILES, $USER;
    // Don't even start attempting to parse if there are previous errors
    if ($form->has_errors()) {
        return;
    }
    require_once 'csvfile.php';
    $zipfile = $values['file'];
    if (!is_file($zipfile)) {
        $form->set_error('file', get_string('importfilenotafile', 'admin'));
        return;
    }
    if (!is_readable($zipfile)) {
        $form->set_error('file', get_string('importfilenotreadable', 'admin'));
        return;
    }
    // Create temporary directory
    $importdir = get_config('dataroot') . 'import/' . $USER->get('id') . '/' . time() . '/';
    if (!check_dir_exists($importdir)) {
        throw new SystemException("Couldn't create the temporary export directory {$importdir}");
    }
    $archive = new ZipArchive();
    if ($archive->open($zipfile) && $archive->extractTo($importdir)) {
        // successfully extracted
        $archive->close();
        log_debug("Unzipped {$zipfile} into {$importdir}");
    } else {
        throw new SystemException(get_string('unzipfailed', 'admin', hsc($zipfile)));
    }
    $csvfilename = $importdir . '/usernames.csv';
    if (!is_readable($csvfilename)) {
        $form->set_error('file', get_string('importfilemissinglisting', 'admin'));
        return;
    }
    $csvusers = new CsvFile($csvfilename);
    $csvusers->set('headerExists', false);
    $csvusers->set('format', array('username', 'filename'));
    $csvdata = $csvusers->get_data();
    if (!empty($csvdata->errors['file'])) {
        $form->set_error('file', get_string('invalidlistingfile', 'admin'));
        return;
    }
    foreach ($csvdata->data as $user) {
        $username = $user[0];
        $filename = $user[1];
        $LEAP2AFILES[$username] = "{$importdir}/users/{$filename}";
    }
}
/**
 * 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;
}
示例#6
0
/**
 * Browser for files area.
 *
 * @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_filebrowser(Pieform $form, $element)
{
    require_once 'license.php';
    global $USER, $_PIEFORM_FILEBROWSERS;
    $smarty = smarty_core();
    // See if the filebrowser has indicated it's a group element
    if (!empty($element['group'])) {
        $group = $element['group'];
    } else {
        // otherwise check if the form knows it's in a group setting
        $group = $form->get_property('group');
    }
    // See if the filebrowser has indicated it's an institution element
    if (!empty($element['institution'])) {
        $institution = $element['institution'];
    } else {
        // otherwise check if the form knows it's in an institution setting
        $institution = $form->get_property('institution');
    }
    $formid = $form->get_name();
    $prefix = $formid . '_' . $element['name'];
    if (!empty($element['tabs'])) {
        $tabdata = pieform_element_filebrowser_configure_tabs($element['tabs'], $prefix);
        $smarty->assign('tabs', $tabdata);
        if (!$group && $tabdata['owner'] == 'group') {
            $group = $tabdata['ownerid'];
        } else {
            if (!$institution) {
                if ($tabdata['owner'] == 'institution') {
                    $institution = $tabdata['ownerid'];
                } else {
                    if ($tabdata['owner'] == 'site') {
                        $institution = 'mahara';
                    }
                }
            }
        }
    }
    $userid = $group || $institution ? null : $USER->get('id');
    // refresh quotas
    if ($userid) {
        $USER->quota_refresh();
    }
    $folder = $element['folder'];
    if ($group && !pieform_element_filebrowser_view_group_folder($group, $folder)) {
        $folder = null;
    }
    $path = pieform_element_filebrowser_get_path($folder);
    $smarty->assign('folder', $folder);
    $smarty->assign('foldername', $path[0]->title);
    $smarty->assign('path', array_reverse($path));
    $smarty->assign('highlight', $element['highlight'][0]);
    $smarty->assign('edit', !empty($element['edit']) ? $element['edit'] : -1);
    if (isset($element['browse'])) {
        $smarty->assign('browse', (int) $element['browse']);
    }
    $config = array_map('intval', $element['config']);
    if ($group && $config['edit']) {
        $smarty->assign('groupinfo', pieform_element_filebrowser_get_groupinfo($group));
    }
    if ($config['select']) {
        if (function_exists($element['selectlistcallback'])) {
            if ($form->is_submitted() && $form->has_errors() && isset($_POST[$prefix . '_selected']) && is_array($_POST[$prefix . '_selected'])) {
                $value = array_keys($_POST[$prefix . '_selected']);
            } else {
                if (isset($element['defaultvalue'])) {
                    $value = $element['defaultvalue'];
                } else {
                    $value = null;
                }
            }
            // check to see if attached artefact items in $value array are actually allowed
            // to be seen by this user
            if (!empty($value)) {
                foreach ($value as $k => $v) {
                    $file = artefact_instance_from_id($v);
                    if (!$file instanceof ArtefactTypeFile && !$file instanceof ArtefactTypeFolder || !$USER->can_view_artefact($file)) {
                        unset($value[$k]);
                    }
                }
            }
            $selected = $element['selectlistcallback']($value);
        }
        $smarty->assign('selectedlist', $selected);
        $selectedliststr = json_encode($selected);
    }
    if ($config['uploadagreement']) {
        if (get_config_plugin('artefact', 'file', 'usecustomagreement')) {
            $smarty->assign('agreementtext', get_field('site_content', 'content', 'name', 'uploadcopyright'));
        } else {
            $smarty->assign('agreementtext', get_string('uploadcopyrightdefaultcontent', 'install'));
        }
    } else {
        if (!isset($config['simpleupload'])) {
            $config['simpleupload'] = 1;
        }
    }
    $licensing = '<div class="fileuploadlicense">' . license_form_files($prefix) . '</div>';
    $smarty->assign('licenseform', $licensing);
    if ($config['resizeonuploaduseroption'] == 1) {
        $smarty->assign('resizeonuploadenable', get_config_plugin('artefact', 'file', 'resizeonuploadenable'));
        $smarty->assign('resizeonuploadmaxwidth', get_config_plugin('artefact', 'file', 'resizeonuploadmaxwidth'));
        $smarty->assign('resizeonuploadmaxheight', get_config_plugin('artefact', 'file', 'resizeonuploadmaxheight'));
    }
    if ($config['upload']) {
        $maxuploadsize = display_size(get_max_upload_size(!$institution && !$group));
        $smarty->assign('maxuploadsize', $maxuploadsize);
        $smarty->assign('phpmaxfilesize', get_max_upload_size(false));
        if ($group) {
            $smarty->assign('uploaddisabled', !pieform_element_filebrowser_edit_group_folder($group, $folder));
        }
    }
    if (!empty($element['browsehelp'])) {
        $config['plugintype'] = $form->get_property('plugintype');
        $config['pluginname'] = $form->get_property('pluginname');
        $config['browsehelp'] = $element['browsehelp'];
    }
    $config['showtags'] = !empty($config['tag']) ? (int) $userid : 0;
    $config['editmeta'] = (int) ($userid && !$config['edit'] && !empty($config['tag']));
    $smarty->assign('config', $config);
    $filters = isset($element['filters']) ? $element['filters'] : null;
    $filedata = ArtefactTypeFileBase::get_my_files_data($folder, $userid, $group, $institution, $filters);
    $smarty->assign('filelist', $filedata);
    $configstr = json_encode($config);
    $fileliststr = json_encode($filedata);
    $smarty->assign('prefix', $prefix);
    $accepts = isset($element['accept']) ? 'accept="' . Pieform::hsc($element['accept']) . '"' : '';
    $smarty->assign('accepts', $accepts);
    $initjs = "{$prefix} = new FileBrowser('{$prefix}', {$folder}, {$configstr}, config);\n{$prefix}.filedata = {$fileliststr};";
    if ($config['select']) {
        $initjs .= "{$prefix}.selecteddata = {$selectedliststr};";
    }
    if (isset($tabdata)) {
        $initjs .= "{$prefix}.tabdata = " . json_encode($tabdata) . ';';
    }
    $_PIEFORM_FILEBROWSERS[$prefix]['views_js'] = $initjs;
    $initjs .= "addLoadEvent({$prefix}.init);";
    $initjs .= "upload_max_filesize = '" . get_real_size(ini_get('upload_max_filesize')) . "';";
    $smarty->assign('initjs', $initjs);
    $smarty->assign('querybase', $element['page'] . (strpos($element['page'], '?') === false ? '?' : '&'));
    $params = 'folder=' . $folder;
    if ($group) {
        $params .= '&group=' . $group;
    }
    if ($institution) {
        $params .= '&institution=' . $institution;
    }
    $switchwidth = ArtefactTypeFileBase::get_switch_width();
    $smarty->assign('switchwidth', $switchwidth);
    $smarty->assign('folderparams', $params);
    return $smarty->fetch('artefact:file:form/filebrowser.tpl');
}
示例#7
0
/**
 * 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;
}
示例#8
0
文件: div.php 项目: agwells/Mahara-1
/**
 * Renders form elements inside <div>s.
 *
 * @param Pieform $form    The form the element is being rendered for
 * @param array   $element The element to be rendered
 * @return string          The element rendered inside an appropriate container
 */
function pieform_renderer_div(Pieform $form, $element)
{
    /*{{{*/
    $formname = $form->get_name();
    // Set the class of the enclosing <div> to match that of the element
    $prefix = '';
    $suffix = '';
    $inner = '';
    // allow forms to be rendered without a wrapping div
    if (!isset($element['renderelementsonly'])) {
        $prefix = '<div';
        if (isset($element['name'])) {
            $prefix .= ' id="' . $formname . '_' . Pieform::hsc($element['name']) . '_container"';
        }
        // all elements should be form groups by default except button
        if (!isset($element['isformgroup'])) {
            $element['isformgroup'] = true;
        }
        if (isset($element['type'])) {
            $element['isformgroup'] = $element['type'] === 'button' ? false : $element['isformgroup'];
        }
        // add form-group classes to all real form fields
        $formgroupclass = $element['isformgroup'] ? 'form-group' : '';
        if (isset($element['class'])) {
            // remove form-control class and btn class (these should be on the element only)
            $element['class'] = str_replace("btn-", " ", $element['class']);
            $element['class'] = str_replace("form-control ", "", $element['class']);
            $element['class'] = $element['class'] . ' ' . $formgroupclass;
        } else {
            $element['class'] = $formgroupclass;
        }
        if (isset($element['collapsible'])) {
            $element['class'] = $element['class'] . ' collapsible-group';
        }
        // add bootstrap has-error class to any error fields
        if (strpos($element['class'], 'error') !== false) {
            $element['class'] = $element['class'] . ' has-error';
        }
        $prefix .= ' class="' . Pieform::hsc($element['class']) . '"';
        $prefix .= '>';
    }
    if (isset($element['labelhtml'])) {
        $inner .= $element['labelhtml'];
    }
    if (isset($element['prehtml'])) {
        $inner .= '<span class="prehtml">' . $element['prehtml'] . '</span>';
    }
    if (isset($element['html'])) {
        $inner .= $element['html'];
    }
    if (isset($element['posthtml'])) {
        $inner .= '<span class="posthtml">' . $element['posthtml'] . '</span>';
    }
    if (isset($element['helphtml'])) {
        $inner .= ' ' . $element['helphtml'];
    }
    // Description - optional description of the element, or other note that should be visible
    // on the form itself (without the user having to hover over contextual help
    if ((!$form->has_errors() || $form->get_property('showdescriptiononerror')) && !empty($element['descriptionhtml'])) {
        $inner .= '<div class="description"> ' . $element['descriptionhtml'] . "</div>";
    }
    if (!empty($element['error'])) {
        $inner .= '<div class="errmsg">' . $element['errorhtml'] . '</div>';
    }
    if (!isset($element['renderelementsonly'])) {
        $suffix .= "</div>\n";
    }
    $result = $prefix . $inner . $suffix;
    return $result;
}
示例#9
0
/**
 * 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;
}
示例#10
0
/**
 * Browser for files area.
 *
 * @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_filebrowser(Pieform $form, $element)
{
    global $USER, $_PIEFORM_FILEBROWSERS;
    $smarty = smarty_core();
    $group = $form->get_property('group');
    $institution = $form->get_property('institution');
    if (!empty($element['tabs'])) {
        $tabdata = pieform_element_filebrowser_configure_tabs($element['tabs']);
        $smarty->assign('tabs', $tabdata);
        if (!$group && $tabdata['owner'] == 'group') {
            $group = $tabdata['ownerid'];
        } else {
            if (!$institution) {
                if ($tabdata['owner'] == 'institution') {
                    $institution = $tabdata['ownerid'];
                } else {
                    if ($tabdata['owner'] == 'site') {
                        $institution = 'mahara';
                    }
                }
            }
        }
    }
    $userid = $group || $institution ? null : $USER->get('id');
    // refresh quotas
    if ($userid) {
        $USER->quota_refresh();
    }
    $folder = $element['folder'];
    $path = pieform_element_filebrowser_get_path($folder);
    $smarty->assign('folder', $folder);
    $smarty->assign('foldername', $path[0]->title);
    $smarty->assign('path', array_reverse($path));
    $smarty->assign('highlight', $element['highlight'][0]);
    $smarty->assign('edit', !empty($element['edit']) ? $element['edit'] : -1);
    if (isset($element['browse'])) {
        $smarty->assign('browse', (int) $element['browse']);
    }
    $config = array_map('intval', $element['config']);
    if ($group && $config['edit']) {
        $smarty->assign('groupinfo', pieform_element_filebrowser_get_groupinfo($group));
    }
    $formid = $form->get_name();
    $prefix = $formid . '_' . $element['name'];
    if ($config['select']) {
        if (function_exists($element['selectlistcallback'])) {
            if ($form->is_submitted() && $form->has_errors() && isset($_POST[$prefix . '_selected']) && is_array($_POST[$prefix . '_selected'])) {
                $value = array_keys($_POST[$prefix . '_selected']);
            } else {
                if (isset($element['defaultvalue'])) {
                    $value = $element['defaultvalue'];
                } else {
                    $value = null;
                }
            }
            $selected = $element['selectlistcallback']($value);
        }
        $smarty->assign('selectedlist', $selected);
        $selectedliststr = json_encode($selected);
    }
    if ($config['uploadagreement']) {
        if (get_config_plugin('artefact', 'file', 'usecustomagreement')) {
            $smarty->assign('agreementtext', get_field('site_content', 'content', 'name', 'uploadcopyright'));
        } else {
            $smarty->assign('agreementtext', get_string('uploadcopyrightdefaultcontent', 'install'));
        }
    }
    if ($config['upload']) {
        $maxuploadsize = min(get_real_size(ini_get('post_max_size')), get_real_size(ini_get('upload_max_filesize')));
        if (!$institution && !$group) {
            $userquotaremaining = $USER->get('quota') - $USER->get('quotaused');
            $maxuploadsize = min($maxuploadsize, $userquotaremaining);
        }
        $maxuploadsize = display_size($maxuploadsize);
        $smarty->assign('maxuploadsize', $maxuploadsize);
    }
    if (!empty($element['browsehelp'])) {
        $config['plugintype'] = $form->get_property('plugintype');
        $config['pluginname'] = $form->get_property('pluginname');
        $config['browsehelp'] = $element['browsehelp'];
    }
    $config['showtags'] = !empty($config['tag']) ? (int) $userid : 0;
    $config['editmeta'] = (int) ($userid && !$config['edit'] && !empty($config['tag']));
    $smarty->assign('config', $config);
    $filters = isset($element['filters']) ? $element['filters'] : null;
    $filedata = ArtefactTypeFileBase::get_my_files_data($folder, $userid, $group, $institution, $filters);
    $smarty->assign('filelist', $filedata);
    $configstr = json_encode($config);
    $fileliststr = json_encode($filedata);
    $smarty->assign('prefix', $prefix);
    $initjs = "{$prefix} = new FileBrowser('{$prefix}', {$folder}, {$configstr}, config);\n{$prefix}.filedata = {$fileliststr};";
    if ($config['select']) {
        $initjs .= "{$prefix}.selecteddata = {$selectedliststr};";
    }
    $_PIEFORM_FILEBROWSERS[$prefix]['views_js'] = $initjs;
    $initjs .= "addLoadEvent({$prefix}.init);";
    $smarty->assign('initjs', $initjs);
    $smarty->assign('querybase', $element['page'] . (strpos($element['page'], '?') === false ? '?' : '&'));
    return $smarty->fetch('artefact:file:form/filebrowser.tpl');
}
/**
 * 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;
}
示例#12
0
/**
 * Renders form elements inside a <table>.
 *
 * @param Pieform $form    The form the element is being rendered for
 * @param string  $element The element to be rendered
 * @return string          The element rendered inside an appropriate container
 */
function pieform_renderer_maharatable(Pieform $form, $element)
{
    $formname = $form->get_name();
    if ($element['type'] == 'fieldset') {
        // Add table tags to the build element, to preserve HTML compliance
        $builtelement = $element['html'];
        if (0 === strpos($builtelement, "\n<fieldset")) {
            $closelegendpos = strpos($builtelement, '</legend>');
            if ($closelegendpos !== false) {
                $closelegendpos += 9;
                $builtelement = substr($builtelement, 0, $closelegendpos) . '<table>' . substr($builtelement, $closelegendpos);
            } else {
                $pos = strpos($builtelement, '>') + 1;
                $builtelement = substr($builtelement, 0, $pos) . '<table>' . substr($builtelement, $pos);
            }
        } else {
            $builtelement = substr($builtelement, 0, 11) . '<table>' . substr($builtelement, 11);
        }
        $builtelement = substr($builtelement, 0, -12) . '</table></fieldset>';
        $result = "\t<tr>\n\t\t<td colspan=\"2\">";
        $result .= $builtelement;
        $result .= "</td>\n\t</tr>";
        return $result;
    }
    $result = '';
    if (isset($element['labelhtml']) && $element['labelhtml'] !== '') {
        $result .= "\t<tr";
        $result .= ' id="' . $formname . '_' . $element['name'] . '_header"';
        // Set the class of the enclosing <tr> to match that of the element
        if ($element['class']) {
            $result .= ' class="' . $element['class'] . '"';
        }
        $result .= ">\n\t\t";
        $result .= '<th>';
        $result .= $element['labelhtml'];
        $result .= "</th>\n\t</tr>\n";
    }
    $result .= "\t<tr id=\"{$formname}_{$element['name']}_container\">\n\t\t<td>";
    // Wrap WYSIWYG elements in a table with two cells side by side, one for the element and one for the help icon
    if (!empty($element['help']) && $element['type'] == 'wysiwyg') {
        $result .= '<table class="help-wrapper"><tr><td>';
    }
    // Add the element itself
    $result .= $element['html'];
    if (!empty($element['help']) && $element['type'] == 'wysiwyg') {
        $result .= '</td><td>';
    }
    // Contextual help
    if (!empty($element['help'])) {
        $result .= get_help_icon($form->get_property('plugintype'), $form->get_property('pluginname'), $form->get_name(), $element['name']);
        if ($element['type'] == 'wysiwyg') {
            $result .= '</td></tr></table>';
        }
    }
    $result .= "</td>\n\t</tr>\n";
    // Description - optional description of the element, or other note that should be visible
    // on the form itself (without the user having to hover over contextual help
    if ((!$form->has_errors() || $form->get_property('showdescriptiononerror')) && !empty($element['description'])) {
        $result .= "\t<tr>\n\t\t<td class=\"description\">";
        $result .= $element['description'];
        $result .= "</td>\n\t</tr>\n";
    }
    if (!empty($element['error'])) {
        $result .= "\t<tr>\n\t\t<td class=\"errmsg\">";
        $result .= $element['error'];
        $result .= "</td>\n\t</tr>\n";
    }
    return $result;
}
示例#13
0
/**
 * 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'));
    }
}