示例#1
0
/**
 * 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->geoip2file) and file_exists($CFG->geoip2file)) {
        $reader = new GeoIp2\Database\Reader($CFG->geoip2file);
        $record = $reader->city($ip);
        if (empty($record)) {
            $info['error'] = get_string('iplookupfailed', 'error', $ip);
            return $info;
        }
        $info['city'] = core_text::convert($record->city->name, 'iso-8859-1', 'utf-8');
        $info['title'][] = $info['city'];
        $countrycode = $record->country->isoCode;
        $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'] = $record->country->names['en'];
        }
        $info['title'][] = $info['country'];
        $info['longitude'] = $record->location->longitude;
        $info['latitude'] = $record->location->latitude;
        $info['note'] = get_string('iplookupmaxmindnote', 'admin');
        return $info;
    } else {
        require_once $CFG->libdir . '/filelib.php';
        if (strpos($ip, ':') !== false) {
            // IPv6 is not supported by geoplugin.net.
            $info['error'] = get_string('invalidipformat', 'error');
            return $info;
        }
        $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;
    }
}
示例#2
0
 /**
  * Gets quoted csv variable string.
  *
  * @param string $varstr csv variable string
  * @return quoted csv variable string
  */
 public function quote($varstr)
 {
     if ($this->_excelcsv) {
         return core_text::convert('"' . str_replace('"', "'", $varstr) . '"', 'UTF-8', 'UTF-16LE');
     } else {
         return '"' . str_replace('"', "'", $varstr) . '"';
     }
 }
示例#3
0
function csv_quote($value)
{
    global $excel;
    if ($excel) {
        return core_text::convert('"' . str_replace('"', "'", $value) . '"', 'UTF-8', 'UTF-16LE');
    } else {
        return '"' . str_replace('"', "'", $value) . '"';
    }
}
示例#4
0
 /**
  * Authenticates user against the selected authentication provide (Ad web service)
  *
  * @param string $username The username (with system magic quotes)
  * @param string $password The password (with system magic quotes)
  * @return bool Authentication success or failure.
  */
 function user_login($username, $password)
 {
     global $DB, $CFG;
     $extusername = core_text::convert($username, 'utf-8', $this->config->extencoding);
     $extpassword = core_text::convert($password, 'utf-8', $this->config->extencoding);
     if (!$username or !$password) {
         // Don't allow blank usernames or passwords
         return false;
     }
     //retrieve the user matching username
     if ($user = $DB->get_record('user', array('username' => $username, 'mnethostid' => $CFG->mnet_localhost_id, 'auth' => $this->authtype))) {
         return validate_internal_user_password($user, $password);
     } else {
         return false;
     }
     //username must exist and have the right authentication method
     if (!empty($user) && $user->auth == 'adwebservice') {
         return true;
     }
     return false;
 }
示例#5
0
文件: lib.php 项目: evltuma/moodle
 /**
  * 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.
     core_php_time_limit::raise();
     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 = core_text::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(core_text::strtolower($fields[0]));
             $fields[1] = trim(core_text::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;
 }
示例#6
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 = @core_text::convert($name, $this->encoding, 'utf-8');
                     $original = core_text::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 'EUC-JP':
                             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 = @core_text::convert($name, $encoding, 'utf-8');
                     $original = core_text::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;
     }
 }
示例#7
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
  * @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 = core_text::convert($content, $encoding, 'utf-8');
     // remove Unicode BOM from first line
     $content = core_text::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,
     // do not try using fgetcsv() because there is nothing
     // to split rows properly - fgetcsv() itself can not do it.
     $tempfile = tempnam(make_temp_directory('/csvimport'), 'tmp');
     if (!($fp = fopen($tempfile, 'w+b'))) {
         $this->_error = get_string('cannotsavedata', 'error');
         @unlink($tempfile);
         return false;
     }
     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);
         unlink($tempfile);
         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);
             unlink($tempfile);
             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);
             unlink($tempfile);
             $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);
     unlink($tempfile);
     fclose($filepointer);
     $datacount = count($columns);
     return $datacount;
 }
示例#8
0
 /**
  * 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 = core_text::convert($_SERVER['REMOTE_USER'], 'iso-8859-1', 'utf-8');
         switch ($this->config->ntlmsso_type) {
             case 'ntlm':
                 // The format is now configurable, so try to extract the username
                 $username = $this->get_ntlm_remote_user($username);
                 if (empty($username)) {
                     return false;
                 }
                 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 = core_text::strtolower($username);
         // Compatibility hack
         set_cache_flag($this->pluginconfig . '/ntlmsess', $sesskey, $username, AUTH_NTLMTIMEOUT);
         return true;
     }
     return false;
 }
示例#9
0
/**
 * Send an email to a specified user
 *
 * @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, either relative to $CFG->dataroot or a full path to a file in $CFG->tempdir
 * @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) or empty($user->id)) {
        debugging('Can not send email to null user', DEBUG_DEVELOPER);
        return false;
    }
    if (empty($user->email)) {
        debugging('Can not send email to user without email: ' . $user->id, DEBUG_DEVELOPER);
        return false;
    }
    if (!empty($user->deleted)) {
        debugging('Can not send email to deleted user: '******'BEHAT_SITE_RUNNING')) {
        // Fake email sending in behat.
        return true;
    }
    if (!empty($CFG->noemailever)) {
        // Hidden setting for development sites, set in config.php if needed.
        debugging('Not sending email due to $CFG->noemailever config setting', DEBUG_NORMAL);
        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.
        debugging("email_to_user: User {$user->id} (" . fullname($user) . ") email ({$user->email}) is invalid! Not sending.");
        return false;
    }
    if (over_bounce_threshold($user)) {
        debugging("email_to_user: User {$user->id} (" . fullname($user) . ") is over bounce threshold! Not sending.");
        return false;
    }
    // TLD .invalid  is specifically reserved for invalid domain names.
    // For More information, see {@link http://tools.ietf.org/html/rfc2606#section-2}.
    if (substr($user->email, -8) == '.invalid') {
        debugging("email_to_user: User {$user->id} (" . fullname($user) . ") email domain ({$user->email}) is invalid! Not sending.");
        return true;
        // This is not an error.
    }
    // 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 = core_user::get_support_user();
    // 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 (!empty($CFG->emailonlyfromnoreplyaddress)) {
        $usetrueaddress = false;
        if (empty($replyto) && $from->maildisplay) {
            $replyto = $from->email;
            $replytoname = fullname($from);
        }
    }
    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));
    // Set word wrap.
    $mail->WordWrap = $wordwrapwidth;
    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';
        $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);
            $attachmentpath = $attachment;
            // Before doing the comparison, make sure that the paths are correct (Windows uses slashes in the other direction).
            $attachpath = str_replace('\\', '/', $attachmentpath);
            // Make sure both variables are normalised before comparing.
            $temppath = str_replace('\\', '/', $CFG->tempdir);
            // If the attachment is a full path to a file in the tempdir, use it as is,
            // otherwise assume it is a relative path from the dataroot (for backwards compatibility reasons).
            if (strpos($attachpath, realpath($temppath)) !== 0) {
                $attachmentpath = $CFG->dataroot . '/' . $attachmentpath;
            }
            $mail->addAttachment($attachmentpath, $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 = core_text::convert($mail->FromName, 'utf-8', strtolower($charset));
            $mail->Subject = core_text::convert($mail->Subject, 'utf-8', strtolower($charset));
            $mail->Body = core_text::convert($mail->Body, 'utf-8', strtolower($charset));
            $mail->AltBody = core_text::convert($mail->AltBody, 'utf-8', strtolower($charset));
            foreach ($temprecipients as $key => $values) {
                $temprecipients[$key][1] = core_text::convert($values[1], 'utf-8', strtolower($charset));
            }
            foreach ($tempreplyto as $key => $values) {
                $tempreplyto[$key][1] = core_text::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);
        if (!empty($mail->SMTPDebug)) {
            echo '</pre>';
        }
        return true;
    } else {
        // Trigger event for failing to send email.
        $event = \core\event\email_failed::create(array('context' => context_system::instance(), 'userid' => $from->id, 'relateduserid' => $user->id, 'other' => array('subject' => $subject, 'message' => $messagetext, 'errorinfo' => $mail->ErrorInfo)));
        $event->trigger();
        if (CLI_SCRIPT) {
            mtrace('Error: lib/moodlelib.php email_to_user(): ' . $mail->ErrorInfo);
        }
        if (!empty($mail->SMTPDebug)) {
            echo '</pre>';
        }
        return false;
    }
}
示例#10
0
 /**
  * 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 stdClass $olduser     Userobject before modifications
  * @param stdClass $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 = core_text::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(core_text::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;
 }
示例#11
0
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 core_text::convert($text, $enc);
    }
}
示例#12
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 = core_text::convert($result, $this->encoding, 'utf-8');
     }
     return clean_param($result, PARAM_PATH);
 }
示例#13
0
 /**
  * Tests the static strtoupper.
  */
 public function test_strtoupper()
 {
     $str = "Žluťoučký koníček";
     $up = 'ŽLUŤOUČKÝ KONÍČEK';
     $this->assertSame($up, core_text::strtoupper($str));
     $iso2 = pack("H*", "ae6c75bb6f75e86bfd206b6f6eede8656b");
     $this->assertSame(core_text::convert($up, 'utf-8', 'iso-8859-2'), core_text::strtoupper($iso2, 'iso-8859-2'));
     $win = pack("H*", "8e6c759d6f75e86bfd206b6f6eede8656b");
     $this->assertSame(core_text::convert($up, 'utf-8', 'cp1250'), core_text::strtoupper($win, 'cp1250'));
     $str = '言語設定';
     $this->assertSame($str, core_text::strtoupper($str));
     $str = '简体中文';
     $this->assertSame($str, core_text::strtoupper($str));
     $str = pack("H*", "1b24423840386c405f446a1b2842");
     // ISO-2022-JP
     $this->assertSame($str, core_text::strtoupper($str, 'ISO-2022-JP'));
     $str = pack("H*", "8cbe8cea90dd92e8");
     // SHIFT-JIS
     $this->assertSame($str, core_text::strtoupper($str, 'SHIFT-JIS'));
     $str = pack("H*", "bcf2cce5d6d0cec4");
     // GB2312
     $this->assertSame($str, core_text::strtoupper($str, 'GB2312'));
     $str = pack("H*", "bcf2cce5d6d0cec4");
     // GB18030
     $this->assertSame($str, core_text::strtoupper($str, 'GB18030'));
 }
示例#14
0
     print_error('nomanualenrol', 'local_ltiprovider');
 }
 // Transform to utf8 all the post and get data
 if (class_exists('textlib')) {
     $textlib = new textlib();
 } else {
     try {
         // for older moodle instances
         $textlib = textlib_get_instance();
     } catch (Exception $e) {
         // updated to use new core_text lib as required by Moodle 2.9
         $textlib = new core_text();
     }
 }
 foreach ($_POST as $key => $value) {
     $_POST[$key] = $textlib->convert($value, $tool->encoding);
 }
 foreach ($_GET as $key => $value) {
     $_GET[$key] = $textlib->convert($value, $tool->encoding);
 }
 // We need an username without extended chars
 // Later accounts add the ConsumerKey - we silently upgrade old accounts
 // Might want a flag for this -- Chuck
 $username = local_ltiprovider_create_username($context->info['oauth_consumer_key'], $context->info['user_id']);
 $dbuser = $DB->get_record('user', array('username' => $username));
 if (!$dbuser) {
     $old_username = '******' . md5($context->getUserKey());
     $dbuser = $DB->get_record('user', array('username' => $old_username));
     if ($dbuser) {
         // Probably should log this
         $DB->set_field('user', 'username', $username, array('id' => $dbuser->id));
示例#15
0
/**
 * Reads user information from ldap and returns it in array()
 *
 * Function should return all information available. If you are saving
 * this information to moodle user-table you should honor syncronization flags
 *
 * @param object $ldapauth the ldap authentication instance
 * @param string $username username
 * @param array $options an array with CLI input options
 *
 * @return mixed array with no magic quotes or false on error
 */
function local_ent_installer_get_userinfo($ldapauth, $username, $options = array())
{
    static $entattributes;
    // Load some cached static data.
    if (!isset($entattributes)) {
        // aggregate additional ent specific attributes that hold interesting information
        $configattribs = get_config('local_ent_installer', 'ent_userinfo_attributes');
        if (empty($configattribs)) {
            $entattributes = array('ENTPersonFonctions', 'ENTPersonJointure', 'ENTEleveClasses', 'ENTEleveGroupes', 'ENTEleveTransport', 'ENTEleveRegime', 'ENTPersonProfils', 'objectGUID');
        } else {
            $entattributes = explode(',', $configattribs);
        }
    }
    $extusername = core_text::convert($username, 'utf-8', $ldapauth->config->ldapencoding);
    $ldapconnection = $ldapauth->ldap_connect();
    if (!($user_dn = $ldapauth->ldap_find_userdn($ldapconnection, $extusername))) {
        $ldapauth->ldap_close();
        return false;
    }
    $search_attribs = array();
    $attrmap = $ldapauth->ldap_attributes();
    foreach ($attrmap as $key => $values) {
        if (!is_array($values)) {
            $values = array($values);
        }
        foreach ($values as $value) {
            if (!in_array($value, $search_attribs)) {
                array_push($search_attribs, $value);
            }
        }
    }
    foreach ($entattributes as $value) {
        if (!in_array($value, $search_attribs)) {
            array_push($search_attribs, $value);
            // Add attributes to $attrmap so they are pulled down into final user object.
            $attrmap[$value] = strtolower($value);
        }
    }
    if ($options['verbose']) {
        mtrace("Getting {$user_dn} for " . implode(',', $search_attribs));
    }
    if (!($user_info_result = ldap_read($ldapconnection, $user_dn, '(objectClass=*)', $search_attribs))) {
        $ldapauth->ldap_close();
        return false;
    }
    $user_entry = ldap_get_entries_moodle($ldapconnection, $user_info_result);
    if (empty($user_entry)) {
        $ldapauth->ldap_close();
        return false;
        // Entry not found.
    }
    $result = array();
    foreach ($attrmap as $key => $values) {
        if (!is_array($values)) {
            $values = array($values);
        }
        $ldapval = NULL;
        foreach ($values as $value) {
            $entry = array_change_key_case($user_entry[0], CASE_LOWER);
            if ($value == 'dn' || $value == 'distinguishedname') {
                $result[$key] = $user_dn;
                continue;
            }
            if (!array_key_exists($value, $entry)) {
                if ($options['verbose']) {
                    mtrace("Requested value {$value} but missing in record");
                }
                continue;
                // wrong data mapping!
            }
            if ($value == 'objectguid') {
                if (strlen($entry[$value][0]) == 16) {
                    $tmp = bin2hex($entry[$value][0]);
                    $t = $tmp[6] . $tmp[7] . $tmp[4] . $tmp[5] . $tmp[2] . $tmp[3] . $tmp[0] . $tmp[1] . '-';
                    $t .= $tmp[10] . $tmp[11] . $tmp[8] . $tmp[9] . '-';
                    $t .= $tmp[14] . $tmp[15] . $tmp[12] . $tmp[13] . '-';
                    $t .= substr($tmp, 16, 4) . '-';
                    $t .= substr($tmp, 20);
                    $objectguid = $t;
                }
                $newval = $objectguid;
            } else {
                if ($value == 'entelevegroupes' && is_array($entry[$value])) {
                    $newval = array();
                    foreach ($entry[$value] as $subkey => $subvalue) {
                        if ($subkey !== 'count') {
                            $newval[] = core_text::convert($subvalue, $ldapauth->config->ldapencoding, 'utf-8');
                        }
                    }
                } else {
                    if (is_array($entry[$value])) {
                        $newval = core_text::convert($entry[$value][0], $ldapauth->config->ldapencoding, 'utf-8');
                    } else {
                        $newval = core_text::convert($entry[$value], $ldapauth->config->ldapencoding, 'utf-8');
                    }
                }
            }
            if (!empty($newval)) {
                // Favour ldap entries that are set.
                $ldapval = $newval;
            }
        }
        if (!is_null($ldapval)) {
            $result[$key] = $ldapval;
        }
    }
    $ldapauth->ldap_close();
    return $result;
}
示例#16
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 = core_text::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)));
 }
示例#17
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 = core_text::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;
 }
示例#18
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') {
         core_text::convert($data, 'UTF-8', $this->output_encoding);
     }
     return $data;
 }
示例#19
0
 /**
  * Process the messagedata and part data to extract the content of this part.
  *
  * @param \Horde_Imap_Client_Data_Fetch $messagedata The structure and part of the message body
  * @param \Horde_Mime_Part $partdata The part data
  * @param string $part The part ID
  * @return string
  */
 private function process_message_part_body($messagedata, $partdata, $part)
 {
     // This is a content section for the main body.
     // Get the string version of it.
     $content = $messagedata->getBodyPart($part);
     if (!$messagedata->getBodyPartDecode($part)) {
         // Decode the content.
         $partdata->setContents($content);
         $content = $partdata->getContents();
     }
     // Convert the text from the current encoding to UTF8.
     $content = \core_text::convert($content, $partdata->getCharset());
     // Fix any invalid UTF8 characters.
     // Note: XSS cleaning is not the responsibility of this code. It occurs immediately before display when
     // format_text is called.
     $content = clean_param($content, PARAM_RAW);
     return $content;
 }
示例#20
0
文件: lib.php 项目: evltuma/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'] = core_text::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;
    }
}
/**
 * Send an email to a specified user
 *
 * @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) or empty($user->id)) {
        debugging('Can not send email to null user', DEBUG_DEVELOPER);
        return false;
    }
    if (empty($user->email)) {
        debugging('Can not send email to user without email: ' . $user->id, DEBUG_DEVELOPER);
        return false;
    }
    if (!empty($user->deleted)) {
        debugging('Can not send email to deleted user: '******'Not sending email due to $CFG->noemailever config setting', DEBUG_NORMAL);
        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 = core_user::get_support_user();
    // 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));
    // Set word wrap.
    $mail->WordWrap = $wordwrapwidth;
    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';
        $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 = core_text::convert($mail->FromName, 'utf-8', strtolower($charset));
            $mail->Subject = core_text::convert($mail->Subject, 'utf-8', strtolower($charset));
            $mail->Body = core_text::convert($mail->Body, 'utf-8', strtolower($charset));
            $mail->AltBody = core_text::convert($mail->AltBody, 'utf-8', strtolower($charset));
            foreach ($temprecipients as $key => $values) {
                $temprecipients[$key][1] = core_text::convert($values[1], 'utf-8', strtolower($charset));
            }
            foreach ($tempreplyto as $key => $values) {
                $tempreplyto[$key][1] = core_text::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);
        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;
    }
}
示例#22
0
 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 core_text::convert($text, $dbenc, 'utf-8');
     }
 }
示例#23
0
 /**
  * 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 = core_text::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;
 }
示例#24
0
/**
 * 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 core_text::convert($html, $enc, 'utf-8');
        }
    }
    return iconv('UTF-8', 'UTF-8//IGNORE', $html);
}
示例#25
0
 /**
  * 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 = core_text::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;
 }
示例#26
0
 public function readquestions($lines)
 {
     $webctnumberregex = '[+-]?([0-9]+(\\.[0-9]*)?|\\.[0-9]+)((e|E|\\*10\\*\\*)([+-]?[0-9]+|\\([+-]?[0-9]+\\)))?';
     $questions = 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 = core_text::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.
                     $this->error(get_string('missinganswer', 'qformat_webct', $nquestionstartline), '', $question->name);
                     $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;
                                 $this->error(get_string('wronggrade', 'qformat_webct', $nlinecounter) . ' ' . get_string('fractionsnomax', 'question', $maxfraction), '', $question->name);
                                 $questionok = false;
                             }
                             break;
                         case 'multichoice':
                             $question = $this->add_blank_combined_feedback($question);
                             if ($question->single) {
                                 if ($maxfraction != 1) {
                                     $maxfraction = $maxfraction * 100;
                                     $this->error(get_string('wronggrade', 'qformat_webct', $nlinecounter) . ' ' . get_string('fractionsnomax', 'question', $maxfraction), '', $question->name);
                                     $questionok = false;
                                 }
                             } else {
                                 $totalfraction = round($totalfraction, 2);
                                 if ($totalfraction != 1) {
                                     $totalfraction = $totalfraction * 100;
                                     $this->error(get_string('wronggrade', 'qformat_webct', $nlinecounter) . ' ' . get_string('fractionsaddwrong', 'qtype_multichoice', $totalfraction), '', $question->name);
                                     $questionok = false;
                                 }
                             }
                             break;
                         case 'calculated':
                             foreach ($question->answer 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;
                             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->responserequired = 1;
             $question->responsefieldlines = 15;
             $question->attachments = 0;
             $question->attachmentsrequired = 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($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;
 }
示例#27
0
/**
 * Send an email to a specified user
 *
 * @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, either relative to $CFG->dataroot or a full path to a file in $CFG->tempdir
 * @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, $PAGE, $SITE;
    if (empty($user) or empty($user->id)) {
        debugging('Can not send email to null user', DEBUG_DEVELOPER);
        return false;
    }
    if (empty($user->email)) {
        debugging('Can not send email to user without email: ' . $user->id, DEBUG_DEVELOPER);
        return false;
    }
    if (!empty($user->deleted)) {
        debugging('Can not send email to deleted user: '******'BEHAT_SITE_RUNNING')) {
        // Fake email sending in behat.
        return true;
    }
    if (!empty($CFG->noemailever)) {
        // Hidden setting for development sites, set in config.php if needed.
        debugging('Not sending email due to $CFG->noemailever config setting', DEBUG_NORMAL);
        return true;
    }
    if (email_should_be_diverted($user->email)) {
        $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.
        debugging("email_to_user: User {$user->id} (" . fullname($user) . ") email ({$user->email}) is invalid! Not sending.");
        return false;
    }
    if (over_bounce_threshold($user)) {
        debugging("email_to_user: User {$user->id} (" . fullname($user) . ") is over bounce threshold! Not sending.");
        return false;
    }
    // TLD .invalid  is specifically reserved for invalid domain names.
    // For More information, see {@link http://tools.ietf.org/html/rfc2606#section-2}.
    if (substr($user->email, -8) == '.invalid') {
        debugging("email_to_user: User {$user->id} (" . fullname($user) . ") email domain ({$user->email}) is invalid! Not sending.");
        return true;
        // This is not an error.
    }
    // 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();
    // Make sure that we fall back onto some reasonable no-reply address.
    $noreplyaddress = empty($CFG->noreplyaddress) ? 'noreply@' . get_host_from_url($CFG->wwwroot) : $CFG->noreplyaddress;
    // 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 = $noreplyaddress;
    }
    $alloweddomains = null;
    if (!empty($CFG->allowedemaildomains)) {
        $alloweddomains = explode(PHP_EOL, $CFG->allowedemaildomains);
    }
    // Email will be sent using no reply address.
    if (empty($alloweddomains)) {
        $usetrueaddress = false;
    }
    if (is_string($from)) {
        // So we can pass whatever we want if there is need.
        $mail->From = $noreplyaddress;
        $mail->FromName = $from;
        // Check if using the true address is true, and the email is in the list of allowed domains for sending email,
        // and that the senders email setting is either displayed to everyone, or display to only other users that are enrolled
        // in a course with the sender.
    } else {
        if ($usetrueaddress && can_send_from_real_email_address($from, $user, $alloweddomains)) {
            $mail->From = $from->email;
            $fromdetails = new stdClass();
            $fromdetails->name = fullname($from);
            $fromdetails->url = $CFG->wwwroot;
            $fromstring = $fromdetails->name;
            if ($CFG->emailfromvia == EMAIL_VIA_ALWAYS) {
                $fromstring = get_string('emailvia', 'core', $fromdetails);
            }
            $mail->FromName = $fromstring;
            if (empty($replyto)) {
                $tempreplyto[] = array($from->email, fullname($from));
            }
        } else {
            $mail->From = $noreplyaddress;
            $fromdetails = new stdClass();
            $fromdetails->name = fullname($from);
            $fromdetails->url = $CFG->wwwroot;
            $fromstring = $fromdetails->name;
            if ($CFG->emailfromvia != EMAIL_VIA_NEVER) {
                $fromstring = get_string('emailvia', 'core', $fromdetails);
            }
            $mail->FromName = $fromstring;
            if (empty($replyto)) {
                $tempreplyto[] = array($noreplyaddress, get_string('noreplyname'));
            }
        }
    }
    if (!empty($replyto)) {
        $tempreplyto[] = array($replyto, $replytoname);
    }
    $temprecipients[] = array($user->email, fullname($user));
    // Set word wrap.
    $mail->WordWrap = $wordwrapwidth;
    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 the X-PHP-Originating-Script email header is on then also add an additional
    // header with details of where exactly in moodle the email was triggered from,
    // either a call to message_send() or to email_to_user().
    if (ini_get('mail.add_x_header')) {
        $stack = debug_backtrace(false);
        $origin = $stack[0];
        foreach ($stack as $depth => $call) {
            if ($call['function'] == 'message_send') {
                $origin = $call;
            }
        }
        $originheader = $CFG->wwwroot . ' => ' . gethostname() . ':' . str_replace($CFG->dirroot . '/', '', $origin['file']) . ':' . $origin['line'];
        $mail->addCustomHeader('X-Moodle-Originating-Script: ' . $originheader);
    }
    if (!empty($from->priority)) {
        $mail->Priority = $from->priority;
    }
    $renderer = $PAGE->get_renderer('core');
    $context = array('sitefullname' => $SITE->fullname, 'siteshortname' => $SITE->shortname, 'sitewwwroot' => $CFG->wwwroot, 'subject' => $subject, 'to' => $user->email, 'toname' => fullname($user), 'from' => $mail->From, 'fromname' => $mail->FromName);
    if (!empty($tempreplyto[0])) {
        $context['replyto'] = $tempreplyto[0][0];
        $context['replytoname'] = $tempreplyto[0][1];
    }
    if ($user->id > 0) {
        $context['touserid'] = $user->id;
        $context['tousername'] = $user->username;
    }
    if (!empty($user->mailformat) && $user->mailformat == 1) {
        // Only process html templates if the user preferences allow html email.
        if ($messagehtml) {
            // If html has been given then pass it through the template.
            $context['body'] = $messagehtml;
            $messagehtml = $renderer->render_from_template('core/email_html', $context);
        } else {
            // If no html has been given, BUT there is an html wrapping template then
            // auto convert the text to html and then wrap it.
            $autohtml = trim(text_to_html($messagetext));
            $context['body'] = $autohtml;
            $temphtml = $renderer->render_from_template('core/email_html', $context);
            if ($autohtml != $temphtml) {
                $messagehtml = $temphtml;
            }
        }
    }
    $context['body'] = $messagetext;
    $mail->Subject = $renderer->render_from_template('core/email_subject', $context);
    $mail->FromName = $renderer->render_from_template('core/email_fromname', $context);
    $messagetext = $renderer->render_from_template('core/email_text', $context);
    // Autogenerate a MessageID if it's missing.
    if (empty($mail->MessageID)) {
        $mail->MessageID = generate_email_messageid();
    }
    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';
        $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);
            $attachmentpath = $attachment;
            // Before doing the comparison, make sure that the paths are correct (Windows uses slashes in the other direction).
            $attachpath = str_replace('\\', '/', $attachmentpath);
            // Make sure both variables are normalised before comparing.
            $temppath = str_replace('\\', '/', realpath($CFG->tempdir));
            // If the attachment is a full path to a file in the tempdir, use it as is,
            // otherwise assume it is a relative path from the dataroot (for backwards compatibility reasons).
            if (strpos($attachpath, $temppath) !== 0) {
                $attachmentpath = $CFG->dataroot . '/' . $attachmentpath;
            }
            $mail->addAttachment($attachmentpath, $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 = core_text::convert($mail->FromName, 'utf-8', strtolower($charset));
            $mail->Subject = core_text::convert($mail->Subject, 'utf-8', strtolower($charset));
            $mail->Body = core_text::convert($mail->Body, 'utf-8', strtolower($charset));
            $mail->AltBody = core_text::convert($mail->AltBody, 'utf-8', strtolower($charset));
            foreach ($temprecipients as $key => $values) {
                $temprecipients[$key][1] = core_text::convert($values[1], 'utf-8', strtolower($charset));
            }
            foreach ($tempreplyto as $key => $values) {
                $tempreplyto[$key][1] = core_text::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);
        if (!empty($mail->SMTPDebug)) {
            echo '</pre>';
        }
        return true;
    } else {
        // Trigger event for failing to send email.
        $event = \core\event\email_failed::create(array('context' => context_system::instance(), 'userid' => $from->id, 'relateduserid' => $user->id, 'other' => array('subject' => $subject, 'message' => $messagetext, 'errorinfo' => $mail->ErrorInfo)));
        $event->trigger();
        if (CLI_SCRIPT) {
            mtrace('Error: lib/moodlelib.php email_to_user(): ' . $mail->ErrorInfo);
        }
        if (!empty($mail->SMTPDebug)) {
            echo '</pre>';
        }
        return false;
    }
}
示例#28
0
             print_error('cantdeterminecontext', 'local_ltiprovider');
         }
     }
 }
 // Check that we can perform enrolments
 if (enrol_is_enabled('manual')) {
     $manual = enrol_get_plugin('manual');
 } else {
     print_error('nomanualenrol', 'local_ltiprovider');
 }
 // Transform to utf8 all the post and get data
 foreach ($_POST as $key => $value) {
     $_POST[$key] = core_text::convert($value, $tool->encoding);
 }
 foreach ($_GET as $key => $value) {
     $_GET[$key] = core_text::convert($value, $tool->encoding);
 }
 // We need an username without extended chars
 // Later accounts add the ConsumerKey - we silently upgrade old accounts
 // Might want a flag for this -- Chuck
 $username = local_ltiprovider_create_username($context->info['oauth_consumer_key'], $context->info['user_id']);
 $dbuser = $DB->get_record('user', array('username' => $username));
 if (!$dbuser) {
     $old_username = '******' . md5($context->getUserKey());
     $dbuser = $DB->get_record('user', array('username' => $old_username));
     if ($dbuser) {
         // Probably should log this
         $DB->set_field('user', 'username', $username, array('id' => $dbuser->id));
     }
     $dbuser = $DB->get_record('user', array('username' => $username));
 }