コード例 #1
0
ファイル: index.php プロジェクト: Jtgadbois/Pedadida
function csv_quote($value) {
    global $excel;
    if ($excel) {
        return textlib::convert('"'.str_replace('"',"'",$value).'"','UTF-8','UTF-16LE');
    } else {
        return '"'.str_replace('"',"'",$value).'"';
    }
}
コード例 #2
0
 public function sanitize($data, $type, $base = '')
 {
     $data = trim($data);
     if ($data === '') {
         return '';
     }
     if ($type & SIMPLEPIE_CONSTRUCT_BASE64) {
         $data = base64_decode($data);
     }
     if ($type & SIMPLEPIE_CONSTRUCT_MAYBE_HTML) {
         if (preg_match('/(&(#(x[0-9a-fA-F]+|[0-9]+)|[a-zA-Z0-9]+)|<\\/[A-Za-z][^\\x09\\x0A\\x0B\\x0C\\x0D\\x20\\x2F\\x3E]*' . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . '>)/', $data)) {
             $type |= SIMPLEPIE_CONSTRUCT_HTML;
         } else {
             $type |= SIMPLEPIE_CONSTRUCT_TEXT;
         }
     }
     if ($type & SIMPLEPIE_CONSTRUCT_IRI) {
         $absolute = $this->registry->call('Misc', 'absolutize_url', array($data, $base));
         if ($absolute !== false) {
             $data = $absolute;
         }
         $data = clean_param($data, PARAM_URL);
     }
     if ($type & (SIMPLEPIE_CONSTRUCT_TEXT | SIMPLEPIE_CONSTRUCT_IRI)) {
         $data = htmlspecialchars($data, ENT_COMPAT, 'UTF-8');
     }
     $data = purify_html($data);
     if ($this->remove_div) {
         $data = preg_replace('/^<div' . SIMPLEPIE_PCRE_XML_ATTRIBUTE . '>/', '', $data);
         $data = preg_replace('/<\\/div>$/', '', $data);
     } else {
         $data = preg_replace('/^<div' . SIMPLEPIE_PCRE_XML_ATTRIBUTE . '>/', '<div>', $data);
     }
     if ($this->output_encoding !== 'UTF-8') {
         textlib::convert($data, 'UTF-8', $this->output_encoding);
     }
     return $data;
 }
コード例 #3
0
ファイル: lib.php プロジェクト: numbas/moodle
/**
 * Returns location information
 * @param string $ip
 * @return array
 */
function iplookup_find_location($ip)
{
    global $CFG;
    $info = array('city' => null, 'country' => null, 'longitude' => null, 'latitude' => null, 'error' => null, 'note' => '', 'title' => array());
    if (!empty($CFG->geoipfile) and file_exists($CFG->geoipfile)) {
        require_once 'Net/GeoIP.php';
        $geoip = Net_GeoIP::getInstance($CFG->geoipfile, Net_GeoIP::STANDARD);
        $location = $geoip->lookupLocation($ip);
        $geoip->close();
        if (empty($location)) {
            $info['error'] = get_string('iplookupfailed', 'error', $ip);
            return $info;
        }
        if (!empty($location->city)) {
            $info['city'] = textlib::convert($location->city, 'iso-8859-1', 'utf-8');
            $info['title'][] = $info['city'];
        }
        if (!empty($location->country_code)) {
            $countries = get_string_manager()->get_list_of_countries(true);
            if (isset($countries[$location->country_code])) {
                // prefer our localized country names
                $info['country'] = $countries[$location->country_code];
            } else {
                $info['country'] = $location->country_name;
            }
            $info['title'][] = $info['country'];
        }
        $info['longitude'] = $location->longitude;
        $info['latitude'] = $location->latitude;
        $info['note'] = get_string('iplookupmaxmindnote', 'admin');
        return $info;
    } else {
        require_once $CFG->libdir . '/filelib.php';
        $ipdata = download_file_content('http://netgeo.caida.org/perl/netgeo.cgi?target=' . $ip);
        if ($ipdata === false) {
            $info['error'] = get_string('cannotnetgeo', 'error');
            return $info;
        }
        $matches = null;
        if (!preg_match('/LAT:\\s*(-?\\d+\\.\\d+)/s', $ipdata, $matches)) {
            $info['error'] = get_string('iplookupfailed', 'error', $ip);
            return $info;
        }
        $info['latitude'] = (double) $matches[1];
        if (!preg_match('/LONG:\\s*(-?\\d+\\.\\d+)/s', $ipdata, $matches)) {
            $info['error'] = get_string('iplookupfailed', 'error', $ip);
            return $info;
        }
        $info['longitude'] = (double) $matches[1];
        if (preg_match('/CITY:\\s*([^<]*)/', $ipdata, $matches)) {
            if (!empty($matches[1])) {
                $info['city'] = s($matches[1]);
                $info['title'][] = $info['city'];
            }
        }
        if (preg_match('/COUNTRY:\\s*([^<]*)/', $ipdata, $matches)) {
            if (!empty($matches[1])) {
                $countrycode = $matches[1];
                $countries = get_string_manager()->get_list_of_countries(true);
                if (isset($countries[$countrycode])) {
                    // prefer our localized country names
                    $info['country'] = $countries[$countrycode];
                } else {
                    $info['country'] = $countrycode;
                }
                $info['title'][] = $info['country'];
            }
        }
        $info['note'] = get_string('iplookupnetgeonote', 'admin');
        return $info;
    }
}
コード例 #4
0
    } else if ($type === 'file') {
        // Large files are likely to take their time and memory. Let PHP know
        // that we'll take longer, and that the process should be recycled soon
        // to free up memory.
        @set_time_limit(0);
        @raise_memory_limit("192M");
        if (function_exists('apache_child_terminate')) {
            @apache_child_terminate();
        }

        $text = $form->get_file_content('userfile');

        // Trim utf-8 bom.
        $text = textlib::trim_utf8_bom($text);
        // Do the encoding conversion.
        $rawinput = textlib::convert($text, $data->encoding);
    }

    // Replace commas with newlines and remove carriage returns.
    $rawinput = str_replace(array("\r\n", "\r", ","), "\n", $rawinput);

    $addusers = clean_param($rawinput, PARAM_NOTAGS);
    // Turn into array.
    $addusers = explode("\n", $addusers);
    // Remove any leading or trailing spaces.
    $addusers = array_map('trim', $addusers);
    // Filter out empty strings/false/null using array_filter.
    $addusers = array_filter($addusers);

    // Bulk add results
    $errors = array();
コード例 #5
0
ファイル: auth.php プロジェクト: verbazend/AWFA
 /**
  * Returns true if user should be coursecreator.
  *
  * @param mixed $username    username (without system magic quotes)
  * @return boolean result
  */
 function iscreator($username)
 {
     if (empty($this->config->host_url) or empty($this->config->attrcreators) && empty($this->config->groupecreators) or empty($this->config->memberattribute)) {
         return false;
     }
     $extusername = textlib::convert($username, 'utf-8', $this->config->ldapencoding);
     // Test for group creator
     if (!empty($this->config->groupecreators)) {
         $ldapconnection = $this->ldap_connect();
         if ($this->config->memberattribute_isdn) {
             if (!($userid = $this->ldap_find_userdn($ldapconnection, $extusername))) {
                 return false;
             }
         } else {
             $userid = $extusername;
         }
         $group_dns = explode(';', $this->config->groupecreators);
         if (ldap_isgroupmember($ldapconnection, $userid, $group_dns, $this->config->memberattribute)) {
             return true;
         }
     }
     // Build filter for attrcreator
     if (!empty($this->config->attrcreators)) {
         $attrs = explode(';', $this->config->attrcreators);
         $filter = '(& (' . $this->config->user_attribute . "={$username})(|";
         foreach ($attrs as $attr) {
             if (strpos($attr, '=')) {
                 $filter .= "({$attr})";
             } else {
                 $filter .= '(' . $this->config->memberattribute . "={$attr})";
             }
         }
         $filter .= '))';
         // Search
         $result = $this->ldap_get_userlist($filter);
         if (count($result) != 0) {
             return true;
         }
     }
     return false;
 }
コード例 #6
0
 /**
  * Parse this content
  *
  * @global object
  * @global object
  * @param string $content passed by ref for memory reasons, unset after return
  * @param string $encoding content encoding
  * @param string $delimiter_name separator (comma, semicolon, colon, cfg)
  * @param string $column_validation name of function for columns validation, must have one param $columns
  * @return bool false if error, count of data lines if ok; use get_error() to get error string
  */
 function load_csv_content(&$content, $encoding, $delimiter_name, $column_validation = null)
 {
     global $USER, $CFG;
     $this->close();
     $this->_error = null;
     $content = textlib::convert($content, $encoding, 'utf-8');
     // remove Unicode BOM from first line
     $content = textlib::trim_utf8_bom($content);
     // Fix mac/dos newlines
     $content = preg_replace('!\\r\\n?!', "\n", $content);
     // is there anyting in file?
     $columns = strtok($content, "\n");
     if ($columns === false) {
         $this->_error = get_string('csvemptyfile', 'error');
         return false;
     }
     $csv_delimiter = csv_import_reader::get_delimiter($delimiter_name);
     $csv_encode = csv_import_reader::get_encoded_delimiter($delimiter_name);
     // process header - list of columns
     $columns = explode($csv_delimiter, $columns);
     $col_count = count($columns);
     if ($col_count === 0) {
         $this->_error = get_string('csvemptyfile', 'error');
         return false;
     }
     foreach ($columns as $key => $value) {
         $columns[$key] = str_replace($csv_encode, $csv_delimiter, trim($value));
     }
     if ($column_validation) {
         $result = $column_validation($columns);
         if ($result !== true) {
             $this->_error = $result;
             return false;
         }
     }
     $this->_columns = $columns;
     // cached columns
     // open file for writing
     $filename = $CFG->tempdir . '/csvimport/' . $this->_type . '/' . $USER->id . '/' . $this->_iid;
     $fp = fopen($filename, "w");
     fwrite($fp, serialize($columns) . "\n");
     // again - do we have any data for processing?
     $line = strtok("\n");
     $data_count = 0;
     while ($line !== false) {
         $line = explode($csv_delimiter, $line);
         foreach ($line as $key => $value) {
             $line[$key] = str_replace($csv_encode, $csv_delimiter, trim($value));
         }
         if (count($line) !== $col_count) {
             // this is critical!!
             $this->_error = get_string('csvweirdcolumns', 'error');
             fclose($fp);
             $this->cleanup();
             return false;
         }
         fwrite($fp, serialize($line) . "\n");
         $data_count++;
         $line = strtok("\n");
     }
     fclose($fp);
     return $data_count;
 }
コード例 #7
0
ファイル: lib.php プロジェクト: Jtgadbois/Pedadida
 /**
  * Return multidimensional array with details of user courses (at
  * least dn and idnumber).
  *
  * @param string $memberuid user idnumber (without magic quotes).
  * @param object role is a record from the mdl_role table.
  * @return array
  */
 protected function find_ext_enrolments($memberuid, $role)
 {
     global $CFG;
     require_once $CFG->libdir . '/ldaplib.php';
     if (empty($memberuid)) {
         // No "idnumber" stored for this user, so no LDAP enrolments
         return array();
     }
     $ldap_contexts = trim($this->get_config('contexts_role' . $role->id));
     if (empty($ldap_contexts)) {
         // No role contexts, so no LDAP enrolments
         return array();
     }
     $extmemberuid = textlib::convert($memberuid, 'utf-8', $this->get_config('ldapencoding'));
     if ($this->get_config('memberattribute_isdn')) {
         if (!($extmemberuid = $this->ldap_find_userdn($extmemberuid))) {
             return array();
         }
     }
     $ldap_search_pattern = '';
     if ($this->get_config('nested_groups')) {
         $usergroups = $this->ldap_find_user_groups($extmemberuid);
         if (count($usergroups) > 0) {
             foreach ($usergroups as $group) {
                 $ldap_search_pattern .= '(' . $this->get_config('memberattribute_role' . $role->id) . '=' . $group . ')';
             }
         }
     }
     // Default return value
     $courses = array();
     // Get all the fields we will want for the potential course creation
     // as they are light. don't get membership -- potentially a lot of data.
     $ldap_fields_wanted = array('dn', $this->get_config('course_idnumber'));
     $fullname = $this->get_config('course_fullname');
     $shortname = $this->get_config('course_shortname');
     $summary = $this->get_config('course_summary');
     if (isset($fullname)) {
         array_push($ldap_fields_wanted, $fullname);
     }
     if (isset($shortname)) {
         array_push($ldap_fields_wanted, $shortname);
     }
     if (isset($summary)) {
         array_push($ldap_fields_wanted, $summary);
     }
     // Define the search pattern
     if (empty($ldap_search_pattern)) {
         $ldap_search_pattern = '(' . $this->get_config('memberattribute_role' . $role->id) . '=' . ldap_filter_addslashes($extmemberuid) . ')';
     } else {
         $ldap_search_pattern = '(|' . $ldap_search_pattern . '(' . $this->get_config('memberattribute_role' . $role->id) . '=' . ldap_filter_addslashes($extmemberuid) . ')' . ')';
     }
     $ldap_search_pattern = '(&' . $this->get_config('objectclass') . $ldap_search_pattern . ')';
     // Get all contexts and look for first matching user
     $ldap_contexts = explode(';', $ldap_contexts);
     $ldap_pagedresults = ldap_paged_results_supported($this->get_config('ldap_version'));
     foreach ($ldap_contexts as $context) {
         $context = trim($context);
         if (empty($context)) {
             continue;
         }
         $ldap_cookie = '';
         $flat_records = array();
         do {
             if ($ldap_pagedresults) {
                 ldap_control_paged_result($this->ldapconnection, $this->config->pagesize, true, $ldap_cookie);
             }
             if ($this->get_config('course_search_sub')) {
                 // Use ldap_search to find first user from subtree
                 $ldap_result = @ldap_search($this->ldapconnection, $context, $ldap_search_pattern, $ldap_fields_wanted);
             } else {
                 // Search only in this context
                 $ldap_result = @ldap_list($this->ldapconnection, $context, $ldap_search_pattern, $ldap_fields_wanted);
             }
             if (!$ldap_result) {
                 continue;
             }
             if ($ldap_pagedresults) {
                 ldap_control_paged_result_response($this->ldapconnection, $ldap_result, $ldap_cookie);
             }
             // Check and push results. ldap_get_entries() already
             // lowercases the attribute index, so there's no need to
             // use array_change_key_case() later.
             $records = ldap_get_entries($this->ldapconnection, $ldap_result);
             // LDAP libraries return an odd array, really. Fix it.
             for ($c = 0; $c < $records['count']; $c++) {
                 array_push($flat_records, $records[$c]);
             }
             // Free some mem
             unset($records);
         } while ($ldap_pagedresults && !empty($ldap_cookie));
         // If LDAP paged results were used, the current connection must be completely
         // closed and a new one created, to work without paged results from here on.
         if ($ldap_pagedresults) {
             $this->ldap_close();
             $this->ldap_connect();
         }
         if (count($flat_records)) {
             $courses = array_merge($courses, $flat_records);
         }
     }
     return $courses;
 }
コード例 #8
0
ファイル: moodlelib.php プロジェクト: nmicha/moodle
/**
 * Send an email to a specified user
 *
 * @global object
 * @global string
 * @global string IdentityProvider(IDP) URL user hits to jump to mnet peer.
 * @uses SITEID
 * @param stdClass $user  A {@link $USER} object
 * @param stdClass $from A {@link $USER} object
 * @param string $subject plain text subject line of the email
 * @param string $messagetext plain text version of the message
 * @param string $messagehtml complete html version of the message (optional)
 * @param string $attachment a file on the filesystem, relative to $CFG->dataroot
 * @param string $attachname the name of the file (extension indicates MIME)
 * @param bool $usetrueaddress determines whether $from email address should
 *          be sent out. Will be overruled by user profile setting for maildisplay
 * @param string $replyto Email address to reply to
 * @param string $replytoname Name of reply to recipient
 * @param int $wordwrapwidth custom word wrap width, default 79
 * @return bool Returns true if mail was sent OK and false if there was an error.
 */
function email_to_user($user, $from, $subject, $messagetext, $messagehtml = '', $attachment = '', $attachname = '', $usetrueaddress = true, $replyto = '', $replytoname = '', $wordwrapwidth = 79)
{
    global $CFG;
    if (empty($user) || empty($user->email)) {
        $nulluser = '******';
        error_log($nulluser);
        if (CLI_SCRIPT) {
            mtrace('Error: lib/moodlelib.php email_to_user(): ' . $nulluser);
        }
        return false;
    }
    if (!empty($user->deleted)) {
        // do not mail deleted users
        $userdeleted = 'User is deleted';
        error_log($userdeleted);
        if (CLI_SCRIPT) {
            mtrace('Error: lib/moodlelib.php email_to_user(): ' . $userdeleted);
        }
        return false;
    }
    if (!empty($CFG->noemailever)) {
        // hidden setting for development sites, set in config.php if needed
        $noemail = 'Not sending email due to noemailever config setting';
        error_log($noemail);
        if (CLI_SCRIPT) {
            mtrace('Error: lib/moodlelib.php email_to_user(): ' . $noemail);
        }
        return true;
    }
    if (!empty($CFG->divertallemailsto)) {
        $subject = "[DIVERTED {$user->email}] {$subject}";
        $user = clone $user;
        $user->email = $CFG->divertallemailsto;
    }
    // skip mail to suspended users
    if (isset($user->auth) && $user->auth == 'nologin' or isset($user->suspended) && $user->suspended) {
        return true;
    }
    if (!validate_email($user->email)) {
        // we can not send emails to invalid addresses - it might create security issue or confuse the mailer
        $invalidemail = "User {$user->id} (" . fullname($user) . ") email ({$user->email}) is invalid! Not sending.";
        error_log($invalidemail);
        if (CLI_SCRIPT) {
            mtrace('Error: lib/moodlelib.php email_to_user(): ' . $invalidemail);
        }
        return false;
    }
    if (over_bounce_threshold($user)) {
        $bouncemsg = "User {$user->id} (" . fullname($user) . ") is over bounce threshold! Not sending.";
        error_log($bouncemsg);
        if (CLI_SCRIPT) {
            mtrace('Error: lib/moodlelib.php email_to_user(): ' . $bouncemsg);
        }
        return false;
    }
    // If the user is a remote mnet user, parse the email text for URL to the
    // wwwroot and modify the url to direct the user's browser to login at their
    // home site (identity provider - idp) before hitting the link itself
    if (is_mnet_remote_user($user)) {
        require_once $CFG->dirroot . '/mnet/lib.php';
        $jumpurl = mnet_get_idp_jump_url($user);
        $callback = partial('mnet_sso_apply_indirection', $jumpurl);
        $messagetext = preg_replace_callback("%({$CFG->wwwroot}[^[:space:]]*)%", $callback, $messagetext);
        $messagehtml = preg_replace_callback("%href=[\"'`]({$CFG->wwwroot}[\\w_:\\?=#&@/;.~-]*)[\"'`]%", $callback, $messagehtml);
    }
    $mail = get_mailer();
    if (!empty($mail->SMTPDebug)) {
        echo '<pre>' . "\n";
    }
    $temprecipients = array();
    $tempreplyto = array();
    $supportuser = generate_email_supportuser();
    // make up an email address for handling bounces
    if (!empty($CFG->handlebounces)) {
        $modargs = 'B' . base64_encode(pack('V', $user->id)) . substr(md5($user->email), 0, 16);
        $mail->Sender = generate_email_processing_address(0, $modargs);
    } else {
        $mail->Sender = $supportuser->email;
    }
    if (is_string($from)) {
        // So we can pass whatever we want if there is need
        $mail->From = $CFG->noreplyaddress;
        $mail->FromName = $from;
    } else {
        if ($usetrueaddress and $from->maildisplay) {
            $mail->From = $from->email;
            $mail->FromName = fullname($from);
        } else {
            $mail->From = $CFG->noreplyaddress;
            $mail->FromName = fullname($from);
            if (empty($replyto)) {
                $tempreplyto[] = array($CFG->noreplyaddress, get_string('noreplyname'));
            }
        }
    }
    if (!empty($replyto)) {
        $tempreplyto[] = array($replyto, $replytoname);
    }
    $mail->Subject = substr($subject, 0, 900);
    $temprecipients[] = array($user->email, fullname($user));
    $mail->WordWrap = $wordwrapwidth;
    // set word wrap
    if (!empty($from->customheaders)) {
        // Add custom headers
        if (is_array($from->customheaders)) {
            foreach ($from->customheaders as $customheader) {
                $mail->AddCustomHeader($customheader);
            }
        } else {
            $mail->AddCustomHeader($from->customheaders);
        }
    }
    if (!empty($from->priority)) {
        $mail->Priority = $from->priority;
    }
    if ($messagehtml && !empty($user->mailformat) && $user->mailformat == 1) {
        // Don't ever send HTML to users who don't want it
        $mail->IsHTML(true);
        $mail->Encoding = 'quoted-printable';
        // Encoding to use
        $mail->Body = $messagehtml;
        $mail->AltBody = "\n{$messagetext}\n";
    } else {
        $mail->IsHTML(false);
        $mail->Body = "\n{$messagetext}\n";
    }
    if ($attachment && $attachname) {
        if (preg_match("~\\.\\.~", $attachment)) {
            // Security check for ".." in dir path
            $temprecipients[] = array($supportuser->email, fullname($supportuser, true));
            $mail->AddStringAttachment('Error in attachment.  User attempted to attach a filename with a unsafe name.', 'error.txt', '8bit', 'text/plain');
        } else {
            require_once $CFG->libdir . '/filelib.php';
            $mimetype = mimeinfo('type', $attachname);
            $mail->AddAttachment($CFG->dataroot . '/' . $attachment, $attachname, 'base64', $mimetype);
        }
    }
    // Check if the email should be sent in an other charset then the default UTF-8
    if (!empty($CFG->sitemailcharset) || !empty($CFG->allowusermailcharset)) {
        // use the defined site mail charset or eventually the one preferred by the recipient
        $charset = $CFG->sitemailcharset;
        if (!empty($CFG->allowusermailcharset)) {
            if ($useremailcharset = get_user_preferences('mailcharset', '0', $user->id)) {
                $charset = $useremailcharset;
            }
        }
        // convert all the necessary strings if the charset is supported
        $charsets = get_list_of_charsets();
        unset($charsets['UTF-8']);
        if (in_array($charset, $charsets)) {
            $mail->CharSet = $charset;
            $mail->FromName = textlib::convert($mail->FromName, 'utf-8', strtolower($charset));
            $mail->Subject = textlib::convert($mail->Subject, 'utf-8', strtolower($charset));
            $mail->Body = textlib::convert($mail->Body, 'utf-8', strtolower($charset));
            $mail->AltBody = textlib::convert($mail->AltBody, 'utf-8', strtolower($charset));
            foreach ($temprecipients as $key => $values) {
                $temprecipients[$key][1] = textlib::convert($values[1], 'utf-8', strtolower($charset));
            }
            foreach ($tempreplyto as $key => $values) {
                $tempreplyto[$key][1] = textlib::convert($values[1], 'utf-8', strtolower($charset));
            }
        }
    }
    foreach ($temprecipients as $values) {
        $mail->AddAddress($values[0], $values[1]);
    }
    foreach ($tempreplyto as $values) {
        $mail->AddReplyTo($values[0], $values[1]);
    }
    if ($mail->Send()) {
        set_send_count($user);
        $mail->IsSMTP();
        // use SMTP directly
        if (!empty($mail->SMTPDebug)) {
            echo '</pre>';
        }
        return true;
    } else {
        add_to_log(SITEID, 'library', 'mailer', qualified_me(), 'ERROR: ' . $mail->ErrorInfo);
        if (CLI_SCRIPT) {
            mtrace('Error: lib/moodlelib.php email_to_user(): ' . $mail->ErrorInfo);
        }
        if (!empty($mail->SMTPDebug)) {
            echo '</pre>';
        }
        return false;
    }
}
コード例 #9
0
ファイル: index.php プロジェクト: saurabh947/MoodleLearning
$mform2 = new grade_import_mapping_form(null, array('gradeitems' => $gradeitems, 'header' => $header));
// if import form is submitted
if ($formdata = $mform->get_data()) {
    // Large files are likely to take their time and memory. Let PHP know
    // that we'll take longer, and that the process should be recycled soon
    // to free up memory.
    @set_time_limit(0);
    raise_memory_limit(MEMORY_EXTRA);
    // use current (non-conflicting) time stamp
    $importcode = get_new_importcode();
    $filename = make_temp_directory('gradeimport/cvs/' . $USER->id);
    $filename = $filename . '/' . $importcode;
    $text = $mform->get_file_content('userfile');
    // trim utf-8 bom
    /// normalize line endings and do the encoding conversion
    $text = textlib::convert($text, $formdata->encoding);
    $text = textlib::trim_utf8_bom($text);
    // Fix mac/dos newlines
    $text = preg_replace('!\\r\\n?!', "\n", $text);
    $fp = fopen($filename, "w");
    fwrite($fp, $text);
    fclose($fp);
    if (!($fp = fopen($filename, "r"))) {
        print_error('cannotopenfile');
    }
    // --- get header (field names) ---
    $header = explode($csv_delimiter, fgets($fp, GRADE_CSV_LINE_LENGTH));
    // print some preview
    $numlines = 0;
    // 0 preview lines displayed
    echo $OUTPUT->heading(get_string('importpreview', 'grades'));
コード例 #10
0
 /**
  * 
  * returns the distinct values of the target LDAP attribute
  * these will be the idnumbers of the synched Moodle cohorts
  * @returns array of string 
  */
 function get_attribute_distinct_values()
 {
     //return array ('affiliate','retired','student','faculty','staff','employee','affiliate','member','alum','emeritus','researcher');
     global $CFG, $DB;
     // only these cohorts will be synched
     if (!empty($this->config->cohort_synching_ldap_attribute_idnumbers)) {
         return explode(',', $this->config->cohort_synching_ldap_attribute_idnumbers);
     }
     //build a filter to fetch all users having something in the target LDAP attribute
     $filter = '(&(' . $this->config->user_attribute . '=*)' . $this->config->objectclass . ')';
     $filter = '(&' . $filter . '(' . $this->config->cohort_synching_ldap_attribute_attribute . '=*))';
     if ($CFG->debug_ldap_groupes) {
         pp_print_object('looking for ', $filter);
     }
     $ldapconnection = $this->ldap_connect();
     $contexts = explode(';', $this->config->contexts);
     if (!empty($this->config->create_context)) {
         array_push($contexts, $this->config->create_context);
     }
     $matchings = array();
     foreach ($contexts as $context) {
         $context = trim($context);
         if (empty($context)) {
             continue;
         }
         if ($this->config->search_sub) {
             // Use ldap_search to find first user from subtree
             $ldap_result = ldap_search($ldapconnection, $context, $filter, array($this->config->cohort_synching_ldap_attribute_attribute));
         } else {
             // Search only in this context
             $ldap_result = ldap_list($ldapconnection, $context, $filter, array($this->config->cohort_synching_ldap_attribute_attribute));
         }
         if (!$ldap_result) {
             continue;
         }
         // this API function returns all attributes as an array
         // wether they are single or multiple
         $users = ldap_get_entries_moodle($ldapconnection, $ldap_result);
         // Add found DISTINCT values to list
         for ($i = 0; $i < count($users); $i++) {
             $count = $users[$i][$this->config->cohort_synching_ldap_attribute_attribute]['count'];
             for ($j = 0; $j < $count; $j++) {
                 $value = textlib::convert($users[$i][$this->config->cohort_synching_ldap_attribute_attribute][$j], $this->config->ldapencoding, 'utf-8');
                 if (!in_array($value, $matchings)) {
                     array_push($matchings, $value);
                 }
             }
         }
     }
     $this->ldap_close();
     return $matchings;
 }
コード例 #11
0
ファイル: lib.php プロジェクト: masaterutakeno/MoodleMobile
/**
 * Returns location information
 * @param string $ip
 * @return array
 */
function iplookup_find_location($ip)
{
    global $CFG;
    $info = array('city' => null, 'country' => null, 'longitude' => null, 'latitude' => null, 'error' => null, 'note' => '', 'title' => array());
    if (!empty($CFG->geoipfile) and file_exists($CFG->geoipfile)) {
        require_once 'Net/GeoIP.php';
        $geoip = Net_GeoIP::getInstance($CFG->geoipfile, Net_GeoIP::STANDARD);
        $location = $geoip->lookupLocation($ip);
        $geoip->close();
        if (empty($location)) {
            $info['error'] = get_string('iplookupfailed', 'error', $ip);
            return $info;
        }
        if (!empty($location->city)) {
            $info['city'] = textlib::convert($location->city, 'iso-8859-1', 'utf-8');
            $info['title'][] = $info['city'];
        }
        if (!empty($location->countryCode)) {
            $countries = get_string_manager()->get_list_of_countries(true);
            if (isset($countries[$location->countryCode])) {
                // prefer our localized country names
                $info['country'] = $countries[$location->countryCode];
            } else {
                $info['country'] = $location->countryName;
            }
            $info['title'][] = $info['country'];
        } else {
            if (!empty($location->countryName)) {
                $info['country'] = $location->countryName;
                $info['title'][] = $info['country'];
            }
        }
        $info['longitude'] = $location->longitude;
        $info['latitude'] = $location->latitude;
        $info['note'] = get_string('iplookupmaxmindnote', 'admin');
        return $info;
    } else {
        require_once $CFG->libdir . '/filelib.php';
        $ipdata = download_file_content('http://www.geoplugin.net/json.gp?ip=' . $ip);
        if ($ipdata) {
            $ipdata = preg_replace('/^geoPlugin\\((.*)\\)\\s*$/s', '$1', $ipdata);
            $ipdata = json_decode($ipdata, true);
        }
        if (!is_array($ipdata)) {
            $info['error'] = get_string('cannotgeoplugin', 'error');
            return $info;
        }
        $info['latitude'] = (double) $ipdata['geoplugin_latitude'];
        $info['longitude'] = (double) $ipdata['geoplugin_longitude'];
        $info['city'] = s($ipdata['geoplugin_city']);
        $countrycode = $ipdata['geoplugin_countryCode'];
        $countries = get_string_manager()->get_list_of_countries(true);
        if (isset($countries[$countrycode])) {
            // prefer our localized country names
            $info['country'] = $countries[$countrycode];
        } else {
            $info['country'] = s($ipdata['geoplugin_countryName']);
        }
        $info['note'] = get_string('iplookupgeoplugin', 'admin');
        $info['title'][] = $info['city'];
        $info['title'][] = $info['country'];
        return $info;
    }
}
コード例 #12
0
 /**
  * Write one string somewhere in the worksheet
  *
  * @param integer $row    Zero indexed row
  * @param integer $col    Zero indexed column
  * @param string  $str    The string to write
  * @param mixed   $format The XF format for the cell
  */
 function write_string($row, $col, $str, $format = null)
 {
     /// Calculate the internal PEAR format
     $format = $this->MoodleExcelFormat2PearExcelFormat($format);
     /// Convert the text from its original encoding to UTF-16LE
     if (!$this->latin_output) {
         /// Only if don't want to use latin (win1252) stronger output
         $str = textlib::convert($str, 'utf-8', 'utf-16le');
     } else {
         /// else, convert to latin (win1252)
         $str = textlib::convert($str, 'utf-8', 'windows-1252');
     }
     /// Add the string safely to the PEAR Worksheet
     $this->pear_excel_worksheet->writeString($row, $col, $str, $format);
 }
コード例 #13
0
 /**
  * Tries to convert $localname into utf-8
  * please note that it may fail really badly.
  * The resulting file name is cleaned.
  *
  * @param string $localname name of file in $this->encoding
  * @return string in utf-8
  */
 protected function unmangle_pathname($localname)
 {
     $result = str_replace('\\', '/', $localname);
     // no MS \ separators
     $result = ltrim($result, '/');
     // no leading /
     if ($this->encoding !== 'utf-8') {
         $result = textlib::convert($result, $this->encoding, 'utf-8');
     }
     return clean_param($result, PARAM_PATH);
 }
コード例 #14
0
ファイル: auth.php プロジェクト: nigeli/moodle
 /**
  * To be called from a page running under NTLM's
  * "Integrated Windows Authentication".
  *
  * If successful, it will set a special "cookie" (not an HTTP cookie!)
  * in cache_flags under the $this->pluginconfig/ntlmsess "plugin" and return true.
  * The "cookie" will be picked up by ntlmsso_finish() to complete the
  * process.
  *
  * On failure it will return false for the caller to display an appropriate
  * error message (probably saying that Integrated Windows Auth isn't enabled!)
  *
  * NOTE that this code will execute under the OS user credentials,
  * so we MUST avoid dealing with files -- such as session files.
  * (The caller should define('NO_MOODLE_COOKIES', true) before including config.php)
  *
  */
 function ntlmsso_magic($sesskey)
 {
     if (isset($_SERVER['REMOTE_USER']) && !empty($_SERVER['REMOTE_USER'])) {
         // HTTP __headers__ seem to be sent in ISO-8859-1 encoding
         // (according to my reading of RFC-1945, RFC-2616 and RFC-2617 and
         // my local tests), so we need to convert the REMOTE_USER value
         // (i.e., what we got from the HTTP WWW-Authenticate header) into UTF-8
         $username = textlib::convert($_SERVER['REMOTE_USER'], 'iso-8859-1', 'utf-8');
         switch ($this->config->ntlmsso_type) {
             case 'ntlm':
                 // Format is DOMAIN\username
                 $username = substr(strrchr($username, '\\'), 1);
                 break;
             case 'kerberos':
                 // Format is username@DOMAIN
                 $username = substr($username, 0, strpos($username, '@'));
                 break;
             default:
                 error_log($this->errorlogtag . get_string('ntlmsso_unknowntype', 'auth_ldap'));
                 return false;
                 // Should never happen!
         }
         $username = textlib::strtolower($username);
         // Compatibility hack
         set_cache_flag($this->pluginconfig . '/ntlmsess', $sesskey, $username, AUTH_NTLMTIMEOUT);
         return true;
     }
     return false;
 }
コード例 #15
0
ファイル: locallib.php プロジェクト: Jtgadbois/Pedadida
/**
 * Convert some html content to utf8, getting original encoding from html headers
 *
 * @param string $html html content to convert
 * @return string html content converted to utf8
 */
function toolbook_importhtml_fix_encoding($html) {
    if (preg_match('/<head[^>]*>(.+)<\/head>/is', $html, $matches)) {
        $head = $matches[1];
        if (preg_match('/charset=([^"]+)/is', $head, $matches)) {
            $enc = $matches[1];
            return textlib::convert($html, $enc, 'utf-8');
        }
    }
    return iconv('UTF-8', 'UTF-8//IGNORE', $html);
}
コード例 #16
0
 /**
  * Tests the static strtoupper
  * @return void
  */
 public function test_strtoupper()
 {
     $str = "Žluťoučký koníček";
     $up = 'ŽLUŤOUČKÝ KONÍČEK';
     $this->assertSame(textlib::strtoupper($str), $up);
     $iso2 = pack("H*", "ae6c75bb6f75e86bfd206b6f6eede8656b");
     $this->assertSame(textlib::strtoupper($iso2, 'iso-8859-2'), textlib::convert($up, 'utf-8', 'iso-8859-2'));
     $win = pack("H*", "8e6c759d6f75e86bfd206b6f6eede8656b");
     $this->assertSame(textlib::strtoupper($win, 'cp1250'), textlib::convert($up, 'utf-8', 'cp1250'));
     $str = '言語設定';
     $this->assertSame(textlib::strtoupper($str), $str);
     $str = '简体中文';
     $this->assertSame(textlib::strtoupper($str), $str);
     $str = pack("H*", "1b24423840386c405f446a1b2842");
     //ISO-2022-JP
     $this->assertSame(textlib::strtoupper($str, 'ISO-2022-JP'), $str);
     $str = pack("H*", "8cbe8cea90dd92e8");
     //SHIFT-JIS
     $this->assertSame(textlib::strtoupper($str, 'SHIFT-JIS'), $str);
     $str = pack("H*", "bcf2cce5d6d0cec4");
     //GB2312
     $this->assertSame(textlib::strtoupper($str, 'GB2312'), $str);
     $str = pack("H*", "bcf2cce5d6d0cec4");
     //GB18030
     $this->assertSame(textlib::strtoupper($str, 'GB18030'), $str);
 }
コード例 #17
0
ファイル: import.php プロジェクト: verbazend/AWFA
function feedback_check_xml_utf8($text) {
    //find the encoding
    $searchpattern = '/^\<\?xml.+(encoding=\"([a-z0-9-]*)\").+\?\>/is';

    if (!preg_match($searchpattern, $text, $match)) {
        return false; //no xml-file
    }

    //$match[0] = \<\? xml ... \?\> (without \)
    //$match[1] = encoding="...."
    //$match[2] = ISO-8859-1 or so on
    if (isset($match[0]) AND !isset($match[1])) { //no encoding given. we assume utf-8
        return $text;
    }

    //encoding is given in $match[2]
    if (isset($match[0]) AND isset($match[1]) AND isset($match[2])) {
        $enc = $match[2];
        return textlib::convert($text, $enc);
    }
}
コード例 #18
0
ファイル: auth.php プロジェクト: saurabh947/MoodleLearning
 /**
  * Called when the user record is updated.
  * Modifies user in external database. It takes olduser (before changes) and newuser (after changes)
  * compares information saved modified information to external db.
  *
  * @param mixed $olduser     Userobject before modifications
  * @param mixed $newuser     Userobject new modified userobject
  * @return boolean result
  *
  */
 function user_update($olduser, $newuser)
 {
     if (isset($olduser->username) and isset($newuser->username) and $olduser->username != $newuser->username) {
         error_log("ERROR:User renaming not allowed in ext db");
         return false;
     }
     if (isset($olduser->auth) and $olduser->auth != $this->authtype) {
         return true;
         // just change auth and skip update
     }
     $curruser = $this->get_userinfo($olduser->username);
     if (empty($curruser)) {
         error_log("ERROR:User {$olduser->username} found in ext db");
         return false;
     }
     $extusername = textlib::convert($olduser->username, 'utf-8', $this->config->extencoding);
     $authdb = $this->db_init();
     $update = array();
     foreach ($curruser as $key => $value) {
         if ($key == 'username') {
             continue;
             // skip this
         }
         if (empty($this->config->{"field_updateremote_{$key}"})) {
             continue;
             // remote update not requested
         }
         if (!isset($newuser->{$key})) {
             continue;
         }
         $nuvalue = $newuser->{$key};
         if ($nuvalue != $value) {
             $update[] = $this->config->{"field_map_{$key}"} . "='" . $this->ext_addslashes(textlib::convert($nuvalue, 'utf-8', $this->config->extencoding)) . "'";
         }
     }
     if (!empty($update)) {
         $authdb->Execute("UPDATE {$this->config->table}\n                                 SET " . implode(',', $update) . "\n                               WHERE {$this->config->fielduser}='" . $this->ext_addslashes($extusername) . "'");
     }
     $authdb->Close();
     return true;
 }
コード例 #19
0
ファイル: lib.php プロジェクト: masaterutakeno/MoodleMobile
 /**
  * Process flatfile.
  * @param progress_trace $trace
  * @return bool true if any data processed, false if not
  */
 protected function process_file(progress_trace $trace)
 {
     global $CFG, $DB;
     // We may need more memory here.
     @set_time_limit(0);
     raise_memory_limit(MEMORY_HUGE);
     $filelocation = $this->get_config('location');
     if (empty($filelocation)) {
         // Default legacy location.
         $filelocation = "{$CFG->dataroot}/1/enrolments.txt";
     }
     $disclosefile = $this->obfuscate_filepath($filelocation);
     if (!file_exists($filelocation)) {
         $trace->output("Flatfile enrolments file not found: {$disclosefile}");
         $trace->finished();
         return false;
     }
     $trace->output("Processing flat file enrolments from: {$disclosefile} ...");
     $content = file_get_contents($filelocation);
     if ($content !== false) {
         $rolemap = $this->get_role_map($trace);
         $content = textlib::convert($content, $this->get_config('encoding', 'utf-8'), 'utf-8');
         $content = str_replace("\r", '', $content);
         $content = explode("\n", $content);
         $line = 0;
         foreach ($content as $fields) {
             $line++;
             if (trim($fields) === '') {
                 // Empty lines are ignored.
                 continue;
             }
             // Deal with different separators.
             if (strpos($fields, ',') !== false) {
                 $fields = explode(',', $fields);
             } else {
                 $fields = explode(';', $fields);
             }
             // If a line is incorrectly formatted ie does not have 4 comma separated fields then ignore it.
             if (count($fields) < 4 or count($fields) > 6) {
                 $trace->output("Line incorrectly formatted - ignoring {$line}", 1);
                 continue;
             }
             $fields[0] = trim(textlib::strtolower($fields[0]));
             $fields[1] = trim(textlib::strtolower($fields[1]));
             $fields[2] = trim($fields[2]);
             $fields[3] = trim($fields[3]);
             $fields[4] = isset($fields[4]) ? (int) trim($fields[4]) : 0;
             $fields[5] = isset($fields[5]) ? (int) trim($fields[5]) : 0;
             // Deal with quoted values - all or nothing, we need to support "' in idnumbers, sorry.
             if (strpos($fields[0], "'") === 0) {
                 foreach ($fields as $k => $v) {
                     $fields[$k] = trim($v, "'");
                 }
             } else {
                 if (strpos($fields[0], '"') === 0) {
                     foreach ($fields as $k => $v) {
                         $fields[$k] = trim($v, '"');
                     }
                 }
             }
             $trace->output("{$line}: {$fields['0']}, {$fields['1']}, {$fields['2']}, {$fields['3']}, {$fields['4']}, {$fields['5']}", 1);
             // Check correct formatting of operation field.
             if ($fields[0] !== "add" and $fields[0] !== "del") {
                 $trace->output("Unknown operation in field 1 - ignoring line {$line}", 1);
                 continue;
             }
             // Check correct formatting of role field.
             if (!isset($rolemap[$fields[1]])) {
                 $trace->output("Unknown role in field2 - ignoring line {$line}", 1);
                 continue;
             }
             $roleid = $rolemap[$fields[1]];
             if (empty($fields[2]) or !($user = $DB->get_record("user", array("idnumber" => $fields[2], 'deleted' => 0)))) {
                 $trace->output("Unknown user idnumber or deleted user in field 3 - ignoring line {$line}", 1);
                 continue;
             }
             if (!($course = $DB->get_record("course", array("idnumber" => $fields[3])))) {
                 $trace->output("Unknown course idnumber in field 4 - ignoring line {$line}", 1);
                 continue;
             }
             if ($fields[4] > $fields[5] and $fields[5] != 0) {
                 $trace->output("Start time was later than end time - ignoring line {$line}", 1);
                 continue;
             }
             $this->process_records($trace, $fields[0], $roleid, $user, $course, $fields[4], $fields[5]);
         }
         unset($content);
     }
     if (!unlink($filelocation)) {
         $eventdata = new stdClass();
         $eventdata->modulename = 'moodle';
         $eventdata->component = 'enrol_flatfile';
         $eventdata->name = 'flatfile_enrolment';
         $eventdata->userfrom = get_admin();
         $eventdata->userto = get_admin();
         $eventdata->subject = get_string('filelockedmailsubject', 'enrol_flatfile');
         $eventdata->fullmessage = get_string('filelockedmail', 'enrol_flatfile', $filelocation);
         $eventdata->fullmessageformat = FORMAT_PLAIN;
         $eventdata->fullmessagehtml = '';
         $eventdata->smallmessage = '';
         message_send($eventdata);
         $trace->output("Error deleting enrolment file: {$disclosefile}", 1);
     } else {
         $trace->output("Deleted enrolment file", 1);
     }
     $trace->output("...finished enrolment file processing.");
     $trace->finished();
     return true;
 }
コード例 #20
0
 /**
  * Create a map of file names used in zip archive.
  * @return void
  */
 protected function init_namelookup()
 {
     if ($this->emptyziphack) {
         $this->namelookup = array();
         return;
     }
     if (!isset($this->za)) {
         return;
     }
     if (isset($this->namelookup)) {
         return;
     }
     $this->namelookup = array();
     if ($this->mode != file_archive::OPEN) {
         // No need to tweak existing names when creating zip file because there are none yet!
         return;
     }
     if (!file_exists($this->archivepathname)) {
         return;
     }
     if (!($fp = fopen($this->archivepathname, 'rb'))) {
         return;
     }
     if (!($filesize = filesize($this->archivepathname))) {
         return;
     }
     $centralend = self::zip_get_central_end($fp, $filesize);
     if ($centralend === false or $centralend['disk'] !== 0 or $centralend['disk_start'] !== 0 or $centralend['offset'] === 0xffffffff) {
         // Single disk archives only and o support for ZIP64, sorry.
         fclose($fp);
         return;
     }
     fseek($fp, $centralend['offset']);
     $data = fread($fp, $centralend['size']);
     $pos = 0;
     $files = array();
     for ($i = 0; $i < $centralend['entries']; $i++) {
         $file = self::zip_parse_file_header($data, $centralend, $pos);
         if ($file === false) {
             // Wrong header, sorry.
             fclose($fp);
             return;
         }
         $files[] = $file;
     }
     fclose($fp);
     foreach ($files as $file) {
         $name = $file['name'];
         if (preg_match('/^[a-zA-Z0-9_\\-\\.]*$/', $file['name'])) {
             // No need to fix ASCII.
             $name = fix_utf8($name);
         } else {
             if (!($file['general'] & pow(2, 11))) {
                 // First look for unicode name alternatives.
                 $found = false;
                 foreach ($file['extra'] as $extra) {
                     if ($extra['id'] === 0x7075) {
                         $data = unpack('cversion/Vcrc', substr($extra['data'], 0, 5));
                         if ($data['crc'] === crc32($name)) {
                             $found = true;
                             $name = substr($extra['data'], 5);
                         }
                     }
                 }
                 if (!$found and !empty($this->encoding) and $this->encoding !== 'utf-8') {
                     // Try the encoding from open().
                     $newname = @textlib::convert($name, $this->encoding, 'utf-8');
                     $original = textlib::convert($newname, 'utf-8', $this->encoding);
                     if ($original === $name) {
                         $found = true;
                         $name = $newname;
                     }
                 }
                 if (!$found and $file['version'] === 0x315) {
                     // This looks like OS X build in zipper.
                     $newname = fix_utf8($name);
                     if ($newname === $name) {
                         $found = true;
                         $name = $newname;
                     }
                 }
                 if (!$found and $file['version'] === 0) {
                     // This looks like our old borked Moodle 2.2 file.
                     $newname = fix_utf8($name);
                     if ($newname === $name) {
                         $found = true;
                         $name = $newname;
                     }
                 }
                 if (!$found and $encoding = get_string('oldcharset', 'langconfig')) {
                     // Last attempt - try the dos/unix encoding from current language.
                     $windows = true;
                     foreach ($file['extra'] as $extra) {
                         // In Windows archivers do not usually set any extras with the exception of NTFS flag in WinZip/WinRar.
                         $windows = false;
                         if ($extra['id'] === 0xa) {
                             $windows = true;
                             break;
                         }
                     }
                     if ($windows === true) {
                         switch (strtoupper($encoding)) {
                             case 'ISO-8859-1':
                                 $encoding = 'CP850';
                                 break;
                             case 'ISO-8859-2':
                                 $encoding = 'CP852';
                                 break;
                             case 'ISO-8859-4':
                                 $encoding = 'CP775';
                                 break;
                             case 'ISO-8859-5':
                                 $encoding = 'CP866';
                                 break;
                             case 'ISO-8859-6':
                                 $encoding = 'CP720';
                                 break;
                             case 'ISO-8859-7':
                                 $encoding = 'CP737';
                                 break;
                             case 'ISO-8859-8':
                                 $encoding = 'CP862';
                                 break;
                             case 'UTF-8':
                                 if ($winchar = get_string('localewincharset', 'langconfig')) {
                                     // Most probably works only for zh_cn,
                                     // if there are more problems we could add zipcharset to langconfig files.
                                     $encoding = $winchar;
                                 }
                                 break;
                         }
                     }
                     $newname = @textlib::convert($name, $encoding, 'utf-8');
                     $original = textlib::convert($newname, 'utf-8', $encoding);
                     if ($original === $name) {
                         $name = $newname;
                     }
                 }
             }
         }
         $name = str_replace('\\', '/', $name);
         // no MS \ separators
         $name = clean_param($name, PARAM_PATH);
         // only safe chars
         $name = ltrim($name, '/');
         // no leading slash
         if (function_exists('normalizer_normalize')) {
             $name = normalizer_normalize($name, Normalizer::FORM_C);
         }
         $this->namelookup[$file['name']] = $name;
     }
 }
コード例 #21
0
ファイル: csvlib.class.php プロジェクト: Burick/moodle
 /**
  * Parse this content
  *
  * @global object
  * @global object
  * @param string $content passed by ref for memory reasons, unset after return
  * @param string $encoding content encoding
  * @param string $delimiter_name separator (comma, semicolon, colon, cfg)
  * @param string $column_validation name of function for columns validation, must have one param $columns
  * @param string $enclosure field wrapper. One character only.
  * @return bool false if error, count of data lines if ok; use get_error() to get error string
  */
 function load_csv_content(&$content, $encoding, $delimiter_name, $column_validation = null, $enclosure = '"')
 {
     global $USER, $CFG;
     $this->close();
     $this->_error = null;
     $content = textlib::convert($content, $encoding, 'utf-8');
     // remove Unicode BOM from first line
     $content = textlib::trim_utf8_bom($content);
     // Fix mac/dos newlines
     $content = preg_replace('!\\r\\n?!', "\n", $content);
     // Remove any spaces or new lines at the end of the file.
     if ($delimiter_name == 'tab') {
         // trim() by default removes tabs from the end of content which is undesirable in a tab separated file.
         $content = trim($content, chr(0x20) . chr(0xa) . chr(0xd) . chr(0x0) . chr(0xb));
     } else {
         $content = trim($content);
     }
     $csv_delimiter = csv_import_reader::get_delimiter($delimiter_name);
     // $csv_encode    = csv_import_reader::get_encoded_delimiter($delimiter_name);
     // create a temporary file and store the csv file there.
     $fp = tmpfile();
     fwrite($fp, $content);
     fseek($fp, 0);
     // Create an array to store the imported data for error checking.
     $columns = array();
     // str_getcsv doesn't iterate through the csv data properly. It has
     // problems with line returns.
     while ($fgetdata = fgetcsv($fp, 0, $csv_delimiter, $enclosure)) {
         // Check to see if we have an empty line.
         if (count($fgetdata) == 1) {
             if ($fgetdata[0] !== null) {
                 // The element has data. Add it to the array.
                 $columns[] = $fgetdata;
             }
         } else {
             $columns[] = $fgetdata;
         }
     }
     $col_count = 0;
     // process header - list of columns
     if (!isset($columns[0])) {
         $this->_error = get_string('csvemptyfile', 'error');
         fclose($fp);
         return false;
     } else {
         $col_count = count($columns[0]);
     }
     // Column validation.
     if ($column_validation) {
         $result = $column_validation($columns[0]);
         if ($result !== true) {
             $this->_error = $result;
             fclose($fp);
             return false;
         }
     }
     $this->_columns = $columns[0];
     // cached columns
     // check to make sure that the data columns match up with the headers.
     foreach ($columns as $rowdata) {
         if (count($rowdata) !== $col_count) {
             $this->_error = get_string('csvweirdcolumns', 'error');
             fclose($fp);
             $this->cleanup();
             return false;
         }
     }
     $filename = $CFG->tempdir . '/csvimport/' . $this->_type . '/' . $USER->id . '/' . $this->_iid;
     $filepointer = fopen($filename, "w");
     // The information has been stored in csv format, as serialized data has issues
     // with special characters and line returns.
     $storedata = csv_export_writer::print_array($columns, ',', '"', true);
     fwrite($filepointer, $storedata);
     fclose($fp);
     fclose($filepointer);
     $datacount = count($columns);
     return $datacount;
 }
コード例 #22
0
 public function readquestions($lines)
 {
     $webctnumberregex = '[+-]?([0-9]+(\\.[0-9]*)?|\\.[0-9]+)((e|E|\\*10\\*\\*)([+-]?[0-9]+|\\([+-]?[0-9]+\\)))?';
     $questions = array();
     $errors = array();
     $warnings = array();
     $webctoptions = array();
     $ignorerestofquestion = false;
     $nlinecounter = 0;
     $nquestionstartline = 0;
     $bishtmltext = false;
     $lines[] = ":EOF:";
     // For an easiest processing of the last line.
     // We don't call defaultquestion() here, it will be called later.
     foreach ($lines as $line) {
         $nlinecounter++;
         $line = textlib::convert($line, 'windows-1252', 'utf-8');
         // Processing multiples lines strings.
         if (isset($questiontext) and is_string($questiontext)) {
             if (preg_match("~^:~", $line)) {
                 $questiontext = $this->text_field(trim($questiontext));
                 $question->questiontext = $questiontext['text'];
                 $question->questiontextformat = $questiontext['format'];
                 if (isset($questiontext['itemid'])) {
                     $question->questiontextitemid = $questiontext['itemid'];
                 }
                 unset($questiontext);
             } else {
                 $questiontext .= str_replace('\\:', ':', $line);
                 continue;
             }
         }
         if (isset($answertext) and is_string($answertext)) {
             if (preg_match("~^:~", $line)) {
                 $answertext = trim($answertext);
                 if ($question->qtype == 'multichoice' || $question->qtype == 'match') {
                     $question->answer[$currentchoice] = $this->text_field($answertext);
                     $question->subanswers[$currentchoice] = $question->answer[$currentchoice];
                 } else {
                     $question->answer[$currentchoice] = $answertext;
                     $question->subanswers[$currentchoice] = $answertext;
                 }
                 unset($answertext);
             } else {
                 $answertext .= str_replace('\\:', ':', $line);
                 continue;
             }
         }
         if (isset($responsetext) and is_string($responsetext)) {
             if (preg_match("~^:~", $line)) {
                 $question->subquestions[$currentchoice] = trim($responsetext);
                 unset($responsetext);
             } else {
                 $responsetext .= str_replace('\\:', ':', $line);
                 continue;
             }
         }
         if (isset($feedbacktext) and is_string($feedbacktext)) {
             if (preg_match("~^:~", $line)) {
                 $question->feedback[$currentchoice] = $this->text_field(trim($feedbacktext));
                 unset($feedbacktext);
             } else {
                 $feedbacktext .= str_replace('\\:', ':', $line);
                 continue;
             }
         }
         if (isset($generalfeedbacktext) and is_string($generalfeedbacktext)) {
             if (preg_match("~^:~", $line)) {
                 $question->tempgeneralfeedback = trim($generalfeedbacktext);
                 unset($generalfeedbacktext);
             } else {
                 $generalfeedbacktext .= str_replace('\\:', ':', $line);
                 continue;
             }
         }
         if (isset($graderinfo) and is_string($graderinfo)) {
             if (preg_match("~^:~", $line)) {
                 $question->graderinfo['text'] = trim($graderinfo);
                 $question->graderinfo['format'] = FORMAT_HTML;
                 unset($graderinfo);
             } else {
                 $graderinfo .= str_replace('\\:', ':', $line);
                 continue;
             }
         }
         $line = trim($line);
         if (preg_match("~^:(TYPE|EOF):~i", $line)) {
             // New Question or End of File.
             if (isset($question)) {
                 // If previous question exists, complete, check and save it.
                 // Setup default value of missing fields.
                 if (!isset($question->name)) {
                     $question->name = $this->create_default_question_name($question->questiontext, get_string('questionname', 'question'));
                 }
                 if (!isset($question->defaultmark)) {
                     $question->defaultmark = 1;
                 }
                 if (!isset($question->image)) {
                     $question->image = '';
                 }
                 // Perform sanity checks.
                 $questionok = true;
                 if (strlen($question->questiontext) == 0) {
                     $warnings[] = get_string('missingquestion', 'qformat_webct', $nquestionstartline);
                     $questionok = false;
                 }
                 if (count($question->answer) < 1) {
                     // A question must have at least 1 answer.
                     $errors[] = get_string('missinganswer', 'qformat_webct', $nquestionstartline);
                     $questionok = false;
                 } else {
                     // Create empty feedback array.
                     foreach ($question->answer as $key => $dataanswer) {
                         if (!isset($question->feedback[$key])) {
                             $question->feedback[$key]['text'] = '';
                             $question->feedback[$key]['format'] = FORMAT_HTML;
                         }
                     }
                     // This tempgeneralfeedback allows the code to work with versions from 1.6 to 1.9.
                     // When question->generalfeedback is undefined, the webct feedback is added to each answer feedback.
                     if (isset($question->tempgeneralfeedback)) {
                         if (isset($question->generalfeedback)) {
                             $generalfeedback = $this->text_field($question->tempgeneralfeedback);
                             $question->generalfeedback = $generalfeedback['text'];
                             $question->generalfeedbackformat = $generalfeedback['format'];
                             if (isset($generalfeedback['itemid'])) {
                                 $question->genralfeedbackitemid = $generalfeedback['itemid'];
                             }
                         } else {
                             foreach ($question->answer as $key => $dataanswer) {
                                 if ($question->tempgeneralfeedback != '') {
                                     $question->feedback[$key]['text'] = $question->tempgeneralfeedback . '<br/>' . $question->feedback[$key]['text'];
                                 }
                             }
                         }
                         unset($question->tempgeneralfeedback);
                     }
                     $maxfraction = -1;
                     $totalfraction = 0;
                     foreach ($question->fraction as $fraction) {
                         if ($fraction > 0) {
                             $totalfraction += $fraction;
                         }
                         if ($fraction > $maxfraction) {
                             $maxfraction = $fraction;
                         }
                     }
                     switch ($question->qtype) {
                         case 'shortanswer':
                             if ($maxfraction != 1) {
                                 $maxfraction = $maxfraction * 100;
                                 $errors[] = "'{$question->name}': " . get_string('wronggrade', 'qformat_webct', $nlinecounter) . ' ' . get_string('fractionsnomax', 'question', $maxfraction);
                                 $questionok = false;
                             }
                             break;
                         case 'multichoice':
                             $question = $this->add_blank_combined_feedback($question);
                             if ($question->single) {
                                 if ($maxfraction != 1) {
                                     $maxfraction = $maxfraction * 100;
                                     $errors[] = "'{$question->name}': " . get_string('wronggrade', 'qformat_webct', $nlinecounter) . ' ' . get_string('fractionsnomax', 'question', $maxfraction);
                                     $questionok = false;
                                 }
                             } else {
                                 $totalfraction = round($totalfraction, 2);
                                 if ($totalfraction != 1) {
                                     $totalfraction = $totalfraction * 100;
                                     $errors[] = "'{$question->name}': " . get_string('wronggrade', 'qformat_webct', $nlinecounter) . ' ' . get_string('fractionsaddwrong', 'question', $totalfraction);
                                     $questionok = false;
                                 }
                             }
                             break;
                         case 'calculated':
                             foreach ($question->answers as $answer) {
                                 if ($formulaerror = qtype_calculated_find_formula_errors($answer)) {
                                     $warnings[] = "'{$question->name}': " . $formulaerror;
                                     $questionok = false;
                                 }
                             }
                             foreach ($question->dataset as $dataset) {
                                 $dataset->itemcount = count($dataset->datasetitem);
                             }
                             $question->import_process = true;
                             unset($question->answer);
                             // Not used in calculated question.
                             break;
                         case 'match':
                             // MDL-10680:
                             // Switch subquestions and subanswers.
                             $question = $this->add_blank_combined_feedback($question);
                             foreach ($question->subquestions as $id => $subquestion) {
                                 $temp = $question->subquestions[$id];
                                 $question->subquestions[$id] = $question->subanswers[$id];
                                 $question->subanswers[$id] = $temp;
                             }
                             if (count($question->answer) < 3) {
                                 // Add a dummy missing question.
                                 $question->name = 'Dummy question added ' . $question->name;
                                 $question->answer[] = 'dummy';
                                 $question->subanswers[] = 'dummy';
                                 $question->subquestions[] = 'dummy';
                                 $question->fraction[] = '0.0';
                                 $question->feedback[] = '';
                             }
                             break;
                         default:
                             // No problemo.
                     }
                 }
                 if ($questionok) {
                     $questions[] = $question;
                     // Store it.
                     unset($question);
                     // And prepare a new one.
                     $question = $this->defaultquestion();
                 }
             }
             $nquestionstartline = $nlinecounter;
         }
         // Processing Question Header.
         if (preg_match("~^:TYPE:MC:1(.*)~i", $line, $webctoptions)) {
             // Multiple Choice Question with only one good answer.
             $question = $this->defaultquestion();
             $question->feedback = array();
             $question->qtype = 'multichoice';
             $question->single = 1;
             // Only one answer is allowed.
             $ignorerestofquestion = false;
             continue;
         }
         if (preg_match("~^:TYPE:MC:N(.*)~i", $line, $webctoptions)) {
             // Multiple Choice Question with several good answers.
             $question = $this->defaultquestion();
             $question->feedback = array();
             $question->qtype = 'multichoice';
             $question->single = 0;
             // Many answers allowed.
             $ignorerestofquestion = false;
             continue;
         }
         if (preg_match("~^:TYPE:S~i", $line)) {
             // Short Answer Question.
             $question = $this->defaultquestion();
             $question->feedback = array();
             $question->qtype = 'shortanswer';
             $question->usecase = 0;
             // Ignore case.
             $ignorerestofquestion = false;
             continue;
         }
         if (preg_match("~^:TYPE:C~i", $line)) {
             // Calculated Question.
             $question = $this->defaultquestion();
             $question->qtype = 'calculated';
             $question->answer = array();
             // No problem as they go as :FORMULA: from webct.
             $question->units = array();
             $question->dataset = array();
             $question->fraction = array('1.0');
             $question->feedback = array();
             $currentchoice = -1;
             $ignorerestofquestion = false;
             continue;
         }
         if (preg_match("~^:TYPE:M~i", $line)) {
             // Match Question.
             $question = $this->defaultquestion();
             $question->qtype = 'match';
             $question->feedback = array();
             $ignorerestofquestion = false;
             // Match question processing is not debugged.
             continue;
         }
         if (preg_match("~^:TYPE:P~i", $line)) {
             // Paragraph Question.
             $question = $this->defaultquestion();
             $question->qtype = 'essay';
             $question->responseformat = 'editor';
             $question->responsefieldlines = 15;
             $question->attachments = 0;
             $question->graderinfo = array('text' => '', 'format' => FORMAT_HTML);
             $question->feedback = array();
             $question->generalfeedback = '';
             $question->generalfeedbackformat = FORMAT_HTML;
             $question->generalfeedbackfiles = array();
             $question->responsetemplate = $this->text_field('');
             $question->questiontextformat = FORMAT_HTML;
             $ignorerestofquestion = false;
             // To make us pass the end-of-question sanity checks.
             $question->answer = array('dummy');
             $question->fraction = array('1.0');
             continue;
         }
         if (preg_match("~^:TYPE:~i", $line)) {
             // Unknow question type.
             $warnings[] = get_string('unknowntype', 'qformat_webct', $nlinecounter);
             unset($question);
             $ignorerestofquestion = true;
             // Question Type not handled by Moodle.
             continue;
         }
         if ($ignorerestofquestion) {
             continue;
         }
         if (preg_match("~^:TITLE:(.*)~i", $line, $webctoptions)) {
             $name = trim($webctoptions[1]);
             $question->name = $this->clean_question_name($name);
             continue;
         }
         if (preg_match("~^:IMAGE:(.*)~i", $line, $webctoptions)) {
             $filename = trim($webctoptions[1]);
             if (preg_match("~^http://~i", $filename)) {
                 $question->image = $filename;
             }
             continue;
         }
         // Need to put the parsing of calculated items here to avoid ambitiuosness:
         // if question isn't defined yet there is nothing to do here (avoid notices).
         if (!isset($question)) {
             continue;
         }
         if (isset($question->qtype) && 'calculated' == $question->qtype && preg_match("~^:([[:lower:]].*|::.*)-(MIN|MAX|DEC|VAL([0-9]+))::?:?({$webctnumberregex})~", $line, $webctoptions)) {
             $datasetname = preg_replace('/^::/', '', $webctoptions[1]);
             $datasetvalue = qformat_webct_convert_formula($webctoptions[4]);
             switch ($webctoptions[2]) {
                 case 'MIN':
                     $question->dataset[$datasetname]->min = $datasetvalue;
                     break;
                 case 'MAX':
                     $question->dataset[$datasetname]->max = $datasetvalue;
                     break;
                 case 'DEC':
                     $datasetvalue = floor($datasetvalue);
                     // Int only!
                     $question->dataset[$datasetname]->length = max(0, $datasetvalue);
                     break;
                 default:
                     // The VAL case.
                     $question->dataset[$datasetname]->datasetitem[$webctoptions[3]] = new stdClass();
                     $question->dataset[$datasetname]->datasetitem[$webctoptions[3]]->itemnumber = $webctoptions[3];
                     $question->dataset[$datasetname]->datasetitem[$webctoptions[3]]->value = $datasetvalue;
                     break;
             }
             continue;
         }
         $bishtmltext = preg_match("~:H\$~i", $line);
         // True if next lines are coded in HTML.
         if (preg_match("~^:QUESTION~i", $line)) {
             $questiontext = '';
             // Start gathering next lines.
             continue;
         }
         if (preg_match("~^:ANSWER([0-9]+):([^:]+):([0-9\\.\\-]+):(.*)~i", $line, $webctoptions)) {
             // Shortanswer.
             $currentchoice = $webctoptions[1];
             $answertext = $webctoptions[2];
             // Start gathering next lines.
             $question->fraction[$currentchoice] = $webctoptions[3] / 100;
             continue;
         }
         if (preg_match("~^:ANSWER([0-9]+):([0-9\\.\\-]+)~i", $line, $webctoptions)) {
             $answertext = '';
             // Start gathering next lines.
             $currentchoice = $webctoptions[1];
             $question->fraction[$currentchoice] = $webctoptions[2] / 100;
             continue;
         }
         if (preg_match('~^:ANSWER:~i', $line)) {
             // Essay.
             $graderinfo = '';
             // Start gathering next lines.
             continue;
         }
         if (preg_match('~^:FORMULA:(.*)~i', $line, $webctoptions)) {
             // Answer for a calculated question.
             ++$currentchoice;
             $question->answer[$currentchoice] = qformat_webct_convert_formula($webctoptions[1]);
             // Default settings.
             $question->fraction[$currentchoice] = 1.0;
             $question->tolerance[$currentchoice] = 0.0;
             $question->tolerancetype[$currentchoice] = 2;
             // Nominal (units in webct).
             $question->feedback[$currentchoice]['text'] = '';
             $question->feedback[$currentchoice]['format'] = FORMAT_HTML;
             $question->correctanswerlength[$currentchoice] = 4;
             $datasetnames = question_bank::get_qtype('calculated')->find_dataset_names($webctoptions[1]);
             foreach ($datasetnames as $datasetname) {
                 $question->dataset[$datasetname] = new stdClass();
                 $question->dataset[$datasetname]->datasetitem = array();
                 $question->dataset[$datasetname]->name = $datasetname;
                 $question->dataset[$datasetname]->distribution = 'uniform';
                 $question->dataset[$datasetname]->status = 'private';
             }
             continue;
         }
         if (preg_match("~^:L([0-9]+)~i", $line, $webctoptions)) {
             $answertext = '';
             // Start gathering next lines.
             $currentchoice = $webctoptions[1];
             $question->fraction[$currentchoice] = 1;
             continue;
         }
         if (preg_match("~^:R([0-9]+)~i", $line, $webctoptions)) {
             $responsetext = '';
             // Start gathering next lines.
             $currentchoice = $webctoptions[1];
             continue;
         }
         if (preg_match("~^:REASON([0-9]+):?~i", $line, $webctoptions)) {
             $feedbacktext = '';
             // Start gathering next lines.
             $currentchoice = $webctoptions[1];
             continue;
         }
         if (preg_match("~^:FEEDBACK([0-9]+):?~i", $line, $webctoptions)) {
             $generalfeedbacktext = '';
             // Start gathering next lines.
             $currentchoice = $webctoptions[1];
             continue;
         }
         if (preg_match('~^:FEEDBACK:(.*)~i', $line, $webctoptions)) {
             $generalfeedbacktext = '';
             // Start gathering next lines.
             continue;
         }
         if (preg_match('~^:LAYOUT:(.*)~i', $line, $webctoptions)) {
             // Ignore  since layout in question_multichoice  is no more used in Moodle.
             // $webctoptions[1] contains either vertical or horizontal.
             continue;
         }
         if (isset($question->qtype) && 'calculated' == $question->qtype && preg_match('~^:ANS-DEC:([1-9][0-9]*)~i', $line, $webctoptions)) {
             // We can but hope that this always appear before the ANSTYPE property.
             $question->correctanswerlength[$currentchoice] = $webctoptions[1];
             continue;
         }
         if (isset($question->qtype) && 'calculated' == $question->qtype && preg_match("~^:TOL:({$webctnumberregex})~i", $line, $webctoptions)) {
             // We can but hope that this always appear before the TOL property.
             $question->tolerance[$currentchoice] = qformat_webct_convert_formula($webctoptions[1]);
             continue;
         }
         if (isset($question->qtype) && 'calculated' == $question->qtype && preg_match('~^:TOLTYPE:percent~i', $line)) {
             // Percentage case is handled as relative in Moodle.
             $question->tolerance[$currentchoice] /= 100;
             $question->tolerancetype[$currentchoice] = 1;
             // Relative.
             continue;
         }
         if (preg_match('~^:UNITS:(.+)~i', $line, $webctoptions) and $webctunits = trim($webctoptions[1])) {
             // This is a guess - I really do not know how different webct units are separated...
             $webctunits = explode(':', $webctunits);
             $unitrec->multiplier = 1.0;
             // Webct does not seem to support this.
             foreach ($webctunits as $webctunit) {
                 $unitrec->unit = trim($webctunit);
                 $question->units[] = $unitrec;
             }
             continue;
         }
         if (!empty($question->units) && preg_match('~^:UNITREQ:(.*)~i', $line, $webctoptions) && !$webctoptions[1]) {
             // There are units but units are not required so add the no unit alternative.
             // We can but hope that the UNITS property always appear before this property.
             $unitrec->unit = '';
             $unitrec->multiplier = 1.0;
             $question->units[] = $unitrec;
             continue;
         }
         if (!empty($question->units) && preg_match('~^:UNITCASE:~i', $line)) {
             // This could be important but I was not able to figure out how
             // it works so I ignore it for now.
             continue;
         }
         if (isset($question->qtype) && 'calculated' == $question->qtype && preg_match('~^:ANSTYPE:dec~i', $line)) {
             $question->correctanswerformat[$currentchoice] = '1';
             continue;
         }
         if (isset($question->qtype) && 'calculated' == $question->qtype && preg_match('~^:ANSTYPE:sig~i', $line)) {
             $question->correctanswerformat[$currentchoice] = '2';
             continue;
         }
     }
     if (count($errors) > 0) {
         echo '<p>' . get_string('errorsdetected', 'qformat_webct', count($errors)) . '</p><ul>';
         foreach ($errors as $error) {
             echo "<li>{$error}</li>";
         }
         echo '</ul>';
         unset($questions);
         // No questions imported.
     }
     if (count($warnings) > 0) {
         echo '<p>' . get_string('warningsdetected', 'qformat_webct', count($warnings)) . '</p><ul>';
         foreach ($warnings as $warning) {
             echo "<li>{$warning}</li>";
         }
         echo '</ul>';
     }
     return $questions;
 }
コード例 #23
0
 /**
  * Returns HTML entity transliteration table.
  * @return array with (html entity => utf-8) elements
  */
 protected static function get_entities_table()
 {
     static $trans_tbl = null;
     // Generate/create $trans_tbl
     if (!isset($trans_tbl)) {
         if (version_compare(phpversion(), '5.3.4') < 0) {
             $trans_tbl = array();
             foreach (get_html_translation_table(HTML_ENTITIES) as $val => $key) {
                 $trans_tbl[$key] = textlib::convert($val, 'ISO-8859-1', 'utf-8');
             }
         } else {
             if (version_compare(phpversion(), '5.4.0') < 0) {
                 $trans_tbl = get_html_translation_table(HTML_ENTITIES, ENT_COMPAT, 'UTF-8');
                 $trans_tbl = array_flip($trans_tbl);
             } else {
                 $trans_tbl = get_html_translation_table(HTML_ENTITIES, ENT_COMPAT | ENT_HTML401, 'UTF-8');
                 $trans_tbl = array_flip($trans_tbl);
             }
         }
     }
     return $trans_tbl;
 }
コード例 #24
0
ファイル: lib.php プロジェクト: vinoth4891/clinique
 protected function db_decode($text)
 {
     $dbenc = $this->get_config('dbencoding');
     if (empty($dbenc) or $dbenc == 'utf-8') {
         return $text;
     }
     if (is_array($text)) {
         foreach ($text as $k => $value) {
             $text[$k] = $this->db_decode($value);
         }
         return $text;
     } else {
         return textlib::convert($text, $dbenc, 'utf-8');
     }
 }
コード例 #25
0
 public function test_sync()
 {
     global $CFG, $DB;
     $this->resetAfterTest();
     /** @var enrol_flatfile_plugin $flatfileplugin  */
     $flatfileplugin = enrol_get_plugin('flatfile');
     /** @var enrol_manual_plugin $manualplugin  */
     $manualplugin = enrol_get_plugin('manual');
     $this->assertNotEmpty($manualplugin);
     $trace = new null_progress_trace();
     $this->enable_plugin();
     $file = "{$CFG->dataroot}/enrol.txt";
     $studentrole = $DB->get_record('role', array('shortname' => 'student'));
     $this->assertNotEmpty($studentrole);
     $teacherrole = $DB->get_record('role', array('shortname' => 'teacher'));
     $this->assertNotEmpty($teacherrole);
     $managerrole = $DB->get_record('role', array('shortname' => 'manager'));
     $this->assertNotEmpty($managerrole);
     $user1 = $this->getDataGenerator()->create_user(array('idnumber' => 'u1'));
     $user2 = $this->getDataGenerator()->create_user(array('idnumber' => 'u2'));
     $user3 = $this->getDataGenerator()->create_user(array('idnumber' => 'u3'));
     $user4 = $this->getDataGenerator()->create_user(array('idnumber' => 'čtvrtý'));
     $user5 = $this->getDataGenerator()->create_user(array('idnumber' => 'u5'));
     $user6 = $this->getDataGenerator()->create_user(array('idnumber' => 'u6'));
     $user7 = $this->getDataGenerator()->create_user(array('idnumber' => ''));
     $course1 = $this->getDataGenerator()->create_course(array('idnumber' => 'c1'));
     $course2 = $this->getDataGenerator()->create_course(array('idnumber' => 'c2'));
     $course3 = $this->getDataGenerator()->create_course(array('idnumber' => 'c3'));
     $context1 = context_course::instance($course1->id);
     $context2 = context_course::instance($course2->id);
     $context3 = context_course::instance($course3->id);
     $maninstance1 = $DB->get_record('enrol', array('courseid' => $course1->id, 'enrol' => 'manual'), '*', MUST_EXIST);
     $maninstance2 = $DB->get_record('enrol', array('courseid' => $course2->id, 'enrol' => 'manual'), '*', MUST_EXIST);
     $maninstance3 = $DB->get_record('enrol', array('courseid' => $course3->id, 'enrol' => 'manual'), '*', MUST_EXIST);
     // Rename teacher role.
     $flatfileplugin->set_config('map_' . $teacherrole->id, 'ucitel');
     // Disable manager role.
     $flatfileplugin->set_config('map_' . $managerrole->id, '');
     // Set file location.
     $flatfileplugin->set_config('location', $file);
     $now = time();
     $before = $now - 60;
     $future = $now + 60 * 60 * 5;
     $farfuture = $now + 60 * 60 * 24 * 5;
     // Test add action.
     $data = "'add','student','u1','c1'\n\n            \"add\" , \"ucitel\", u2 , c2\n            add,manager,u3,c1\n            add,student,čtvrtý,c2,{$before}\n            add,student,u5,c1,0,0,1\n            add,student,u5,c2,20,10\n            add,student,u6,c1,0,{$future}\n            add,student,u6,c2,{$future},0\n            add,student,u6,c3,{$future},{$farfuture}\n            add,student,,c2";
     file_put_contents($file, $data);
     $this->assertEquals(0, $DB->count_records('user_enrolments'));
     $this->assertEquals(0, $DB->count_records('role_assignments'));
     $this->assertEquals(0, $DB->count_records('enrol_flatfile'));
     $this->assertTrue(file_exists($file));
     $flatfileplugin->sync($trace);
     $this->assertFalse(file_exists($file));
     $this->assertEquals(4, $DB->count_records('user_enrolments'));
     $this->assertEquals(4, $DB->count_records('role_assignments'));
     $this->assertTrue($DB->record_exists('role_assignments', array('contextid' => $context1->id, 'userid' => $user1->id, 'roleid' => $studentrole->id, 'component' => 'enrol_flatfile')));
     $this->assertTrue($DB->record_exists('role_assignments', array('contextid' => $context2->id, 'userid' => $user2->id, 'roleid' => $teacherrole->id, 'component' => 'enrol_flatfile')));
     $this->assertTrue($DB->record_exists('role_assignments', array('contextid' => $context2->id, 'userid' => $user4->id, 'roleid' => $studentrole->id, 'component' => 'enrol_flatfile')));
     $this->assertTrue($DB->record_exists('role_assignments', array('contextid' => $context1->id, 'userid' => $user6->id, 'roleid' => $studentrole->id, 'component' => 'enrol_flatfile')));
     // Test buffer.
     $this->assertEquals(2, $DB->count_records('enrol_flatfile'));
     $flatfileplugin->sync($trace);
     $this->assertEquals(2, $DB->count_records('enrol_flatfile'));
     $this->assertEquals(4, $DB->count_records('user_enrolments'));
     $this->assertEquals(4, $DB->count_records('role_assignments'));
     $DB->set_field('enrol_flatfile', 'timestart', time() - 60, array('timestart' => $future, 'timeend' => 0));
     $flatfileplugin->sync($trace);
     $this->assertEquals(1, $DB->count_records('enrol_flatfile'));
     $this->assertEquals(5, $DB->count_records('user_enrolments'));
     $this->assertEquals(5, $DB->count_records('role_assignments'));
     $this->assertTrue($DB->record_exists('role_assignments', array('contextid' => $context2->id, 'userid' => $user6->id, 'roleid' => $studentrole->id, 'component' => 'enrol_flatfile')));
     $this->assertTrue($DB->record_exists('enrol_flatfile', array('userid' => $user6->id, 'roleid' => $studentrole->id, 'timeend' => $farfuture)));
     // Test encoding.
     $data = "add;student;čtvrtý;c3";
     $data = textlib::convert($data, 'utf-8', 'iso-8859-2');
     file_put_contents($file, $data);
     $flatfileplugin->set_config('encoding', 'iso-8859-2');
     $flatfileplugin->sync($trace);
     $this->assertEquals(6, $DB->count_records('user_enrolments'));
     $this->assertEquals(6, $DB->count_records('role_assignments'));
     $this->assertTrue($DB->record_exists('role_assignments', array('contextid' => $context3->id, 'userid' => $user4->id, 'roleid' => $studentrole->id, 'component' => 'enrol_flatfile')));
     $flatfileplugin->set_config('encoding', 'UTF-8');
     // Test unenrolling purges buffer.
     $manualplugin->enrol_user($maninstance1, $user1->id, $teacherrole->id);
     $manualplugin->enrol_user($maninstance3, $user5->id, $teacherrole->id);
     $this->assertEquals(8, $DB->count_records('user_enrolments'));
     $this->assertEquals(8, $DB->count_records('role_assignments'));
     $this->assertEquals(1, $DB->count_records('enrol_flatfile'));
     $this->assertTrue($DB->record_exists('role_assignments', array('contextid' => $context1->id, 'userid' => $user1->id, 'roleid' => $teacherrole->id)));
     $flatfileplugin->set_config('unenrolaction', ENROL_EXT_REMOVED_KEEP);
     $data = "del,student,u1,c1\ndel,teacher,u6,c3";
     file_put_contents($file, $data);
     $flatfileplugin->sync($trace);
     $this->assertEquals(8, $DB->count_records('user_enrolments'));
     $this->assertEquals(8, $DB->count_records('role_assignments'));
     $this->assertEquals(1, $DB->count_records('enrol_flatfile'));
     $data = "del,student,u6,c3";
     file_put_contents($file, $data);
     $flatfileplugin->sync($trace);
     $this->assertEquals(8, $DB->count_records('user_enrolments'));
     $this->assertEquals(8, $DB->count_records('role_assignments'));
     $this->assertEquals(0, $DB->count_records('enrol_flatfile'));
     $flatfileplugin->set_config('unenrolaction', ENROL_EXT_REMOVED_SUSPENDNOROLES);
     $data = "\n            del,student,u1,c1\n            del,grrr,u5,c1\n            del,guest,u5,c2\n            del,student,u6,c2\n            del,ucitel,u5,c3";
     file_put_contents($file, $data);
     $this->assertTrue($DB->record_exists('role_assignments', array('contextid' => $context1->id, 'userid' => $user1->id, 'roleid' => $studentrole->id, 'component' => 'enrol_flatfile')));
     $this->assertTrue($DB->record_exists('role_assignments', array('contextid' => $context2->id, 'userid' => $user6->id, 'roleid' => $studentrole->id)));
     $this->assertTrue($DB->record_exists('role_assignments', array('contextid' => $context3->id, 'userid' => $user5->id, 'roleid' => $teacherrole->id)));
     $flatfileplugin->sync($trace);
     $this->assertEquals(8, $DB->count_records('user_enrolments'));
     $this->assertEquals(5, $DB->count_records('role_assignments'));
     $this->assertFalse($DB->record_exists('role_assignments', array('contextid' => $context1->id, 'userid' => $user1->id, 'roleid' => $studentrole->id, 'component' => 'enrol_flatfile')));
     $this->assertTrue($DB->record_exists('role_assignments', array('contextid' => $context1->id, 'userid' => $user1->id, 'roleid' => $teacherrole->id)));
     $this->assertFalse($DB->record_exists('role_assignments', array('contextid' => $context2->id, 'userid' => $user6->id, 'roleid' => $studentrole->id)));
     $this->assertFalse($DB->record_exists('role_assignments', array('contextid' => $context3->id, 'userid' => $user5->id, 'roleid' => $teacherrole->id)));
     $flatfileplugin->set_config('unenrolaction', ENROL_EXT_REMOVED_UNENROL);
     $manualplugin->enrol_user($maninstance3, $user5->id, $teacherrole->id);
     $data = "\n            add,student,u1,c1\n            add,student,u6,c2";
     file_put_contents($file, $data);
     $flatfileplugin->sync($trace);
     $this->assertEquals(8, $DB->count_records('user_enrolments'));
     $this->assertEquals(8, $DB->count_records('role_assignments'));
     $this->assertEquals(0, $DB->count_records('enrol_flatfile'));
     $this->assertTrue($DB->record_exists('role_assignments', array('contextid' => $context1->id, 'userid' => $user1->id, 'roleid' => $studentrole->id, 'component' => 'enrol_flatfile')));
     $this->assertTrue($DB->record_exists('role_assignments', array('contextid' => $context2->id, 'userid' => $user6->id, 'roleid' => $studentrole->id)));
     $this->assertTrue($DB->record_exists('role_assignments', array('contextid' => $context3->id, 'userid' => $user5->id, 'roleid' => $teacherrole->id)));
     $this->assertTrue($DB->record_exists('user_enrolments', array('userid' => $user5->id, 'enrolid' => $maninstance3->id)));
     $this->assertTrue($DB->record_exists('user_enrolments', array('userid' => $user1->id, 'enrolid' => $maninstance1->id)));
     $data = "\n            del,student,u1,c1\n            del,grrr,u5,c1\n            del,guest,u5,c2\n            del,student,u6,c2\n            del,ucitel,u5,c3";
     file_put_contents($file, $data);
     $flatfileplugin->sync($trace);
     $this->assertEquals(5, $DB->count_records('user_enrolments'));
     $this->assertEquals(5, $DB->count_records('role_assignments'));
     $this->assertFalse($DB->record_exists('role_assignments', array('contextid' => $context1->id, 'userid' => $user1->id, 'roleid' => $studentrole->id, 'component' => 'enrol_flatfile')));
     $this->assertTrue($DB->record_exists('role_assignments', array('contextid' => $context1->id, 'userid' => $user1->id, 'roleid' => $teacherrole->id)));
     $this->assertFalse($DB->record_exists('role_assignments', array('contextid' => $context2->id, 'userid' => $user6->id, 'roleid' => $studentrole->id)));
     $this->assertFalse($DB->record_exists('role_assignments', array('contextid' => $context3->id, 'userid' => $user5->id, 'roleid' => $teacherrole->id)));
     $this->assertFalse($DB->record_exists('user_enrolments', array('userid' => $user5->id, 'enrolid' => $maninstance3->id)));
     $this->assertTrue($DB->record_exists('user_enrolments', array('userid' => $user1->id, 'enrolid' => $maninstance1->id)));
 }