Moodle  2.2.1
http://www.collinsharper.com
C:/xampp/htdocs/moodle/lib/outputcomponents.php
Go to the documentation of this file.
00001 <?php
00002 
00003 // This file is part of Moodle - http://moodle.org/
00004 //
00005 // Moodle is free software: you can redistribute it and/or modify
00006 // it under the terms of the GNU General Public License as published by
00007 // the Free Software Foundation, either version 3 of the License, or
00008 // (at your option) any later version.
00009 //
00010 // Moodle is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 // GNU General Public License for more details.
00014 //
00015 // You should have received a copy of the GNU General Public License
00016 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
00017 
00030 defined('MOODLE_INTERNAL') || die();
00031 
00036 interface renderable {
00037     // intentionally empty
00038 }
00039 
00047 class file_picker implements renderable {
00048     public $options;
00049     public function __construct(stdClass $options) {
00050         global $CFG, $USER, $PAGE;
00051         require_once($CFG->dirroot. '/repository/lib.php');
00052         $defaults = array(
00053             'accepted_types'=>'*',
00054             'return_types'=>FILE_INTERNAL,
00055             'env' => 'filepicker',
00056             'client_id' => uniqid(),
00057             'itemid' => 0,
00058             'maxbytes'=>-1,
00059             'maxfiles'=>1,
00060             'buttonname'=>false
00061         );
00062         foreach ($defaults as $key=>$value) {
00063             if (empty($options->$key)) {
00064                 $options->$key = $value;
00065             }
00066         }
00067 
00068         $options->currentfile = '';
00069         if (!empty($options->itemid)) {
00070             $fs = get_file_storage();
00071             $usercontext = get_context_instance(CONTEXT_USER, $USER->id);
00072             if (empty($options->filename)) {
00073                 if ($files = $fs->get_area_files($usercontext->id, 'user', 'draft', $options->itemid, 'id DESC', false)) {
00074                     $file = reset($files);
00075                 }
00076             } else {
00077                 $file = $fs->get_file($usercontext->id, 'user', 'draft', $options->itemid, $options->filepath, $options->filename);
00078             }
00079             if (!empty($file)) {
00080                 $options->currentfile = html_writer::link(moodle_url::make_draftfile_url($file->get_itemid(), $file->get_filepath(), $file->get_filename()), $file->get_filename());
00081             }
00082         }
00083 
00084         // initilise options, getting files in root path
00085         $this->options = initialise_filepicker($options);
00086 
00087         // copying other options
00088         foreach ($options as $name=>$value) {
00089             if (!isset($this->options->$name)) {
00090                 $this->options->$name = $value;
00091             }
00092         }
00093     }
00094 }
00095 
00103 class user_picture implements renderable {
00107     protected static $fields = array('id', 'picture', 'firstname', 'lastname', 'imagealt', 'email'); //TODO: add deleted
00108 
00112     public $user;
00117     public $courseid;
00121     public $link = true;
00125     public $size = 35;
00130     public $alttext = true;
00134     public $popup = false;
00138     public $class = 'userpicture';
00139 
00146     public function __construct(stdClass $user) {
00147         global $DB;
00148 
00149         if (empty($user->id)) {
00150             throw new coding_exception('User id is required when printing user avatar image.');
00151         }
00152 
00153         // only touch the DB if we are missing data and complain loudly...
00154         $needrec = false;
00155         foreach (self::$fields as $field) {
00156             if (!array_key_exists($field, $user)) {
00157                 $needrec = true;
00158                 debugging('Missing '.$field.' property in $user object, this is a performance problem that needs to be fixed by a developer. '
00159                           .'Please use user_picture::fields() to get the full list of required fields.', DEBUG_DEVELOPER);
00160                 break;
00161             }
00162         }
00163 
00164         if ($needrec) {
00165             $this->user = $DB->get_record('user', array('id'=>$user->id), self::fields(), MUST_EXIST);
00166         } else {
00167             $this->user = clone($user);
00168         }
00169     }
00170 
00184     public static function fields($tableprefix = '', array $extrafields = NULL, $idalias = 'id', $fieldprefix = '') {
00185         if (!$tableprefix and !$extrafields and !$idalias) {
00186             return implode(',', self::$fields);
00187         }
00188         if ($tableprefix) {
00189             $tableprefix .= '.';
00190         }
00191         $fields = array();
00192         foreach (self::$fields as $field) {
00193             if ($field === 'id' and $idalias and $idalias !== 'id') {
00194                 $fields[$field] = "$tableprefix$field AS $idalias";
00195             } else {
00196                 if ($fieldprefix and $field !== 'id') {
00197                     $fields[$field] = "$tableprefix$field AS $fieldprefix$field";
00198                 } else {
00199                     $fields[$field] = "$tableprefix$field";
00200                 }
00201             }
00202         }
00203         // add extra fields if not already there
00204         if ($extrafields) {
00205             foreach ($extrafields as $e) {
00206                 if ($e === 'id' or isset($fields[$e])) {
00207                     continue;
00208                 }
00209                 if ($fieldprefix) {
00210                     $fields[$e] = "$tableprefix$e AS $fieldprefix$e";
00211                 } else {
00212                     $fields[$e] = "$tableprefix$e";
00213                 }
00214             }
00215         }
00216         return implode(',', $fields);
00217     }
00218 
00231     public static function unalias(stdClass $record, array $extrafields=null, $idalias='id', $fieldprefix='') {
00232 
00233         if (empty($idalias)) {
00234             $idalias = 'id';
00235         }
00236 
00237         $return = new stdClass();
00238 
00239         foreach (self::$fields as $field) {
00240             if ($field === 'id') {
00241                 if (property_exists($record, $idalias)) {
00242                     $return->id = $record->{$idalias};
00243                 }
00244             } else {
00245                 if (property_exists($record, $fieldprefix.$field)) {
00246                     $return->{$field} = $record->{$fieldprefix.$field};
00247                 }
00248             }
00249         }
00250         // add extra fields if not already there
00251         if ($extrafields) {
00252             foreach ($extrafields as $e) {
00253                 if ($e === 'id' or property_exists($return, $e)) {
00254                     continue;
00255                 }
00256                 $return->{$e} = $record->{$fieldprefix.$e};
00257             }
00258         }
00259 
00260         return $return;
00261     }
00262 
00272     public function get_url(moodle_page $page, renderer_base $renderer = null) {
00273         global $CFG;
00274 
00275         if (is_null($renderer)) {
00276             $renderer = $page->get_renderer('core');
00277         }
00278 
00279         if ((!empty($CFG->forcelogin) and !isloggedin()) ||
00280                 (!empty($CFG->forceloginforprofileimage) && (!isloggedin() || isguestuser()))) {
00281             // protect images if login required and not logged in;
00282             // also if login is required for profile images and is not logged in or guest
00283             // do not use require_login() because it is expensive and not suitable here anyway
00284             return $renderer->pix_url('u/f1');
00285         }
00286 
00287         // Sort out the filename and size. Size is only required for the gravatar
00288         // implementation presently.
00289         if (empty($this->size)) {
00290             $filename = 'f2';
00291             $size = 35;
00292         } else if ($this->size === true or $this->size == 1) {
00293             $filename = 'f1';
00294             $size = 100;
00295         } else if ($this->size >= 50) {
00296             $filename = 'f1';
00297             $size = (int)$this->size;
00298         } else {
00299             $filename = 'f2';
00300             $size = (int)$this->size;
00301         }
00302 
00303         // First we need to determine whether the user has uploaded a profile
00304         // picture of not.
00305         if (!empty($this->user->deleted) or !$context = context_user::instance($this->user->id, IGNORE_MISSING)) {
00306             $hasuploadedfile = false;
00307         } else {
00308             $fs = get_file_storage();
00309             $hasuploadedfile = ($fs->file_exists($context->id, 'user', 'icon', 0, '/', $filename.'/.png') || $fs->file_exists($context->id, 'user', 'icon', 0, '/', $filename.'/.jpg'));
00310         }
00311 
00312         $imageurl = $renderer->pix_url('u/'.$filename);
00313         if ($hasuploadedfile && $this->user->picture == 1) {
00314             $path = '/';
00315             if (clean_param($page->theme->name, PARAM_THEME) == $page->theme->name) {
00316                 // We append the theme name to the file path if we have it so that
00317                 // in the circumstance that the profile picture is not available
00318                 // when the user actually requests it they still get the profile
00319                 // picture for the correct theme.
00320                 $path .= $page->theme->name.'/';
00321             }
00322             // Set the image URL to the URL for the uploaded file.
00323             $imageurl = moodle_url::make_pluginfile_url($context->id, 'user', 'icon', NULL, $path, $filename);
00324         } else if (!empty($CFG->enablegravatar)) {
00325             // Normalise the size variable to acceptable bounds
00326             if ($size < 1 || $size > 512) {
00327                 $size = 35;
00328             }
00329             // Hash the users email address
00330             $md5 = md5(strtolower(trim($this->user->email)));
00331             // Build a gravatar URL with what we know.
00332             // If the currently requested page is https then we'll return an
00333             // https gravatar page.
00334             if (strpos($CFG->httpswwwroot, 'https:') === 0) {
00335                 $imageurl = new moodle_url("https://secure.gravatar.com/avatar/{$md5}", array('s' => $size, 'd' => $imageurl->out(false)));
00336             } else {
00337                 $imageurl = new moodle_url("http://www.gravatar.com/avatar/{$md5}", array('s' => $size, 'd' => $imageurl->out(false)));
00338             }
00339         }
00340 
00341         // Return the URL that has been generated.
00342         return $imageurl;
00343     }
00344 }
00345 
00353 class old_help_icon implements renderable {
00357     public $helpidentifier;
00361     public $title = null;
00365     public $component = 'moodle';
00369     public $linktext = null;
00370 
00379     public function __construct($helpidentifier, $title, $component = 'moodle') {
00380         if (empty($title)) {
00381             throw new coding_exception('A help_icon object requires a $text parameter');
00382         }
00383         if (empty($helpidentifier)) {
00384             throw new coding_exception('A help_icon object requires a $helpidentifier parameter');
00385         }
00386 
00387         $this->helpidentifier  = $helpidentifier;
00388         $this->title           = $title;
00389         $this->component       = $component;
00390     }
00391 }
00392 
00400 class help_icon implements renderable {
00406     public $identifier;
00410     public $component;
00414     public $linktext = null;
00415 
00423     public function __construct($identifier, $component) {
00424         $this->identifier = $identifier;
00425         $this->component  = $component;
00426     }
00427 
00431     public function diag_strings() {
00432         $sm = get_string_manager();
00433         if (!$sm->string_exists($this->identifier, $this->component)) {
00434             debugging("Help title string does not exist: [$this->identifier, $this->component]");
00435         }
00436         if (!$sm->string_exists($this->identifier.'_help', $this->component)) {
00437             debugging("Help contents string does not exist: [{$this->identifier}_help, $this->component]");
00438         }
00439     }
00440 }
00441 
00442 
00450 class pix_icon implements renderable {
00451     var $pix;
00452     var $component;
00453     var $attributes = array();
00454 
00462     public function __construct($pix, $alt, $component='moodle', array $attributes = null) {
00463         $this->pix        = $pix;
00464         $this->component  = $component;
00465         $this->attributes = (array)$attributes;
00466 
00467         $this->attributes['alt'] = $alt;
00468         if (empty($this->attributes['class'])) {
00469             $this->attributes['class'] = 'smallicon';
00470         }
00471         if (!isset($this->attributes['title'])) {
00472             $this->attributes['title'] = $this->attributes['alt'];
00473         }
00474     }
00475 }
00476 
00482 class pix_emoticon extends pix_icon implements renderable {
00483 
00491     public function __construct($pix, $alt, $component = 'moodle', array $attributes = array()) {
00492         if (empty($attributes['class'])) {
00493             $attributes['class'] = 'emoticon';
00494         }
00495         parent::__construct($pix, $alt, $component, $attributes);
00496     }
00497 }
00498 
00506 class single_button implements renderable {
00511     var $url;
00516     var $label;
00521     var $method = 'post';
00526     var $class = 'singlebutton';
00531     var $disabled = false;
00536     var $tooltip = null;
00541     var $formid;
00546     var $actions = array();
00547 
00554     public function __construct(moodle_url $url, $label, $method='post') {
00555         $this->url    = clone($url);
00556         $this->label  = $label;
00557         $this->method = $method;
00558     }
00559 
00566     public function add_confirm_action($confirmmessage) {
00567         $this->add_action(new confirm_action($confirmmessage));
00568     }
00569 
00575     public function add_action(component_action $action) {
00576         $this->actions[] = $action;
00577     }
00578 }
00579 
00580 
00589 class single_select implements renderable {
00594     var $url;
00599     var $name;
00607     var $options;
00612     var $selected;
00617     var $nothing;
00622     var $attributes = array();
00627     var $label = '';
00632     var $method = 'get';
00637     var $class = 'singleselect';
00642     var $disabled = false;
00647     var $tooltip = null;
00652     var $formid = null;
00657     var $helpicon = null;
00667     public function __construct(moodle_url $url, $name, array $options, $selected='', $nothing=array(''=>'choosedots'), $formid=null) {
00668         $this->url      = $url;
00669         $this->name     = $name;
00670         $this->options  = $options;
00671         $this->selected = $selected;
00672         $this->nothing  = $nothing;
00673         $this->formid   = $formid;
00674     }
00675 
00682     public function add_confirm_action($confirmmessage) {
00683         $this->add_action(new component_action('submit', 'M.util.show_confirm_dialog', array('message' => $confirmmessage)));
00684     }
00685 
00691     public function add_action(component_action $action) {
00692         $this->actions[] = $action;
00693     }
00694 
00703     public function set_old_help_icon($helppage, $title, $component = 'moodle') {
00704         $this->helpicon = new old_help_icon($helppage, $title, $component);
00705     }
00706 
00714     public function set_help_icon($identifier, $component = 'moodle') {
00715         $this->helpicon = new help_icon($identifier, $component);
00716     }
00717 
00723     public function set_label($label) {
00724         $this->label = $label;
00725     }
00726 }
00727 
00728 
00735 class url_select implements renderable {
00743     var $urls;
00748     var $selected;
00753     var $nothing;
00758     var $attributes = array();
00763     var $label = '';
00768     var $class = 'urlselect';
00773     var $disabled = false;
00778     var $tooltip = null;
00783     var $formid = null;
00788     var $helpicon = null;
00792     var $showbutton = null;
00802     public function __construct(array $urls, $selected='', $nothing=array(''=>'choosedots'),
00803             $formid=null, $showbutton=null) {
00804         $this->urls       = $urls;
00805         $this->selected   = $selected;
00806         $this->nothing    = $nothing;
00807         $this->formid     = $formid;
00808         $this->showbutton = $showbutton;
00809     }
00810 
00819     public function set_old_help_icon($helppage, $title, $component = 'moodle') {
00820         $this->helpicon = new old_help_icon($helppage, $title, $component);
00821     }
00822 
00830     public function set_help_icon($identifier, $component = 'moodle') {
00831         $this->helpicon = new help_icon($identifier, $component);
00832     }
00833 
00839     public function set_label($label) {
00840         $this->label = $label;
00841     }
00842 }
00843 
00844 
00851 class action_link implements renderable {
00856     var $url;
00861     var $text;
00866     var $attributes;
00871     var $actions;
00872 
00880     public function __construct(moodle_url $url, $text, component_action $action=null, array $attributes=null) {
00881         $this->url       = clone($url);
00882         $this->text      = $text;
00883         $this->attributes = (array)$attributes;
00884         if ($action) {
00885             $this->add_action($action);
00886         }
00887     }
00888 
00894     public function add_action(component_action $action) {
00895         $this->actions[] = $action;
00896     }
00897 
00898     public function add_class($class) {
00899         if (empty($this->attributes['class'])) {
00900             $this->attributes['class'] = $class;
00901         } else {
00902             $this->attributes['class'] .= ' ' . $class;
00903         }
00904     }
00905 }
00906 
00907 // ==== HTML writer and helper classes, will be probably moved elsewhere ======
00908 
00913 class html_writer {
00921     public static function tag($tagname, $contents, array $attributes = null) {
00922         return self::start_tag($tagname, $attributes) . $contents . self::end_tag($tagname);
00923     }
00924 
00931     public static function start_tag($tagname, array $attributes = null) {
00932         return '<' . $tagname . self::attributes($attributes) . '>';
00933     }
00934 
00940     public static function end_tag($tagname) {
00941         return '</' . $tagname . '>';
00942     }
00943 
00950     public static function empty_tag($tagname, array $attributes = null) {
00951         return '<' . $tagname . self::attributes($attributes) . ' />';
00952     }
00953 
00961     public static function nonempty_tag($tagname, $contents, array $attributes = null) {
00962         if ($contents === '' || is_null($contents)) {
00963             return '';
00964         }
00965         return self::tag($tagname, $contents, $attributes);
00966     }
00967 
00974     public static function attribute($name, $value) {
00975         if (is_array($value)) {
00976             debugging("Passed an array for the HTML attribute $name", DEBUG_DEVELOPER);
00977         }
00978         if ($value instanceof moodle_url) {
00979             return ' ' . $name . '="' . $value->out() . '"';
00980         }
00981 
00982         // special case, we do not want these in output
00983         if ($value === null) {
00984             return '';
00985         }
00986 
00987         // no sloppy trimming here!
00988         return ' ' . $name . '="' . s($value) . '"';
00989     }
00990 
00997     public static function attributes(array $attributes = null) {
00998         $attributes = (array)$attributes;
00999         $output = '';
01000         foreach ($attributes as $name => $value) {
01001             $output .= self::attribute($name, $value);
01002         }
01003         return $output;
01004     }
01005 
01011     public static function random_id($base='random') {
01012         static $counter = 0;
01013         static $uniq;
01014 
01015         if (!isset($uniq)) {
01016             $uniq = uniqid();
01017         }
01018 
01019         $counter++;
01020         return $base.$uniq.$counter;
01021     }
01022 
01030     public static function link($url, $text, array $attributes = null) {
01031         $attributes = (array)$attributes;
01032         $attributes['href']  = $url;
01033         return self::tag('a', $text, $attributes);
01034     }
01035 
01045     public static function checkbox($name, $value, $checked = true, $label = '', array $attributes = null) {
01046         $attributes = (array)$attributes;
01047         $output = '';
01048 
01049         if ($label !== '' and !is_null($label)) {
01050             if (empty($attributes['id'])) {
01051                 $attributes['id'] = self::random_id('checkbox_');
01052             }
01053         }
01054         $attributes['type']    = 'checkbox';
01055         $attributes['value']   = $value;
01056         $attributes['name']    = $name;
01057         $attributes['checked'] = $checked ? 'checked' : null;
01058 
01059         $output .= self::empty_tag('input', $attributes);
01060 
01061         if ($label !== '' and !is_null($label)) {
01062             $output .= self::tag('label', $label, array('for'=>$attributes['id']));
01063         }
01064 
01065         return $output;
01066     }
01067 
01075     public static function select_yes_no($name, $selected=true, array $attributes = null) {
01076         $options = array('1'=>get_string('yes'), '0'=>get_string('no'));
01077         return self::select($options, $name, $selected, null, $attributes);
01078     }
01079 
01093     public static function select(array $options, $name, $selected = '', $nothing = array(''=>'choosedots'), array $attributes = null) {
01094         $attributes = (array)$attributes;
01095         if (is_array($nothing)) {
01096             foreach ($nothing as $k=>$v) {
01097                 if ($v === 'choose' or $v === 'choosedots') {
01098                     $nothing[$k] = get_string('choosedots');
01099                 }
01100             }
01101             $options = $nothing + $options; // keep keys, do not override
01102 
01103         } else if (is_string($nothing) and $nothing !== '') {
01104             // BC
01105             $options = array(''=>$nothing) + $options;
01106         }
01107 
01108         // we may accept more values if multiple attribute specified
01109         $selected = (array)$selected;
01110         foreach ($selected as $k=>$v) {
01111             $selected[$k] = (string)$v;
01112         }
01113 
01114         if (!isset($attributes['id'])) {
01115             $id = 'menu'.$name;
01116             // name may contaion [], which would make an invalid id. e.g. numeric question type editing form, assignment quickgrading
01117             $id = str_replace('[', '', $id);
01118             $id = str_replace(']', '', $id);
01119             $attributes['id'] = $id;
01120         }
01121 
01122         if (!isset($attributes['class'])) {
01123             $class = 'menu'.$name;
01124             // name may contaion [], which would make an invalid class. e.g. numeric question type editing form, assignment quickgrading
01125             $class = str_replace('[', '', $class);
01126             $class = str_replace(']', '', $class);
01127             $attributes['class'] = $class;
01128         }
01129         $attributes['class'] = 'select ' . $attributes['class']; 
01130 
01131         $attributes['name'] = $name;
01132 
01133         if (!empty($attributes['disabled'])) {
01134             $attributes['disabled'] = 'disabled';
01135         } else {
01136             unset($attributes['disabled']);
01137         }
01138 
01139         $output = '';
01140         foreach ($options as $value=>$label) {
01141             if (is_array($label)) {
01142                 // ignore key, it just has to be unique
01143                 $output .= self::select_optgroup(key($label), current($label), $selected);
01144             } else {
01145                 $output .= self::select_option($label, $value, $selected);
01146             }
01147         }
01148         return self::tag('select', $output, $attributes);
01149     }
01150 
01151     private static function select_option($label, $value, array $selected) {
01152         $attributes = array();
01153         $value = (string)$value;
01154         if (in_array($value, $selected, true)) {
01155             $attributes['selected'] = 'selected';
01156         }
01157         $attributes['value'] = $value;
01158         return self::tag('option', $label, $attributes);
01159     }
01160 
01161     private static function select_optgroup($groupname, $options, array $selected) {
01162         if (empty($options)) {
01163             return '';
01164         }
01165         $attributes = array('label'=>$groupname);
01166         $output = '';
01167         foreach ($options as $value=>$label) {
01168             $output .= self::select_option($label, $value, $selected);
01169         }
01170         return self::tag('optgroup', $output, $attributes);
01171     }
01172 
01182     public static function select_time($type, $name, $currenttime=0, $step=5, array $attributes=null) {
01183         if (!$currenttime) {
01184             $currenttime = time();
01185         }
01186         $currentdate = usergetdate($currenttime);
01187         $userdatetype = $type;
01188         $timeunits = array();
01189 
01190         switch ($type) {
01191             case 'years':
01192                 for ($i=1970; $i<=2020; $i++) {
01193                     $timeunits[$i] = $i;
01194                 }
01195                 $userdatetype = 'year';
01196                 break;
01197             case 'months':
01198                 for ($i=1; $i<=12; $i++) {
01199                     $timeunits[$i] = userdate(gmmktime(12,0,0,$i,15,2000), "%B");
01200                 }
01201                 $userdatetype = 'month';
01202                 $currentdate['month'] = (int)$currentdate['mon'];
01203                 break;
01204             case 'days':
01205                 for ($i=1; $i<=31; $i++) {
01206                     $timeunits[$i] = $i;
01207                 }
01208                 $userdatetype = 'mday';
01209                 break;
01210             case 'hours':
01211                 for ($i=0; $i<=23; $i++) {
01212                     $timeunits[$i] = sprintf("%02d",$i);
01213                 }
01214                 break;
01215             case 'minutes':
01216                 if ($step != 1) {
01217                     $currentdate['minutes'] = ceil($currentdate['minutes']/$step)*$step;
01218                 }
01219 
01220                 for ($i=0; $i<=59; $i+=$step) {
01221                     $timeunits[$i] = sprintf("%02d",$i);
01222                 }
01223                 break;
01224             default:
01225                 throw new coding_exception("Time type $type is not supported by html_writer::select_time().");
01226         }
01227 
01228         if (empty($attributes['id'])) {
01229             $attributes['id'] = self::random_id('ts_');
01230         }
01231         $timerselector = self::select($timeunits, $name, $currentdate[$userdatetype], null, array('id'=>$attributes['id']));
01232         $label = self::tag('label', get_string(substr($type, 0, -1), 'form'), array('for'=>$attributes['id'], 'class'=>'accesshide'));
01233 
01234         return $label.$timerselector;
01235     }
01236 
01244     public static function alist(array $items, array $attributes = null, $tag = 'ul') {
01245         //note: 'list' is a reserved keyword ;-)
01246 
01247         $output = '';
01248 
01249         foreach ($items as $item) {
01250             $output .= html_writer::start_tag('li') . "\n";
01251             $output .= $item . "\n";
01252             $output .= html_writer::end_tag('li') . "\n";
01253         }
01254 
01255         return html_writer::tag($tag, $output, $attributes);
01256     }
01257 
01264     public static function input_hidden_params(moodle_url $url, array $exclude = null) {
01265         $exclude = (array)$exclude;
01266         $params = $url->params();
01267         foreach ($exclude as $key) {
01268             unset($params[$key]);
01269         }
01270 
01271         $output = '';
01272         foreach ($params as $key => $value) {
01273             $attributes = array('type'=>'hidden', 'name'=>$key, 'value'=>$value);
01274             $output .= self::empty_tag('input', $attributes)."\n";
01275         }
01276         return $output;
01277     }
01278 
01286     public static function script($jscode, $url=null) {
01287         if ($jscode) {
01288             $attributes = array('type'=>'text/javascript');
01289             return self::tag('script', "\n//<![CDATA[\n$jscode\n//]]>\n", $attributes) . "\n";
01290 
01291         } else if ($url) {
01292             $attributes = array('type'=>'text/javascript', 'src'=>$url);
01293             return self::tag('script', '', $attributes) . "\n";
01294 
01295         } else {
01296             return '';
01297         }
01298     }
01299 
01311     public static function table(html_table $table) {
01312         // prepare table data and populate missing properties with reasonable defaults
01313         if (!empty($table->align)) {
01314             foreach ($table->align as $key => $aa) {
01315                 if ($aa) {
01316                     $table->align[$key] = 'text-align:'. fix_align_rtl($aa) .';';  // Fix for RTL languages
01317                 } else {
01318                     $table->align[$key] = null;
01319                 }
01320             }
01321         }
01322         if (!empty($table->size)) {
01323             foreach ($table->size as $key => $ss) {
01324                 if ($ss) {
01325                     $table->size[$key] = 'width:'. $ss .';';
01326                 } else {
01327                     $table->size[$key] = null;
01328                 }
01329             }
01330         }
01331         if (!empty($table->wrap)) {
01332             foreach ($table->wrap as $key => $ww) {
01333                 if ($ww) {
01334                     $table->wrap[$key] = 'white-space:nowrap;';
01335                 } else {
01336                     $table->wrap[$key] = '';
01337                 }
01338             }
01339         }
01340         if (!empty($table->head)) {
01341             foreach ($table->head as $key => $val) {
01342                 if (!isset($table->align[$key])) {
01343                     $table->align[$key] = null;
01344                 }
01345                 if (!isset($table->size[$key])) {
01346                     $table->size[$key] = null;
01347                 }
01348                 if (!isset($table->wrap[$key])) {
01349                     $table->wrap[$key] = null;
01350                 }
01351 
01352             }
01353         }
01354         if (empty($table->attributes['class'])) {
01355             $table->attributes['class'] = 'generaltable';
01356         }
01357         if (!empty($table->tablealign)) {
01358             $table->attributes['class'] .= ' boxalign' . $table->tablealign;
01359         }
01360 
01361         // explicitly assigned properties override those defined via $table->attributes
01362         $table->attributes['class'] = trim($table->attributes['class']);
01363         $attributes = array_merge($table->attributes, array(
01364                 'id'            => $table->id,
01365                 'width'         => $table->width,
01366                 'summary'       => $table->summary,
01367                 'cellpadding'   => $table->cellpadding,
01368                 'cellspacing'   => $table->cellspacing,
01369             ));
01370         $output = html_writer::start_tag('table', $attributes) . "\n";
01371 
01372         $countcols = 0;
01373 
01374         if (!empty($table->head)) {
01375             $countcols = count($table->head);
01376 
01377             $output .= html_writer::start_tag('thead', array()) . "\n";
01378             $output .= html_writer::start_tag('tr', array()) . "\n";
01379             $keys = array_keys($table->head);
01380             $lastkey = end($keys);
01381 
01382             foreach ($table->head as $key => $heading) {
01383                 // Convert plain string headings into html_table_cell objects
01384                 if (!($heading instanceof html_table_cell)) {
01385                     $headingtext = $heading;
01386                     $heading = new html_table_cell();
01387                     $heading->text = $headingtext;
01388                     $heading->header = true;
01389                 }
01390 
01391                 if ($heading->header !== false) {
01392                     $heading->header = true;
01393                 }
01394 
01395                 if ($heading->header && empty($heading->scope)) {
01396                     $heading->scope = 'col';
01397                 }
01398 
01399                 $heading->attributes['class'] .= ' header c' . $key;
01400                 if (isset($table->headspan[$key]) && $table->headspan[$key] > 1) {
01401                     $heading->colspan = $table->headspan[$key];
01402                     $countcols += $table->headspan[$key] - 1;
01403                 }
01404 
01405                 if ($key == $lastkey) {
01406                     $heading->attributes['class'] .= ' lastcol';
01407                 }
01408                 if (isset($table->colclasses[$key])) {
01409                     $heading->attributes['class'] .= ' ' . $table->colclasses[$key];
01410                 }
01411                 $heading->attributes['class'] = trim($heading->attributes['class']);
01412                 $attributes = array_merge($heading->attributes, array(
01413                         'style'     => $table->align[$key] . $table->size[$key] . $heading->style,
01414                         'scope'     => $heading->scope,
01415                         'colspan'   => $heading->colspan,
01416                     ));
01417 
01418                 $tagtype = 'td';
01419                 if ($heading->header === true) {
01420                     $tagtype = 'th';
01421                 }
01422                 $output .= html_writer::tag($tagtype, $heading->text, $attributes) . "\n";
01423             }
01424             $output .= html_writer::end_tag('tr') . "\n";
01425             $output .= html_writer::end_tag('thead') . "\n";
01426 
01427             if (empty($table->data)) {
01428                 // For valid XHTML strict every table must contain either a valid tr
01429                 // or a valid tbody... both of which must contain a valid td
01430                 $output .= html_writer::start_tag('tbody', array('class' => 'empty'));
01431                 $output .= html_writer::tag('tr', html_writer::tag('td', '', array('colspan'=>count($table->head))));
01432                 $output .= html_writer::end_tag('tbody');
01433             }
01434         }
01435 
01436         if (!empty($table->data)) {
01437             $oddeven    = 1;
01438             $keys       = array_keys($table->data);
01439             $lastrowkey = end($keys);
01440             $output .= html_writer::start_tag('tbody', array());
01441 
01442             foreach ($table->data as $key => $row) {
01443                 if (($row === 'hr') && ($countcols)) {
01444                     $output .= html_writer::tag('td', html_writer::tag('div', '', array('class' => 'tabledivider')), array('colspan' => $countcols));
01445                 } else {
01446                     // Convert array rows to html_table_rows and cell strings to html_table_cell objects
01447                     if (!($row instanceof html_table_row)) {
01448                         $newrow = new html_table_row();
01449 
01450                         foreach ($row as $item) {
01451                             $cell = new html_table_cell();
01452                             $cell->text = $item;
01453                             $newrow->cells[] = $cell;
01454                         }
01455                         $row = $newrow;
01456                     }
01457 
01458                     $oddeven = $oddeven ? 0 : 1;
01459                     if (isset($table->rowclasses[$key])) {
01460                         $row->attributes['class'] .= ' ' . $table->rowclasses[$key];
01461                     }
01462 
01463                     $row->attributes['class'] .= ' r' . $oddeven;
01464                     if ($key == $lastrowkey) {
01465                         $row->attributes['class'] .= ' lastrow';
01466                     }
01467 
01468                     $output .= html_writer::start_tag('tr', array('class' => trim($row->attributes['class']), 'style' => $row->style, 'id' => $row->id)) . "\n";
01469                     $keys2 = array_keys($row->cells);
01470                     $lastkey = end($keys2);
01471 
01472                     $gotlastkey = false; //flag for sanity checking
01473                     foreach ($row->cells as $key => $cell) {
01474                         if ($gotlastkey) {
01475                             //This should never happen. Why do we have a cell after the last cell?
01476                             mtrace("A cell with key ($key) was found after the last key ($lastkey)");
01477                         }
01478 
01479                         if (!($cell instanceof html_table_cell)) {
01480                             $mycell = new html_table_cell();
01481                             $mycell->text = $cell;
01482                             $cell = $mycell;
01483                         }
01484 
01485                         if (($cell->header === true) && empty($cell->scope)) {
01486                             $cell->scope = 'row';
01487                         }
01488 
01489                         if (isset($table->colclasses[$key])) {
01490                             $cell->attributes['class'] .= ' ' . $table->colclasses[$key];
01491                         }
01492 
01493                         $cell->attributes['class'] .= ' cell c' . $key;
01494                         if ($key == $lastkey) {
01495                             $cell->attributes['class'] .= ' lastcol';
01496                             $gotlastkey = true;
01497                         }
01498                         $tdstyle = '';
01499                         $tdstyle .= isset($table->align[$key]) ? $table->align[$key] : '';
01500                         $tdstyle .= isset($table->size[$key]) ? $table->size[$key] : '';
01501                         $tdstyle .= isset($table->wrap[$key]) ? $table->wrap[$key] : '';
01502                         $cell->attributes['class'] = trim($cell->attributes['class']);
01503                         $tdattributes = array_merge($cell->attributes, array(
01504                                 'style' => $tdstyle . $cell->style,
01505                                 'colspan' => $cell->colspan,
01506                                 'rowspan' => $cell->rowspan,
01507                                 'id' => $cell->id,
01508                                 'abbr' => $cell->abbr,
01509                                 'scope' => $cell->scope,
01510                             ));
01511                         $tagtype = 'td';
01512                         if ($cell->header === true) {
01513                             $tagtype = 'th';
01514                         }
01515                         $output .= html_writer::tag($tagtype, $cell->text, $tdattributes) . "\n";
01516                     }
01517                 }
01518                 $output .= html_writer::end_tag('tr') . "\n";
01519             }
01520             $output .= html_writer::end_tag('tbody') . "\n";
01521         }
01522         $output .= html_writer::end_tag('table') . "\n";
01523 
01524         return $output;
01525     }
01526 
01548     public static function label($text, $for, $colonize=true, array $attributes=array()) {
01549         if (!is_null($for)) {
01550             $attributes = array_merge($attributes, array('for' => $for));
01551         }
01552         $text = trim($text);
01553         $label = self::tag('label', $text, $attributes);
01554 
01555         /*
01556         // TODO $colonize disabled for now yet - see MDL-12192 for details
01557         if (!empty($text) and $colonize) {
01558             // the $text may end with the colon already, though it is bad string definition style
01559             $colon = get_string('labelsep', 'langconfig');
01560             if (!empty($colon)) {
01561                 $trimmed = trim($colon);
01562                 if ((substr($text, -strlen($trimmed)) == $trimmed) or (substr($text, -1) == ':')) {
01563                     //debugging('The label text should not end with colon or other label separator,
01564                     //           please fix the string definition.', DEBUG_DEVELOPER);
01565                 } else {
01566                     $label .= $colon;
01567                 }
01568             }
01569         }
01570         */
01571 
01572         return $label;
01573     }
01574 }
01575 
01576 // ==== JS writer and helper classes, will be probably moved elsewhere ======
01577 
01582 class js_writer {
01590     public static function function_call($function, array $arguments = null, $delay=0) {
01591         if ($arguments) {
01592             $arguments = array_map('json_encode', $arguments);
01593             $arguments = implode(', ', $arguments);
01594         } else {
01595             $arguments = '';
01596         }
01597         $js = "$function($arguments);";
01598 
01599         if ($delay) {
01600             $delay = $delay * 1000; // in miliseconds
01601             $js = "setTimeout(function() { $js }, $delay);";
01602         }
01603         return $js . "\n";
01604     }
01605 
01612     public static function function_call_with_Y($function, array $extraarguments = null) {
01613         if ($extraarguments) {
01614             $extraarguments = array_map('json_encode', $extraarguments);
01615             $arguments = 'Y, ' . implode(', ', $extraarguments);
01616         } else {
01617             $arguments = 'Y';
01618         }
01619         return "$function($arguments);\n";
01620     }
01621 
01631     public static function object_init($var, $class, array $arguments = null, array $requirements = null, $delay=0) {
01632         if (is_array($arguments)) {
01633             $arguments = array_map('json_encode', $arguments);
01634             $arguments = implode(', ', $arguments);
01635         }
01636 
01637         if ($var === null) {
01638             $js = "new $class(Y, $arguments);";
01639         } else if (strpos($var, '.')!==false) {
01640             $js = "$var = new $class(Y, $arguments);";
01641         } else {
01642             $js = "var $var = new $class(Y, $arguments);";
01643         }
01644 
01645         if ($delay) {
01646             $delay = $delay * 1000; // in miliseconds
01647             $js = "setTimeout(function() { $js }, $delay);";
01648         }
01649 
01650         if (count($requirements) > 0) {
01651             $requirements = implode("', '", $requirements);
01652             $js = "Y.use('$requirements', function(Y){ $js });";
01653         }
01654         return $js."\n";
01655     }
01656 
01664     public static function set_variable($name, $value, $usevar=true) {
01665         $output = '';
01666 
01667         if ($usevar) {
01668             if (strpos($name, '.')) {
01669                 $output .= '';
01670             } else {
01671                 $output .= 'var ';
01672             }
01673         }
01674 
01675         $output .= "$name = ".json_encode($value).";";
01676 
01677         return $output;
01678     }
01679 
01688     public static function event_handler($selector, $event, $function, array $arguments = null) {
01689         $selector = json_encode($selector);
01690         $output = "Y.on('$event', $function, $selector, null";
01691         if (!empty($arguments)) {
01692             $output .= ', ' . json_encode($arguments);
01693         }
01694         return $output . ");\n";
01695     }
01696 }
01697 
01710 class html_table {
01714     public $id = null;
01718     public $attributes = array();
01727     public $head;
01737     public $headspan;
01749     public $align;
01758     public $size;
01766     public $wrap;
01791     public $data;
01796     public $width = null;
01801     public $tablealign = null;
01806     public $cellpadding = null;
01811     public $cellspacing = null;
01821     public $rowclasses;
01832     public $colclasses;
01836     public $summary;
01837 
01841     public function __construct() {
01842         $this->attributes['class'] = '';
01843     }
01844 }
01845 
01846 
01854 class html_table_row {
01858     public $id = null;
01862     public $cells = array();
01866     public $style = null;
01870     public $attributes = array();
01871 
01876     public function __construct(array $cells=null) {
01877         $this->attributes['class'] = '';
01878         $cells = (array)$cells;
01879         foreach ($cells as $cell) {
01880             if ($cell instanceof html_table_cell) {
01881                 $this->cells[] = $cell;
01882             } else {
01883                 $this->cells[] = new html_table_cell($cell);
01884             }
01885         }
01886     }
01887 }
01888 
01889 
01897 class html_table_cell {
01901     public $id = null;
01905     public $text;
01909     public $abbr = null;
01913     public $colspan = null;
01917     public $rowspan = null;
01921     public $scope = null;
01925     public $header = null;
01929     public $style = null;
01933     public $attributes = array();
01934 
01935     public function __construct($text = null) {
01936         $this->text = $text;
01937         $this->attributes['class'] = '';
01938     }
01939 }
01940 
01941 
01943 
01944 
01952 class paging_bar implements renderable {
01956     public $maxdisplay = 18;
01960     public $totalcount;
01964     public $page;
01968     public $perpage;
01973     public $baseurl;
01977     public $pagevar;
01981     public $previouslink = null;
01985     public $nextlink = null;
01989     public $firstlink = null;
01993     public $lastlink = null;
01997     public $pagelinks = array();
01998 
02008     public function __construct($totalcount, $page, $perpage, $baseurl, $pagevar = 'page') {
02009         $this->totalcount = $totalcount;
02010         $this->page       = $page;
02011         $this->perpage    = $perpage;
02012         $this->baseurl    = $baseurl;
02013         $this->pagevar    = $pagevar;
02014     }
02015 
02019     public function prepare(renderer_base $output, moodle_page $page, $target) {
02020         if (!isset($this->totalcount) || is_null($this->totalcount)) {
02021             throw new coding_exception('paging_bar requires a totalcount value.');
02022         }
02023         if (!isset($this->page) || is_null($this->page)) {
02024             throw new coding_exception('paging_bar requires a page value.');
02025         }
02026         if (empty($this->perpage)) {
02027             throw new coding_exception('paging_bar requires a perpage value.');
02028         }
02029         if (empty($this->baseurl)) {
02030             throw new coding_exception('paging_bar requires a baseurl value.');
02031         }
02032 
02033         if ($this->totalcount > $this->perpage) {
02034             $pagenum = $this->page - 1;
02035 
02036             if ($this->page > 0) {
02037                 $this->previouslink = html_writer::link(new moodle_url($this->baseurl, array($this->pagevar=>$pagenum)), get_string('previous'), array('class'=>'previous'));
02038             }
02039 
02040             if ($this->perpage > 0) {
02041                 $lastpage = ceil($this->totalcount / $this->perpage);
02042             } else {
02043                 $lastpage = 1;
02044             }
02045 
02046             if ($this->page > 15) {
02047                 $startpage = $this->page - 10;
02048 
02049                 $this->firstlink = html_writer::link(new moodle_url($this->baseurl, array($this->pagevar=>0)), '1', array('class'=>'first'));
02050             } else {
02051                 $startpage = 0;
02052             }
02053 
02054             $currpage = $startpage;
02055             $displaycount = $displaypage = 0;
02056 
02057             while ($displaycount < $this->maxdisplay and $currpage < $lastpage) {
02058                 $displaypage = $currpage + 1;
02059 
02060                 if ($this->page == $currpage) {
02061                     $this->pagelinks[] = $displaypage;
02062                 } else {
02063                     $pagelink = html_writer::link(new moodle_url($this->baseurl, array($this->pagevar=>$currpage)), $displaypage);
02064                     $this->pagelinks[] = $pagelink;
02065                 }
02066 
02067                 $displaycount++;
02068                 $currpage++;
02069             }
02070 
02071             if ($currpage < $lastpage) {
02072                 $lastpageactual = $lastpage - 1;
02073                 $this->lastlink = html_writer::link(new moodle_url($this->baseurl, array($this->pagevar=>$lastpageactual)), $lastpage, array('class'=>'last'));
02074             }
02075 
02076             $pagenum = $this->page + 1;
02077 
02078             if ($pagenum != $displaypage) {
02079                 $this->nextlink = html_writer::link(new moodle_url($this->baseurl, array($this->pagevar=>$pagenum)), get_string('next'), array('class'=>'next'));
02080             }
02081         }
02082     }
02083 }
02084 
02085 
02101 class block_contents {
02103     protected static $idcounter = 1;
02104 
02105     const NOT_HIDEABLE = 0;
02106     const VISIBLE = 1;
02107     const HIDDEN = 2;
02108 
02115     public $skipid;
02116 
02121     public $blockinstanceid = 0;
02122 
02128     public $blockpositionid = 0;
02129 
02134     public $attributes;
02135 
02141     public $title = '';
02142 
02146     public $content = '';
02147 
02151     public $footer = '';
02152 
02159     public $annotation = '';
02160 
02165     public $collapsible = self::NOT_HIDEABLE;
02166 
02173     public $controls = array();
02174 
02175 
02180     public function __construct(array $attributes=null) {
02181         $this->skipid = self::$idcounter;
02182         self::$idcounter += 1;
02183 
02184         if ($attributes) {
02185             // standard block
02186             $this->attributes = $attributes;
02187         } else {
02188             // simple "fake" blocks used in some modules and "Add new block" block
02189             $this->attributes = array('class'=>'block');
02190         }
02191     }
02192 
02198     public function add_class($class) {
02199         $this->attributes['class'] .= ' '.$class;
02200     }
02201 }
02202 
02203 
02215 class block_move_target {
02220     public $url;
02225     public $text;
02226 
02232     public function __construct($text, moodle_url $url) {
02233         $this->text = $text;
02234         $this->url  = $url;
02235     }
02236 }
02237 
02248 class custom_menu_item implements renderable {
02253     protected $text;
02258     protected $url;
02263     protected $title;
02268     protected $sort;
02273     protected $parent;
02278     protected $children = array();
02283     protected $lastsort = 0;
02294     public function __construct($text, moodle_url $url=null, $title=null, $sort = null, custom_menu_item $parent=null) {
02295         $this->text = $text;
02296         $this->url = $url;
02297         $this->title = $title;
02298         $this->sort = (int)$sort;
02299         $this->parent = $parent;
02300     }
02301 
02311     public function add($text, moodle_url $url=null, $title=null, $sort = null) {
02312         $key = count($this->children);
02313         if (empty($sort)) {
02314             $sort = $this->lastsort + 1;
02315         }
02316         $this->children[$key] = new custom_menu_item($text, $url, $title, $sort, $this);
02317         $this->lastsort = (int)$sort;
02318         return $this->children[$key];
02319     }
02324     public function get_text() {
02325         return $this->text;
02326     }
02331     public function get_url() {
02332         return $this->url;
02333     }
02338     public function get_title() {
02339         return $this->title;
02340     }
02345     public function get_children() {
02346         $this->sort();
02347         return $this->children;
02348     }
02353     public function get_sort_order() {
02354         return $this->sort;
02355     }
02360     public function get_parent() {
02361         return $this->parent;
02362     }
02366     public function sort() {
02367         usort($this->children, array('custom_menu','sort_custom_menu_items'));
02368     }
02373     public function has_children() {
02374         return (count($this->children) > 0);
02375     }
02376 
02381     public function set_text($text) {
02382         $this->text = (string)$text;
02383     }
02384 
02389     public function set_title($title) {
02390         $this->title = (string)$title;
02391     }
02392 
02397     public function set_url(moodle_url $url) {
02398         $this->url = $url;
02399     }
02400 }
02401 
02416 class custom_menu extends custom_menu_item {
02417 
02419     protected $currentlanguage = null;
02420 
02427     public function __construct($definition = '', $currentlanguage = null) {
02428 
02429         $this->currentlanguage = $currentlanguage;
02430         parent::__construct('root'); // create virtual root element of the menu
02431         if (!empty($definition)) {
02432             $this->override_children(self::convert_text_to_menu_nodes($definition, $currentlanguage));
02433         }
02434     }
02435 
02440     public function override_children(array $children) {
02441         $this->children = array();
02442         foreach ($children as $child) {
02443             if ($child instanceof custom_menu_item) {
02444                 $this->children[] = $child;
02445             }
02446         }
02447     }
02448 
02475     public static function convert_text_to_menu_nodes($text, $language = null) {
02476         $lines = explode("\n", $text);
02477         $children = array();
02478         $lastchild = null;
02479         $lastdepth = null;
02480         $lastsort = 0;
02481         foreach ($lines as $line) {
02482             $line = trim($line);
02483             $bits = explode('|', $line, 4);    // name|url|title|langs
02484             if (!array_key_exists(0, $bits) or empty($bits[0])) {
02485                 // Every item must have a name to be valid
02486                 continue;
02487             } else {
02488                 $bits[0] = ltrim($bits[0],'-');
02489             }
02490             if (!array_key_exists(1, $bits) or empty($bits[1])) {
02491                 // Set the url to null
02492                 $bits[1] = null;
02493             } else {
02494                 // Make sure the url is a moodle url
02495                 $bits[1] = new moodle_url(trim($bits[1]));
02496             }
02497             if (!array_key_exists(2, $bits) or empty($bits[2])) {
02498                 // Set the title to null seeing as there isn't one
02499                 $bits[2] = $bits[0];
02500             }
02501             if (!array_key_exists(3, $bits) or empty($bits[3])) {
02502                 // The item is valid for all languages
02503                 $itemlangs = null;
02504             } else {
02505                 $itemlangs = array_map('trim', explode(',', $bits[3]));
02506             }
02507             if (!empty($language) and !empty($itemlangs)) {
02508                 // check that the item is intended for the current language
02509                 if (!in_array($language, $itemlangs)) {
02510                     continue;
02511                 }
02512             }
02513             // Set an incremental sort order to keep it simple.
02514             $lastsort++;
02515             if (preg_match('/^(\-*)/', $line, $match) && $lastchild != null && $lastdepth !== null) {
02516                 $depth = strlen($match[1]);
02517                 if ($depth < $lastdepth) {
02518                     $difference = $lastdepth - $depth;
02519                     if ($lastdepth > 1 && $lastdepth != $difference) {
02520                         $tempchild = $lastchild->get_parent();
02521                         for ($i =0; $i < $difference; $i++) {
02522                             $tempchild = $tempchild->get_parent();
02523                         }
02524                         $lastchild = $tempchild->add($bits[0], $bits[1], $bits[2], $lastsort);
02525                     } else {
02526                         $depth = 0;
02527                         $lastchild = new custom_menu_item($bits[0], $bits[1], $bits[2], $lastsort);
02528                         $children[] = $lastchild;
02529                     }
02530                 } else if ($depth > $lastdepth) {
02531                     $depth = $lastdepth + 1;
02532                     $lastchild = $lastchild->add($bits[0], $bits[1], $bits[2], $lastsort);
02533                 } else {
02534                     if ($depth == 0) {
02535                         $lastchild = new custom_menu_item($bits[0], $bits[1], $bits[2], $lastsort);
02536                         $children[] = $lastchild;
02537                     } else {
02538                         $lastchild = $lastchild->get_parent()->add($bits[0], $bits[1], $bits[2], $lastsort);
02539                     }
02540                 }
02541             } else {
02542                 $depth = 0;
02543                 $lastchild = new custom_menu_item($bits[0], $bits[1], $bits[2], $lastsort);
02544                 $children[] = $lastchild;
02545             }
02546             $lastdepth = $depth;
02547         }
02548         return $children;
02549     }
02550 
02561     public static function sort_custom_menu_items(custom_menu_item $itema, custom_menu_item $itemb) {
02562         $itema = $itema->get_sort_order();
02563         $itemb = $itemb->get_sort_order();
02564         if ($itema == $itemb) {
02565             return 0;
02566         }
02567         return ($itema > $itemb) ? +1 : -1;
02568     }
02569 }
 All Data Structures Namespaces Files Functions Variables Enumerations