예제 #1
0
 /**
  * Validates a value using a range comparison
  *
  * @param     string    $value      Value to be checked
  * @param     mixed     $options    Int for length, array for range
  * @access    public
  * @return    boolean   true if value is valid
  */
 function validate($value, $options = null)
 {
     $length = textlib::strlen($value);
     switch ($this->name) {
         case 'minlength':
             return $length >= $options;
         case 'maxlength':
             return $length <= $options;
         default:
             return $length >= $options[0] && $length <= $options[1];
     }
 }
예제 #2
0
파일: lib.php 프로젝트: Jtgadbois/Pedadida
/**
 * @uses LABEL_MAX_NAME_LENGTH
 * @param object $label
 * @return string
 */
function get_label_name($label) {
    $name = strip_tags(format_string($label->intro,true));
    if (textlib::strlen($name) > LABEL_MAX_NAME_LENGTH) {
        $name = textlib::substr($name, 0, LABEL_MAX_NAME_LENGTH)."...";
    }

    if (empty($name)) {
        // arbitrary name
        $name = get_string('modulename','label');
    }

    return $name;
}
예제 #3
0
 protected function action($message, $level, $options = null)
 {
     $columns = $this->columns;
     if ($this->datecol) {
         $columns[$this->datecol] = time();
     }
     if ($this->levelcol) {
         $columns[$this->levelcol] = $level;
     }
     $message = clean_param($message, PARAM_NOTAGS);
     // Check if the message exceeds the 255 character limit in the database,
     // if it does, shorten it so that it can be inserted successfully.
     if (textlib::strlen($message) > 255) {
         $message = textlib::substr($message, 0, 252) . '...';
     }
     $columns[$this->messagecol] = $message;
     return $this->insert_log_record($this->logtable, $columns);
 }
function rfc2445_fold($string)
{
    if (textlib::strlen($string, 'utf-8') <= RFC2445_FOLDED_LINE_LENGTH) {
        return $string;
    }
    $retval = '';
    $i = 0;
    $len_count = 0;
    //multi-byte string, get the correct length
    $section_len = textlib::strlen($string, 'utf-8');
    while ($len_count < $section_len) {
        //get the current portion of the line
        $section = textlib::substr($string, $i * RFC2445_FOLDED_LINE_LENGTH, RFC2445_FOLDED_LINE_LENGTH, 'utf-8');
        //increment the length we've processed by the length of the new portion
        $len_count += textlib::strlen($section, 'utf-8');
        /* Add the portion to the return value, terminating with CRLF.HTAB
           As per RFC 2445, CRLF.HTAB will be replaced by the processor of the 
           data */
        $retval .= $section . RFC2445_CRLF . RFC2445_WSP;
        $i++;
    }
    return $retval;
}
예제 #5
0
 /**
  * Update categories
  *
  * @param array $categories The list of categories to update
  * @return null
  * @since Moodle 2.3
  */
 public static function update_categories($categories)
 {
     global $CFG, $DB;
     require_once $CFG->dirroot . "/course/lib.php";
     // Validate parameters.
     $params = self::validate_parameters(self::update_categories_parameters(), array('categories' => $categories));
     $transaction = $DB->start_delegated_transaction();
     foreach ($params['categories'] as $cat) {
         if (!($category = $DB->get_record('course_categories', array('id' => $cat['id'])))) {
             throw new moodle_exception('unknowcategory');
         }
         $categorycontext = context_coursecat::instance($cat['id']);
         self::validate_context($categorycontext);
         require_capability('moodle/category:manage', $categorycontext);
         if (!empty($cat['name'])) {
             if (textlib::strlen($cat['name']) > 255) {
                 throw new moodle_exception('categorytoolong');
             }
             $category->name = $cat['name'];
         }
         if (!empty($cat['idnumber'])) {
             if (textlib::strlen($cat['idnumber']) > 100) {
                 throw new moodle_exception('idnumbertoolong');
             }
             $category->idnumber = $cat['idnumber'];
         }
         if (!empty($cat['description'])) {
             $category->description = $cat['description'];
             $category->descriptionformat = external_validate_format($cat['descriptionformat']);
         }
         if (!empty($cat['theme'])) {
             $category->theme = $cat['theme'];
         }
         if (!empty($cat['parent']) && $category->parent != $cat['parent']) {
             // First check if parent exists.
             if (!($parent_cat = $DB->get_record('course_categories', array('id' => $cat['parent'])))) {
                 throw new moodle_exception('unknowcategory');
             }
             // Then check if we have capability.
             self::validate_context(get_category_or_system_context((int) $cat['parent']));
             require_capability('moodle/category:manage', get_category_or_system_context((int) $cat['parent']));
             // Finally move the category.
             move_category($category, $parent_cat);
             $category->parent = $cat['parent'];
             // Get updated path by move_category().
             $category->path = $DB->get_field('course_categories', 'path', array('id' => $category->id));
         }
         $DB->update_record('course_categories', $category);
     }
     $transaction->allow_commit();
 }
 /**
  * Strips a large title to size and adds ... if title too long
  *
  * @param string title to shorten
  * @param int max character length of title
  * @return string title s() quoted and shortened if necessary
  */
 function format_title($title, $max = 64)
 {
     if (textlib::strlen($title) <= $max) {
         return s($title);
     } else {
         return s(textlib::substr($title, 0, $max - 3) . '...');
     }
 }
예제 #7
0
파일: lib.php 프로젝트: numbas/moodle
/**
 * given a course object with shortname & fullname, this function will
 * truncate the the number of chars allowed and add ... if it was too long
 */
function course_format_name($course, $max = 100)
{
    $context = get_context_instance(CONTEXT_COURSE, $course->id);
    $shortname = format_string($course->shortname, true, array('context' => $context));
    $fullname = format_string($course->fullname, true, array('context' => get_context_instance(CONTEXT_COURSE, $course->id)));
    $str = $shortname . ': ' . $fullname;
    if (textlib::strlen($str) <= $max) {
        return $str;
    } else {
        return textlib::substr($str, 0, $max - 3) . '...';
    }
}
예제 #8
0
/**
 * Add an entry to the log table.
 *
 * Add an entry to the log table.  These are "action" focussed rather
 * than web server hits, and provide a way to easily reconstruct what
 * any particular student has been doing.
 *
 * @package core
 * @category log
 * @global moodle_database $DB
 * @global stdClass $CFG
 * @global stdClass $USER
 * @uses SITEID
 * @uses DEBUG_DEVELOPER
 * @uses DEBUG_ALL
 * @param    int     $courseid  The course id
 * @param    string  $module  The module name  e.g. forum, journal, resource, course, user etc
 * @param    string  $action  'view', 'update', 'add' or 'delete', possibly followed by another word to clarify.
 * @param    string  $url     The file and parameters used to see the results of the action
 * @param    string  $info    Additional description information
 * @param    string  $cm      The course_module->id if there is one
 * @param    string  $user    If log regards $user other than $USER
 * @return void
 */
function add_to_log($courseid, $module, $action, $url = '', $info = '', $cm = 0, $user = 0)
{
    // Note that this function intentionally does not follow the normal Moodle DB access idioms.
    // This is for a good reason: it is the most frequently used DB update function,
    // so it has been optimised for speed.
    global $DB, $CFG, $USER;
    if ($cm === '' || is_null($cm)) {
        // postgres won't translate empty string to its default
        $cm = 0;
    }
    if ($user) {
        $userid = $user;
    } else {
        if (session_is_loggedinas()) {
            // Don't log
            return;
        }
        $userid = empty($USER->id) ? '0' : $USER->id;
    }
    if (isset($CFG->logguests) and !$CFG->logguests) {
        if (!$userid or isguestuser($userid)) {
            return;
        }
    }
    $REMOTE_ADDR = getremoteaddr();
    $timenow = time();
    $info = $info;
    if (!empty($url)) {
        // could break doing html_entity_decode on an empty var.
        $url = html_entity_decode($url, ENT_QUOTES, 'UTF-8');
    } else {
        $url = '';
    }
    // Restrict length of log lines to the space actually available in the
    // database so that it doesn't cause a DB error. Log a warning so that
    // developers can avoid doing things which are likely to cause this on a
    // routine basis.
    if (!empty($info) && textlib::strlen($info) > 255) {
        $info = textlib::substr($info, 0, 252) . '...';
        debugging('Warning: logged very long info', DEBUG_DEVELOPER);
    }
    // If the 100 field size is changed, also need to alter print_log in course/lib.php
    if (!empty($url) && textlib::strlen($url) > 100) {
        $url = textlib::substr($url, 0, 97) . '...';
        debugging('Warning: logged very long URL', DEBUG_DEVELOPER);
    }
    if (defined('MDL_PERFDB')) {
        global $PERF;
        $PERF->logwrites++;
    }
    $log = array('time' => $timenow, 'userid' => $userid, 'course' => $courseid, 'ip' => $REMOTE_ADDR, 'module' => $module, 'cmid' => $cm, 'action' => $action, 'url' => $url, 'info' => $info);
    try {
        $DB->insert_record_raw('log', $log, false);
    } catch (dml_exception $e) {
        debugging('Error: Could not insert a new entry to the Moodle log. ' . $e->error, DEBUG_ALL);
        // MDL-11893, alert $CFG->supportemail if insert into log failed
        if ($CFG->supportemail and empty($CFG->noemailever)) {
            // email_to_user is not usable because email_to_user tries to write to the logs table,
            // and this will get caught in an infinite loop, if disk is full
            $site = get_site();
            $subject = 'Insert into log failed at your moodle site ' . $site->fullname;
            $message = "Insert into log table failed at " . date('l dS \\of F Y h:i:s A') . ".\n It is possible that your disk is full.\n\n";
            $message .= "The failed query parameters are:\n\n" . var_export($log, true);
            $lasttime = get_config('admin', 'lastloginserterrormail');
            if (empty($lasttime) || time() - $lasttime > 60 * 60 * 24) {
                // limit to 1 email per day
                //using email directly rather than messaging as they may not be able to log in to access a message
                mail($CFG->supportemail, $subject, $message);
                set_config('lastloginserterrormail', time(), 'admin');
            }
        }
    }
}
예제 #9
0
 /**
  * Create a shorten filename
  *
  * @param string $str filename
  * @param int $maxlength max file name length
  * @return string short filename
  */
 public function get_short_filename($str, $maxlength)
 {
     if (textlib::strlen($str) >= $maxlength) {
         return trim(textlib::substr($str, 0, $maxlength)) . '...';
     } else {
         return $str;
     }
 }
예제 #10
0
/**
 * Internal function - prints the search results
 *
 * @param string $query String to search for
 * @return string empty or XHTML
 */
function admin_search_settings_html($query)
{
    global $CFG, $OUTPUT;
    if (textlib::strlen($query) < 2) {
        return '';
    }
    $query = textlib::strtolower($query);
    $adminroot = admin_get_root();
    $findings = $adminroot->search($query);
    $return = '';
    $savebutton = false;
    foreach ($findings as $found) {
        $page = $found->page;
        $settings = $found->settings;
        if ($page->is_hidden()) {
            // hidden pages are not displayed in search results
            continue;
        }
        if ($page instanceof admin_externalpage) {
            $return .= $OUTPUT->heading(get_string('searchresults', 'admin') . ' - <a href="' . $page->url . '">' . highlight($query, $page->visiblename) . '</a>', 2, 'main');
        } else {
            if ($page instanceof admin_settingpage) {
                $return .= $OUTPUT->heading(get_string('searchresults', 'admin') . ' - <a href="' . $CFG->wwwroot . '/' . $CFG->admin . '/settings.php?section=' . $page->name . '">' . highlight($query, $page->visiblename) . '</a>', 2, 'main');
            } else {
                continue;
            }
        }
        if (!empty($settings)) {
            $return .= '<fieldset class="adminsettings">' . "\n";
            foreach ($settings as $setting) {
                if (empty($setting->nosave)) {
                    $savebutton = true;
                }
                $return .= '<div class="clearer"><!-- --></div>' . "\n";
                $fullname = $setting->get_full_name();
                if (array_key_exists($fullname, $adminroot->errors)) {
                    $data = $adminroot->errors[$fullname]->data;
                } else {
                    $data = $setting->get_setting();
                    // do not use defaults if settings not available - upgradesettings handles the defaults!
                }
                $return .= $setting->output_html($data, $query);
            }
            $return .= '</fieldset>';
        }
    }
    if ($savebutton) {
        $return .= '<div class="form-buttons"><input class="form-submit" type="submit" value="' . get_string('savechanges', 'admin') . '" /></div>';
    }
    return $return;
}
예제 #11
0
 /**
  * Ensure that a question name does not contain anything nasty, and will fit in the DB field.
  * @param string $name the raw question name.
  * @return string a safe question name.
  */
 public function clean_question_name($name)
 {
     $name = clean_param($name, PARAM_TEXT);
     // Matches what the question editing form does.
     $name = trim($name);
     $trimlength = 251;
     while (textlib::strlen($name) > 255 && $trimlength > 0) {
         $name = shorten_text($name, $trimlength);
         $trimlength -= 10;
     }
     return $name;
 }
예제 #12
0
    public function save_usage($preferredbehaviour, $attempt, $qas, $quizlayout) {
        $missing = array();

        $layout = explode(',', $attempt->layout);
        $questionkeys = array_combine(array_values($layout), array_keys($layout));

        $this->set_quba_preferred_behaviour($attempt->uniqueid, $preferredbehaviour);

        $i = 0;
        foreach (explode(',', $quizlayout) as $questionid) {
            if ($questionid == 0) {
                continue;
            }
            $i++;

            if (!array_key_exists($questionid, $qas)) {
                $missing[] = $questionid;
                $layout[$questionkeys[$questionid]] = $questionid;
                continue;
            }

            $qa = $qas[$questionid];
            $qa->questionusageid = $attempt->uniqueid;
            $qa->slot = $i;
            if (textlib::strlen($qa->questionsummary) > question_bank::MAX_SUMMARY_LENGTH) {
                // It seems some people write very long quesions! MDL-30760
                $qa->questionsummary = textlib::substr($qa->questionsummary,
                        0, question_bank::MAX_SUMMARY_LENGTH - 3) . '...';
            }
            $this->insert_record('question_attempts', $qa);
            $layout[$questionkeys[$questionid]] = $qa->slot;

            foreach ($qa->steps as $step) {
                $step->questionattemptid = $qa->id;
                $this->insert_record('question_attempt_steps', $step);

                foreach ($step->data as $name => $value) {
                    $datum = new stdClass();
                    $datum->attemptstepid = $step->id;
                    $datum->name = $name;
                    $datum->value = $value;
                    $this->insert_record('question_attempt_step_data', $datum, false);
                }
            }
        }

        $this->set_quiz_attempt_layout($attempt->uniqueid, implode(',', $layout));

        if ($missing) {
            notify("Question sessions for questions " .
                    implode(', ', $missing) .
                    " were missing when upgrading question usage {$attempt->uniqueid}.");
        }
    }
예제 #13
0
 /**
  * Returns all files and optionally directories
  *
  * @param int $contextid context ID
  * @param string $component component
  * @param string $filearea file area
  * @param int $itemid item ID
  * @param int $filepath directory path
  * @param bool $recursive include all subdirectories
  * @param bool $includedirs include files and directories
  * @param string $sort A fragment of SQL to use for sorting
  * @return array of stored_files indexed by pathanmehash
  */
 public function get_directory_files($contextid, $component, $filearea, $itemid, $filepath, $recursive = false, $includedirs = true, $sort = "filepath, filename")
 {
     global $DB;
     if (!($directory = $this->get_file($contextid, $component, $filearea, $itemid, $filepath, '.'))) {
         return array();
     }
     $orderby = !empty($sort) ? " ORDER BY {$sort}" : '';
     if ($recursive) {
         $dirs = $includedirs ? "" : "AND filename <> '.'";
         $length = textlib::strlen($filepath);
         $sql = "SELECT " . self::instance_sql_fields('f', 'r') . "\n                      FROM {files} f\n                 LEFT JOIN {files_reference} r\n                           ON f.referencefileid = r.id\n                     WHERE f.contextid = :contextid AND f.component = :component AND f.filearea = :filearea AND f.itemid = :itemid\n                           AND " . $DB->sql_substr("f.filepath", 1, $length) . " = :filepath\n                           AND f.id <> :dirid\n                           {$dirs}\n                           {$orderby}";
         $params = array('contextid' => $contextid, 'component' => $component, 'filearea' => $filearea, 'itemid' => $itemid, 'filepath' => $filepath, 'dirid' => $directory->get_id());
         $files = array();
         $dirs = array();
         $filerecords = $DB->get_records_sql($sql, $params);
         foreach ($filerecords as $filerecord) {
             if ($filerecord->filename == '.') {
                 $dirs[$filerecord->pathnamehash] = $this->get_file_instance($filerecord);
             } else {
                 $files[$filerecord->pathnamehash] = $this->get_file_instance($filerecord);
             }
         }
         $result = array_merge($dirs, $files);
     } else {
         $result = array();
         $params = array('contextid' => $contextid, 'component' => $component, 'filearea' => $filearea, 'itemid' => $itemid, 'filepath' => $filepath, 'dirid' => $directory->get_id());
         $length = textlib::strlen($filepath);
         if ($includedirs) {
             $sql = "SELECT " . self::instance_sql_fields('f', 'r') . "\n                          FROM {files} f\n                     LEFT JOIN {files_reference} r\n                               ON f.referencefileid = r.id\n                         WHERE f.contextid = :contextid AND f.component = :component AND f.filearea = :filearea\n                               AND f.itemid = :itemid AND f.filename = '.'\n                               AND " . $DB->sql_substr("f.filepath", 1, $length) . " = :filepath\n                               AND f.id <> :dirid\n                               {$orderby}";
             $reqlevel = substr_count($filepath, '/') + 1;
             $filerecords = $DB->get_records_sql($sql, $params);
             foreach ($filerecords as $filerecord) {
                 if (substr_count($filerecord->filepath, '/') !== $reqlevel) {
                     continue;
                 }
                 $result[$filerecord->pathnamehash] = $this->get_file_instance($filerecord);
             }
         }
         $sql = "SELECT " . self::instance_sql_fields('f', 'r') . "\n                      FROM {files} f\n                 LEFT JOIN {files_reference} r\n                           ON f.referencefileid = r.id\n                     WHERE f.contextid = :contextid AND f.component = :component AND f.filearea = :filearea AND f.itemid = :itemid\n                           AND f.filepath = :filepath AND f.filename <> '.'\n                           {$orderby}";
         $filerecords = $DB->get_records_sql($sql, $params);
         foreach ($filerecords as $filerecord) {
             $result[$filerecord->pathnamehash] = $this->get_file_instance($filerecord);
         }
     }
     return $result;
 }
예제 #14
0
파일: weblib.php 프로젝트: numbas/moodle
/**
 * Returns a popup menu with course activity modules
 *
 * Given a course
 * This function returns a small popup menu with all the
 * course activity modules in it, as a navigation menu
 * outputs a simple list structure in XHTML
 * The data is taken from the serialised array stored in
 * the course record
 *
 * @todo Finish documenting this function
 *
 * @global object
 * @uses CONTEXT_COURSE
 * @param course $course A {@link $COURSE} object.
 * @param string $sections
 * @param string $modinfo
 * @param string $strsection
 * @param string $strjumpto
 * @param int $width
 * @param string $cmid
 * @return string The HTML block
 */
function navmenulist($course, $sections, $modinfo, $strsection, $strjumpto, $width=50, $cmid=0) {

    global $CFG, $OUTPUT;

    $section = -1;
    $url = '';
    $menu = array();
    $doneheading = false;

    $coursecontext = get_context_instance(CONTEXT_COURSE, $course->id);

    $menu[] = '<ul class="navmenulist"><li class="jumpto section"><span>'.$strjumpto.'</span><ul>';
    foreach ($modinfo->cms as $mod) {
        if (!$mod->has_view()) {
            // Don't show modules which you can't link to!
            continue;
        }

        if ($mod->sectionnum > $course->numsections) {   /// Don't show excess hidden sections
            break;
        }

        if (!$mod->uservisible) { // do not icnlude empty sections at all
            continue;
        }

        if ($mod->sectionnum >= 0 and $section != $mod->sectionnum) {
            $thissection = $sections[$mod->sectionnum];

            if ($thissection->visible or !$course->hiddensections or
                      has_capability('moodle/course:viewhiddensections', $coursecontext)) {
                $thissection->summary = strip_tags(format_string($thissection->summary,true));
                if (!$doneheading) {
                    $menu[] = '</ul></li>';
                }
                if ($course->format == 'weeks' or empty($thissection->summary)) {
                    $item = $strsection ." ". $mod->sectionnum;
                } else {
                    if (textlib::strlen($thissection->summary) < ($width-3)) {
                        $item = $thissection->summary;
                    } else {
                        $item = textlib::substr($thissection->summary, 0, $width).'...';
                    }
                }
                $menu[] = '<li class="section"><span>'.$item.'</span>';
                $menu[] = '<ul>';
                $doneheading = true;

                $section = $mod->sectionnum;
            } else {
                // no activities from this hidden section shown
                continue;
            }
        }

        $url = $mod->modname .'/view.php?id='. $mod->id;
        $mod->name = strip_tags(format_string($mod->name ,true));
        if (textlib::strlen($mod->name) > ($width+5)) {
            $mod->name = textlib::substr($mod->name, 0, $width).'...';
        }
        if (!$mod->visible) {
            $mod->name = '('.$mod->name.')';
        }
        $class = 'activity '.$mod->modname;
        $class .= ($cmid == $mod->id) ? ' selected' : '';
        $menu[] = '<li class="'.$class.'">'.
                  '<img src="'.$OUTPUT->pix_url('icon', $mod->modname) . '" alt="" />'.
                  '<a href="'.$CFG->wwwroot.'/mod/'.$url.'">'.$mod->name.'</a></li>';
    }

    if ($doneheading) {
        $menu[] = '</ul></li>';
    }
    $menu[] = '</ul></li></ul>';

    return implode("\n", $menu);
}
예제 #15
0
/**
 * Given some text (which may contain HTML) and an ideal length,
 * this function truncates the text neatly on a word boundary if possible
 *
 * @category string
 * @global stdClass $CFG
 * @param string $text text to be shortened
 * @param int $ideal ideal string length
 * @param boolean $exact if false, $text will not be cut mid-word
 * @param string $ending The string to append if the passed string is truncated
 * @return string $truncate shortened string
 */
function shorten_text($text, $ideal = 30, $exact = false, $ending = '...')
{
    global $CFG;
    // If the plain text is shorter than the maximum length, return the whole text.
    if (textlib::strlen(preg_replace('/<.*?>/', '', $text)) <= $ideal) {
        return $text;
    }
    // Splits on HTML tags. Each open/close/empty tag will be the first thing
    // and only tag in its 'line'.
    preg_match_all('/(<.+?>)?([^<>]*)/s', $text, $lines, PREG_SET_ORDER);
    $total_length = textlib::strlen($ending);
    $truncate = '';
    // This array stores information about open and close tags and their position
    // in the truncated string. Each item in the array is an object with fields
    // ->open (true if open), ->tag (tag name in lower case), and ->pos
    // (byte position in truncated text).
    $tagdetails = array();
    foreach ($lines as $line_matchings) {
        // If there is any html-tag in this line, handle it and add it (uncounted) to the output.
        if (!empty($line_matchings[1])) {
            // If it's an "empty element" with or without xhtml-conform closing slash (f.e. <br/>).
            if (preg_match('/^<(\\s*.+?\\/\\s*|\\s*(img|br|input|hr|area|base|basefont|col|frame|isindex|link|meta|param)(\\s.+?)?)>$/is', $line_matchings[1])) {
                // Do nothing.
            } else {
                if (preg_match('/^<\\s*\\/([^\\s]+?)\\s*>$/s', $line_matchings[1], $tag_matchings)) {
                    // Record closing tag.
                    $tagdetails[] = (object) array('open' => false, 'tag' => textlib::strtolower($tag_matchings[1]), 'pos' => textlib::strlen($truncate));
                } else {
                    if (preg_match('/^<\\s*([^\\s>!]+).*?>$/s', $line_matchings[1], $tag_matchings)) {
                        // Record opening tag.
                        $tagdetails[] = (object) array('open' => true, 'tag' => textlib::strtolower($tag_matchings[1]), 'pos' => textlib::strlen($truncate));
                    }
                }
            }
            // Add html-tag to $truncate'd text.
            $truncate .= $line_matchings[1];
        }
        // Calculate the length of the plain text part of the line; handle entities as one character.
        $content_length = textlib::strlen(preg_replace('/&[0-9a-z]{2,8};|&#[0-9]{1,7};|&#x[0-9a-f]{1,6};/i', ' ', $line_matchings[2]));
        if ($total_length + $content_length > $ideal) {
            // The number of characters which are left.
            $left = $ideal - $total_length;
            $entities_length = 0;
            // Search for html entities.
            if (preg_match_all('/&[0-9a-z]{2,8};|&#[0-9]{1,7};|&#x[0-9a-f]{1,6};/i', $line_matchings[2], $entities, PREG_OFFSET_CAPTURE)) {
                // calculate the real length of all entities in the legal range
                foreach ($entities[0] as $entity) {
                    if ($entity[1] + 1 - $entities_length <= $left) {
                        $left--;
                        $entities_length += textlib::strlen($entity[0]);
                    } else {
                        // no more characters left
                        break;
                    }
                }
            }
            $breakpos = $left + $entities_length;
            // if the words shouldn't be cut in the middle...
            if (!$exact) {
                // ...search the last occurence of a space...
                for (; $breakpos > 0; $breakpos--) {
                    if ($char = textlib::substr($line_matchings[2], $breakpos, 1)) {
                        if ($char === '.' or $char === ' ') {
                            $breakpos += 1;
                            break;
                        } else {
                            if (strlen($char) > 2) {
                                // Chinese/Japanese/Korean text
                                $breakpos += 1;
                                // can be truncated at any UTF-8
                                break;
                                // character boundary.
                            }
                        }
                    }
                }
            }
            if ($breakpos == 0) {
                // This deals with the test_shorten_text_no_spaces case.
                $breakpos = $left + $entities_length;
            } else {
                if ($breakpos > $left + $entities_length) {
                    // This deals with the previous for loop breaking on the first char.
                    $breakpos = $left + $entities_length;
                }
            }
            $truncate .= textlib::substr($line_matchings[2], 0, $breakpos);
            // maximum length is reached, so get off the loop
            break;
        } else {
            $truncate .= $line_matchings[2];
            $total_length += $content_length;
        }
        // If the maximum length is reached, get off the loop.
        if ($total_length >= $ideal) {
            break;
        }
    }
    // Add the defined ending to the text.
    $truncate .= $ending;
    // Now calculate the list of open html tags based on the truncate position.
    $open_tags = array();
    foreach ($tagdetails as $taginfo) {
        if ($taginfo->open) {
            // Add tag to the beginning of $open_tags list.
            array_unshift($open_tags, $taginfo->tag);
        } else {
            // Can have multiple exact same open tags, close the last one.
            $pos = array_search($taginfo->tag, array_reverse($open_tags, true));
            if ($pos !== false) {
                unset($open_tags[$pos]);
            }
        }
    }
    // Close all unclosed html-tags.
    foreach ($open_tags as $tag) {
        $truncate .= '</' . $tag . '>';
    }
    return $truncate;
}
예제 #16
0
파일: lib.php 프로젝트: neogic/moodle
/**
 * Print a select box allowing the user to choose to view new messages, course participants etc.
 *
 * Called by message_print_contact_selector()
 * @param int $viewing What page is the user viewing ie MESSAGE_VIEW_UNREAD_MESSAGES, MESSAGE_VIEW_RECENT_CONVERSATIONS etc
 * @param array $courses array of course objects. The courses the user is enrolled in.
 * @param array $coursecontexts array of course contexts. Keyed on course id.
 * @param int $countunreadtotal how many unread messages does the user have?
 * @param int $countblocked how many users has the current user blocked?
 * @param string $strunreadmessages a preconstructed message about the number of unread messages the user has
 * @return void
 */
function message_print_usergroup_selector($viewing, $courses, $coursecontexts, $countunreadtotal, $countblocked, $strunreadmessages) {
    $options = array();

    if ($countunreadtotal>0) { //if there are unread messages
        $options[MESSAGE_VIEW_UNREAD_MESSAGES] = $strunreadmessages;
    }

    $str = get_string('mycontacts', 'message');
    $options[MESSAGE_VIEW_CONTACTS] = $str;

    $options[MESSAGE_VIEW_RECENT_CONVERSATIONS] = get_string('mostrecentconversations', 'message');
    $options[MESSAGE_VIEW_RECENT_NOTIFICATIONS] = get_string('mostrecentnotifications', 'message');

    if (!empty($courses)) {
        $courses_options = array();

        foreach($courses as $course) {
            if (has_capability('moodle/course:viewparticipants', $coursecontexts[$course->id])) {
                //Not using short_text() as we want the end of the course name. Not the beginning.
                $shortname = format_string($course->shortname, true, array('context' => $coursecontexts[$course->id]));
                if (textlib::strlen($shortname) > MESSAGE_MAX_COURSE_NAME_LENGTH) {
                    $courses_options[MESSAGE_VIEW_COURSE.$course->id] = '...'.textlib::substr($shortname, -MESSAGE_MAX_COURSE_NAME_LENGTH);
                } else {
                    $courses_options[MESSAGE_VIEW_COURSE.$course->id] = $shortname;
                }
            }
        }

        if (!empty($courses_options)) {
            $options[] = array(get_string('courses') => $courses_options);
        }
    }

    if ($countblocked>0) {
        $str = get_string('blockedusers','message', $countblocked);
        $options[MESSAGE_VIEW_BLOCKED] = $str;
    }

    echo html_writer::start_tag('form', array('id' => 'usergroupform','method' => 'get','action' => ''));
    echo html_writer::start_tag('fieldset');
    echo html_writer::label(get_string('messagenavigation', 'message'), 'viewing');
    echo html_writer::select($options, 'viewing', $viewing, false, array('id' => 'viewing','onchange' => 'this.form.submit()'));
    echo html_writer::end_tag('fieldset');
    echo html_writer::end_tag('form');
}
예제 #17
0
파일: locallib.php 프로젝트: verbazend/AWFA
/**
 * This function trims any given text and returns it with some dots at the end
 *
 * @param string $text
 * @param string $limit
 *
 * @return string
 */
function wiki_trim_string($text, $limit = 25) {

    if (textlib::strlen($text) > $limit) {
        $text = textlib::substr($text, 0, $limit) . '...';
    }

    return $text;
}
예제 #18
0
파일: sql.php 프로젝트: Jtgadbois/Pedadida
        case 'term':
            $params['hook2'] = $hook;
            $printpivot = 0;
            $sqlfrom .= " LEFT JOIN {glossary_alias} ga on ge.id = ga.entryid";
            $where = "AND (ge.concept = :hook OR ga.alias = :hook2) ";
        break;

        case 'entry':
            $printpivot = 0;
            $where = "AND ge.id = :hook";
        break;

        case 'letter':
            if ($hook != 'ALL' and $hook != 'SPECIAL') {
                $params['hookup'] = textlib::strtoupper($hook);
                $where = "AND " . $DB->sql_substr("upper(concept)", 1, textlib::strlen($hook)) . " = :hookup";
            }
            if ($hook == 'SPECIAL') {
                //Create appropiate IN contents
                $alphabet = explode(",", get_string('alphabet', 'langconfig'));
                list($nia, $aparams) = $DB->get_in_or_equal($alphabet, SQL_PARAMS_NAMED, $start='a', false);
                $params = array_merge($params, $aparams);
                $where = "AND " . $DB->sql_substr("upper(concept)", 1, 1) . " $nia";
            }
        break;
        }

        $sqlwhere   = "WHERE (ge.glossaryid = :gid1 or ge.sourceglossaryid = :gid2) AND
                             (ge.approved <> 0 $userid)
                              $where";
        switch ( $tab ) {
예제 #19
0
파일: lib.php 프로젝트: ncsu-delta/moodle
    /**
     * Migrates one given file stored on disk
     *
     * @param string $sourcepath the path to the source local file within the backup archive {@example 'moddata/foobar/file.ext'}
     * @param string $filepath the file path of the migrated file, defaults to the root directory '/' {@example '/sub/dir/'}
     * @param string $filename the name of the migrated file, defaults to the same as the source file has
     * @param int $sortorder the sortorder of the file (main files have sortorder set to 1)
     * @param int $timecreated override the timestamp of when the migrated file should appear as created
     * @param int $timemodified override the timestamp of when the migrated file should appear as modified
     * @return int id of the migrated file
     */
    public function migrate_file($sourcepath, $filepath = '/', $filename = null, $sortorder = 0, $timecreated = null, $timemodified = null) {

        // Normalise Windows paths a bit.
        $sourcepath = str_replace('\\', '/', $sourcepath);

        // PARAM_PATH must not be used on full OS path!
        if ($sourcepath !== clean_param($sourcepath, PARAM_PATH)) {
            throw new moodle1_convert_exception('file_invalid_path', $sourcepath);
        }

        $sourcefullpath = $this->basepath.'/'.$sourcepath;

        if (!is_readable($sourcefullpath)) {
            throw new moodle1_convert_exception('file_not_readable', $sourcefullpath);
        }

        // sanitize filepath
        if (empty($filepath)) {
            $filepath = '/';
        }
        if (substr($filepath, -1) !== '/') {
            $filepath .= '/';
        }
        $filepath = clean_param($filepath, PARAM_PATH);

        if (textlib::strlen($filepath) > 255) {
            throw new moodle1_convert_exception('file_path_longer_than_255_chars');
        }

        if (is_null($filename)) {
            $filename = basename($sourcefullpath);
        }

        $filename = clean_param($filename, PARAM_FILE);

        if ($filename === '') {
            throw new moodle1_convert_exception('unsupported_chars_in_filename');
        }

        if (is_null($timecreated)) {
            $timecreated = filectime($sourcefullpath);
        }

        if (is_null($timemodified)) {
            $timemodified = filemtime($sourcefullpath);
        }

        $filerecord = $this->make_file_record(array(
            'filepath'      => $filepath,
            'filename'      => $filename,
            'sortorder'     => $sortorder,
            'mimetype'      => mimeinfo('type', $sourcefullpath),
            'timecreated'   => $timecreated,
            'timemodified'  => $timemodified,
        ));

        list($filerecord['contenthash'], $filerecord['filesize'], $newfile) = $this->add_file_to_pool($sourcefullpath);
        $this->stash_file($filerecord);

        return $filerecord['id'];
    }
예제 #20
0
/**
 * This function is used to generate and display selector form
 *
 * @global stdClass $USER
 * @global stdClass $CFG
 * @global moodle_database $DB
 * @global core_renderer $OUTPUT
 * @global stdClass $SESSION
 * @uses CONTEXT_SYSTEM
 * @uses COURSE_MAX_COURSES_PER_DROPDOWN
 * @uses CONTEXT_COURSE
 * @uses SEPARATEGROUPS
 * @param  stdClass $course course instance
 * @param  int      $selecteduser id of the selected user
 * @param  string   $selecteddate Date selected
 * @param  string   $modname course_module->id
 * @param  string   $modid number or 'site_errors'
 * @param  string   $modaction an action as recorded in the logs
 * @param  int      $selectedgroup Group to display
 * @param  int      $showcourses whether to show courses if we're over our limit.
 * @param  int      $showusers whether to show users if we're over our limit.
 * @param  string   $logformat Format of the logs (downloadascsv, showashtml, downloadasods, downloadasexcel)
 * @return void
 */
function report_log_print_selector_form($course, $selecteduser = 0, $selecteddate = 'today', $modname = "", $modid = 0, $modaction = '', $selectedgroup = -1, $showcourses = 0, $showusers = 0, $logformat = 'showashtml')
{
    global $USER, $CFG, $DB, $OUTPUT, $SESSION;
    // first check to see if we can override showcourses and showusers
    $numcourses = $DB->count_records("course");
    if ($numcourses < COURSE_MAX_COURSES_PER_DROPDOWN && !$showcourses) {
        $showcourses = 1;
    }
    $sitecontext = get_context_instance(CONTEXT_SYSTEM);
    $context = get_context_instance(CONTEXT_COURSE, $course->id);
    /// Setup for group handling.
    if ($course->groupmode == SEPARATEGROUPS and !has_capability('moodle/site:accessallgroups', $context)) {
        $selectedgroup = -1;
        $showgroups = false;
    } else {
        if ($course->groupmode) {
            $showgroups = true;
        } else {
            $selectedgroup = 0;
            $showgroups = false;
        }
    }
    if ($selectedgroup === -1) {
        if (isset($SESSION->currentgroup[$course->id])) {
            $selectedgroup = $SESSION->currentgroup[$course->id];
        } else {
            $selectedgroup = groups_get_all_groups($course->id, $USER->id);
            if (is_array($selectedgroup)) {
                $selectedgroup = array_shift(array_keys($selectedgroup));
                $SESSION->currentgroup[$course->id] = $selectedgroup;
            } else {
                $selectedgroup = 0;
            }
        }
    }
    // Get all the possible users
    $users = array();
    // Define limitfrom and limitnum for queries below
    // If $showusers is enabled... don't apply limitfrom and limitnum
    $limitfrom = empty($showusers) ? 0 : '';
    $limitnum = empty($showusers) ? COURSE_MAX_USERS_PER_DROPDOWN + 1 : '';
    $courseusers = get_enrolled_users($context, '', $selectedgroup, 'u.id, u.firstname, u.lastname', 'lastname ASC, firstname ASC', $limitfrom, $limitnum);
    if (count($courseusers) < COURSE_MAX_USERS_PER_DROPDOWN && !$showusers) {
        $showusers = 1;
    }
    if ($showusers) {
        if ($courseusers) {
            foreach ($courseusers as $courseuser) {
                $users[$courseuser->id] = fullname($courseuser, has_capability('moodle/site:viewfullnames', $context));
            }
        }
        $users[$CFG->siteguest] = get_string('guestuser');
    }
    if (has_capability('report/log:view', $sitecontext) && $showcourses) {
        if ($ccc = $DB->get_records("course", null, "fullname", "id,shortname,fullname,category")) {
            foreach ($ccc as $cc) {
                if ($cc->category) {
                    $courses["{$cc->id}"] = format_string(get_course_display_name_for_list($cc));
                } else {
                    $courses["{$cc->id}"] = format_string($cc->fullname) . ' (Site)';
                }
            }
        }
        asort($courses);
    }
    $activities = array();
    $selectedactivity = "";
    /// Casting $course->modinfo to string prevents one notice when the field is null
    if ($modinfo = unserialize((string) $course->modinfo)) {
        $section = 0;
        $sections = get_all_sections($course->id);
        foreach ($modinfo as $mod) {
            if ($mod->mod == "label") {
                continue;
            }
            if ($mod->section > 0 and $section != $mod->section) {
                $activities["section/{$mod->section}"] = '--- ' . get_section_name($course, $sections[$mod->section]) . ' ---';
            }
            $section = $mod->section;
            $mod->name = strip_tags(format_string($mod->name, true));
            if (textlib::strlen($mod->name) > 55) {
                $mod->name = textlib::substr($mod->name, 0, 50) . "...";
            }
            if (!$mod->visible) {
                $mod->name = "(" . $mod->name . ")";
            }
            $activities["{$mod->cm}"] = $mod->name;
            if ($mod->cm == $modid) {
                $selectedactivity = "{$mod->cm}";
            }
        }
    }
    if (has_capability('report/log:view', $sitecontext) && $course->id == SITEID) {
        $activities["site_errors"] = get_string("siteerrors");
        if ($modid === "site_errors") {
            $selectedactivity = "site_errors";
        }
    }
    $strftimedate = get_string("strftimedate");
    $strftimedaydate = get_string("strftimedaydate");
    asort($users);
    // Prepare the list of action options.
    $actions = array('view' => get_string('view'), 'add' => get_string('add'), 'update' => get_string('update'), 'delete' => get_string('delete'), '-view' => get_string('allchanges'));
    // Get all the possible dates
    // Note that we are keeping track of real (GMT) time and user time
    // User time is only used in displays - all calcs and passing is GMT
    $timenow = time();
    // GMT
    // What day is it now for the user, and when is midnight that day (in GMT).
    $timemidnight = $today = usergetmidnight($timenow);
    // Put today up the top of the list
    $dates = array("{$timemidnight}" => get_string("today") . ", " . userdate($timenow, $strftimedate));
    if (!$course->startdate or $course->startdate > $timenow) {
        $course->startdate = $course->timecreated;
    }
    $numdates = 1;
    while ($timemidnight > $course->startdate and $numdates < 365) {
        $timemidnight = $timemidnight - 86400;
        $timenow = $timenow - 86400;
        $dates["{$timemidnight}"] = userdate($timenow, $strftimedaydate);
        $numdates++;
    }
    if ($selecteddate == "today") {
        $selecteddate = $today;
    }
    echo "<form class=\"logselectform\" action=\"{$CFG->wwwroot}/report/log/index.php\" method=\"get\">\n";
    echo "<div>\n";
    echo "<input type=\"hidden\" name=\"chooselog\" value=\"1\" />\n";
    echo "<input type=\"hidden\" name=\"showusers\" value=\"{$showusers}\" />\n";
    echo "<input type=\"hidden\" name=\"showcourses\" value=\"{$showcourses}\" />\n";
    if (has_capability('report/log:view', $sitecontext) && $showcourses) {
        echo html_writer::label(get_string('selectacourse'), 'menuid', false, array('class' => 'accesshide'));
        echo html_writer::select($courses, "id", $course->id, false);
    } else {
        //        echo '<input type="hidden" name="id" value="'.$course->id.'" />';
        $courses = array();
        $courses[$course->id] = get_course_display_name_for_list($course) . ($course->id == SITEID ? ' (' . get_string('site') . ') ' : '');
        echo html_writer::label(get_string('selectacourse'), 'menuid', false, array('class' => 'accesshide'));
        echo html_writer::select($courses, "id", $course->id, false);
        if (has_capability('report/log:view', $sitecontext)) {
            $a = new stdClass();
            $a->url = "{$CFG->wwwroot}/report/log/index.php?chooselog=0&group={$selectedgroup}&user={$selecteduser}" . "&id={$course->id}&date={$selecteddate}&modid={$selectedactivity}&showcourses=1&showusers={$showusers}";
            print_string('logtoomanycourses', 'moodle', $a);
        }
    }
    if ($showgroups) {
        if ($cgroups = groups_get_all_groups($course->id)) {
            foreach ($cgroups as $cgroup) {
                $groups[$cgroup->id] = $cgroup->name;
            }
        } else {
            $groups = array();
        }
        echo html_writer::label(get_string('selectagroup'), 'menugroup', false, array('class' => 'accesshide'));
        echo html_writer::select($groups, "group", $selectedgroup, get_string("allgroups"));
    }
    if ($showusers) {
        echo html_writer::label(get_string('selctauser'), 'menuuser', false, array('class' => 'accesshide'));
        echo html_writer::select($users, "user", $selecteduser, get_string("allparticipants"));
    } else {
        $users = array();
        if (!empty($selecteduser)) {
            $user = $DB->get_record('user', array('id' => $selecteduser));
            $users[$selecteduser] = fullname($user);
        } else {
            $users[0] = get_string('allparticipants');
        }
        echo html_writer::label(get_string('selctauser'), 'menuuser', false, array('class' => 'accesshide'));
        echo html_writer::select($users, "user", $selecteduser, false);
        $a = new stdClass();
        $a->url = "{$CFG->wwwroot}/report/log/index.php?chooselog=0&group={$selectedgroup}&user={$selecteduser}" . "&id={$course->id}&date={$selecteddate}&modid={$selectedactivity}&showusers=1&showcourses={$showcourses}";
        print_string('logtoomanyusers', 'moodle', $a);
    }
    echo html_writer::label(get_string('date'), 'menudate', false, array('class' => 'accesshide'));
    echo html_writer::select($dates, "date", $selecteddate, get_string("alldays"));
    echo html_writer::label(get_string('activities'), 'menumodid', false, array('class' => 'accesshide'));
    echo html_writer::select($activities, "modid", $selectedactivity, get_string("allactivities"));
    echo html_writer::label(get_string('actions'), 'menumodaction', false, array('class' => 'accesshide'));
    echo html_writer::select($actions, 'modaction', $modaction, get_string("allactions"));
    $logformats = array('showashtml' => get_string('displayonpage'), 'downloadascsv' => get_string('downloadtext'), 'downloadasods' => get_string('downloadods'), 'downloadasexcel' => get_string('downloadexcel'));
    echo html_writer::label(get_string('logsformat', 'report_log'), 'menulogformat', false, array('class' => 'accesshide'));
    echo html_writer::select($logformats, 'logformat', $logformat, false);
    echo '<input type="submit" value="' . get_string('gettheselogs') . '" />';
    echo '</div>';
    echo '</form>';
}
예제 #21
0
/**
 * Given a record in the {blog_external} table, checks the blog's URL
 * for new entries not yet copied into Moodle.
 * Also attempts to identify and remove deleted blog entries
 *
 * @param object $externalblog
 * @return boolean False if the Feed is invalid
 */
function blog_sync_external_entries($externalblog)
{
    global $CFG, $DB;
    require_once $CFG->libdir . '/simplepie/moodle_simplepie.php';
    $rssfile = new moodle_simplepie_file($externalblog->url);
    $filetest = new SimplePie_Locator($rssfile);
    if (!$filetest->is_feed($rssfile)) {
        $externalblog->failedlastsync = 1;
        $DB->update_record('blog_external', $externalblog);
        return false;
    } else {
        if (!empty($externalblog->failedlastsync)) {
            $externalblog->failedlastsync = 0;
            $DB->update_record('blog_external', $externalblog);
        }
    }
    $rss = new moodle_simplepie($externalblog->url);
    if (empty($rss->data)) {
        return null;
    }
    //used to identify blog posts that have been deleted from the source feed
    $oldesttimestamp = null;
    $uniquehashes = array();
    foreach ($rss->get_items() as $entry) {
        // If filtertags are defined, use them to filter the entries by RSS category
        if (!empty($externalblog->filtertags)) {
            $containsfiltertag = false;
            $categories = $entry->get_categories();
            $filtertags = explode(',', $externalblog->filtertags);
            $filtertags = array_map('trim', $filtertags);
            $filtertags = array_map('strtolower', $filtertags);
            foreach ($categories as $category) {
                if (in_array(trim(strtolower($category->term)), $filtertags)) {
                    $containsfiltertag = true;
                }
            }
            if (!$containsfiltertag) {
                continue;
            }
        }
        $uniquehashes[] = $entry->get_permalink();
        $newentry = new stdClass();
        $newentry->userid = $externalblog->userid;
        $newentry->module = 'blog_external';
        $newentry->content = $externalblog->id;
        $newentry->uniquehash = $entry->get_permalink();
        $newentry->publishstate = 'site';
        $newentry->format = FORMAT_HTML;
        // Clean subject of html, just in case
        $newentry->subject = clean_param($entry->get_title(), PARAM_TEXT);
        // Observe 128 max chars in DB
        // TODO: +1 to raise this to 255
        if (textlib::strlen($newentry->subject) > 128) {
            $newentry->subject = textlib::substr($newentry->subject, 0, 125) . '...';
        }
        $newentry->summary = $entry->get_description();
        //used to decide whether to insert or update
        //uses enty permalink plus creation date if available
        $existingpostconditions = array('uniquehash' => $entry->get_permalink());
        //our DB doesnt allow null creation or modified timestamps so check the external blog supplied one
        $entrydate = $entry->get_date('U');
        if (!empty($entrydate)) {
            $existingpostconditions['created'] = $entrydate;
        }
        //the post ID or false if post not found in DB
        $postid = $DB->get_field('post', 'id', $existingpostconditions);
        $timestamp = null;
        if (empty($entrydate)) {
            $timestamp = time();
        } else {
            $timestamp = $entrydate;
        }
        //only set created if its a new post so we retain the original creation timestamp if the post is edited
        if ($postid === false) {
            $newentry->created = $timestamp;
        }
        $newentry->lastmodified = $timestamp;
        if (empty($oldesttimestamp) || $timestamp < $oldesttimestamp) {
            //found an older post
            $oldesttimestamp = $timestamp;
        }
        if (textlib::strlen($newentry->uniquehash) > 255) {
            // The URL for this item is too long for the field. Rather than add
            // the entry without the link we will skip straight over it.
            // RSS spec says recommended length 500, we use 255.
            debugging('External blog entry skipped because of oversized URL', DEBUG_DEVELOPER);
            continue;
        }
        if ($postid === false) {
            $id = $DB->insert_record('post', $newentry);
            // Set tags
            if ($tags = tag_get_tags_array('blog_external', $externalblog->id)) {
                tag_set('post', $id, $tags);
            }
        } else {
            $newentry->id = $postid;
            $DB->update_record('post', $newentry);
        }
    }
    // Look at the posts we have in the database to check if any of them have been deleted from the feed.
    // Only checking posts within the time frame returned by the rss feed. Older items may have been deleted or
    // may just not be returned anymore. We can't tell the difference so we leave older posts alone.
    $sql = "SELECT id, uniquehash\n              FROM {post}\n             WHERE module = 'blog_external'\n                   AND " . $DB->sql_compare_text('content') . " = " . $DB->sql_compare_text(':blogid') . "\n                   AND created > :ts";
    $dbposts = $DB->get_records_sql($sql, array('blogid' => $externalblog->id, 'ts' => $oldesttimestamp));
    $todelete = array();
    foreach ($dbposts as $dbpost) {
        if (!in_array($dbpost->uniquehash, $uniquehashes)) {
            $todelete[] = $dbpost->id;
        }
    }
    $DB->delete_records_list('post', 'id', $todelete);
    $DB->update_record('blog_external', array('id' => $externalblog->id, 'timefetched' => time()));
}
예제 #22
0
/**
 * Trim inputted text to the given maximum length.
 * @param string $text
 * @param int $length
 * @return string The trimmed string with a '...' appended for display.
 */
function lightboxgallery_resize_text($text, $length)
{
    $textlib = new textlib();
    return $textlib->strlen($text) > $length ? $textlib->substr($text, 0, $length) . '...' : $text;
}
예제 #23
0
    public function subquestion(question_attempt $qa, question_display_options $options,
            $index, question_graded_automatically $subq) {

        $fieldprefix = 'sub' . $index . '_';
        $fieldname = $fieldprefix . 'answer';

        $response = $qa->get_last_qt_var($fieldname);
        if ($subq->qtype->name() == 'shortanswer') {
            $matchinganswer = $subq->get_matching_answer(array('answer' => $response));
        } else if ($subq->qtype->name() == 'numerical') {
            list($value, $unit, $multiplier) = $subq->ap->apply_units($response, '');
            $matchinganswer = $subq->get_matching_answer($value, 1);
        } else {
            $matchinganswer = $subq->get_matching_answer($response);
        }

        if (!$matchinganswer) {
            if (is_null($response) || $response === '') {
                $matchinganswer = new question_answer(0, '', null, '', FORMAT_HTML);
            } else {
                $matchinganswer = new question_answer(0, '', 0.0, '', FORMAT_HTML);
            }
        }

        // Work out a good input field size.
        $size = max(1, textlib::strlen(trim($response)) + 1);
        foreach ($subq->answers as $ans) {
            $size = max($size, textlib::strlen(trim($ans->answer)));
        }
        $size = min(60, round($size + rand(0, $size*0.15)));
        // The rand bit is to make guessing harder.

        $inputattributes = array(
            'type' => 'text',
            'name' => $qa->get_qt_field_name($fieldname),
            'value' => $response,
            'id' => $qa->get_qt_field_name($fieldname),
            'size' => $size,
        );
        if ($options->readonly) {
            $inputattributes['readonly'] = 'readonly';
        }

        $feedbackimg = '';
        if ($options->correctness) {
            $inputattributes['class'] = $this->feedback_class($matchinganswer->fraction);
            $feedbackimg = $this->feedback_image($matchinganswer->fraction);
        }

        if ($subq->qtype->name() == 'shortanswer') {
            $correctanswer = $subq->get_matching_answer($subq->get_correct_response());
        } else {
            $correctanswer = $subq->get_correct_answer();
        }

        $feedbackpopup = $this->feedback_popup($subq, $matchinganswer->fraction,
                $subq->format_text($matchinganswer->feedback, $matchinganswer->feedbackformat,
                        $qa, 'question', 'answerfeedback', $matchinganswer->id),
                s($correctanswer->answer), $options);

        $output = html_writer::start_tag('span', array('class' => 'subquestion'));
        $output .= html_writer::tag('label', get_string('answer'),
                array('class' => 'subq accesshide', 'for' => $inputattributes['id']));
        $output .= html_writer::empty_tag('input', $inputattributes);
        $output .= $feedbackimg;
        $output .= $feedbackpopup;
        $output .= html_writer::end_tag('span');

        return $output;
    }
예제 #24
0
 /**
  * Tests the static string length method
  * @return void
  */
 public function test_strlen()
 {
     $str = "Žluťoučký koníček";
     $this->assertSame(textlib::strlen($str), 17);
     $iso2 = pack("H*", "ae6c75bb6f75e86bfd206b6f6eede8656b");
     $this->assertSame(textlib::strlen($iso2, 'iso-8859-2'), 17);
     $win = pack("H*", "8e6c759d6f75e86bfd206b6f6eede8656b");
     $this->assertSame(textlib::strlen($win, 'cp1250'), 17);
     $str = pack("H*", "b8ec");
     //EUC-JP
     $this->assertSame(textlib::strlen($str, 'EUC-JP'), 1);
     $str = pack("H*", "b8c0b8ecc0dfc4ea");
     //EUC-JP
     $this->assertSame(textlib::strlen($str, 'EUC-JP'), 4);
     $str = pack("H*", "1b2442386c1b2842");
     //ISO-2022-JP
     $this->assertSame(textlib::strlen($str, 'ISO-2022-JP'), 1);
     $str = pack("H*", "1b24423840386c405f446a1b2842");
     //ISO-2022-JP
     $this->assertSame(textlib::strlen($str, 'ISO-2022-JP'), 4);
     $str = pack("H*", "8cea");
     //SHIFT-JIS
     $this->assertSame(textlib::strlen($str, 'SHIFT-JIS'), 1);
     $str = pack("H*", "8cbe8cea90dd92e8");
     //SHIFT-JIS
     $this->assertSame(textlib::strlen($str, 'SHIFT-JIS'), 4);
     $str = pack("H*", "cce5");
     //GB2312
     $this->assertSame(textlib::strlen($str, 'GB2312'), 1);
     $str = pack("H*", "bcf2cce5d6d0cec4");
     //GB2312
     $this->assertSame(textlib::strlen($str, 'GB2312'), 4);
     $str = pack("H*", "cce5");
     //GB18030
     $this->assertSame(textlib::strlen($str, 'GB18030'), 1);
     $str = pack("H*", "bcf2cce5d6d0cec4");
     //GB18030
     $this->assertSame(textlib::strlen($str, 'GB18030'), 4);
 }
예제 #25
0
/**
 * Prints an individual user box
 *
 * @param user_object  $user  (contains the following fields: id, firstname, lastname and picture)
 * @param bool         $return if true return html string
 * @return string|null a HTML string or null if this function does the output
 */
function tag_print_user_box($user, $return = false)
{
    global $CFG, $OUTPUT;
    $usercontext = get_context_instance(CONTEXT_USER, $user->id);
    $profilelink = '';
    if ($usercontext and has_capability('moodle/user:viewdetails', $usercontext) || has_coursecontact_role($user->id)) {
        $profilelink = $CFG->wwwroot . '/user/view.php?id=' . $user->id;
    }
    $output = $OUTPUT->box_start('user-box', 'user' . $user->id);
    $fullname = fullname($user);
    $alt = '';
    if (!empty($profilelink)) {
        $output .= '<a href="' . $profilelink . '">';
        $alt = $fullname;
    }
    $output .= $OUTPUT->user_picture($user, array('size' => 100));
    $output .= '<br />';
    if (!empty($profilelink)) {
        $output .= '</a>';
    }
    //truncate name if it's too big
    if (textlib::strlen($fullname) > 26) {
        $fullname = textlib::substr($fullname, 0, 26) . '...';
    }
    $output .= '<strong>' . $fullname . '</strong>';
    $output .= $OUTPUT->box_end();
    if ($return) {
        return $output;
    } else {
        echo $output;
    }
}
예제 #26
0
파일: moodlelib.php 프로젝트: nmicha/moodle
/**
 * If new messages are waiting for the current user, then insert
 * JavaScript to pop up the messaging window into the page
 *
 * @global moodle_page $PAGE
 * @return void
 */
function message_popup_window()
{
    global $USER, $DB, $PAGE, $CFG, $SITE;
    if (!$PAGE->get_popup_notification_allowed() || empty($CFG->messaging)) {
        return;
    }
    if (!isloggedin() || isguestuser()) {
        return;
    }
    if (!isset($USER->message_lastpopup)) {
        $USER->message_lastpopup = 0;
    } else {
        if ($USER->message_lastpopup > time() - 120) {
            //dont run the query to check whether to display a popup if its been run in the last 2 minutes
            return;
        }
    }
    //a quick query to check whether the user has new messages
    $messagecount = $DB->count_records('message', array('useridto' => $USER->id));
    if ($messagecount < 1) {
        return;
    }
    //got unread messages so now do another query that joins with the user table
    $messagesql = "SELECT m.id, m.smallmessage, m.fullmessageformat, m.notification, u.firstname, u.lastname\n                     FROM {message} m\n                     JOIN {message_working} mw ON m.id=mw.unreadmessageid\n                     JOIN {message_processors} p ON mw.processorid=p.id\n                     JOIN {user} u ON m.useridfrom=u.id\n                    WHERE m.useridto = :userid\n                      AND p.name='popup'";
    //if the user was last notified over an hour ago we can renotify them of old messages
    //so don't worry about when the new message was sent
    $lastnotifiedlongago = $USER->message_lastpopup < time() - 3600;
    if (!$lastnotifiedlongago) {
        $messagesql .= 'AND m.timecreated > :lastpopuptime';
    }
    $message_users = $DB->get_records_sql($messagesql, array('userid' => $USER->id, 'lastpopuptime' => $USER->message_lastpopup));
    //if we have new messages to notify the user about
    if (!empty($message_users)) {
        $strmessages = '';
        if (count($message_users) > 1) {
            $strmessages = get_string('unreadnewmessages', 'message', count($message_users));
        } else {
            $message_users = reset($message_users);
            //show who the message is from if its not a notification
            if (!$message_users->notification) {
                $strmessages = get_string('unreadnewmessage', 'message', fullname($message_users));
            }
            //try to display the small version of the message
            $smallmessage = null;
            if (!empty($message_users->smallmessage)) {
                //display the first 200 chars of the message in the popup
                $smallmessage = null;
                if (textlib::strlen($message_users->smallmessage) > 200) {
                    $smallmessage = textlib::substr($message_users->smallmessage, 0, 200) . '...';
                } else {
                    $smallmessage = $message_users->smallmessage;
                }
                //prevent html symbols being displayed
                if ($message_users->fullmessageformat == FORMAT_HTML) {
                    $smallmessage = html_to_text($smallmessage);
                } else {
                    $smallmessage = s($smallmessage);
                }
            } else {
                if ($message_users->notification) {
                    //its a notification with no smallmessage so just say they have a notification
                    $smallmessage = get_string('unreadnewnotification', 'message');
                }
            }
            if (!empty($smallmessage)) {
                $strmessages .= '<div id="usermessage">' . s($smallmessage) . '</div>';
            }
        }
        $strgomessage = get_string('gotomessages', 'message');
        $strstaymessage = get_string('ignore', 'admin');
        $url = $CFG->wwwroot . '/message/index.php';
        $content = html_writer::start_tag('div', array('id' => 'newmessageoverlay', 'class' => 'mdl-align')) . html_writer::start_tag('div', array('id' => 'newmessagetext')) . $strmessages . html_writer::end_tag('div') . html_writer::start_tag('div', array('id' => 'newmessagelinks')) . html_writer::link($url, $strgomessage, array('id' => 'notificationyes')) . '&nbsp;&nbsp;&nbsp;' . html_writer::link('', $strstaymessage, array('id' => 'notificationno')) . html_writer::end_tag('div');
        html_writer::end_tag('div');
        $PAGE->requires->js_init_call('M.core_message.init_notification', array('', $content, $url));
        $USER->message_lastpopup = time();
    }
}
예제 #27
0
 /**
  * Truncate a string in the center
  * @param string $string The string to truncate
  * @param int $length The length to truncate to
  * @return string The truncated string
  */
 protected function trim_center($string, $length)
 {
     $trimlength = ceil($length / 2);
     $start = textlib::substr($string, 0, $trimlength);
     $end = textlib::substr($string, textlib::strlen($string) - $trimlength);
     $string = $start . '...' . $end;
     return $string;
 }
예제 #28
0
                $search = $val;
            }
        }

    } else {
        $search = optional_param('search', $SESSION->dataprefs[$data->id]['search'], PARAM_NOTAGS);
        //Paging variable not used for standard search. Set it to null.
        $paging = NULL;
    }

    // Disable search filters if $filter is not true:
    if (! $filter) {
        $search = '';
    }

    if (textlib::strlen($search) < 2) {
        $search = '';
    }
    $SESSION->dataprefs[$data->id]['search'] = $search;   // Make it sticky

    $sort = optional_param('sort', $SESSION->dataprefs[$data->id]['sort'], PARAM_INT);
    $SESSION->dataprefs[$data->id]['sort'] = $sort;       // Make it sticky

    $order = (optional_param('order', $SESSION->dataprefs[$data->id]['order'], PARAM_ALPHA) == 'ASC') ? 'ASC': 'DESC';
    $SESSION->dataprefs[$data->id]['order'] = $order;     // Make it sticky


    $oldperpage = get_user_preferences('data_perpage_'.$data->id, 10);
    $perpage = optional_param('perpage', $oldperpage, PARAM_INT);

    if ($perpage < 2) {
/**
 * Migrate giportfolio files stored in moddata folders.
 *
 * Please note it was a big mistake to store the files there in the first place!
 *
 * @param stdClass $giportfolio
 * @param stdClass $context
 * @param string $path
 * @return void
 */
function mod_giportfolio_migrate_moddata_dir_to_legacy($giportfolio, $context, $path)
{
    global $OUTPUT, $CFG;
    $base = "{$CFG->dataroot}/{$giportfolio->course}/{$CFG->moddata}/giportfolio/{$giportfolio->id}";
    $fulldir = $base . $path;
    if (!is_dir($fulldir)) {
        // Does not exist.
        return;
    }
    $fs = get_file_storage();
    $items = new DirectoryIterator($fulldir);
    foreach ($items as $item) {
        if ($item->isDot()) {
            unset($item);
            // Release file handle.
            continue;
        }
        if ($item->isLink()) {
            // Do not follow symlinks - they were never supported in moddata, sorry.
            unset($item);
            // Release file handle.
            continue;
        }
        if ($item->isFile()) {
            if (!$item->isReadable()) {
                echo $OUTPUT->notification(" File not readable, skipping: " . $fulldir . $item->getFilename());
                unset($item);
                // Release file handle.
                continue;
            }
            $filepath = clean_param("/{$CFG->moddata}/giportfolio/{$giportfolio->id}" . $path, PARAM_PATH);
            $filename = clean_param($item->getFilename(), PARAM_FILE);
            if ($filename === '') {
                // Unsupported chars, sorry.
                unset($item);
                // Release file handle.
                continue;
            }
            if (textlib::strlen($filepath) > 255) {
                echo $OUTPUT->notification(" File path longer than 255 chars, skipping: " . $fulldir . $item->getFilename());
                unset($item);
                // Release file handle.
                continue;
            }
            if (!$fs->file_exists($context->id, 'course', 'legacy', '0', $filepath, $filename)) {
                $filerecord = array('contextid' => $context->id, 'component' => 'course', 'filearea' => 'legacy', 'itemid' => 0, 'filepath' => $filepath, 'filename' => $filename, 'timecreated' => $item->getCTime(), 'timemodified' => $item->getMTime());
                $fs->create_file_from_pathname($filerecord, $fulldir . $item->getFilename());
            }
            $oldpathname = $fulldir . $item->getFilename();
            unset($item);
            // Release file handle.
            @unlink($oldpathname);
        } else {
            // Migrate recursively all subdirectories.
            $oldpathname = $base . $item->getFilename() . '/';
            $subpath = $path . $item->getFilename() . '/';
            unset($item);
            // Release file handle.
            giportfolio_migrate_moddata_dir_to_legacy($giportfolio, $context, $subpath);
            @rmdir($oldpathname);
            // Deletes dir if empty.
        }
    }
    unset($items);
    // Release file handles.
}
예제 #30
0
 /**
  * Updates the record with either form data or raw data
  *
  * Please note that this function does not verify access control.
  *
  * This function calls coursecat::change_parent_raw if field 'parent' is updated.
  * It also calls coursecat::hide_raw or coursecat::show_raw if 'visible' is updated.
  * Visibility is changed first and then parent is changed. This means that
  * if parent category is hidden, the current category will become hidden
  * too and it may overwrite whatever was set in field 'visible'.
  *
  * Note that fields 'path' and 'depth' can not be updated manually
  * Also coursecat::update() can not directly update the field 'sortoder'
  *
  * @param array|stdClass $data
  * @param array $editoroptions if specified, the data is considered to be
  *    form data and file_postupdate_standard_editor() is being called to
  *    process images in description.
  * @throws moodle_exception
  */
 public function update($data, $editoroptions = null)
 {
     global $DB, $CFG;
     if (!$this->id) {
         // there is no actual DB record associated with root category
         return;
     }
     $data = (object) $data;
     $newcategory = new stdClass();
     $newcategory->id = $this->id;
     // copy all description* fields regardless of whether this is form data or direct field update
     foreach ($data as $key => $value) {
         if (preg_match("/^description/", $key)) {
             $newcategory->{$key} = $value;
         }
     }
     if (isset($data->name) && empty($data->name)) {
         throw new moodle_exception('categorynamerequired');
     }
     if (!empty($data->name) && $data->name !== $this->name) {
         if (textlib::strlen($data->name) > 255) {
             throw new moodle_exception('categorytoolong');
         }
         $newcategory->name = $data->name;
     }
     if (isset($data->idnumber) && $data->idnumber != $this->idnumber) {
         if (textlib::strlen($data->idnumber) > 100) {
             throw new moodle_exception('idnumbertoolong');
         }
         if ($DB->record_exists('course_categories', array('idnumber' => $data->idnumber))) {
             throw new moodle_exception('categoryidnumbertaken');
         }
         $newcategory->idnumber = $data->idnumber;
     }
     if (isset($data->theme) && !empty($CFG->allowcategorythemes)) {
         $newcategory->theme = $data->theme;
     }
     $changes = false;
     if (isset($data->visible)) {
         if ($data->visible) {
             $changes = $this->show_raw();
         } else {
             $changes = $this->hide_raw(0);
         }
     }
     if (isset($data->parent) && $data->parent != $this->parent) {
         if ($changes) {
             cache_helper::purge_by_event('changesincoursecat');
         }
         $parentcat = self::get($data->parent, MUST_EXIST, true);
         $this->change_parent_raw($parentcat);
         fix_course_sortorder();
     }
     $newcategory->timemodified = time();
     if ($editoroptions) {
         $categorycontext = context_coursecat::instance($this->id);
         $newcategory = file_postupdate_standard_editor($newcategory, 'description', $editoroptions, $categorycontext, 'coursecat', 'description', 0);
     }
     $DB->update_record('course_categories', $newcategory);
     add_to_log(SITEID, "category", 'update', "editcategory.php?id={$this->id}", $this->id);
     fix_course_sortorder();
     // purge cache even if fix_course_sortorder() did not do it
     cache_helper::purge_by_event('changesincoursecat');
     // update all fields in the current object
     $this->restore();
 }