���ѧۧݧ�ӧ�� �ާ֧ߧ֧էا֧� - ���֧էѧܧ�ڧ��ӧѧ�� - /home3/cpr76684/public_html/output.tar
���ѧ٧ѧ�
renderer.php 0000644 00000033405 15152013573 0007072 0 ustar 00 <?php // This file is part of Moodle - http://moodle.org/ // // Moodle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Moodle is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with Moodle. If not, see <http://www.gnu.org/licenses/>. /** * Output rendering for the plugin. * * @package tool_oauth2 * @copyright 2017 Damyon Wiese * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ namespace tool_oauth2\output; use plugin_renderer_base; use html_table; use html_table_cell; use html_table_row; use html_writer; use core\oauth2\issuer; use core\oauth2\api; use moodle_url; defined('MOODLE_INTERNAL') || die(); /** * Implements the plugin renderer * * @copyright 2017 Damyon Wiese * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class renderer extends plugin_renderer_base { /** * This function will render one beautiful table with all the issuers. * * @param \core\oauth2\issuer[] $issuers - list of all issuers. * @return string HTML to output. */ public function issuers_table($issuers) { global $CFG; $table = new html_table(); $table->head = [ get_string('name'), get_string('issuerusedforlogin', 'tool_oauth2'), get_string('logindisplay', 'tool_oauth2'), get_string('issuerusedforinternal', 'tool_oauth2'), get_string('discoverystatus', 'tool_oauth2') . ' ' . $this->help_icon('discovered', 'tool_oauth2'), get_string('systemauthstatus', 'tool_oauth2') . ' ' . $this->help_icon('systemaccountconnected', 'tool_oauth2'), get_string('edit'), ]; $table->attributes['class'] = 'admintable generaltable'; $data = []; $index = 0; foreach ($issuers as $issuer) { // We need to handle the first and last ones specially. $first = false; if ($index == 0) { $first = true; } $last = false; if ($index == count($issuers) - 1) { $last = true; } // Name. $name = $issuer->get('name'); $image = $issuer->get('image'); if ($image) { $name = '<img width="24" height="24" alt="" src="' . s($image) . '"> ' . s($name); } $namecell = new html_table_cell($name); $namecell->header = true; // Login issuer. if ((int)$issuer->get('showonloginpage') == issuer::SERVICEONLY) { $loginissuer = $this->pix_icon('no', get_string('notloginissuer', 'tool_oauth2'), 'tool_oauth2'); $logindisplayas = ''; } else { $logindisplayas = s($issuer->get_display_name()); if ($issuer->get('id') && $issuer->is_configured() && !empty($issuer->get_endpoint_url('userinfo'))) { $loginissuer = $this->pix_icon('yes', get_string('loginissuer', 'tool_oauth2'), 'tool_oauth2'); } else { $loginissuer = $this->pix_icon('notconfigured', get_string('notconfigured', 'tool_oauth2'), 'tool_oauth2'); } } $loginissuerstatuscell = new html_table_cell($loginissuer); // Internal services issuer. if ((int)$issuer->get('showonloginpage') == issuer::LOGINONLY) { $serviceissuer = $this->pix_icon('no', get_string('issuersservicesnotallow', 'tool_oauth2'), 'tool_oauth2'); } else if ($issuer->get('id') && $issuer->is_configured()) { $serviceissuer = $this->pix_icon('yes', get_string('issuersservicesallow', 'tool_oauth2'), 'tool_oauth2'); } else { $serviceissuer = $this->pix_icon('notconfigured', get_string('notconfigured', 'tool_oauth2'), 'tool_oauth2'); } $internalissuerstatuscell = new html_table_cell($serviceissuer); // Discovered. if (!empty($issuer->get('scopessupported'))) { $discovered = $this->pix_icon('yes', get_string('discovered', 'tool_oauth2'), 'tool_oauth2'); } else { if (!empty($issuer->get_endpoint_url('discovery'))) { $discovered = $this->pix_icon('no', get_string('notdiscovered', 'tool_oauth2'), 'tool_oauth2'); } else { $discovered = '-'; } } $discoverystatuscell = new html_table_cell($discovered); // Connected. if ($issuer->is_system_account_connected()) { $systemaccount = \core\oauth2\api::get_system_account($issuer); $systemauth = s($systemaccount->get('email')) . ' (' . s($systemaccount->get('username')). ') '; $systemauth .= $this->pix_icon('yes', get_string('systemaccountconnected', 'tool_oauth2'), 'tool_oauth2'); } else { $systemauth = $this->pix_icon('no', get_string('systemaccountnotconnected', 'tool_oauth2'), 'tool_oauth2'); } $params = ['id' => $issuer->get('id'), 'action' => 'auth']; $authurl = new moodle_url('/admin/tool/oauth2/issuers.php', $params); $icon = $this->pix_icon('auth', get_string('connectsystemaccount', 'tool_oauth2'), 'tool_oauth2'); $authlink = html_writer::link($authurl, $icon); $systemauth .= ' ' . $authlink; $systemauthstatuscell = new html_table_cell($systemauth); $links = ''; // Action links. $editurl = new moodle_url('/admin/tool/oauth2/issuers.php', ['id' => $issuer->get('id'), 'action' => 'edit']); $editlink = html_writer::link($editurl, $this->pix_icon('t/edit', get_string('edit'))); $links .= ' ' . $editlink; // Endpoints. $editendpointsurl = new moodle_url('/admin/tool/oauth2/endpoints.php', ['issuerid' => $issuer->get('id')]); $str = get_string('editendpoints', 'tool_oauth2'); $editendpointlink = html_writer::link($editendpointsurl, $this->pix_icon('t/viewdetails', $str)); $links .= ' ' . $editendpointlink; // User field mapping. $params = ['issuerid' => $issuer->get('id')]; $edituserfieldmappingsurl = new moodle_url('/admin/tool/oauth2/userfieldmappings.php', $params); $str = get_string('edituserfieldmappings', 'tool_oauth2'); $edituserfieldmappinglink = html_writer::link($edituserfieldmappingsurl, $this->pix_icon('t/user', $str)); $links .= ' ' . $edituserfieldmappinglink; // Delete. $deleteurl = new moodle_url('/admin/tool/oauth2/issuers.php', ['id' => $issuer->get('id'), 'action' => 'delete']); $deletelink = html_writer::link($deleteurl, $this->pix_icon('t/delete', get_string('delete'))); $links .= ' ' . $deletelink; // Enable / Disable. if ($issuer->get('enabled')) { // Disable. $disableparams = ['id' => $issuer->get('id'), 'sesskey' => sesskey(), 'action' => 'disable']; $disableurl = new moodle_url('/admin/tool/oauth2/issuers.php', $disableparams); $disablelink = html_writer::link($disableurl, $this->pix_icon('t/hide', get_string('disable'))); $links .= ' ' . $disablelink; } else { // Enable. $enableparams = ['id' => $issuer->get('id'), 'sesskey' => sesskey(), 'action' => 'enable']; $enableurl = new moodle_url('/admin/tool/oauth2/issuers.php', $enableparams); $enablelink = html_writer::link($enableurl, $this->pix_icon('t/show', get_string('enable'))); $links .= ' ' . $enablelink; } if (!$last) { // Move down. $params = ['id' => $issuer->get('id'), 'action' => 'movedown', 'sesskey' => sesskey()]; $movedownurl = new moodle_url('/admin/tool/oauth2/issuers.php', $params); $movedownlink = html_writer::link($movedownurl, $this->pix_icon('t/down', get_string('movedown'))); $links .= ' ' . $movedownlink; } if (!$first) { // Move up. $params = ['id' => $issuer->get('id'), 'action' => 'moveup', 'sesskey' => sesskey()]; $moveupurl = new moodle_url('/admin/tool/oauth2/issuers.php', $params); $moveuplink = html_writer::link($moveupurl, $this->pix_icon('t/up', get_string('moveup'))); $links .= ' ' . $moveuplink; } $editcell = new html_table_cell($links); $row = new html_table_row([ $namecell, $loginissuerstatuscell, $logindisplayas, $internalissuerstatuscell, $discoverystatuscell, $systemauthstatuscell, $editcell, ]); if (!$issuer->get('enabled')) { $row->attributes['class'] = 'dimmed_text'; } $data[] = $row; $index++; } $table->data = $data; return html_writer::table($table); } /** * This function will render one beautiful table with all the endpoints. * * @param \core\oauth2\endpoint[] $endpoints - list of all endpoints. * @param int $issuerid * @return string HTML to output. */ public function endpoints_table($endpoints, $issuerid) { global $CFG; $table = new html_table(); $table->head = [ get_string('name'), get_string('url'), get_string('edit'), ]; $table->attributes['class'] = 'admintable generaltable'; $data = []; $index = 0; foreach ($endpoints as $endpoint) { // Name. $name = $endpoint->get('name'); $namecell = new html_table_cell(s($name)); $namecell->header = true; // Url. $url = $endpoint->get('url'); $urlcell = new html_table_cell(s($url)); $links = ''; // Action links. $editparams = ['issuerid' => $issuerid, 'endpointid' => $endpoint->get('id'), 'action' => 'edit']; $editurl = new moodle_url('/admin/tool/oauth2/endpoints.php', $editparams); $editlink = html_writer::link($editurl, $this->pix_icon('t/edit', get_string('edit'))); $links .= ' ' . $editlink; // Delete. $deleteparams = ['issuerid' => $issuerid, 'endpointid' => $endpoint->get('id'), 'action' => 'delete']; $deleteurl = new moodle_url('/admin/tool/oauth2/endpoints.php', $deleteparams); $deletelink = html_writer::link($deleteurl, $this->pix_icon('t/delete', get_string('delete'))); $links .= ' ' . $deletelink; $editcell = new html_table_cell($links); $row = new html_table_row([ $namecell, $urlcell, $editcell, ]); $data[] = $row; $index++; } $table->data = $data; return html_writer::table($table); } /** * This function will render one beautiful table with all the user_field_mappings. * * @param \core\oauth2\user_field_mapping[] $userfieldmappings - list of all user_field_mappings. * @param int $issuerid * @return string HTML to output. */ public function user_field_mappings_table($userfieldmappings, $issuerid) { global $CFG; $table = new html_table(); $table->head = [ get_string('userfieldexternalfield', 'tool_oauth2'), get_string('userfieldinternalfield', 'tool_oauth2'), get_string('edit'), ]; $table->attributes['class'] = 'admintable generaltable'; $data = []; $index = 0; foreach ($userfieldmappings as $userfieldmapping) { // External field. $externalfield = $userfieldmapping->get('externalfield'); $externalfieldcell = new html_table_cell(s($externalfield)); // Internal field. $internalfield = $userfieldmapping->get('internalfield'); $internalfieldcell = new html_table_cell(s($internalfield)); $links = ''; // Action links. $editparams = ['issuerid' => $issuerid, 'userfieldmappingid' => $userfieldmapping->get('id'), 'action' => 'edit']; $editurl = new moodle_url('/admin/tool/oauth2/userfieldmappings.php', $editparams); $editlink = html_writer::link($editurl, $this->pix_icon('t/edit', get_string('edit'))); $links .= ' ' . $editlink; // Delete. $deleteparams = ['issuerid' => $issuerid, 'userfieldmappingid' => $userfieldmapping->get('id'), 'action' => 'delete']; $deleteurl = new moodle_url('/admin/tool/oauth2/userfieldmappings.php', $deleteparams); $deletelink = html_writer::link($deleteurl, $this->pix_icon('t/delete', get_string('delete'))); $links .= ' ' . $deletelink; $editcell = new html_table_cell($links); $row = new html_table_row([ $externalfieldcell, $internalfieldcell, $editcell, ]); $data[] = $row; $index++; } $table->data = $data; return html_writer::table($table); } } main.php 0000644 00000043251 15152013573 0006210 0 ustar 00 <?php // This file is part of Moodle - http://moodle.org/ // // Moodle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Moodle is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with Moodle. If not, see <http://www.gnu.org/licenses/>. /** * Class containing data for my overview block. * * @package block_myoverview * @copyright 2017 Ryan Wyllie <ryan@moodle.com> * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ namespace block_myoverview\output; defined('MOODLE_INTERNAL') || die(); use renderable; use renderer_base; use templatable; use stdClass; require_once($CFG->dirroot . '/blocks/myoverview/lib.php'); /** * Class containing data for my overview block. * * @copyright 2018 Bas Brands <bas@moodle.com> * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class main implements renderable, templatable { /** * Store the grouping preference. * * @var string String matching the grouping constants defined in myoverview/lib.php */ private $grouping; /** * Store the sort preference. * * @var string String matching the sort constants defined in myoverview/lib.php */ private $sort; /** * Store the view preference. * * @var string String matching the view/display constants defined in myoverview/lib.php */ private $view; /** * Store the paging preference. * * @var string String matching the paging constants defined in myoverview/lib.php */ private $paging; /** * Store the display categories config setting. * * @var boolean */ private $displaycategories; /** * Store the configuration values for the myoverview block. * * @var array Array of available layouts matching view/display constants defined in myoverview/lib.php */ private $layouts; /** * Store a course grouping option setting * * @var boolean */ private $displaygroupingallincludinghidden; /** * Store a course grouping option setting. * * @var boolean */ private $displaygroupingall; /** * Store a course grouping option setting. * * @var boolean */ private $displaygroupinginprogress; /** * Store a course grouping option setting. * * @var boolean */ private $displaygroupingfuture; /** * Store a course grouping option setting. * * @var boolean */ private $displaygroupingpast; /** * Store a course grouping option setting. * * @var boolean */ private $displaygroupingfavourites; /** * Store a course grouping option setting. * * @var boolean */ private $displaygroupinghidden; /** * Store a course grouping option setting. * * @var bool */ private $displaygroupingcustomfield; /** * Store the custom field used by customfield grouping. * * @var string */ private $customfiltergrouping; /** * Store the selected custom field value to group by. * * @var string */ private $customfieldvalue; /** * main constructor. * Initialize the user preferences * * @param string $grouping Grouping user preference * @param string $sort Sort user preference * @param string $view Display user preference * @param int $paging * @param string $customfieldvalue * * @throws \dml_exception */ public function __construct($grouping, $sort, $view, $paging, $customfieldvalue = null) { global $CFG; // Get plugin config. $config = get_config('block_myoverview'); // Build the course grouping option name to check if the given grouping is enabled afterwards. $groupingconfigname = 'displaygrouping'.$grouping; // Check the given grouping and remember it if it is enabled. if ($grouping && $config->$groupingconfigname == true) { $this->grouping = $grouping; // Otherwise fall back to another grouping in a reasonable order. // This is done to prevent one-time UI glitches in the case when a user has chosen a grouping option previously which // was then disabled by the admin in the meantime. } else { $this->grouping = $this->get_fallback_grouping($config); } unset ($groupingconfigname); // Remember which custom field value we were using, if grouping by custom field. $this->customfieldvalue = $customfieldvalue; // Check and remember the given sorting. if ($sort) { $this->sort = $sort; } else if ($CFG->courselistshortnames) { $this->sort = BLOCK_MYOVERVIEW_SORTING_SHORTNAME; } else { $this->sort = BLOCK_MYOVERVIEW_SORTING_TITLE; } // In case sorting remembered is shortname and display extended course names not checked, // we should revert sorting to title. if (!$CFG->courselistshortnames && $sort == BLOCK_MYOVERVIEW_SORTING_SHORTNAME) { $this->sort = BLOCK_MYOVERVIEW_SORTING_TITLE; } // Check and remember the given view. $this->view = $view ? $view : BLOCK_MYOVERVIEW_VIEW_CARD; // Check and remember the given page size, `null` indicates no page size set // while a `0` indicates a paging size of `All`. if (!is_null($paging) && $paging == BLOCK_MYOVERVIEW_PAGING_ALL) { $this->paging = BLOCK_MYOVERVIEW_PAGING_ALL; } else { $this->paging = $paging ? $paging : BLOCK_MYOVERVIEW_PAGING_12; } // Check and remember if the course categories should be shown or not. if (!$config->displaycategories) { $this->displaycategories = BLOCK_MYOVERVIEW_DISPLAY_CATEGORIES_OFF; } else { $this->displaycategories = BLOCK_MYOVERVIEW_DISPLAY_CATEGORIES_ON; } // Get and remember the available layouts. $this->set_available_layouts(); $this->view = $view ? $view : reset($this->layouts); // Check and remember if the particular grouping options should be shown or not. $this->displaygroupingallincludinghidden = $config->displaygroupingallincludinghidden; $this->displaygroupingall = $config->displaygroupingall; $this->displaygroupinginprogress = $config->displaygroupinginprogress; $this->displaygroupingfuture = $config->displaygroupingfuture; $this->displaygroupingpast = $config->displaygroupingpast; $this->displaygroupingfavourites = $config->displaygroupingfavourites; $this->displaygroupinghidden = $config->displaygroupinghidden; $this->displaygroupingcustomfield = ($config->displaygroupingcustomfield && $config->customfiltergrouping); $this->customfiltergrouping = $config->customfiltergrouping; // Check and remember if the grouping selector should be shown at all or not. // It will be shown if more than 1 grouping option is enabled. $displaygroupingselectors = array($this->displaygroupingallincludinghidden, $this->displaygroupingall, $this->displaygroupinginprogress, $this->displaygroupingfuture, $this->displaygroupingpast, $this->displaygroupingfavourites, $this->displaygroupinghidden); $displaygroupingselectorscount = count(array_filter($displaygroupingselectors)); if ($displaygroupingselectorscount > 1 || $this->displaygroupingcustomfield) { $this->displaygroupingselector = true; } else { $this->displaygroupingselector = false; } unset ($displaygroupingselectors, $displaygroupingselectorscount); } /** * Determine the most sensible fallback grouping to use (in cases where the stored selection * is no longer available). * @param object $config * @return string */ private function get_fallback_grouping($config) { if ($config->displaygroupingall == true) { return BLOCK_MYOVERVIEW_GROUPING_ALL; } if ($config->displaygroupingallincludinghidden == true) { return BLOCK_MYOVERVIEW_GROUPING_ALLINCLUDINGHIDDEN; } if ($config->displaygroupinginprogress == true) { return BLOCK_MYOVERVIEW_GROUPING_INPROGRESS; } if ($config->displaygroupingfuture == true) { return BLOCK_MYOVERVIEW_GROUPING_FUTURE; } if ($config->displaygroupingpast == true) { return BLOCK_MYOVERVIEW_GROUPING_PAST; } if ($config->displaygroupingfavourites == true) { return BLOCK_MYOVERVIEW_GROUPING_FAVOURITES; } if ($config->displaygroupinghidden == true) { return BLOCK_MYOVERVIEW_GROUPING_HIDDEN; } if ($config->displaygroupingcustomfield == true) { return BLOCK_MYOVERVIEW_GROUPING_CUSTOMFIELD; } // In this case, no grouping option is enabled and the grouping is not needed at all. // But it's better not to leave $this->grouping unset for any unexpected case. return BLOCK_MYOVERVIEW_GROUPING_ALLINCLUDINGHIDDEN; } /** * Set the available layouts based on the config table settings, * if none are available, defaults to the cards view. * * @throws \dml_exception * */ public function set_available_layouts() { if ($config = get_config('block_myoverview', 'layouts')) { $this->layouts = explode(',', $config); } else { $this->layouts = array(BLOCK_MYOVERVIEW_VIEW_CARD); } } /** * Get the user preferences as an array to figure out what has been selected. * * @return array $preferences Array with the pref as key and value set to true */ public function get_preferences_as_booleans() { $preferences = []; $preferences[$this->sort] = true; $preferences[$this->grouping] = true; // Only use the user view/display preference if it is in available layouts. if (in_array($this->view, $this->layouts)) { $preferences[$this->view] = true; } else { $preferences[reset($this->layouts)] = true; } return $preferences; } /** * Format a layout into an object for export as a Context variable to template. * * @param string $layoutname * * @return \stdClass $layout an object representation of a layout * @throws \coding_exception */ public function format_layout_for_export($layoutname) { $layout = new stdClass(); $layout->id = $layoutname; $layout->name = get_string($layoutname, 'block_myoverview'); $layout->active = $this->view == $layoutname ? true : false; $layout->arialabel = get_string('aria:' . $layoutname, 'block_myoverview'); return $layout; } /** * Get the available layouts formatted for export. * * @return array an array of objects representing available layouts */ public function get_formatted_available_layouts_for_export() { return array_map(array($this, 'format_layout_for_export'), $this->layouts); } /** * Get the list of values to add to the grouping dropdown * @return object[] containing name, value and active fields */ public function get_customfield_values_for_export() { global $DB, $USER; if (!$this->displaygroupingcustomfield) { return []; } $fieldid = $DB->get_field('customfield_field', 'id', ['shortname' => $this->customfiltergrouping]); if (!$fieldid) { return []; } $courses = enrol_get_all_users_courses($USER->id, true); if (!$courses) { return []; } list($csql, $params) = $DB->get_in_or_equal(array_keys($courses), SQL_PARAMS_NAMED); $select = "instanceid $csql AND fieldid = :fieldid"; $params['fieldid'] = $fieldid; $distinctablevalue = $DB->sql_compare_text('value'); $values = $DB->get_records_select_menu('customfield_data', $select, $params, '', "DISTINCT $distinctablevalue, $distinctablevalue AS value2"); \core_collator::asort($values, \core_collator::SORT_NATURAL); $values = array_filter($values); if (!$values) { return []; } $field = \core_customfield\field_controller::create($fieldid); $isvisible = $field->get_configdata_property('visibility') == \core_course\customfield\course_handler::VISIBLETOALL; // Only visible fields to everybody supporting course grouping will be displayed. if (!$field->supports_course_grouping() || !$isvisible) { return []; // The field shouldn't have been selectable in the global settings, but just skip it now. } $values = $field->course_grouping_format_values($values); $customfieldactive = ($this->grouping === BLOCK_MYOVERVIEW_GROUPING_CUSTOMFIELD); $ret = []; foreach ($values as $value => $name) { $ret[] = (object)[ 'name' => $name, 'value' => $value, 'active' => ($customfieldactive && ($this->customfieldvalue == $value)), ]; } return $ret; } /** * Export this data so it can be used as the context for a mustache template. * * @param \renderer_base $output * @return array Context variables for the template * @throws \coding_exception * */ public function export_for_template(renderer_base $output) { global $CFG, $USER; $nocoursesurl = $output->image_url('courses', 'block_myoverview')->out(); $newcourseurl = ''; $coursecat = \core_course_category::user_top(); if ($coursecat && ($category = \core_course_category::get_nearest_editable_subcategory($coursecat, ['create']))) { $newcourseurl = new \moodle_url('/course/edit.php', ['category' => $category->id]); } $customfieldvalues = $this->get_customfield_values_for_export(); $selectedcustomfield = ''; if ($this->grouping == BLOCK_MYOVERVIEW_GROUPING_CUSTOMFIELD) { foreach ($customfieldvalues as $field) { if ($field->value == $this->customfieldvalue) { $selectedcustomfield = $field->name; break; } } // If the selected custom field value has not been found (possibly because the field has // been changed in the settings) find a suitable fallback. if (!$selectedcustomfield) { $this->grouping = $this->get_fallback_grouping(get_config('block_myoverview')); if ($this->grouping == BLOCK_MYOVERVIEW_GROUPING_CUSTOMFIELD) { // If the fallback grouping is still customfield, then select the first field. $firstfield = reset($customfieldvalues); if ($firstfield) { $selectedcustomfield = $firstfield->name; $this->customfieldvalue = $firstfield->value; } } } } $preferences = $this->get_preferences_as_booleans(); $availablelayouts = $this->get_formatted_available_layouts_for_export(); $sort = ''; if ($this->sort == BLOCK_MYOVERVIEW_SORTING_SHORTNAME) { $sort = 'shortname'; } else { $sort = $this->sort == BLOCK_MYOVERVIEW_SORTING_TITLE ? 'fullname' : 'ul.timeaccess desc'; } $defaultvariables = [ 'totalcoursecount' => count(enrol_get_all_users_courses($USER->id, true)), 'nocoursesimg' => $nocoursesurl, 'newcourseurl' => $newcourseurl, 'grouping' => $this->grouping, 'sort' => $sort, // If the user preference display option is not available, default to first available layout. 'view' => in_array($this->view, $this->layouts) ? $this->view : reset($this->layouts), 'paging' => $this->paging, 'layouts' => $availablelayouts, 'displaycategories' => $this->displaycategories, 'displaydropdown' => (count($availablelayouts) > 1) ? true : false, 'displaygroupingallincludinghidden' => $this->displaygroupingallincludinghidden, 'displaygroupingall' => $this->displaygroupingall, 'displaygroupinginprogress' => $this->displaygroupinginprogress, 'displaygroupingfuture' => $this->displaygroupingfuture, 'displaygroupingpast' => $this->displaygroupingpast, 'displaygroupingfavourites' => $this->displaygroupingfavourites, 'displaygroupinghidden' => $this->displaygroupinghidden, 'displaygroupingselector' => $this->displaygroupingselector, 'displaygroupingcustomfield' => $this->displaygroupingcustomfield && $customfieldvalues, 'customfieldname' => $this->customfiltergrouping, 'customfieldvalue' => $this->customfieldvalue, 'customfieldvalues' => $customfieldvalues, 'selectedcustomfield' => $selectedcustomfield, 'showsortbyshortname' => $CFG->courselistshortnames, ]; return array_merge($defaultvariables, $preferences); } } main_action_menu.php 0000644 00000011624 15152036112 0010562 0 ustar 00 <?php // This file is part of Moodle - http://moodle.org/ // // Moodle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Moodle is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with Moodle. If not, see <http://www.gnu.org/licenses/>. /** * Output the action menu for this activity. * * @package mod_book * @copyright 2021 Adrian Greeve <adrian@moodle.com> * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ namespace mod_book\output; use templatable; use renderable; use moodle_url; use stdClass; /** * Output the action menu for the book activity. * * @package mod_book * @copyright 2021 Adrian Greeve <adrian@moodle.com> * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class main_action_menu implements templatable, renderable { /** @var int The course module ID. */ protected $cmid; /** @var stdClass[] Chapters of the book. */ protected $chapters; /** @var stdClass Current chapter of the book. */ protected $chapter; /** * Constructor for this class. * * @param int $cmid The course module ID. * @param array $chapters Chapters of this book. * @param stdClass $chapter The current chapter. */ public function __construct(int $cmid, array $chapters, stdClass $chapter) { $this->cmid = $cmid; $this->chapters = $chapters; $this->chapter = $chapter; } /** * Get the next chapter in the book. * * @return ?stdClass The next chapter of the book. */ protected function get_next_chapter(): ?stdClass { $nextpageid = $this->chapter->pagenum + 1; // Early return if the current chapter is also the last chapter. if ($nextpageid > count($this->chapters)) { return null; } while ((!$nextchapter = $this->get_chapter($nextpageid))) { // Break the loop if this is the last chapter. if ($nextpageid === count($this->chapters)) { break; } $nextpageid++; } return $nextchapter; } /** * Get the previous chapter in the book. * * @return ?stdClass The previous chapter of the book. */ protected function get_previous_chapter(): ?stdClass { $prevpageid = $this->chapter->pagenum - 1; // Early return if the current chapter is also the first chapter. if ($prevpageid < 1) { return null; } while ((!$prevchapter = $this->get_chapter($prevpageid))) { // Break the loop if this is the first chapter. if ($prevpageid === 1) { break; } $prevpageid--; } return $prevchapter; } /** * Get the specific chapter of the book. * * @param int $id The chapter id to retrieve. * @return ?stdClass The requested chapter. */ protected function get_chapter(int $id): ?stdClass { $context = \context_module::instance($this->cmid); $viewhidden = has_capability('mod/book:viewhiddenchapters', $context); foreach ($this->chapters as $chapter) { // Also make sure that the chapter is not hidden or the user can view hidden chapters before returning // the chapter object. if (($chapter->pagenum == $id) && (!$chapter->hidden || $viewhidden)) { return $chapter; } } return null; } /** * Exports the navigation buttons around the book. * * @param \renderer_base $output renderer base output. * @return array Data to render. */ public function export_for_template(\renderer_base $output): array { $next = $this->get_next_chapter(); $previous = $this->get_previous_chapter(); $context = \context_module::instance($this->cmid); $data = []; if ($next) { $nextdata = [ 'title' => get_string('navnext', 'mod_book'), 'url' => (new moodle_url('/mod/book/view.php', ['id' => $this->cmid, 'chapterid' => $next->id]))->out(false) ]; $data['next'] = $nextdata; } if ($previous) { $previousdata = [ 'title' => get_string('navprev', 'mod_book'), 'url' => (new moodle_url('/mod/book/view.php', ['id' => $this->cmid, 'chapterid' => $previous->id]))->out(false) ]; $data['previous'] = $previousdata; } return $data; } } langimport_page.php 0000644 00000007776 15152167464 0010461 0 ustar 00 <?php // This file is part of Moodle - http://moodle.org/ // // Moodle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Moodle is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with Moodle. If not, see <http://www.gnu.org/licenses/>. /** * Language import page. * * @package tool_langimport * @copyright 2016 Jun Pataleta * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ namespace tool_langimport\output; use core_collator; use moodle_url; use renderable; use renderer_base; use stdClass; use templatable; /** * Language import page class. * * @package tool_langimport * @copyright 2016 Jun Pataleta * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class langimport_page implements renderable, templatable { /** @var array Array of currently installed languages. */ protected $installedlanguages; /** @var array Array of languages that can be installed. */ protected $availablelanguages; /** @var moodle_url The URL to be used for uninstalling the selected existing language packs. */ protected $uninstallurl; /** @var moodle_url The URL to be used for updating the installed language packs. */ protected $updateurl; /** @var moodle_url The URL to be used for installing the selected language packs to be installed. */ protected $installurl; /** * langimport_page constructor. * * @param array $installedlanguages Array of currently installed languages. * @param array $availablelanguages Array of languages that can be installed. * @param moodle_url $uninstallurl The URL to be used for uninstalling the selected existing language packs. * @param moodle_url $updateurl The URL to be used for updating the installed language packs. * @param moodle_url $installurl The URL to be used for installing the selected language packs to be installed. */ public function __construct($installedlanguages, $availablelanguages, $uninstallurl, $updateurl, $installurl) { $this->installedlanguages = $installedlanguages; $this->availablelanguages = $availablelanguages; $this->uninstallurl = $uninstallurl; $this->updateurl = $updateurl; $this->installurl = $installurl; } /** * Export the data. * * @param renderer_base $output * @return stdClass */ public function export_for_template(renderer_base $output) { $data = new stdClass(); $data->uninstallurl = $this->uninstallurl; $data->sesskey = sesskey(); $data->installedoptions = []; foreach ($this->installedlanguages as $code => $language) { $option = new stdClass(); $option->value = $code; $option->text = $language; $data->installedoptions[] = $option; } $data->updateurl = $this->updateurl; if (!empty($this->availablelanguages)) { $data->toinstalloptions = []; core_collator::asort($this->availablelanguages); foreach ($this->availablelanguages as $code => $language) { $option = new stdClass(); $option->value = $code; $option->text = $language; $data->toinstalloptions[] = $option; } $data->installurl = $this->installurl; $data->caninstall = true; } if (count($this->installedlanguages) > 3) { $data->hasmanyinstalledlanguages = true; $data->updatelangstaskname = get_string('updatelangs', 'tool_langimport'); } return $data; } } mustache_quote_helper_test.php 0000644 00000005640 15152171463 0012713 0 ustar 00 <?php // This file is part of Moodle - http://moodle.org/ // // Moodle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Moodle is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with Moodle. If not, see <http://www.gnu.org/licenses/>. declare(strict_types=1); namespace core\output; /** * Unit tests for the mustache_quote_helper class. * * @package core * @category test * @copyright 2022 TU Berlin * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @coversDefaultClass \core\output\mustache_quote_helper */ class mustache_quote_helper_test extends \basic_testcase { /** * Tests the quote helper * * @covers ::quote */ public function test_quote() { $engine = new \Mustache_Engine(); $context = new \Mustache_Context([ 'world' => '{{planet}}', 'planet' => '<earth>' ]); $lambdahelper = new \Mustache_LambdaHelper($engine, $context); $quotehelper = new mustache_quote_helper(); // Simple string. $this->assertEquals('"Hello world!"', $quotehelper->quote('Hello world!', $lambdahelper)); // Special JSON characters in string. $this->assertEquals( '"Hello \\"world\\"! (\\b,\\f,\\n,\\r,\\t,\\\\)"', $quotehelper->quote('Hello "world"! (' . chr(8) . ",\f,\n,\r,\t,\\)", $lambdahelper) ); // Double curly braces in string. $this->assertEquals( '"Hello {{=<% %>=}}{{<%={{ }}=%>world{{=<% %>=}}}}<%={{ }}=%>!"', $quotehelper->quote('{{=<% %>=}}Hello {{world}}!<%={{ }}=%>', $lambdahelper) ); // Triple curly braces in string. $this->assertEquals( '"Hello {{=<% %>=}}{{{<%={{ }}=%>world{{=<% %>=}}}}}<%={{ }}=%>!"', $quotehelper->quote('{{=<% %>=}}Hello {{{world}}}!<%={{ }}=%>', $lambdahelper) ); // Variable interpolation with double braces. $this->assertEquals( '"Hello <earth>!"', $quotehelper->quote('Hello {{planet}}!', $lambdahelper) ); // Variable interpolation with triple braces. $this->assertEquals( '"Hello <earth>!"', $quotehelper->quote('Hello {{{planet}}}!', $lambdahelper) ); // Variables interpolated only once. $this->assertEquals( '"Hello {{=<% %>=}}{{<%={{ }}=%>planet{{=<% %>=}}}}<%={{ }}=%>!"', $quotehelper->quote('Hello {{world}}!', $lambdahelper) ); } } mustache_helper_collection_test.php 0000644 00000020025 15152171463 0013703 0 ustar 00 <?php // This file is part of Moodle - http://moodle.org/ // // Moodle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Moodle is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with Moodle. If not, see <http://www.gnu.org/licenses/>. namespace core\output; /** * Unit tests for the mustache_helper_collection class. * * @package core * @copyright 2019 Ryan Wyllie <ryan@moodle.com> * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @covers \core\output\mustache_helper_collection */ class mustache_helper_collection_test extends \advanced_testcase { /** * Test cases to confirm that disallowed helpers are stripped from the source * text by the helper before being passed to other another helper. This prevents * nested calls to helpers. */ public function get_strip_disallowed_helpers_testcases() { return [ 'no disallowed' => [ 'disallowed' => [], 'input' => 'core, move, {{#js}} some nasty JS {{/js}}', 'expected' => 'core, move, {{#js}} some nasty JS {{/js}}' ], 'disallowed no match' => [ 'disallowed' => ['foo'], 'input' => 'core, move, {{#js}} some nasty JS {{/js}}', 'expected' => 'core, move, {{#js}} some nasty JS {{/js}}' ], 'disallowed partial match 1' => [ 'disallowed' => ['js'], 'input' => 'core, move, {{#json}} some nasty JS {{/json}}', 'expected' => 'core, move, {{#json}} some nasty JS {{/json}}' ], 'disallowed partial match 2' => [ 'disallowed' => ['js'], 'input' => 'core, move, {{#onjs}} some nasty JS {{/onjs}}', 'expected' => 'core, move, {{#onjs}} some nasty JS {{/onjs}}' ], 'single disallowed 1' => [ 'disallowed' => ['js'], 'input' => 'core, move, {{#js}} some nasty JS {{/js}}', 'expected' => 'core, move, {{}}' ], 'single disallowed 2' => [ 'disallowed' => ['js'], 'input' => 'core, move, {{ # js }} some nasty JS {{ / js }}', 'expected' => 'core, move, {{}}' ], 'single disallowed 3' => [ 'disallowed' => ['js'], 'input' => 'core, {{#js}} some nasty JS {{/js}}, test', 'expected' => 'core, {{}}, test' ], 'single disallowed 4' => [ 'disallowed' => ['js'], 'input' => 'core, {{#ok}} this is ok {{/ok}}, {{#js}} some nasty JS {{/js}}', 'expected' => 'core, {{#ok}} this is ok {{/ok}}, {{}}' ], 'single disallowed multiple matches 1' => [ 'disallowed' => ['js'], 'input' => 'core, {{#js}} some nasty JS {{/js}}, {{#js}} some nasty JS {{/js}}', 'expected' => 'core, {{}}' ], 'single disallowed multiple matches 2' => [ 'disallowed' => ['js'], 'input' => 'core, {{ # js }} some nasty JS {{ / js }}, {{ # js }} some nasty JS {{ / js }}', 'expected' => 'core, {{}}' ], 'single disallowed multiple matches nested 1' => [ 'disallowed' => ['js'], 'input' => 'core, move, {{#js}} some nasty JS {{#js}} some nasty JS {{/js}} {{/js}}', 'expected' => 'core, move, {{}}' ], 'single disallowed multiple matches nested 2' => [ 'disallowed' => ['js'], 'input' => 'core, move, {{ # js }} some nasty JS {{ # js }} some nasty JS {{ / js }}{{ / js }}', 'expected' => 'core, move, {{}}' ], 'multiple disallowed 1' => [ 'disallowed' => ['js', 'foo'], 'input' => 'core, move, {{#js}} some nasty JS {{/js}}', 'expected' => 'core, move, {{}}' ], 'multiple disallowed 2' => [ 'disallowed' => ['js', 'foo'], 'input' => 'core, {{#foo}} blah {{/foo}}, {{#js}} js {{/js}}', 'expected' => 'core, {{}}, {{}}' ], 'multiple disallowed 3' => [ 'disallowed' => ['js', 'foo'], 'input' => '{{#foo}} blah {{/foo}}, {{#foo}} blah {{/foo}}, {{#js}} js {{/js}}', 'expected' => '{{}}, {{}}' ], 'multiple disallowed 4' => [ 'disallowed' => ['js', 'foo'], 'input' => '{{#foo}} blah {{/foo}}, {{#js}} js {{/js}}, {{#foo}} blah {{/foo}}', 'expected' => '{{}}' ], 'multiple disallowed 5' => [ 'disallowed' => ['js', 'foo'], 'input' => 'core, move, {{#js}} JS {{#foo}} blah {{/foo}} {{/js}}', 'expected' => 'core, move, {{}}' ], ]; } /** * Test that the mustache_helper_collection class correctly strips * @dataProvider get_strip_disallowed_helpers_testcases() * @param string[] $disallowed The list of helpers to strip * @param string $input The input string for the helper * @param string $expected The expected output of the string after disallowed strip */ public function test_strip_disallowed_helpers($disallowed, $input, $expected) { $collection = new mustache_helper_collection(null, $disallowed); $this->assertEquals($expected, $collection->strip_disallowed_helpers($disallowed, $input)); } /** * Test that the disallowed helpers are disabled during the execution of other * helpers. * * Any allowed helper should still be available to call during the * execution of a helper. */ public function test_disallowed_helpers_disabled_during_execution() { $engine = new \Mustache_Engine(); $context = new \Mustache_Context(); $lambdahelper = new \Mustache_LambdaHelper($engine, $context); $disallowed = ['bad']; $collection = new mustache_helper_collection(null, $disallowed); $badcalled = false; $goodcalled = false; $badhelper = function() use (&$badcalled) { $badcalled = true; return ''; }; $goodhelper = function() use (&$goodcalled) { $goodcalled = true; return ''; }; // A test helper that just returns the text without modifying it. $testhelper = function($text, $lambda) use ($collection) { $collection->get('good')($text, $lambda); $collection->get('bad')($text, $lambda); return $text; }; $collection->add('bad', $badhelper); $collection->add('good', $goodhelper); $collection->add('test', $testhelper); $this->assertEquals('success output', $collection->get('test')('success output', $lambdahelper)); $this->assertTrue($goodcalled); $this->assertFalse($badcalled); } /** * Test that calling deprecated method strip_blacklisted_helpers() still works and shows developer debugging. */ public function test_deprecated_strip_blacklisted_helpers() { $collection = new mustache_helper_collection(null, ['js']); $stripped = $collection->strip_blacklisted_helpers(['js'], '{{#js}} JS {{/js}}'); $this->assertEquals('{{}}', $stripped); $this->assertDebuggingCalled('mustache_helper_collection::strip_blacklisted_helpers() is deprecated. ' . 'Please use mustache_helper_collection::strip_disallowed_helpers() instead.', DEBUG_DEVELOPER); } } activity_header_test.php 0000644 00000010405 15152171463 0011465 0 ustar 00 <?php // This file is part of Moodle - http://moodle.org/ // // Moodle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Moodle is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with Moodle. If not, see <http://www.gnu.org/licenses/>. namespace core\output; /** * Unit tests for activity header * * @package core * @category test * @coversDefaultClass \core\output\activity_header * @copyright 2021 Peter * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class activity_header_test extends \advanced_testcase { /** * Test the title setter * * @dataProvider set_title_provider * @param string $value * @param string $expected * @covers ::set_title */ public function test_set_title(string $value, string $expected): void { global $PAGE, $DB; $this->resetAfterTest(); $course = $this->getDataGenerator()->create_course(['enablecompletion' => true]); $assign = $this->getDataGenerator()->create_module('assign', [ 'course' => $course->id, 'completion' => COMPLETION_TRACKING_AUTOMATIC, 'completionview' => 1 ]); $this->setAdminUser(); $cm = $DB->get_record('course_modules', ['id' => $assign->cmid]); $PAGE->set_cm($cm); $PAGE->set_activity_record($assign); $header = $PAGE->activityheader; $header->set_title($value); $data = $header->export_for_template($PAGE->get_renderer('core')); $this->assertEquals($expected, $data['title']); } /** * Provider for the test_set_title unit test. * @return array */ public function set_title_provider(): array { return [ "Set the title with a plain text" => [ "Activity title", "Activity title" ], "Set the title with a string with standard header tags" => [ "<h2>Activity title</h2>", "Activity title" ], "Set the title with a string with multiple header content" => [ "<h2 id='heading'>Activity title</h2><h2>Header 2</h2>", "Activity title</h2><h2>Header 2" ], ]; } /** * Test setting multiple attributes * * @covers ::set_attrs */ public function test_set_attrs(): void { global $DB, $PAGE; $this->resetAfterTest(); $course = $this->getDataGenerator()->create_course(['enablecompletion' => true]); $assign = $this->getDataGenerator()->create_module('assign', [ 'course' => $course->id, 'completion' => COMPLETION_TRACKING_AUTOMATIC, 'completionview' => 1 ]); $cm = $DB->get_record('course_modules', ['id' => $assign->cmid]); $PAGE->set_cm($cm); $PAGE->set_activity_record($assign); $PAGE->activityheader->set_attrs([ 'hidecompletion' => true, 'additionalnavitems' => new \url_select([]), 'hideoverflow' => true, 'title' => 'My title', 'description' => 'My description', ]); $renderer = $PAGE->get_renderer('core'); $export = $PAGE->activityheader->export_for_template($renderer); $this->assertEquals('My title', $export['title']); $this->assertEquals('My description', $export['description']); $this->assertEmpty($export['completion']); // Because hidecompletion = true. $this->assertEmpty($export['additional_items']); // Because hideoverflow = true. } /** * Test calling set_attrs with an invalid variable name * * @covers ::set_attrs */ public function test_set_attrs_invalid_variable(): void { global $PAGE; $PAGE->activityheader->set_attrs(['unknown' => true]); $this->assertDebuggingCalledCount(1, ['Invalid class member variable: unknown']); } } mustache_template_source_loader_test.php 0000644 00000043467 15152171463 0014751 0 ustar 00 <?php // This file is part of Moodle - http://moodle.org/ // // Moodle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Moodle is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with Moodle. If not, see <http://www.gnu.org/licenses/>. namespace core\output; /** * Unit tests for the Mustache source loader class. * * Unit tests for lib/classes/output/mustache_template_source_loader.php * * @package core * @copyright 2018 Ryan Wyllie <ryan@moodle.com> * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class mustache_template_source_loader_test extends \advanced_testcase { /** * Ensure that stripping comments from templates does not mutilate the template body. */ public function test_strip_template_comments() { $templatebody = <<<'TBD' <h1>{{# str }} pluginname, mod_lemmings {{/ str }}</h1> <div>{{test}}</div> <div>{{{unescapedtest}}}</div> {{#lemmings}} <div> <h2>{{name}}</h2> {{> mod_lemmings/lemmingprofile }} {{# pix }} t/edit, core, Edit Lemming {{/ pix }} </div> {{/lemmings}} {{^lemmings}}Sorry, no lemmings today{{/lemmings}} <div id="{{ uniqid }}-tab-container"> {{# tabheader }} <ul role="tablist" class="nav nav-tabs"> {{# iconlist }} {{# icons }} {{> core/pix_icon }} {{/ icons }} {{/ iconlist }} </ul> {{/ tabheader }} {{# tabbody }} <div class="tab-content"> {{# tabcontent }} {{# tabs }} {{> core/notification_info}} {{/ tabs }} {{/ tabcontent }} </div> {{/ tabbody }} </div> {{#js}} require(['jquery','core/tabs'], function($, tabs) { var container = $("#{{ uniqid }}-tab-container"); tabs.create(container); }); {{/js}} TBD; $templatewithcomment = <<<TBC {{! This file is part of Moodle - http://moodle.org/ Moodle is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Moodle is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Moodle. If not, see <http://www.gnu.org/licenses/>. }} {{! @template mod_lemmings/lemmings Lemmings template. The purpose of this template is to render a lot of lemmings. Classes required for JS: * none Data attributes required for JS: * none Context variables required for this template: * attributes Array of name / value pairs. Example context (json): { "lemmings": [ { "name": "Lemmy Winks", "age" : 1, "size" : "big" }, { "name": "Rocky", "age" : 2, "size" : "small" } ] } }} $templatebody {{! Here's some more comment text Note, there is no need to test bracketed variables inside comments as gherkin does not support that! See this issue: https://github.com/mustache/spec/issues/8 }} TBC; $loader = new mustache_template_source_loader(); $actual = \phpunit_util::call_internal_method( $loader, 'strip_template_comments', [$templatewithcomment], \core\output\mustache_template_source_loader::class ); $this->assertEquals(trim($templatebody), trim($actual)); } /** * Data provider for the test_load function. */ public function load_test_cases() { $cache = [ 'core' => [ 'test' => '{{! a comment }}The rest of the template' ] ]; $loader = $this->build_loader_from_static_cache($cache); return [ 'with comments' => [ 'loader' => $loader, 'component' => 'core', 'name' => 'test', 'includecomments' => true, 'expected' => '{{! a comment }}The rest of the template' ], 'without comments' => [ 'loader' => $loader, 'component' => 'core', 'name' => 'test', 'includecomments' => false, 'expected' => 'The rest of the template' ], ]; } /** * Test the load function. * * @dataProvider load_test_cases * @param mustache_template_source_loader $loader The loader * @param string $component The moodle component * @param string $name The template name * @param bool $includecomments Whether to strip comments * @param string $expected The expected output */ public function test_load($loader, $component, $name, $includecomments, $expected) { $this->assertEquals($expected, $loader->load($component, $name, 'boost', $includecomments)); } /** * Data provider for the load_with_dependencies function. */ public function load_with_dependencies_test_cases() { // Create a bunch of templates that include one another in various ways. There is // multiple instances of recursive inclusions to test that the code doensn't get // stuck in an infinite loop. $foo = '{{! a comment }}{{> core/bar }}{{< test/bop }}{{/ test/bop}}{{#str}} help, core {{/str}}'; $foo2 = '{{! a comment }}hello'; $bar = '{{! a comment }}{{> core/baz }}'; $baz = '{{! a comment }}{{#str}} hide, core {{/str}}'; $bop = '{{! a comment }}{{< test/bim }}{{/ test/bim }}{{> core/foo }}'; $bim = '{{! a comment }}{{< core/foo }}{{/ core/foo}}{{> test/foo }}'; $foonocomment = '{{> core/bar }}{{< test/bop }}{{/ test/bop}}{{#str}} help, core {{/str}}'; $foo2nocomment = 'hello'; $barnocomment = '{{> core/baz }}'; $baznocomment = '{{#str}} hide, core {{/str}}'; $bopnocomment = '{{< test/bim }}{{/ test/bim }}{{> core/foo }}'; $bimnocomment = '{{< core/foo }}{{/ core/foo}}{{> test/foo }}'; $cache = [ 'core' => [ 'foo' => $foo, 'bar' => $bar, 'baz' => $baz, ], 'test' => [ 'foo' => $foo2, 'bop' => $bop, 'bim' => $bim ] ]; $loader = $this->build_loader_from_static_cache($cache); return [ 'no template includes w comments' => [ 'loader' => $loader, 'component' => 'test', 'name' => 'foo', 'includecomments' => true, 'expected' => [ 'templates' => [ 'test' => [ 'foo' => $foo2 ] ], 'strings' => [] ] ], 'no template includes w/o comments' => [ 'loader' => $loader, 'component' => 'test', 'name' => 'foo', 'includecomments' => false, 'expected' => [ 'templates' => [ 'test' => [ 'foo' => $foo2nocomment ] ], 'strings' => [] ] ], 'no template includes with string w comments' => [ 'loader' => $loader, 'component' => 'core', 'name' => 'baz', 'includecomments' => true, 'expected' => [ 'templates' => [ 'core' => [ 'baz' => $baz ] ], 'strings' => [ 'core' => [ 'hide' => 'Hide' ] ] ] ], 'no template includes with string w/o comments' => [ 'loader' => $loader, 'component' => 'core', 'name' => 'baz', 'includecomments' => false, 'expected' => [ 'templates' => [ 'core' => [ 'baz' => $baznocomment ] ], 'strings' => [ 'core' => [ 'hide' => 'Hide' ] ] ] ], 'full with comments' => [ 'loader' => $loader, 'component' => 'core', 'name' => 'foo', 'includecomments' => true, 'expected' => [ 'templates' => [ 'core' => [ 'foo' => $foo, 'bar' => $bar, 'baz' => $baz ], 'test' => [ 'foo' => $foo2, 'bop' => $bop, 'bim' => $bim ] ], 'strings' => [ 'core' => [ 'help' => 'Help', 'hide' => 'Hide' ] ] ] ], 'full without comments' => [ 'loader' => $loader, 'component' => 'core', 'name' => 'foo', 'includecomments' => false, 'expected' => [ 'templates' => [ 'core' => [ 'foo' => $foonocomment, 'bar' => $barnocomment, 'baz' => $baznocomment ], 'test' => [ 'foo' => $foo2nocomment, 'bop' => $bopnocomment, 'bim' => $bimnocomment ] ], 'strings' => [ 'core' => [ 'help' => 'Help', 'hide' => 'Hide' ] ] ] ] ]; } /** * Test the load_with_dependencies function. * * @dataProvider load_with_dependencies_test_cases * @param mustache_template_source_loader $loader The loader * @param string $component The moodle component * @param string $name The template name * @param bool $includecomments Whether to strip comments * @param string $expected The expected output */ public function test_load_with_dependencies($loader, $component, $name, $includecomments, $expected) { $actual = $loader->load_with_dependencies($component, $name, 'boost', $includecomments); $this->assertEquals($expected, $actual); } /** * Data provider for the test_load function. */ public function scan_template_source_for_dependencies_test_cases() { $foo = '{{! a comment }}{{> core/bar }}{{< test/bop }}{{/ test/bop}}{{#str}} help, core {{/str}}'; $bar = '{{! a comment }}{{> core/baz }}'; $baz = '{{! a comment }}{{#str}} hide, core {{/str}}'; $bop = '{{! a comment }}hello'; $multiline1 = <<<TEMPLATE {{! a comment }}{{#str}} authorreplyingprivatelytoauthor, mod_forum {{/str}} TEMPLATE; $multiline2 = <<<TEMPLATE {{! a comment }}{{#str}} authorreplyingprivatelytoauthor, mod_forum {{/str}} TEMPLATE; $multiline3 = <<<TEMPLATE {{! a comment }}{{#str}} authorreplyingprivatelytoauthor, mod_forum {{/str}} TEMPLATE; $multiline4 = <<<TEMPLATE {{! a comment }}{{#str}} authorreplyingprivatelytoauthor, mod_forum {{/str}} TEMPLATE; $multiline5 = <<<TEMPLATE {{! a comment }}{{#str}} hide {{/str}} TEMPLATE; $cache = [ 'core' => [ 'foo' => $foo, 'bar' => $bar, 'baz' => $baz, 'bop' => $bop, 'multiline1' => $multiline1, 'multiline2' => $multiline2, 'multiline3' => $multiline3, 'multiline4' => $multiline4, 'multiline5' => $multiline5, ] ]; $loader = $this->build_loader_from_static_cache($cache); return [ 'single template include' => [ 'loader' => $loader, 'source' => $bar, 'expected' => [ 'templates' => [ 'core' => ['baz'] ], 'strings' => [] ] ], 'single string include' => [ 'loader' => $loader, 'source' => $baz, 'expected' => [ 'templates' => [], 'strings' => [ 'core' => ['hide'] ] ] ], 'no include' => [ 'loader' => $loader, 'source' => $bop, 'expected' => [ 'templates' => [], 'strings' => [] ] ], 'all include' => [ 'loader' => $loader, 'source' => $foo, 'expected' => [ 'templates' => [ 'core' => ['bar'], 'test' => ['bop'] ], 'strings' => [ 'core' => ['help'] ] ] ], 'string: component on new line' => [ 'loader' => $loader, 'source' => $multiline1, 'expected' => [ 'templates' => [], 'strings' => [ 'mod_forum' => ['authorreplyingprivatelytoauthor'] ] ] ], 'string: identifier on own line' => [ 'loader' => $loader, 'source' => $multiline2, 'expected' => [ 'templates' => [], 'strings' => [ 'mod_forum' => ['authorreplyingprivatelytoauthor'] ] ] ], 'string: all parts on new lines' => [ 'loader' => $loader, 'source' => $multiline3, 'expected' => [ 'templates' => [], 'strings' => [ 'mod_forum' => ['authorreplyingprivatelytoauthor'] ] ] ], 'string: id and component on own line' => [ 'loader' => $loader, 'source' => $multiline4, 'expected' => [ 'templates' => [], 'strings' => [ 'mod_forum' => ['authorreplyingprivatelytoauthor'] ] ] ], 'string: no component' => [ 'loader' => $loader, 'source' => $multiline5, 'expected' => [ 'templates' => [], 'strings' => [ 'core' => ['hide'] ] ] ], ]; } /** * Test the scan_template_source_for_dependencies function. * * @dataProvider scan_template_source_for_dependencies_test_cases() * @param mustache_template_source_loader $loader The loader * @param string $source The template to test * @param string $expected The expected output */ public function test_scan_template_source_for_dependencies($loader, $source, $expected) { $actual = \phpunit_util::call_internal_method( $loader, 'scan_template_source_for_dependencies', [$source], \core\output\mustache_template_source_loader::class ); $this->assertEquals($expected, $actual); } /** * Create an instance of mustache_template_source_loader which loads its templates * from the given cache rather than disk. * * @param array $cache A cache of templates * @return mustache_template_source_loader */ private function build_loader_from_static_cache(array $cache) : mustache_template_source_loader { return new mustache_template_source_loader(function($component, $name, $themename) use ($cache) { return $cache[$component][$name]; }); } } mustache_template_finder_test.php 0000644 00000016510 15152171463 0013357 0 ustar 00 <?php // This file is part of Moodle - http://moodle.org/ // // Moodle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Moodle is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with Moodle. If not, see <http://www.gnu.org/licenses/>. namespace core\output; /** * Unit tests for lib/classes/output/mustache_template_finder.php * * Unit tests for the Mustache template finder class (contains logic about * resolving mustache template locations. * * @package core * @category test * @copyright 2015 Damyon Wiese * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class mustache_template_finder_test extends \advanced_testcase { /** * Data provider which reutrns a set of valid template directories to be used when testing * get_template_directories_for_component. * * @return array */ public function valid_template_directories_provider(): array { return [ 'plugin: mod_assign' => [ 'component' => 'mod_assign', 'theme' => '', 'paths' => [ 'theme/boost/templates/mod_assign/', 'mod/assign/templates/' ], ], 'plugin: mod_assign with classic' => [ 'component' => 'mod_assign', 'theme' => 'classic', 'paths' => [ 'theme/classic/templates/mod_assign/', 'theme/boost/templates/mod_assign/', 'mod/assign/templates/' ], ], 'subsystem: core_user' => [ 'component' => 'core_user', 'theme' => 'classic', 'paths' => [ 'theme/classic/templates/core_user/', 'theme/boost/templates/core_user/', 'user/templates/' ], ], 'core' => [ 'component' => 'core', 'theme' => 'classic', 'paths' => [ 'theme/classic/templates/core/', 'theme/boost/templates/core/', 'lib/templates/' ], ], ]; } /** * Tests for get_template_directories_for_component. * * @dataProvider valid_template_directories_provider * @param string $component * @param string $theme * @param array $paths */ public function test_get_template_directories_for_component(string $component, string $theme, array $paths): void { global $CFG; // Test a plugin. $dirs = mustache_template_finder::get_template_directories_for_component($component, $theme, $paths); $correct = array_map(function($path) use ($CFG) { return implode('/', [$CFG->dirroot, $path]); }, $paths); $this->assertEquals($correct, $dirs); } /** * Tests for get_template_directories_for_component when dealing with an invalid component. */ public function test_invalid_component_get_template_directories_for_component() { // Test something invalid. $this->expectException(\coding_exception::class); mustache_template_finder::get_template_directories_for_component('octopus', 'classic'); } /** * Data provider which reutrns a set of valid template directories to be used when testing * get_template_directories_for_component. * * @return array */ public function valid_template_filepath_provider(): array { return [ 'Standard core template' => [ 'template' => 'core/modal', 'theme' => '', 'location' => 'lib/templates/modal.mustache', ], 'Template overridden by theme' => [ 'template' => 'core_form/element-float-inline', 'theme' => '', 'location' => 'theme/boost/templates/core_form/element-float-inline.mustache', ], 'Template overridden by theme but child theme selected' => [ 'template' => 'core_form/element-float-inline', 'theme' => 'classic', 'location' => 'theme/boost/templates/core_form/element-float-inline.mustache', ], 'Template overridden by child theme' => [ 'template' => 'core/full_header', 'theme' => 'classic', 'location' => 'theme/classic/templates/core/full_header.mustache', ], 'Template overridden by child theme but tested against defualt theme' => [ 'template' => 'core/full_header', 'theme' => '', 'location' => 'lib/templates/full_header.mustache', ], 'Standard plugin template' => [ 'template' => 'mod_assign/grading_panel', 'theme' => '', 'location' => 'mod/assign/templates/grading_panel.mustache', ], 'Subsystem template' => [ 'template' => 'core_user/status_details', 'theme' => '', 'location' => 'user/templates/status_details.mustache', ], 'Theme own template' => [ 'template' => 'theme_classic/columns', 'theme' => '', 'location' => 'theme/classic/templates/columns.mustache', ], 'Theme overridden template against that theme' => [ 'template' => 'theme_classic/navbar', 'theme' => 'classic', 'location' => 'theme/classic/templates/navbar.mustache', ], // Note: This one looks strange but is correct. It is legitimate to request theme's component template in // the context of another theme. For example, this is used by child themes making use of parent theme // templates. 'Theme overridden template against the default theme' => [ 'template' => 'theme_classic/navbar', 'theme' => '', 'location' => 'theme/classic/templates/navbar.mustache', ], ]; } /** * Tests for get_template_filepath. * * @dataProvider valid_template_filepath_provider * @param string $template * @param string $theme * @param string $location */ public function test_get_template_filepath(string $template, string $theme, string $location) { global $CFG; $filename = mustache_template_finder::get_template_filepath($template, $theme); $this->assertEquals("{$CFG->dirroot}/{$location}", $filename); } /** * Tests for get_template_filepath when dealing with an invalid component. */ public function test_invalid_component_get_template_filepath() { $this->expectException(\moodle_exception::class); mustache_template_finder::get_template_filepath('core/octopus', 'classic'); } } participants_action_bar_test.php 0000644 00000006175 15152171463 0013214 0 ustar 00 <?php // This file is part of Moodle - http://moodle.org/ // // Moodle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Moodle is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with Moodle. If not, see <http://www.gnu.org/licenses/>. namespace core\output; use ReflectionMethod; /** * Participants tertiary navigation renderable test * * @package core * @category output * @copyright 2021 onwards Peter Dias * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class participants_action_bar_test extends \advanced_testcase { /** * Test the get_content_for_select function * * @dataProvider get_content_for_select_provider * @param string $type Whether we are checking content in the course/module * @param int $expectedcount Expected number of 1st level tertiary items * @param array $expecteditems Expected keys of the 1st level tertiary items. */ public function test_get_content_for_select($type, $expectedcount, $expecteditems) { global $PAGE; $this->resetAfterTest(); $course = $this->getDataGenerator()->create_course(); $module = $this->getDataGenerator()->create_module('assign', [ 'course' => $course->id ]); if ($type == 'course') { $context = \context_course::instance($course->id); $url = new \moodle_url('/course/view.php', ['id' => $course->id]); } else { $url = new \moodle_url('/mod/assign/view.php', ['id' => $module->id]); $context = \context_module::instance($module->cmid); $cm = get_coursemodule_from_instance('assign', $module->id, $course->id); $PAGE->set_cm($cm); } $this->setAdminUser(); $PAGE->set_url($url); $PAGE->set_context($context); $output = new participants_action_bar($course, $PAGE, null); $method = new ReflectionMethod('\core\output\participants_action_bar', 'get_content_for_select'); $method->setAccessible(true); $renderer = $PAGE->get_renderer('core'); $response = $method->invoke($output, $renderer); $this->assertCount($expectedcount, $response); $this->assertSame($expecteditems, array_keys(array_merge(...$response))); } /** * Provider for test_get_content_for_select * @return array[] */ public function get_content_for_select_provider() { return [ 'Get dropdown content when in a course context' => [ 'course', 3, ['Enrolments', 'Groups', 'Permissions'] ], 'Get dropdown content when in a module context' => [ 'module', 1, ['Permissions'] ] ]; } } language_menu_test.php 0000644 00000015333 15152171463 0011135 0 ustar 00 <?php // This file is part of Moodle - http://moodle.org/ // // Moodle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Moodle is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with Moodle. If not, see <http://www.gnu.org/licenses/>. namespace core\output; use ReflectionMethod; /** * Primary navigation renderable test * * @package core * @category output * @copyright 2021 onwards Peter Dias * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class language_menu_test extends \advanced_testcase { /** * Basic setup to make sure the nav objects gets generated without any issues. */ public function setUp(): void { global $PAGE; $this->resetAfterTest(); $PAGE->set_url('/'); } /** * Test the get_lang_menu * * @dataProvider get_lang_menu_provider * @param bool $withadditionallangs * @param string $language * @param array $expected */ public function test_get_lang_menu(bool $withadditionallangs, string $language, array $expected) { global $CFG, $PAGE; // Mimic multiple langs installed. To trigger responses 'get_list_of_translations'. // Note: The text/title of the nodes generated will be 'English(fr), English(de)' but we don't care about this. // We are testing whether the nodes gets generated when the lang menu is available. if ($withadditionallangs) { mkdir("$CFG->dataroot/lang/de", 0777, true); mkdir("$CFG->dataroot/lang/fr", 0777, true); // Ensure the new langs are picked up and not taken from the cache. $stringmanager = get_string_manager(); $stringmanager->reset_caches(true); } force_current_language($language); $output = new language_menu($PAGE); $method = new ReflectionMethod('\core\output\language_menu', 'export_for_template'); $method->setAccessible(true); $renderer = $PAGE->get_renderer('core'); $response = $method->invoke($output, $renderer); if ($withadditionallangs) { // If there are multiple languages installed. // Assert that the title of the language menu matches the expected one. $this->assertEquals($expected['title'], $response['title']); // Assert that the number of language menu items matches the number of the expected items. $this->assertEquals(count($expected['items']), count($response['items'])); foreach ($expected['items'] as $expecteditem) { $lang = $expecteditem['lang']; // We need to manually generate the url key and its value in the expected item array as this cannot // be done in the data provider due to the change of the state of $PAGE. if ($expecteditem['isactive']) { $expecteditem['url'] = new \moodle_url('#'); } else { $expecteditem['url'] = new \moodle_url($PAGE->url, ['lang' => $lang]); // When the language menu item is not the current language, it will contain the lang attribute. $expecteditem['attributes'][] = [ 'key' => 'lang', 'value' => $lang ]; } // The lang value is only used to generate the url, so this key can be removed. unset($expecteditem['lang']); // Assert that the given expected item exists in the returned items. $this->assertTrue(in_array($expecteditem, $response['items'])); } } else { // No multiple languages. $this->assertEquals($expected, $response); } } /** * Provider for test_get_lang_menu * * @return array */ public function get_lang_menu_provider(): array { return [ 'Lang menu with only the current language' => [ false, 'en', [] ], 'Lang menu with only multiple languages installed' => [ true, 'en', [ 'title' => 'English (en)', 'items' => [ [ 'title' => 'English (en)', 'text' => 'English (en)', 'link' => true, 'isactive' => true, 'lang' => 'en' ], [ 'title' => 'English (de)', 'text' => 'English (de)', 'link' => true, 'isactive' => false, 'lang' => 'de' ], [ 'title' => 'English (fr)', 'text' => 'English (fr)', 'link' => true, 'isactive' => false, 'lang' => 'fr' ], ], ], ], 'Lang menu with only multiple languages installed and other than EN set active.' => [ true, 'de', [ 'title' => 'English (de)', 'items' => [ [ 'title' => 'English (en)', 'text' => 'English (en)', 'link' => true, 'isactive' => false, 'lang' => 'en' ], [ 'title' => 'English (de)', 'text' => 'English (de)', 'link' => true, 'isactive' => true, 'lang' => 'de' ], [ 'title' => 'English (fr)', 'text' => 'English (fr)', 'link' => true, 'isactive' => false, 'lang' => 'fr' ], ], ], ], ]; } } mustache_clean_string_helper_test.php 0000644 00000004003 15152171463 0014216 0 ustar 00 <?php // This file is part of Moodle - http://moodle.org/ // // Moodle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Moodle is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with Moodle. If not, see <http://www.gnu.org/licenses/>. declare(strict_types=1); namespace core\output; /** * Unit tests for the mustache_clean_string_helper class. * * @package core * @category test * @copyright 2021 Shamim Rezaie <shamim@moodle.com> * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @coversDefaultClass \core\output\mustache_clean_string_helper */ class mustache_clean_string_helper_test extends \basic_testcase { /** * Test the get_lang_menu * * @covers ::cleanstr */ function test_cleanstr() { $engine = new \Mustache_Engine(); $context = new \Mustache_Context(); $lambdahelper = new \Mustache_LambdaHelper($engine, $context); $cleanstringhelper = new mustache_clean_string_helper(); // Simple string. $this->assertEquals('Log in', $cleanstringhelper->cleanstr('login, core', $lambdahelper)); // Quotes in string. $this->assertEquals('Today's logs', $cleanstringhelper->cleanstr('todaylogs, core', $lambdahelper)); // Quotes in string with parameter. $this->assertEquals('After "test"', $cleanstringhelper->cleanstr('movecontentafter, core, test', $lambdahelper)); // Quotes in parameter. $this->assertEquals('Add a new "'&', $cleanstringhelper->cleanstr('addnew, core, "\'&', $lambdahelper)); } } icon_system_test.php 0000644 00000020226 15152171463 0010657 0 ustar 00 <?php // This file is part of Moodle - http://moodle.org/ // // Moodle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Moodle is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with Moodle. If not, see <http://www.gnu.org/licenses/>. /** * Unit tests for lib/outputcomponents.php. * * @package core * @category test * @copyright 2011 David Mudrak <david@moodle.com> * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ namespace core\output; use advanced_testcase; use coding_exception; /** * Unit tests for the `icon_system` class. * * @coversDefaultClass \core\output\icon_system */ class icon_system_test extends advanced_testcase { /** * Check whether the supplied classes are valid icon subsystems of the supplied one. * * @covers ::is_valid_system * @dataProvider is_valid_subsystem_provider * @param string $parent The class to call ::is_valid_system() on * @param string $system The class to request * @param bool $expected Whether the supplied relationship is valid */ public function test_is_valid_subsystem(string $parent, string $system, bool $expected): void { $this->assertEquals($expected, $parent::is_valid_system($system)); } /** * Ensure that the ::instance() function throws an appropriate Exception when an inappropriate relationship is * specified. * * @covers ::instance * @dataProvider invalid_instance_provider * @param string $parent The class to call ::instance() on * @param string $system The class to request */ public function test_invalid_instance(string $parent, string $system): void { $this->expectException(coding_exception::class); $this->expectExceptionMessage("Invalid icon system requested '{$system}'"); $parent::instance($system); } /** * Ensure that the ::instance() function returns an instance of the supplied system for a valid icon system * relationship. * * @covers ::instance * @dataProvider valid_instance_provider * @param string $parent The class to call ::instance() on * @param string $system The class to request */ public function test_valid_instance(string $parent, string $system): void { $instance = $parent::instance($system); $this->assertInstanceOf($parent, $instance); $this->assertInstanceOf($system, $instance); } /** * Ensure that subsequent calls without arguments to ::instance() return the exact same instance. * * @covers ::instance */ public function test_instance_singleton(): void { $singleton = icon_system::instance(); // Calling instance() again returns the same singleton. $this->assertSame($singleton, icon_system::instance()); } /** * Ensure thaat subsequent calls with an argument to ::instance() return the exact same instance. * * @covers ::instance */ public function test_instance_singleton_named_default(): void { global $PAGE; $singleton = icon_system::instance(); $defaultsystem = $PAGE->theme->get_icon_system(); $this->assertSame($singleton, icon_system::instance($defaultsystem)); } /** * Ensure that ::instance() returns an instance of the correct icon system when requested on the core icon_system * class. * * @covers ::instance * @dataProvider valid_instance_provider * @param string $parent The class to call ::instance() on * @param string $child The class to request */ public function test_instance_singleton_named(string $parent, string $child): void { $iconsystem = icon_system::instance($child); $this->assertInstanceOf($child, $iconsystem); } /** * Ensure that ::instance() returns an instance of the correct icon system when called on a named parent class. * * @covers ::instance * @dataProvider valid_instance_provider * @param string $parent The class to call ::instance() on * @param string $child The class to request */ public function test_instance_singleton_named_child(string $parent, string $child): void { $iconsystem = $parent::instance($child); $this->assertInstanceOf($parent, $iconsystem); $this->assertInstanceOf($child, $iconsystem); } /** * Ensure that the ::reset_caches() function resets the stored instance such that ::instance() returns a new * instance in subsequent calls. * * @covers ::instance * @covers ::reset_caches */ public function test_instance_singleton_reset(): void { $singleton = icon_system::instance(); // Reset the cache. icon_system::reset_caches(); // Calling instance() again returns a new singleton. $newsingleton = icon_system::instance(); $this->assertNotSame($singleton, $newsingleton); // Calling it again gets the new singleton. $this->assertSame($newsingleton, icon_system::instance()); } /** * Returns data for data providers containing: * - parent icon system * - child icon system * - whether it is a valid child * * @return array */ public function icon_system_provider(): array { return [ 'icon_system => icon_system_standard' => [ icon_system::class, icon_system_standard::class, true, ], 'icon_system => icon_system_fontawesome' => [ icon_system::class, icon_system_fontawesome::class, true, ], 'icon_system => \theme_classic\output\icon_system_fontawesome' => [ icon_system::class, \theme_classic\output\icon_system_fontawesome::class, true, ], 'icon_system => notification' => [ icon_system::class, notification::class, false, ], 'icon_system_standard => icon_system_standard' => [ icon_system_standard::class, icon_system_standard::class, true, ], 'icon_system_standard => icon_system_fontawesome' => [ icon_system_standard::class, icon_system_fontawesome::class, false, ], 'icon_system_standard => \theme_classic\output\icon_system_fontawesome' => [ icon_system_standard::class, \theme_classic\output\icon_system_fontawesome::class, false, ], 'icon_system_fontawesome => icon_system_standard' => [ icon_system_fontawesome::class, icon_system_standard::class, false, ], ]; } /** * Data provider for tests of `is_valid`. * * @return array */ public function is_valid_subsystem_provider(): array { return $this->icon_system_provider(); } /** * Data provider for tests of `instance` containing only invalid tests. * * @return array */ public function invalid_instance_provider(): array { return array_filter( $this->icon_system_provider(), function($data) { return !$data[2]; }, ARRAY_FILTER_USE_BOTH ); } /** * Data provider for tests of `instance` containing only valid tests. * * @return array */ public function valid_instance_provider(): array { return array_filter( $this->icon_system_provider(), function($data) { return $data[2]; }, ARRAY_FILTER_USE_BOTH ); } } tagcollsearchable.php 0000644 00000005510 15152206121 0010710 0 ustar 00 <?php // This file is part of Moodle - http://moodle.org/ // // Moodle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Moodle is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with Moodle. If not, see <http://www.gnu.org/licenses/>. /** * Contains class core_tag\output\tagcollsearchable * * @package core_tag * @copyright 2016 Marina Glancy * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ namespace core_tag\output; use context_system; use lang_string; use core_tag_collection; /** * Class to display tag collection searchable control * * @package core_tag * @copyright 2016 Marina Glancy * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class tagcollsearchable extends \core\output\inplace_editable { /** * Constructor. * * @param \stdClass $tagcoll */ public function __construct($tagcoll) { $defaultid = core_tag_collection::get_default(); $editable = $tagcoll->id != $defaultid && has_capability('moodle/tag:manage', context_system::instance()); $edithint = new lang_string('editsearchable', 'core_tag'); $value = $tagcoll->searchable ? 1 : 0; parent::__construct('core_tag', 'tagcollsearchable', $tagcoll->id, $editable, $value, $value, $edithint); $this->set_type_toggle(); } /** * Export this data so it can be used as the context for a mustache template. * * @param \renderer_base $output * @return \stdClass */ public function export_for_template(\renderer_base $output) { if ($this->value) { $this->displayvalue = $output->pix_icon('i/checked', get_string('yes')); } else { $this->displayvalue = $output->pix_icon('i/unchecked', get_string('no')); } return parent::export_for_template($output); } /** * Updates the value in database and returns itself, called from inplace_editable callback * * @param int $itemid * @param mixed $newvalue * @return \self */ public static function update($itemid, $newvalue) { global $DB; require_capability('moodle/tag:manage', context_system::instance()); $tagcoll = $DB->get_record('tag_coll', array('id' => $itemid), '*', MUST_EXIST); core_tag_collection::update($tagcoll, array('searchable' => $newvalue)); return new self($tagcoll); } } tagname.php 0000644 00000004454 15152206121 0006673 0 ustar 00 <?php // This file is part of Moodle - http://moodle.org/ // // Moodle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Moodle is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with Moodle. If not, see <http://www.gnu.org/licenses/>. /** * Contains class core_tag\output\tagname * * @package core_tag * @copyright 2016 Marina Glancy * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ namespace core_tag\output; use context_system; use lang_string; use html_writer; use core_tag_tag; /** * Class to preapare a tag name for display. * * @package core_tag * @copyright 2016 Marina Glancy * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class tagname extends \core\output\inplace_editable { /** * Constructor. * * @param \stdClass|core_tag_tag $tag */ public function __construct($tag) { $editable = has_capability('moodle/tag:manage', context_system::instance()); $edithint = new lang_string('editname', 'core_tag'); $editlabel = new lang_string('newnamefor', 'core_tag', $tag->rawname); $value = $tag->rawname; $displayvalue = html_writer::link(core_tag_tag::make_url($tag->tagcollid, $tag->rawname), core_tag_tag::make_display_name($tag)); parent::__construct('core_tag', 'tagname', $tag->id, $editable, $displayvalue, $value, $edithint, $editlabel); } /** * Updates the value in database and returns itself, called from inplace_editable callback * * @param int $itemid * @param mixed $newvalue * @return \self */ public static function update($itemid, $newvalue) { require_capability('moodle/tag:manage', context_system::instance()); $tag = core_tag_tag::get($itemid, '*', MUST_EXIST); $tag->update(array('rawname' => $newvalue)); return new self($tag); } } tagcloud.php 0000644 00000007600 15152206121 0007055 0 ustar 00 <?php // This file is part of Moodle - http://moodle.org/ // // Moodle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Moodle is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with Moodle. If not, see <http://www.gnu.org/licenses/>. /** * Contains class core_tag\output\tagindex * * @package core_tag * @copyright 2015 Marina Glancy * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ namespace core_tag\output; use renderable; use templatable; use renderer_base; use stdClass; use moodle_url; use core_tag_tag; /** * Class to display a tag cloud - set of tags where each has a weight. * * @package core_tag * @copyright 2015 Marina Glancy * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class tagcloud implements templatable { /** @var array */ protected $tagset; /** @var int */ protected $totalcount; /** * Constructor * * @param array $tagset array of core_tag or stdClass elements, each of them must have attributes: * name, rawname, tagcollid * preferrably also have attributes: * isstandard, count, flag * @param int $totalcount total count of tags (for example to indicate that there are more tags than the count of tagset) * leave 0 if count of tagset is the actual count of tags * @param int $fromctx context id where this tag cloud is displayed * @param int $ctx context id for tag view link * @param int $rec recursive argument for tag view link */ public function __construct($tagset, $totalcount = 0, $fromctx = 0, $ctx = 0, $rec = 1) { $canmanagetags = has_capability('moodle/tag:manage', \context_system::instance()); $maxcount = 1; foreach ($tagset as $tag) { if (isset($tag->count) && $tag->count > $maxcount) { $maxcount = $tag->count; } } $this->tagset = array(); foreach ($tagset as $idx => $tag) { $this->tagset[$idx] = new stdClass(); $this->tagset[$idx]->name = core_tag_tag::make_display_name($tag, false); if ($canmanagetags && !empty($tag->flag)) { $this->tagset[$idx]->flag = 1; } $viewurl = core_tag_tag::make_url($tag->tagcollid, $tag->rawname, 0, $fromctx, $ctx, $rec); $this->tagset[$idx]->viewurl = $viewurl->out(false); if (isset($tag->isstandard)) { $this->tagset[$idx]->isstandard = $tag->isstandard ? 1 : 0; } if (!empty($tag->count)) { $this->tagset[$idx]->count = $tag->count; $this->tagset[$idx]->size = (int)($tag->count / $maxcount * 20); } } $this->totalcount = $totalcount ? $totalcount : count($this->tagset); } /** * Returns number of tags in the cloud * @return int */ public function get_count() { return count($this->tagset); } /** * Export this data so it can be used as the context for a mustache template. * * @param renderer_base $output * @return stdClass */ public function export_for_template(renderer_base $output) { $cnt = count($this->tagset); return (object)array( 'tags' => $this->tagset, 'tagscount' => $cnt, 'totalcount' => $this->totalcount, 'overflow' => ($this->totalcount > $cnt) ? 1 : 0, ); } } tagindex.php 0000644 00000012440 15152206121 0007054 0 ustar 00 <?php // This file is part of Moodle - http://moodle.org/ // // Moodle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Moodle is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with Moodle. If not, see <http://www.gnu.org/licenses/>. /** * Contains class core_tag\output\tagindex * * @package core_tag * @copyright 2015 Marina Glancy * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ namespace core_tag\output; use renderable; use templatable; use renderer_base; use stdClass; use moodle_url; use core_tag_tag; /** * Class to display items tagged with a specific tag * * @package core_tag * @copyright 2015 Marina Glancy * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class tagindex implements templatable { /** @var core_tag_tag|stdClass */ protected $tag; /** @var stdClass */ protected $tagarea; /** @var stdClass */ protected $record; /** * Constructor * * @param core_tag_tag|stdClass $tag * @param string $component * @param string $itemtype * @param string $content * @param bool $exclusivemode * @param int $fromctx context id where the link was displayed, may be used by callbacks * to display items in the same context first * @param int $ctx context id where we need to search for items * @param int $rec search items in sub contexts as well * @param int $page * @param bool $totalpages */ public function __construct($tag, $component, $itemtype, $content, $exclusivemode = false, $fromctx = 0, $ctx = 0, $rec = 1, $page = 0, $totalpages = 1) { $this->record = new stdClass(); $this->tag = $tag; $tagareas = \core_tag_area::get_areas(); if (!isset($tagareas[$itemtype][$component])) { throw new \coding_exception('Tag area for component '.$component.' and itemtype '.$itemtype.' is not defined'); } $this->tagarea = $tagareas[$itemtype][$component]; $this->record->tagid = $tag->id; $this->record->ta = $this->tagarea->id; $this->record->itemtype = $itemtype; $this->record->component = $component; $a = (object)array( 'tagarea' => \core_tag_area::display_name($component, $itemtype), 'tag' => \core_tag_tag::make_display_name($tag) ); if ($exclusivemode) { $this->record->title = get_string('itemstaggedwith', 'tag', $a); } else { $this->record->title = (string)$a->tagarea; } $this->record->content = $content; $this->record->nextpageurl = null; $this->record->prevpageurl = null; $this->record->exclusiveurl = null; $url = core_tag_tag::make_url($tag->tagcollid, $tag->rawname, $exclusivemode, $fromctx, $ctx, $rec); $urlparams = array('ta' => $this->tagarea->id); if ($totalpages > $page + 1) { $this->record->nextpageurl = new moodle_url($url, $urlparams + array('page' => $page + 1)); } if ($page > 0) { $this->record->prevpageurl = new moodle_url($url, $urlparams + array('page' => $page - 1)); } if (!$exclusivemode && ($totalpages > 1 || $page)) { $this->record->exclusiveurl = new moodle_url($url, $urlparams + array('excl' => 1)); } $this->record->exclusivetext = get_string('exclusivemode', 'tag', $a); $this->record->hascontent = ($totalpages > 1 || $page || $content); $this->record->anchor = $component . '_' . $itemtype; } /** * Magic setter * * @param string $name * @param mixed $value */ public function __set($name, $value) { $this->record->$name = $value; } /** * Magic getter * * @param string $name * @return mixed */ public function __get($name) { return $this->record->$name; } /** * Magic isset * * @param string $name * @return bool */ public function __isset($name) { return isset($this->record->$name); } /** * Export this data so it can be used as the context for a mustache template. * * @param renderer_base $output * @return stdClass */ public function export_for_template(renderer_base $output) { if ($this->record->nextpageurl && $this->record->nextpageurl instanceof moodle_url) { $this->record->nextpageurl = $this->record->nextpageurl->out(false); } if ($this->record->prevpageurl && $this->record->prevpageurl instanceof moodle_url) { $this->record->prevpageurl = $this->record->prevpageurl->out(false); } if ($this->record->exclusiveurl && $this->record->exclusiveurl instanceof moodle_url) { $this->record->exclusiveurl = $this->record->exclusiveurl->out(false); } return $this->record; } } tag.php 0000644 00000006117 15152206121 0006030 0 ustar 00 <?php // This file is part of Moodle - http://moodle.org/ // // Moodle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Moodle is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with Moodle. If not, see <http://www.gnu.org/licenses/>. /** * Contains class core_tag\output\tag * * @package core_tag * @copyright 2015 Marina Glancy * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ namespace core_tag\output; use renderable; use templatable; use renderer_base; use stdClass; use moodle_url; use core_tag_tag; /** * Class to help display tag * * @package core_tag * @copyright 2015 Marina Glancy * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class tag implements renderable, templatable { /** @var core_tag_tag|stdClass */ protected $record; /** * Constructor * * @param core_tag_tag|stdClass $tag */ public function __construct($tag) { if ($tag instanceof core_tag_tag) { $this->record = $tag; return; } $tag = (array)$tag + array( 'name' => '', 'rawname' => '', 'description' => '', 'descriptionformat' => FORMAT_HTML, 'flag' => 0, 'isstandard' => 0, 'id' => 0, 'tagcollid' => 0, ); $this->record = (object)$tag; } /** * Export this data so it can be used as the context for a mustache template. * * @param renderer_base $output * @return stdClass */ public function export_for_template(renderer_base $output) { global $CFG; require_once($CFG->libdir . '/externallib.php'); $r = new stdClass(); $r->id = (int)$this->record->id; $r->tagcollid = clean_param($this->record->tagcollid, PARAM_INT); $r->rawname = clean_param($this->record->rawname, PARAM_TAG); $r->name = clean_param($this->record->name, PARAM_TAG); $format = clean_param($this->record->descriptionformat, PARAM_INT); list($r->description, $r->descriptionformat) = external_format_text($this->record->description, $format, \context_system::instance()->id, 'core', 'tag', $r->id); $r->flag = clean_param($this->record->flag, PARAM_INT); if (isset($this->record->isstandard)) { $r->isstandard = clean_param($this->record->isstandard, PARAM_INT) ? 1 : 0; } $r->official = $r->isstandard; // For backwards compatibility. $url = core_tag_tag::make_url($r->tagcollid, $r->rawname); $r->viewurl = $url->out(false); return $r; } } tagisstandard.php 0000644 00000005352 15152206121 0010105 0 ustar 00 <?php // This file is part of Moodle - http://moodle.org/ // // Moodle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Moodle is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with Moodle. If not, see <http://www.gnu.org/licenses/>. /** * Contains class core_tag\output\tagisstandard * * @package core_tag * @copyright 2016 Marina Glancy * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ namespace core_tag\output; use context_system; use core_tag_tag; /** * Class to display/toggle tag isstandard attribute * * @package core_tag * @copyright 2016 Marina Glancy * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class tagisstandard extends \core\output\inplace_editable { /** * Constructor. * * @param \stdClass|core_tag_tag $tag */ public function __construct($tag) { $editable = has_capability('moodle/tag:manage', context_system::instance()); $value = (int)(bool)$tag->isstandard; parent::__construct('core_tag', 'tagisstandard', $tag->id, $editable, $value, $value); $this->set_type_toggle(); } /** * Export this data so it can be used as the context for a mustache template. * * @param \renderer_base $output * @return \stdClass */ public function export_for_template(\renderer_base $output) { if ($this->value) { $this->edithint = get_string('settypedefault', 'core_tag'); $this->displayvalue = $output->pix_icon('i/checked', $this->edithint); } else { $this->edithint = get_string('settypestandard', 'core_tag'); $this->displayvalue = $output->pix_icon('i/unchecked', $this->edithint); } return parent::export_for_template($output); } /** * Updates the value in database and returns itself, called from inplace_editable callback * * @param int $itemid * @param mixed $newvalue * @return \self */ public static function update($itemid, $newvalue) { require_capability('moodle/tag:manage', context_system::instance()); $tag = core_tag_tag::get($itemid, '*', MUST_EXIST); $newvalue = (int)clean_param($newvalue, PARAM_BOOL); $tag->update(array('isstandard' => $newvalue)); return new self($tag); } } tagcollname.php 0000644 00000004726 15152206121 0007547 0 ustar 00 <?php // This file is part of Moodle - http://moodle.org/ // // Moodle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Moodle is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with Moodle. If not, see <http://www.gnu.org/licenses/>. /** * Contains class core_tag\output\tagcollname * * @package core_tag * @copyright 2016 Marina Glancy * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ namespace core_tag\output; use context_system; use lang_string; use html_writer; use core_tag_collection; use moodle_url; /** * Class to preapare a tag name for display. * * @package core_tag * @copyright 2016 Marina Glancy * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class tagcollname extends \core\output\inplace_editable { /** * Constructor. * * @param \stdClass $tagcoll */ public function __construct($tagcoll) { $editable = has_capability('moodle/tag:manage', context_system::instance()); $edithint = new lang_string('editcollname', 'core_tag'); $value = $tagcoll->name; $name = \core_tag_collection::display_name($tagcoll); $editlabel = new lang_string('newcollnamefor', 'core_tag', $name); $manageurl = new moodle_url('/tag/manage.php', array('tc' => $tagcoll->id)); $displayvalue = html_writer::link($manageurl, $name); parent::__construct('core_tag', 'tagcollname', $tagcoll->id, $editable, $displayvalue, $value, $edithint, $editlabel); } /** * Updates the value in database and returns itself, called from inplace_editable callback * * @param int $itemid * @param mixed $newvalue * @return \self */ public static function update($itemid, $newvalue) { global $DB; require_capability('moodle/tag:manage', context_system::instance()); $tagcoll = $DB->get_record('tag_coll', array('id' => $itemid), '*', MUST_EXIST); \core_tag_collection::update($tagcoll, array('name' => $newvalue)); return new self($tagcoll); } } tagareashowstandard.php 0000644 00000005551 15152206121 0011304 0 ustar 00 <?php // This file is part of Moodle - http://moodle.org/ // // Moodle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Moodle is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with Moodle. If not, see <http://www.gnu.org/licenses/>. /** * Contains class core_tag\output\tagareashowstandard * * @package core_tag * @copyright 2016 Marina Glancy * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ namespace core_tag\output; use context_system; use lang_string; use core_tag_tag; use core_tag_area; /** * Class to display tag area show standard control * * @package core_tag * @copyright 2016 Marina Glancy * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class tagareashowstandard extends \core\output\inplace_editable { /** * Constructor. * * @param \stdClass $tagarea */ public function __construct($tagarea) { $editable = has_capability('moodle/tag:manage', context_system::instance()); $edithint = new lang_string('editisstandard', 'core_tag'); $value = $tagarea->showstandard; $areaname = core_tag_area::display_name($tagarea->component, $tagarea->itemtype); $editlabel = new lang_string('changeshowstandard', 'core_tag', $areaname); parent::__construct('core_tag', 'tagareashowstandard', $tagarea->id, $editable, null, $value, $edithint, $editlabel); $standardchoices = array( core_tag_tag::BOTH_STANDARD_AND_NOT => get_string('standardsuggest', 'tag'), core_tag_tag::STANDARD_ONLY => get_string('standardforce', 'tag'), core_tag_tag::HIDE_STANDARD => get_string('standardhide', 'tag') ); $this->set_type_select($standardchoices); } /** * Updates the value in database and returns itself, called from inplace_editable callback * * @param int $itemid * @param mixed $newvalue * @return \self */ public static function update($itemid, $newvalue) { global $DB; require_capability('moodle/tag:manage', context_system::instance()); $tagarea = $DB->get_record('tag_area', array('id' => $itemid), '*', MUST_EXIST); $newvalue = clean_param($newvalue, PARAM_INT); $data = array('showstandard' => $newvalue); core_tag_area::update($tagarea, $data); $tagarea->showstandard = $newvalue; $tmpl = new self($tagarea); return $tmpl; } } tagareacollection.php 0000644 00000006525 15152206121 0010740 0 ustar 00 <?php // This file is part of Moodle - http://moodle.org/ // // Moodle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Moodle is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with Moodle. If not, see <http://www.gnu.org/licenses/>. /** * Contains class core_tag\output\tagareacollection * * @package core_tag * @copyright 2016 Marina Glancy * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ namespace core_tag\output; use context_system; use lang_string; use core_tag_area; /** * Class to display collection select for the tag area * * @package core_tag * @copyright 2016 Marina Glancy * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class tagareacollection extends \core\output\inplace_editable { /** * Constructor. * * @param \stdClass $tagarea */ public function __construct($tagarea) { if (!empty($tagarea->locked)) { // If the tag collection for the current tag area is locked, display the // name of the collection without possibility to edit it. $tagcoll = \core_tag_collection::get_by_id($tagarea->tagcollid); parent::__construct('core_tag', 'tagareacollection', $tagarea->id, false, \core_tag_collection::display_name($tagcoll), $tagarea->tagcollid); return; } $tagcollections = \core_tag_collection::get_collections_menu(true); $editable = (count($tagcollections) > 1) && has_capability('moodle/tag:manage', context_system::instance()); $areaname = core_tag_area::display_name($tagarea->component, $tagarea->itemtype); $edithint = new lang_string('edittagcollection', 'core_tag'); $editlabel = new lang_string('changetagcoll', 'core_tag', $areaname); $value = $tagarea->tagcollid; parent::__construct('core_tag', 'tagareacollection', $tagarea->id, $editable, null, $value, $edithint, $editlabel); $this->set_type_select($tagcollections); } /** * Updates the value in database and returns itself, called from inplace_editable callback * * @param int $itemid * @param mixed $newvalue * @return \self */ public static function update($itemid, $newvalue) { global $DB; require_capability('moodle/tag:manage', \context_system::instance()); $tagarea = $DB->get_record('tag_area', array('id' => $itemid), '*', MUST_EXIST); $newvalue = clean_param($newvalue, PARAM_INT); $tagcollections = \core_tag_collection::get_collections_menu(true); if (!array_key_exists($newvalue, $tagcollections)) { throw new \moodle_exception('invalidparameter', 'debug'); } $data = array('tagcollid' => $newvalue); core_tag_area::update($tagarea, $data); $tagarea->tagcollid = $newvalue; $tmpl = new self($tagarea); return $tmpl; } } tagfeed.php 0000644 00000004772 15152206121 0006661 0 ustar 00 <?php // This file is part of Moodle - http://moodle.org/ // // Moodle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Moodle is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with Moodle. If not, see <http://www.gnu.org/licenses/>. /** * Contains class core_tag\output\tagfeed * * @package core_tag * @copyright 2015 Marina Glancy * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ namespace core_tag\output; use templatable; use renderer_base; use stdClass; /** * Class to display feed of tagged items * * @package core_tag * @copyright 2015 Marina Glancy * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class tagfeed implements templatable { /** @var array */ protected $items; /** * Constructor * * Usually the most convenient way is to call constructor without arguments and * add items later using add() method. * * @param array $items */ public function __construct($items = array()) { $this->items = array(); if ($items) { foreach ($items as $item) { $item = (array)$item + array('img' => '', 'heading' => '', 'details' => ''); $this->add($item['img'], $item['heading'], $item['details']); } } } /** * Adds one item to the tagfeed * * @param string $img HTML code representing image (or image wrapped in a link), note that * core_tag/tagfeed template expects image to be 35x35 px * @param string $heading HTML for item heading * @param string $details HTML for item details (keep short) */ public function add($img, $heading, $details = '') { $this->items[] = array('img' => $img, 'heading' => $heading, 'details' => $details); } /** * Export this data so it can be used as the context for a mustache template. * * @param renderer_base $output * @return stdClass */ public function export_for_template(renderer_base $output) { return array('items' => $this->items); } } tagareaenabled.php 0000644 00000005454 15152206121 0010177 0 ustar 00 <?php // This file is part of Moodle - http://moodle.org/ // // Moodle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Moodle is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with Moodle. If not, see <http://www.gnu.org/licenses/>. /** * Contains class core_tag\output\tagareaenabled * * @package core_tag * @copyright 2016 Marina Glancy * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ namespace core_tag\output; use context_system; /** * Class to display tag area enabled control * * @package core_tag * @copyright 2016 Marina Glancy * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class tagareaenabled extends \core\output\inplace_editable { /** * Constructor. * * @param \stdClass $tagarea */ public function __construct($tagarea) { $editable = has_capability('moodle/tag:manage', context_system::instance()); $value = $tagarea->enabled ? 1 : 0; parent::__construct('core_tag', 'tagareaenable', $tagarea->id, $editable, '', $value); $this->set_type_toggle(); } /** * Export this data so it can be used as the context for a mustache template. * * @param \renderer_base $output * @return \stdClass */ public function export_for_template(\renderer_base $output) { if ($this->value) { $this->edithint = get_string('disable'); $this->displayvalue = $output->pix_icon('i/hide', get_string('disable')); } else { $this->edithint = get_string('enable'); $this->displayvalue = $output->pix_icon('i/show', get_string('enable')); } return parent::export_for_template($output); } /** * Updates the value in database and returns itself, called from inplace_editable callback * * @param int $itemid * @param mixed $newvalue * @return \self */ public static function update($itemid, $newvalue) { global $DB; require_capability('moodle/tag:manage', context_system::instance()); $tagarea = $DB->get_record('tag_area', array('id' => $itemid), '*', MUST_EXIST); $newvalue = $newvalue ? 1 : 0; $data = array('enabled' => $newvalue); \core_tag_area::update($tagarea, $data); $tagarea->enabled = $newvalue; $tmpl = new self($tagarea); return $tmpl; } } taglist.php 0000644 00000010362 15152206121 0006721 0 ustar 00 <?php // This file is part of Moodle - http://moodle.org/ // // Moodle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Moodle is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with Moodle. If not, see <http://www.gnu.org/licenses/>. /** * Contains class core_tag\output\taglist * * @package core_tag * @copyright 2015 Marina Glancy * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ namespace core_tag\output; use templatable; use renderer_base; use stdClass; use core_tag_tag; use context; /** * Class to preapare a list of tags for display, usually the list of tags some entry is tagged with. * * @package core_tag * @copyright 2015 Marina Glancy * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class taglist implements templatable { /** @var array */ protected $tags; /** @var string */ protected $label; /** @var bool $accesshidelabel if true, the label should have class="accesshide" added. */ protected $accesshidelabel; /** @var string */ protected $classes; /** @var int */ protected $limit; /** * Constructor * * @param array $tags list of instances of \core_tag_tag or \stdClass * @param string $label label to display in front, by default 'Tags' (get_string('tags')), set to null * to use default, set to '' (empty string) to omit the label completely * @param string $classes additional classes for the enclosing div element * @param int $limit limit the number of tags to display, if size of $tags is more than this limit the "more" link * will be appended to the end, JS will toggle the rest of the tags. 0 means no limit. * @param context $pagecontext specify if needed to overwrite the current page context for the view tag link * @param bool $accesshidelabel if true, the label should have class="accesshide" added. */ public function __construct($tags, $label = null, $classes = '', $limit = 10, $pagecontext = null, $accesshidelabel = false) { global $PAGE; $canmanagetags = has_capability('moodle/tag:manage', \context_system::instance()); $this->label = ($label === null) ? get_string('tags') : $label; $this->accesshidelabel = $accesshidelabel; $this->classes = $classes; $fromctx = $pagecontext ? $pagecontext->id : (($PAGE->context->contextlevel == CONTEXT_SYSTEM) ? 0 : $PAGE->context->id); $this->tags = array(); foreach ($tags as $idx => $tag) { $this->tags[$idx] = new stdClass(); $this->tags[$idx]->name = core_tag_tag::make_display_name($tag, false); if ($canmanagetags && !empty($tag->flag)) { $this->tags[$idx]->flag = 1; } $viewurl = core_tag_tag::make_url($tag->tagcollid, $tag->rawname, 0, $fromctx); $this->tags[$idx]->viewurl = $viewurl->out(false); if (isset($tag->isstandard)) { $this->tags[$idx]->isstandard = $tag->isstandard ? 1 : 0; } if ($limit && count($this->tags) > $limit) { $this->tags[$idx]->overlimit = 1; } } $this->limit = $limit; } /** * Export this data so it can be used as the context for a mustache template. * * @param renderer_base $output * @return stdClass */ public function export_for_template(renderer_base $output) { $cnt = count($this->tags); return (object)array( 'tags' => array_values($this->tags), 'label' => $this->label, 'accesshidelabel' => $this->accesshidelabel, 'tagscount' => $cnt, 'overflow' => ($this->limit && $cnt > $this->limit) ? 1 : 0, 'classes' => $this->classes, ); } } tagflag.php 0000644 00000005464 15152206121 0006666 0 ustar 00 <?php // This file is part of Moodle - http://moodle.org/ // // Moodle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Moodle is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with Moodle. If not, see <http://www.gnu.org/licenses/>. /** * Contains class core_tag\output\tagflag * * @package core_tag * @copyright 2016 Marina Glancy * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ namespace core_tag\output; use context_system; use core_tag_tag; /** * Class to display tag flag toggle * * @package core_tag * @copyright 2016 Marina Glancy * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class tagflag extends \core\output\inplace_editable { /** * Constructor. * * @param \stdClass|core_tag_tag $tag */ public function __construct($tag) { $editable = has_capability('moodle/tag:manage', context_system::instance()); $value = (int)$tag->flag; parent::__construct('core_tag', 'tagflag', $tag->id, $editable, $value, $value); $this->set_type_toggle(array(0, $value ? $value : 1)); } /** * Export this data so it can be used as the context for a mustache template. * * @param \renderer_base $output * @return \stdClass */ public function export_for_template(\renderer_base $output) { if ($this->value) { $this->edithint = get_string('resetflag', 'core_tag'); $this->displayvalue = $output->pix_icon('i/flagged', $this->edithint) . " ({$this->value})"; } else { $this->edithint = get_string('flagasinappropriate', 'core_tag'); $this->displayvalue = $output->pix_icon('i/unflagged', $this->edithint); } return parent::export_for_template($output); } /** * Updates the value in database and returns itself, called from inplace_editable callback * * @param int $itemid * @param mixed $newvalue * @return \self */ public static function update($itemid, $newvalue) { require_capability('moodle/tag:manage', context_system::instance()); $tag = core_tag_tag::get($itemid, '*', MUST_EXIST); $newvalue = (int)clean_param($newvalue, PARAM_BOOL); if ($newvalue) { $tag->flag(); } else { $tag->reset_flag(); } return new self($tag); } } libraries.php 0000644 00000007367 15152206143 0007245 0 ustar 00 <?php // This file is part of Moodle - http://moodle.org/ // // Moodle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Moodle is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with Moodle. If not, see <http://www.gnu.org/licenses/>. /** * Contains class core_h5p\output\libraries * * @package core_h5p * @copyright 2020 Ferran Recio * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ namespace core_h5p\output; defined('MOODLE_INTERNAL') || die(); use renderable; use templatable; use renderer_base; use stdClass; use moodle_url; use action_menu; use action_menu_link; use pix_icon; /** * Class to help display H5P library management table. * * @copyright 2020 Ferran Recio * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class libraries implements renderable, templatable { /** @var H5P factory */ protected $factory; /** @var H5P library list */ protected $libraries; /** * Constructor. * * @param factory $factory The H5P factory * @param array $libraries array of h5p libraries records */ public function __construct(\core_h5p\factory $factory, array $libraries) { $this->factory = $factory; $this->libraries = $libraries; } /** * Export this data so it can be used as the context for a mustache template. * * @param renderer_base $output * @return stdClass */ public function export_for_template(renderer_base $output) { $installed = []; $filestorage = $this->factory->get_core()->fs; foreach ($this->libraries as $libraryname => $versions) { foreach ($versions as $version) { // Get the icon URL. $version->icon = $filestorage->get_icon_url( $version->id, $version->machine_name, $version->major_version, $version->minor_version ); // Get the action menu options. $actionmenu = new action_menu(); $actionmenu->set_menu_trigger(get_string('actions', 'core_h5p')); $actionmenu->prioritise = true; $actionmenu->add_primary_action(new action_menu_link( new moodle_url('/h5p/libraries.php', ['deletelibrary' => $version->id]), new pix_icon('t/delete', get_string('deletelibraryversion', 'core_h5p')), get_string('deletelibraryversion', 'core_h5p') )); $version->actionmenu = $actionmenu->export_for_template($output); if ($version->enabled) { $version->toggleenabledurl = new moodle_url('/h5p/libraries.php', [ 'id' => $version->id, 'action' => 'disable', 'sesskey' => sesskey(), ]); } else { $version->toggleenabledurl = new moodle_url('/h5p/libraries.php', [ 'id' => $version->id, 'action' => 'enable', 'sesskey' => sesskey(), ]); } $installed[] = $version; } } $r = new stdClass(); $r->contenttypes = $installed; return $r; } } h5peditor.php 0000644 00000003336 15152206143 0007164 0 ustar 00 <?php // This file is part of Moodle - http://moodle.org/ // // Moodle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Moodle is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with Moodle. If not, see <http://www.gnu.org/licenses/>. /** * Provides {@link \core_h5p\output\h5peditor} class. * * @package core_h5p * @copyright 2020 Victor Deniz <victor@moodle.com> * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ namespace core_h5p\output; defined('MOODLE_INTERNAL') || die(); /** * Displays the H5P Editor * * @copyright 2020 Victor Deniz <victor@moodle.com> * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class h5peditor implements \renderable, \templatable { /** @var \stdClass Context in which the H5P Editor is being used. */ protected $context; /** * h5peditor constructor. * * @param \stdClass $context H5P editor context generated by core_h5p\editor. */ public function __construct(\stdClass $context) { $this->context = $context; } /** * Exports the data required for the H5P Editor. * * @param \renderer_base $output * @return \stdClass */ public function export_for_template(\renderer_base $output) { return $this->context; } } table.php 0000644 00000016622 15152206301 0006346 0 ustar 00 <?php // This file is part of Moodle - http://moodle.org/ // // Moodle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Moodle is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with Moodle. If not, see <http://www.gnu.org/licenses/>. /** * Renderable for display of license manager table. * * @package tool_licensemanager * @copyright 2020 Tom Dickman <tomdickman@catalyst-au.net> * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ namespace tool_licensemanager\output; use html_table; use html_table_cell; use html_table_row; use html_writer; use license_manager; defined('MOODLE_INTERNAL') || die(); /** * Renderable for display of license manager table. * * @package tool_licensemanager * @copyright 2020 Tom Dickman <tomdickman@catalyst-au.net> * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class table implements \renderable { /** * 'Create License' link. * * @return string HTML string. */ public function create_license_link() { $link = html_writer::link(\tool_licensemanager\helper::get_create_license_url(), get_string('createlicensebuttontext', 'tool_licensemanager'), ['class' => 'btn btn-secondary mb-3']); return $link; } /** * Create the HTML table for license management. * * @param array $licenses * @param \renderer_base $output * * @return string HTML for license manager table. */ public function create_license_manager_table(array $licenses, \renderer_base $output) { $table = new html_table(); $table->head = [ get_string('enable'), get_string('license', 'tool_licensemanager'), get_string('version'), get_string('order'), get_string('edit'), get_string('delete'), ]; $table->colclasses = [ 'text-center', 'text-left', 'text-left', 'text-center', 'text-center', 'text-center', ]; $table->id = 'manage-licenses'; $table->attributes['class'] = 'admintable generaltable'; $table->data = []; $rownumber = 0; $rowcount = count($licenses); foreach ($licenses as $key => $value) { $canmoveup = $rownumber > 0; $canmovedown = $rownumber < $rowcount - 1; $table->data[] = $this->get_license_table_row_data($value, $canmoveup, $canmovedown, $output); $rownumber++; } $html = html_writer::table($table); return $html; } /** * Get table row data for a license. * * @param object $license the license to populate row data for. * @param bool $canmoveup can this row move up. * @param bool $canmovedown can this row move down. * @param \renderer_base $output the renderer * * @return \html_table_row of columns values for row. */ protected function get_license_table_row_data($license, bool $canmoveup, bool $canmovedown, \renderer_base $output) { global $CFG; $summary = $license->fullname . ' ('. $license->shortname . ')'; if (!empty($license->source)) { $summary .= html_writer::empty_tag('br'); $summary .= html_writer::link($license->source, $license->source, ['target' => '_blank']); } $summarycell = new html_table_cell($summary); $summarycell->attributes['class'] = 'license-summary'; $versioncell = new html_table_cell($license->version); $versioncell->attributes['class'] = 'license-version'; $deletelicense = ''; if ($license->shortname == $CFG->sitedefaultlicense) { $hideshow = $output->pix_icon('t/locked', get_string('sitedefaultlicenselock', 'tool_licensemanager')); } else { if ($license->enabled == license_manager::LICENSE_ENABLED) { $hideshow = html_writer::link(\tool_licensemanager\helper::get_disable_license_url($license->shortname), $output->pix_icon('t/hide', get_string('disablelicensename', 'tool_licensemanager', $license->fullname))); } else { $hideshow = html_writer::link(\tool_licensemanager\helper::get_enable_license_url($license->shortname), $output->pix_icon('t/show', get_string('enablelicensename', 'tool_licensemanager', $license->fullname))); } if ($license->custom == license_manager::CUSTOM_LICENSE) { // Link url is added by the JS `delete_license` modal used for confirmation of deletion, to avoid // link being usable before JavaScript loads on page. $deletelicense = html_writer::link('#', $output->pix_icon('i/trash', get_string('deletelicensename', 'tool_licensemanager', $license->fullname)), ['class' => 'delete-license', 'data-license' => $license->shortname]); } } $hideshowcell = new html_table_cell($hideshow); $hideshowcell->attributes['class'] = 'license-status'; if ($license->custom == license_manager::CUSTOM_LICENSE) { $editlicense = html_writer::link(\tool_licensemanager\helper::get_update_license_url($license->shortname), $output->pix_icon('t/editinline', get_string('editlicensename', 'tool_licensemanager', $license->fullname)), ['class' => 'edit-license']); } else { $editlicense = ''; } $editlicensecell = new html_table_cell($editlicense); $editlicensecell->attributes['class'] = 'edit-license'; $spacer = $output->pix_icon('spacer', '', 'moodle', ['class' => 'iconsmall']); $updown = ''; if ($canmoveup) { $updown .= html_writer::link(\tool_licensemanager\helper::get_moveup_license_url($license->shortname), $output->pix_icon('t/up', get_string('movelicenseupname', 'tool_licensemanager', $license->fullname), 'moodle', ['class' => 'iconsmall']), ['class' => 'move-up']) . ''; } else { $updown .= $spacer; } if ($canmovedown) { $updown .= ' '.html_writer::link(\tool_licensemanager\helper::get_movedown_license_url($license->shortname), $output->pix_icon('t/down', get_string('movelicensedownname', 'tool_licensemanager', $license->fullname), 'moodle', ['class' => 'iconsmall']), ['class' => 'move-down']); } else { $updown .= $spacer; } $updowncell = new html_table_cell($updown); $updowncell->attributes['class'] = 'license-order'; $row = new html_table_row([$hideshowcell, $summarycell, $versioncell, $updowncell, $editlicensecell, $deletelicense]); $row->attributes['data-license'] = $license->shortname; $row->attributes['class'] = strtolower(get_string('license', 'tool_licensemanager')); return $row; } } primary_test.php 0000644 00000033012 15152360220 0007772 0 ustar 00 <?php // This file is part of Moodle - http://moodle.org/ // // Moodle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Moodle is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with Moodle. If not, see <http://www.gnu.org/licenses/>. namespace core\navigation\output; use ReflectionMethod; /** * Primary navigation renderable test * * @package core * @category navigation * @copyright 2021 onwards Peter Dias * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class primary_test extends \advanced_testcase { /** * Basic setup to make sure the nav objects gets generated without any issues. */ public function setUp(): void { global $PAGE; $this->resetAfterTest(); $pagecourse = $this->getDataGenerator()->create_course(); $assign = $this->getDataGenerator()->create_module('assign', ['course' => $pagecourse->id]); $cm = get_coursemodule_from_id('assign', $assign->cmid); $contextrecord = \context_module::instance($cm->id); $pageurl = new \moodle_url('/mod/assign/view.php', ['id' => $cm->instance]); $PAGE->set_cm($cm); $PAGE->set_url($pageurl); $PAGE->set_course($pagecourse); $PAGE->set_context($contextrecord); } /** * Test the primary export to confirm we are getting the nodes * * @dataProvider primary_export_provider * @param bool $withcustom Setup with custom menu * @param bool $withlang Setup with langs * @param string $userloggedin The type of user ('admin' or 'guest') if creating setup with logged in user, * otherwise consider the user as non-logged in * @param array $expecteditems An array of nodes expected with content in them. */ public function test_primary_export(bool $withcustom, bool $withlang, string $userloggedin, array $expecteditems) { global $PAGE, $CFG; if ($withcustom) { $CFG->custommenuitems = "Course search|/course/search.php Google|https://google.com.au/ Netflix|https://netflix.com/au"; } if ($userloggedin === 'admin') { $this->setAdminUser(); } else if ($userloggedin === 'guest') { $this->setGuestUser(); } else { $this->setUser(0); } // Mimic multiple langs installed. To trigger responses 'get_list_of_translations'. // Note: The text/title of the nodes generated will be 'English(fr), English(de)' but we don't care about this. // We are testing whether the nodes gets generated when the lang menu is available. if ($withlang) { mkdir("$CFG->dataroot/lang/de", 0777, true); mkdir("$CFG->dataroot/lang/fr", 0777, true); // Ensure the new langs are picked up and not taken from the cache. $stringmanager = get_string_manager(); $stringmanager->reset_caches(true); } $primary = new primary($PAGE); $renderer = $PAGE->get_renderer('core'); $data = array_filter($primary->export_for_template($renderer)); // Assert that the number of returned menu items equals the expected result. $this->assertCount(count($expecteditems), $data); // Assert that returned menu items match the expected items. foreach ($data as $menutype => $value) { $this->assertTrue(in_array($menutype, $expecteditems)); } // When the user is logged in (excluding guest access), assert that lang menu is included as a part of the // user menu when multiple languages are installed. if (isloggedin() && !isguestuser()) { // Look for a language menu item within the user menu items. $usermenulang = array_filter($data['user']['items'], function($usermenuitem) { return $usermenuitem->itemtype !== 'divider' && $usermenuitem->title === get_string('language'); }); if ($withlang) { // If multiple languages are installed. // Assert that the language menu exists within the user menu. $this->assertNotEmpty($usermenulang); } else { // If the aren't any additional installed languages. $this->assertEmpty($usermenulang); } } else { // Otherwise assert that the user menu does not contain any items. $this->assertArrayNotHasKey('items', $data['user']); } } /** * Provider for the test_primary_export function. * * @return array */ public function primary_export_provider(): array { return [ "Export the menu data when: custom menu exists; multiple langs installed; user is not logged in." => [ true, true, '', ['mobileprimarynav', 'moremenu', 'lang', 'user'] ], "Export the menu data when: custom menu exists; langs not installed; user is not logged in." => [ true, false, '', ['mobileprimarynav', 'moremenu', 'user'] ], "Export the menu data when: custom menu exists; multiple langs installed; logged in as admin." => [ true, true, 'admin', ['mobileprimarynav', 'moremenu', 'user'] ], "Export the menu data when: custom menu exists; langs not installed; logged in as admin." => [ true, false, 'admin', ['mobileprimarynav', 'moremenu', 'user'] ], "Export the menu data when: custom menu exists; multiple langs installed; logged in as guest." => [ true, true, 'guest', ['mobileprimarynav', 'moremenu', 'lang', 'user'] ], "Export the menu data when: custom menu exists; langs not installed; logged in as guest." => [ true, false, 'guest', ['mobileprimarynav', 'moremenu', 'user'] ], "Export the menu data when: custom menu does not exist; multiple langs installed; logged in as guest." => [ false, true, 'guest', ['mobileprimarynav', 'moremenu', 'lang', 'user'] ], "Export the menu data when: custom menu does not exist; multiple langs installed; logged in as admin." => [ false, true, 'admin', ['mobileprimarynav', 'moremenu', 'user'] ], "Export the menu data when: custom menu does not exist; langs not installed; user is not logged in." => [ false, false, '', ['mobileprimarynav', 'moremenu', 'user'] ], ]; } /** * Test the custom menu getter to confirm the nodes gets generated and are returned correctly. * * @dataProvider custom_menu_provider * @param string $config * @param array $expected */ public function test_get_custom_menu(string $config, array $expected) { global $CFG, $PAGE; $CFG->custommenuitems = $config; $output = new primary($PAGE); $method = new ReflectionMethod('core\navigation\output\primary', 'get_custom_menu'); $method->setAccessible(true); $renderer = $PAGE->get_renderer('core'); // We can't assert the value of each menuitem "moremenuid" property (because it's random). $custommenufilter = static function(array $custommenu) use (&$custommenufilter): void { foreach ($custommenu as $menuitem) { unset($menuitem->moremenuid); // Recursively move through child items. $custommenufilter($menuitem->children); } }; $actual = $method->invoke($output, $renderer); $custommenufilter($actual); $this->assertEquals($expected, $actual); } /** * Provider for test_get_custom_menu * * @return array */ public function custom_menu_provider(): array { return [ 'Simple custom menu' => [ "Course search|/course/search.php Google|https://google.com.au/ Netflix|https://netflix.com/au", [ (object) [ 'text' => 'Course search', 'url' => 'https://www.example.com/moodle/course/search.php', 'title' => '', 'sort' => 1, 'children' => [], 'haschildren' => false, ], (object) [ 'text' => 'Google', 'url' => 'https://google.com.au/', 'title' => '', 'sort' => 2, 'children' => [], 'haschildren' => false, ], (object) [ 'text' => 'Netflix', 'url' => 'https://netflix.com/au', 'title' => '', 'sort' => 3, 'children' => [], 'haschildren' => false, ], ] ], 'Complex, nested custom menu' => [ "Moodle community|http://moodle.org -Moodle free support|http://moodle.org/support -Moodle development|http://moodle.org/development --Moodle Tracker|http://tracker.moodle.org --Moodle Docs|https://docs.moodle.org -Moodle News|http://moodle.org/news Moodle company -Moodle commercial hosting|http://moodle.com/hosting -Moodle commercial support|http://moodle.com/support", [ (object) [ 'text' => 'Moodle community', 'url' => 'http://moodle.org', 'title' => '', 'sort' => 1, 'children' => [ (object) [ 'text' => 'Moodle free support', 'url' => 'http://moodle.org/support', 'title' => '', 'sort' => 2, 'children' => [], 'haschildren' => false, ], (object) [ 'text' => 'Moodle development', 'url' => 'http://moodle.org/development', 'title' => '', 'sort' => 3, 'children' => [ (object) [ 'text' => 'Moodle Tracker', 'url' => 'http://tracker.moodle.org', 'title' => '', 'sort' => 4, 'children' => [], 'haschildren' => false, ], (object) [ 'text' => 'Moodle Docs', 'url' => 'https://docs.moodle.org', 'title' => '', 'sort' => 5, 'children' => [], 'haschildren' => false, ], ], 'haschildren' => true, ], (object) [ 'text' => 'Moodle News', 'url' => 'http://moodle.org/news', 'title' => '', 'sort' => 6, 'children' => [], 'haschildren' => false, ], ], 'haschildren' => true, ], (object) [ 'text' => 'Moodle company', 'url' => null, 'title' => '', 'sort' => 7, 'children' => [ (object) [ 'text' => 'Moodle commercial hosting', 'url' => 'http://moodle.com/hosting', 'title' => '', 'sort' => 8, 'children' => [], 'haschildren' => false, ], (object) [ 'text' => 'Moodle commercial support', 'url' => 'http://moodle.com/support', 'title' => '', 'sort' => 9, 'children' => [], 'haschildren' => false, ], ], 'haschildren' => true, ], ] ] ]; } } actionbar.php 0000644 00000007420 15152604274 0007230 0 ustar 00 <?php // This file is part of Moodle - http://moodle.org/ // // Moodle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Moodle is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with Moodle. If not, see <http://www.gnu.org/licenses/>. namespace mod_survey\output; use moodle_url; use renderable; use renderer_base; use templatable; use url_select; /** * Output the rendered elements for the tertiary nav page action * * @package mod_survey * @copyright 2021 Sujith Haridasan <sujith@moodle.com> * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class actionbar implements renderable, templatable { /** * The course id. * * @var int $id */ private $id; /** * The action decides the url to navigate to. * * @var string $action */ private $action; /** * Current url. * * @var moodle_url $currenturl */ private $currenturl; /** * actionbar constructor. * * @param int $id The course module id. * @param string $action The action string. * @param moodle_url $currenturl The current URL. */ public function __construct(int $id, string $action, moodle_url $currenturl) { $this->id = $id; $this->action = $action; $this->currenturl = $currenturl; } /** * Create select menu for the reports * * @return url_select url_select object. */ private function create_select_menu(): url_select { $menu = []; $actions = $this->get_available_reports(); foreach ($actions as $action => $straction) { $url = new moodle_url($this->currenturl, ['id' => $this->id, 'action' => $action]); $menu[$url->out(false)] = $straction; } return new url_select($menu, $this->currenturl->out(false), null, 'surveyresponseselect'); } /** * Generate available reports list * * @return array The list of available action => action string. */ private function get_available_reports(): array { global $DB; $cm = get_coursemodule_from_id('survey', $this->id); $survey = $DB->get_record("survey", ["id" => $cm->instance]); $actions = []; if ($survey && ($survey->template != SURVEY_CIQ)) { $actions['summary'] = get_string('summary', 'survey'); $actions['scales'] = get_string('scales', 'survey'); } $actions['questions'] = get_string('questions', 'survey'); $actions['students'] = get_string('participants'); return $actions; } /** * Data for the template. * * @param renderer_base $output renderer_base object. * @return array data for the template */ public function export_for_template(renderer_base $output): array { global $PAGE; $selecturl = $this->create_select_menu(); $data = [ 'urlselect' => $selecturl->export_for_template($output) ]; if (has_capability('mod/survey:download', $PAGE->cm->context)) { $downloadlink = (new moodle_url('/mod/survey/report.php', ['id' => $this->id, 'action' => 'download']))->out(false); $data['download'] = [ 'link' => $downloadlink, 'text' => get_string('downloadresults', 'mod_survey'), ]; } return $data; } } html/2 0000644 00000000547 15152661621 0005607 0 ustar 00 <div class="spot"> <p class="spot-block"> <a href="/QA/Tools/Donate"><img style="border:none" class="newsImage" alt="I Love Validator" src="/QA/Tools/I_heart_validator.png" /></a> <a href="http://Donate">Make a donation</a> or become a <a href="http://sponsor">sponsor</a> of the <a href="http://validator.w3.org/">http://validator.w3.org/</a> .</p> </div> html/1 0000644 00000011712 15152661621 0005602 0 ustar 00 <h3><a name="toc-1"></a>Header1</h3> <p> Etiam eget nibh leo. In luctus orci quis tellus sagittis egestas. Praesent et turpis augue, ac accumsan orci? Pellentesque porttitor sodales tortor; vitae faucibus dui auctor vel. Phasellus sit amet sem leo; eu adipiscing ipsum. Aliquam vehicula ipsum at diam imperdiet a condimentum urna commodo? Nunc ac lacus non lorem porttitor malesuada et sit amet diam! Aenean pulvinar lectus et dolor dignissim viverra placerat nisl mattis! Nunc non leo a massa imperdiet porta vel eu tellus. Sed ac est quis orci viverra cursus. Nam tellus mauris, facilisis nec faucibus sit amet, consequat in felis. Ut volutpat lacinia est ut fringilla. Pellentesque augue dui, aliquet et ornare euismod, egestas nec arcu! Vivamus gravida, lorem vitae suscipit condimentum, turpis arcu iaculis tortor; vel ullamcorper lorem ante id nisi. Ut sit amet sem tempor quam dignissim interdum. Nam aliquam, odio vitae volutpat semper; sapien turpis feugiat neque, ac ullamcorper felis enim vitae arcu. Morbi viverra feugiat justo, at ullamcorper ipsum posuere non. </p> <p> Proin ultricies gravida dui a mattis. Integer nec nisl ante. Mauris euismod, tortor et fermentum semper; est mi adipiscing erat, non pellentesque orci dui ac arcu. Nam vitae metus augue. Integer magna nibh, elementum nec molestie eget; commodo sed turpis. Duis neque mi, vehicula sed aliquet id, ultricies sed tortor. Aliquam pharetra ante sapien. Etiam accumsan ipsum sed dolor bibendum congue sollicitudin enim fringilla. Nulla eros risus, auctor placerat vestibulum eget, tincidunt ac eros. Duis ut turpis leo, sit amet ornare arcu. Aliquam eu lorem in arcu accumsan iaculis. Integer placerat lacus in nibh sollicitudin euismod? Sed a urna vel dui sagittis varius cursus sit amet dolor. Nulla ut sem at magna fringilla hendrerit sed nec sapien. Aenean nisi elit, feugiat vel euismod non, laoreet sit amet ligula. Aenean a dui quam. </p> <p> Curabitur dolor ligula, suscipit et eleifend nec, faucibus varius sapien. Quisque ornare felis ac leo tincidunt quis malesuada elit lobortis? Suspendisse potenti. Vestibulum tempus porta dui, at ullamcorper mauris sollicitudin vel? In convallis risus id elit ultrices pellentesque. Sed id quam lectus. Duis tincidunt egestas urna, in tempor tortor rhoncus ac. Sed commodo, nunc sit amet sodales vulputate, purus nisi malesuada urna, ut cursus nisl nunc vel enim. Mauris ut imperdiet risus. Integer sagittis; odio at laoreet venenatis, purus neque fermentum nisi, non elementum urna libero sed ipsum. </p> <h3><a name="toc-2"></a>Header2</h3> <p> Etiam eget nibh leo. In luctus orci quis tellus sagittis egestas. Praesent et turpis augue, ac accumsan orci? Pellentesque porttitor sodales tortor; vitae faucibus dui auctor vel. Phasellus sit amet sem leo; eu adipiscing ipsum. Aliquam vehicula ipsum at diam imperdiet a condimentum urna commodo? Nunc ac lacus non lorem porttitor malesuada et sit amet diam! Aenean pulvinar lectus et dolor dignissim viverra placerat nisl mattis! Nunc non leo a massa imperdiet porta vel eu tellus. Sed ac est quis orci viverra cursus. Nam tellus mauris, facilisis nec faucibus sit amet, consequat in felis. Ut volutpat lacinia est ut fringilla. Pellentesque augue dui, aliquet et ornare euismod, egestas nec arcu! Vivamus gravida, lorem vitae suscipit condimentum, turpis arcu iaculis tortor; vel ullamcorper lorem ante id nisi. Ut sit amet sem tempor quam dignissim interdum. Nam aliquam, odio vitae volutpat semper; sapien turpis feugiat neque, ac ullamcorper felis enim vitae arcu. Morbi viverra feugiat justo, at ullamcorper ipsum posuere non. </p> <p> Proin ultricies gravida dui a mattis. Integer nec nisl ante. Mauris euismod, tortor et fermentum semper; est mi adipiscing erat, non pellentesque orci dui ac arcu. Nam vitae metus augue. Integer magna nibh, elementum nec molestie eget; commodo sed turpis. Duis neque mi, vehicula sed aliquet id, ultricies sed tortor. Aliquam pharetra ante sapien. Etiam accumsan ipsum sed dolor bibendum congue sollicitudin enim fringilla. Nulla eros risus, auctor placerat vestibulum eget, tincidunt ac eros. Duis ut turpis leo, sit amet ornare arcu. Aliquam eu lorem in arcu accumsan iaculis. Integer placerat lacus in nibh sollicitudin euismod? Sed a urna vel dui sagittis varius cursus sit amet dolor. Nulla ut sem at magna fringilla hendrerit sed nec sapien. Aenean nisi elit, feugiat vel euismod non, laoreet sit amet ligula. Aenean a dui quam. </p> <p> Curabitur dolor ligula, suscipit et eleifend nec, faucibus varius sapien. Quisque ornare felis ac leo tincidunt quis malesuada elit lobortis? Suspendisse potenti. Vestibulum tempus porta dui, at ullamcorper mauris sollicitudin vel? In convallis risus id elit ultrices pellentesque. Sed id quam lectus. Duis tincidunt egestas urna, in tempor tortor rhoncus ac. Sed commodo, nunc sit amet sodales vulputate, purus nisi malesuada urna, ut cursus nisl nunc vel enim. Mauris ut imperdiet risus. Integer sagittis; odio at laoreet venenatis, purus neque fermentum nisi, non elementum urna libero sed ipsum. </p> html/3 0000644 00000011712 15152661621 0005604 0 ustar 00 <h3><a name="toc-1"></a>Header1</h3> <p> Etiam eget nibh leo. In luctus orci quis tellus sagittis egestas. Praesent et turpis augue, ac accumsan orci? Pellentesque porttitor sodales tortor; vitae faucibus dui auctor vel. Phasellus sit amet sem leo; eu adipiscing ipsum. Aliquam vehicula ipsum at diam imperdiet a condimentum urna commodo? Nunc ac lacus non lorem porttitor malesuada et sit amet diam! Aenean pulvinar lectus et dolor dignissim viverra placerat nisl mattis! Nunc non leo a massa imperdiet porta vel eu tellus. Sed ac est quis orci viverra cursus. Nam tellus mauris, facilisis nec faucibus sit amet, consequat in felis. Ut volutpat lacinia est ut fringilla. Pellentesque augue dui, aliquet et ornare euismod, egestas nec arcu! Vivamus gravida, lorem vitae suscipit condimentum, turpis arcu iaculis tortor; vel ullamcorper lorem ante id nisi. Ut sit amet sem tempor quam dignissim interdum. Nam aliquam, odio vitae volutpat semper; sapien turpis feugiat neque, ac ullamcorper felis enim vitae arcu. Morbi viverra feugiat justo, at ullamcorper ipsum posuere non. </p> <p> Proin ultricies gravida dui a mattis. Integer nec nisl ante. Mauris euismod, tortor et fermentum semper; est mi adipiscing erat, non pellentesque orci dui ac arcu. Nam vitae metus augue. Integer magna nibh, elementum nec molestie eget; commodo sed turpis. Duis neque mi, vehicula sed aliquet id, ultricies sed tortor. Aliquam pharetra ante sapien. Etiam accumsan ipsum sed dolor bibendum congue sollicitudin enim fringilla. Nulla eros risus, auctor placerat vestibulum eget, tincidunt ac eros. Duis ut turpis leo, sit amet ornare arcu. Aliquam eu lorem in arcu accumsan iaculis. Integer placerat lacus in nibh sollicitudin euismod? Sed a urna vel dui sagittis varius cursus sit amet dolor. Nulla ut sem at magna fringilla hendrerit sed nec sapien. Aenean nisi elit, feugiat vel euismod non, laoreet sit amet ligula. Aenean a dui quam. </p> <p> Curabitur dolor ligula, suscipit et eleifend nec, faucibus varius sapien. Quisque ornare felis ac leo tincidunt quis malesuada elit lobortis? Suspendisse potenti. Vestibulum tempus porta dui, at ullamcorper mauris sollicitudin vel? In convallis risus id elit ultrices pellentesque. Sed id quam lectus. Duis tincidunt egestas urna, in tempor tortor rhoncus ac. Sed commodo, nunc sit amet sodales vulputate, purus nisi malesuada urna, ut cursus nisl nunc vel enim. Mauris ut imperdiet risus. Integer sagittis; odio at laoreet venenatis, purus neque fermentum nisi, non elementum urna libero sed ipsum. </p> <h3><a name="toc-2"></a>Header2</h3> <p> Etiam eget nibh leo. In luctus orci quis tellus sagittis egestas. Praesent et turpis augue, ac accumsan orci? Pellentesque porttitor sodales tortor; vitae faucibus dui auctor vel. Phasellus sit amet sem leo; eu adipiscing ipsum. Aliquam vehicula ipsum at diam imperdiet a condimentum urna commodo? Nunc ac lacus non lorem porttitor malesuada et sit amet diam! Aenean pulvinar lectus et dolor dignissim viverra placerat nisl mattis! Nunc non leo a massa imperdiet porta vel eu tellus. Sed ac est quis orci viverra cursus. Nam tellus mauris, facilisis nec faucibus sit amet, consequat in felis. Ut volutpat lacinia est ut fringilla. Pellentesque augue dui, aliquet et ornare euismod, egestas nec arcu! Vivamus gravida, lorem vitae suscipit condimentum, turpis arcu iaculis tortor; vel ullamcorper lorem ante id nisi. Ut sit amet sem tempor quam dignissim interdum. Nam aliquam, odio vitae volutpat semper; sapien turpis feugiat neque, ac ullamcorper felis enim vitae arcu. Morbi viverra feugiat justo, at ullamcorper ipsum posuere non. </p> <p> Proin ultricies gravida dui a mattis. Integer nec nisl ante. Mauris euismod, tortor et fermentum semper; est mi adipiscing erat, non pellentesque orci dui ac arcu. Nam vitae metus augue. Integer magna nibh, elementum nec molestie eget; commodo sed turpis. Duis neque mi, vehicula sed aliquet id, ultricies sed tortor. Aliquam pharetra ante sapien. Etiam accumsan ipsum sed dolor bibendum congue sollicitudin enim fringilla. Nulla eros risus, auctor placerat vestibulum eget, tincidunt ac eros. Duis ut turpis leo, sit amet ornare arcu. Aliquam eu lorem in arcu accumsan iaculis. Integer placerat lacus in nibh sollicitudin euismod? Sed a urna vel dui sagittis varius cursus sit amet dolor. Nulla ut sem at magna fringilla hendrerit sed nec sapien. Aenean nisi elit, feugiat vel euismod non, laoreet sit amet ligula. Aenean a dui quam. </p> <p> Curabitur dolor ligula, suscipit et eleifend nec, faucibus varius sapien. Quisque ornare felis ac leo tincidunt quis malesuada elit lobortis? Suspendisse potenti. Vestibulum tempus porta dui, at ullamcorper mauris sollicitudin vel? In convallis risus id elit ultrices pellentesque. Sed id quam lectus. Duis tincidunt egestas urna, in tempor tortor rhoncus ac. Sed commodo, nunc sit amet sodales vulputate, purus nisi malesuada urna, ut cursus nisl nunc vel enim. Mauris ut imperdiet risus. Integer sagittis; odio at laoreet venenatis, purus neque fermentum nisi, non elementum urna libero sed ipsum. </p> creole/7 0000644 00000001232 15152661621 0006111 0 ustar 00 <h3><a name="toc-1"></a>In nisi purus, varius in, mollis eget, interdum in, ipsum.</h3> <p>Vivamus lobortis. <strong>Mauris dui dui, rutrum in, egestas nec, porttitor vehicula, risus!</strong> Vivamus aliquam ultrices metus. <em>Donec ultricies, metus eget volutpat condimentum;</em> neque orci mattis dolor, non posuere eros dui et orci. Duis aliquam. Fusce sit amet nisl. Duis tempor dapibus diam? In venenatis congue mi? Aliquam metus erat; facilisis a, suscipit a, pretium vitae; ligula? Ut id metus a pede adipiscing commodo! <tt>**Praesent ultricies urna et sapien.** //Donec adipiscing.//</tt> Donec sit amet lacus.</p> <pre> lkdsjflsdjflsdkjflskdjlfk </pre> creole/2 0000644 00000007564 15152661621 0006122 0 ustar 00 <h3><a name="toc-1"></a>Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.</h3> <p>Phasellus odio? Ut ac leo. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Vivamus enim justo, porttitor at, lacinia vitae; consectetuer et, ante? Maecenas eget libero. Duis est. Curabitur tincidunt dictum ligula. Nunc euismod lectus quis mi. Proin et enim sed nunc scelerisque posuere. Suspendisse enim purus, sodales non, tristique vel, sollicitudin ullamcorper, nulla. Aliquam condimentum; tellus eu vulputate facilisis, ante pede rhoncus elit, vel euismod nulla sapien et metus?</p> <h4><a name="toc-2"></a>Praesent tristique facilisis metus.</h4> <p>Quisque lectus? Morbi ultrices ultricies neque. In ligula sem; pretium eget, iaculis laoreet, pulvinar sed, dui. Proin mattis luctus diam. Aenean eget risus in mauris sagittis vehicula. Vivamus dapibus enim ac dolor. Pellentesque leo. Praesent tristique facilisis metus. Nulla imperdiet ante et urna? Maecenas leo nisi, lacinia sollicitudin, viverra at, aliquet et, justo. Quisque congue dolor.</p> <h5><a name="toc-3"></a>Phasellus ut augue ut felis porttitor condimentum.</h5> <p>Aliquam erat volutpat. Phasellus ut augue ut felis porttitor condimentum. Nam sapien tellus, tempus sed; mattis quis, viverra quis, mauris. Suspendisse venenatis sollicitudin massa. Pellentesque lobortis dolor vitae nisl. Nulla interdum aliquet neque. Duis nisl pede, vestibulum in, tristique eget, viverra vitae, erat. Maecenas justo turpis, convallis sit amet, tristique eu, laoreet et, augue. Fusce sem. Pellentesque ut turpis? Morbi suscipit sollicitudin metus? Morbi pharetra, sem eget ornare tempor, neque erat dapibus lacus, ut tincidunt nisi leo sed nunc. Sed sodales dignissim eros. Duis vitae risus. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Sed lobortis consequat sem. Nunc posuere vulputate velit. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Duis vestibulum pellentesque neque.</p> <h6>Sed adipiscing dui at massa. Nulla consectetuer tristique lacus?</h6> <p>Maecenas lacus justo, pellentesque vitae, mattis vitae, rutrum sit amet, metus! Etiam aliquam odio vel nulla. Suspendisse ante. Pellentesque viverra leo at lorem! Ut pharetra egestas ante. Aliquam erat volutpat. Sed adipiscing dui at massa. Nulla consectetuer tristique lacus? Donec ante leo, condimentum non, consectetuer vel, sodales placerat, tortor. Etiam at diam at elit adipiscing ultrices. Etiam lectus sapien, congue sed, sodales quis, ultricies a, libero. Pellentesque tincidunt!</p> <h4><a name="toc-4"></a>Curabitur euismod sollicitudin nibh</h4> <p>Curabitur euismod sollicitudin nibh. Duis nec diam. Sed nunc quam, lobortis nec; tristique et, dignissim eget, massa. Suspendisse sagittis malesuada tortor. Nullam lectus diam, mollis id, malesuada at, gravida ut, nisl. In hac habitasse platea dictumst. Sed a purus. Etiam velit urna, lacinia et, imperdiet quis, varius quis, orci! Sed dolor ante, mollis in, ultrices in, vestibulum vitae; justo. Vestibulum accumsan vehicula risus. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Vivamus sit amet diam lobortis urna tristique pretium. Quisque erat.</p> <h6>Duis nec diam.</h6> <p>Pellentesque lobortis dolor vitae nisl. Nulla interdum aliquet neque. Duis nisl pede, vestibulum in, tristique eget, viverra vitae, erat. Maecenas justo turpis, convallis sit amet, tristique eu, laoreet et, augue. Fusce sem. Pellentesque ut turpis? Morbi suscipit sollicitudin metus? Morbi pharetra, sem eget ornare tempor, neque erat dapibus lacus, ut tincidunt nisi leo sed nunc. Sed sodales dignissim eros. Duis vitae risus. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Sed lobortis consequat sem. Nunc posuere vulputate velit. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Duis vestibulum pellentesque neque.</p> creole/4 0000644 00000001657 15152661621 0006121 0 ustar 00 <h4><a name="toc-1"></a>Donec ultricies neque eu libero scelerisque feugiat.</h4> <p><strong>Donec ultricies <em>neque eu <a href="http://libero">libero</a> scelerisque </em>feugiat. <em>Cras sed ante.</em> Sed volutpat urna eu diam. Curabitur fringilla lacinia mi.</strong> Quisque lorem. Etiam fringilla consequat dui. Nunc est est; aliquet eu, porttitor auctor; malesuada id, massa. <a href="http://Nullam">Nullam feugiat</a>, nulla eget vulputate facilisis, erat odio vestibulum mi, eget volutpat lorem enim vitae eros. Vestibulum convallis. Maecenas posuere pellentesque mi? Donec consectetur volutpat dolor. <a href="http://%2A%2ACurabitur%2A%2A">**Curabitur**</a> non <strong><a href="http://%2F%2FTellus%2A%2A">tellus nec ligula bibendum pulvinar.</a></strong></p> <p><a href="http://www.google.com">http://www.google.com</a> <a href="http://www.google.com">http://www.google.com</a></p> <p>http://www.apple.com [[Link que no va]]</p> creole/8 0000644 00000003636 15152661621 0006124 0 ustar 00 <h4><a name="toc-1"></a>Testing some tables</h4> <p>Phasellus urna erat; venenatis ac, iaculis sed, pretium ut, pede. Suspendisse mauris tellus, rhoncus a, tempor id, mattis non, nibh. Aliquam magna odio; hendrerit at, eleifend sed, dignissim quis, orci. Donec mollis, ante sit amet convallis porta, augue nibh viverra magna, ac scelerisque dui ligula eu felis. Sed eget magna. Proin eget ligula. Vestibulum ornare; sem molestie congue sollicitudin, mi velit porta est, pellentesque dignissim libero est at velit. Donec congue adipiscing massa? Nunc eget nisi eget elit facilisis ornare. Vestibulum et felis id leo feugiat sagittis. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Sed tellus velit, luctus et, tempor non, tempor vitae, magna. Aliquam viverra tortor sit amet tellus. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque nibh risus, dictum eu, tempor sit amet, posuere et, nulla.</p> <p>Well formed table...</p> <table> <thead> <tr> <th>Name</th> <th>Surname</th> </tr> </thead> <tbody> <tr> <td>George</td> <td>Washington</td> </tr> <tr> <td>Abraham</td> <td>Lincoln</td> </tr> </tbody> </table> <p>Not so well formed table</p> <table> <thead> <tr> <th>Name</th> <th>Surname</th> <th>Erroneous stuff</th> </tr> </thead> <tbody> <tr> <td>George</td> <td>Washington</td> <td></td> </tr> <tr> <td>Abraham</td> <td>Lincoln</td> <td>Error error</td> </tr> </tbody> </table> <p>Bad headers:</p> <table> <thead> <tr> <td>Name</td> <th>Surname</th> </tr> </thead> <tbody> <tr> <th>George</th> <td>Washington</td> </tr> <tr> <td>Abraham</td> <th>Lincoln</th> </tr> </tbody> </table> <p>Two tables (treated as such) with some format:</p> <table> <thead> <tr> <th>Name</th> <th>Surname</th> </tr> </thead> <tbody> <tr> <td><strong>George</strong></td> <td><em>Washington</em></td> </tr> </tbody> </table> <table> <tbody> <tr> <td>Abraham</td> <td>Lincoln</td> </tr> </tbody> </table> creole/1 0000644 00000003716 15152661621 0006114 0 ustar 00 <p>Donec semper, nunc nec imperdiet lacinia, dui magna gravida odio, ut pretium nisl sapien ut lacus. Pellentesque nec pede. Praesent condimentum. Aliquam porttitor mi ut odio! Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed laoreet mauris vitae tellus. Curabitur dignissim. Duis ac leo. Nam gravida pharetra sapien. Sed feugiat lobortis orci. Cras sed nisl. Curabitur congue mollis erat. Quisque dictum! Praesent a lectus. Pellentesque nulla nisi; tempus eget, tincidunt id; tincidunt vel, nisl.</p> <p>Duis consequat vulputate felis. Praesent diam nisi, venenatis vitae; dignissim quis, feugiat ut, pede. Maecenas tincidunt iaculis elit. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Sed sed nulla at eros mollis tempor. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nam bibendum lorem at sem. Morbi blandit. Nullam volutpat mi. Suspendisse dapibus lacus vel nisl. Ut lacinia adipiscing mi! Maecenas ipsum erat, accumsan quis, cursus ut, ultrices in; metus. Nulla adipiscing rhoncus ante? Nulla hendrerit tortor sit amet mauris. Cras varius dui vel leo. Proin vulputate! Phasellus lacus arcu, eleifend a, accumsan at, vulputate sed, neque. Fusce leo ante, interdum ac, tincidunt non, scelerisque eu, velit. Suspendisse sed nunc. Aenean sodales turpis!</p> <p>Suspendisse fringilla fermentum sem. Integer viverra dui id dolor! Mauris ornare eros vel nunc. Phasellus ligula nulla, vestibulum eget, vestibulum vel, aliquam eget, eros. Integer in pede. Fusce ultricies viverra ante. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Pellentesque eget lorem ut mi vestibulum facilisis. Vestibulum augue. Curabitur arcu pede, fringilla eu, placerat id, condimentum sit amet, lectus. Fusce at diam eu justo semper interdum. Vivamus id turpis at justo tempus tempor. Maecenas eros libero, bibendum non, dictum ut, blandit id, augue. Pellentesque facilisis. Aenean aliquet sem. In tellus!</p> creole/9 0000644 00000010632 15152661621 0006117 0 ustar 00 <h3><a name="toc-1"></a>Top-level heading (1)</h3> <h4><a name="toc-2"></a>This a test for creole 0.1 (2)</h4> <h5><a name="toc-3"></a>This is a Subheading (3)</h5> <h6>Subsub (4)</h6> <h6>Subsubsub (5)</h6> <p>The ending equal signs should not be displayed:</p> <p>Top-level heading (1)</p> <h4><a name="toc-4"></a>This a test for creole 0.1 (2)</h4> <h5><a name="toc-5"></a>This is a Subheading (3)</h5> <h6>Subsub (4)</h6> <h6>Subsubsub (5)</h6> <p>You can make things <strong>bold</strong> or <em>italic</em> or <strong><em>both</em></strong> or <em><strong>both</strong></em>.</p> <p>Character formatting extends across line breaks: <strong>bold, this is still bold. This line deliberately does not end in star-star.</strong></p> <p>Not bold. Character formatting does not cross paragraph boundaries.</p> <p>You can use <a href="http://internal+links">internal links</a> or <a href="http://www.wikicreole.org">external links</a>, give the link a <a href="http://internal+links">different</a> name.</p> <p>Here's another sentence: This wisdom is taken from <a href="http://Ward+Cunningham%27s">Ward Cunningham's</a> <a href="http://www.c2.com/doc/wikisym/WikiSym2006.pdf">Presentation at the Wikisym 06</a>.</p> <p>Here's a external link without a description: <a href="http://www.wikicreole.org">http://www.wikicreole.org</a></p> <p>Be careful that italic links are rendered properly: <em><a href="http://my.book.example/">My Book Title</a></em> </p> <p>Free links without braces should be rendered as well, like <a href="http://www.wikicreole.org/">http://www.wikicreole.org/</a> and <a href="http://www.wikicreole.org/users/~example">http://www.wikicreole.org/users/~example</a>. </p> <p>Creole1.0 specifies that <a href="http://bar">http://bar</a> and <a href="ftp://bar">ftp://bar</a> should not render italic, something like foo:<em>bar should render as italic.</em></p> <p>You can use this to draw a line to separate the page:</p> <hr /> <p>You can use lists, start it at the first column for now, please...</p> <p>unnumbered lists are like</p> <ul> <li>item a</li> <li>item b</li> <li><strong>bold item c</strong></li> </ul> <p>blank space is also permitted before lists like:</p> <ul> <li>item a</li> <li>item b</li> <li>item c <ul> <li>item c.a</li> </ul> </li> </ul> <p>or you can number them</p> <ol> <li><a href="http://item+1">item 1</a></li> <li>item 2</li> <li><em> italic item 3 </em> <ol> <li>item 3.1</li> <li>item 3.2</li> </ol> </li> </ol> <p>up to five levels</p> <ul> <li>1 <ul> <li>2 <ul> <li>3 <ul> <li>4 <ul> <li>5</li> </ul> </li> </ul> </li> </ul> </li> </ul> </li> </ul> <ul> <li>You can havemultiline list items</li> <li>this is a second multilinelist item</li> </ul> <p>You can use nowiki syntax if you would like do stuff like this:</p> <pre> Guitar Chord C: ||---|---|---| ||-0-|---|---| ||---|---|---| ||---|-0-|---| ||---|---|-0-| ||---|---|---| </pre> <p>You can also use it inline nowiki <tt> in a sentence </tt> like this.</p> <h3><a name="toc-6"></a>Escapes</h3> <p>Normal Link: <a href="http://wikicreole.org/">http://wikicreole.org/</a> - now same link, but escaped: http://wikicreole.org/ </p> <p>Normal asterisks: **not bold**</p> <p>a tilde alone: ~</p> <p>a tilde escapes itself: ~xxx</p> <h5><a name="toc-7"></a>Creole 0.2</h5> <p>This should be a flower with the ALT text "this is a flower" if your wiki supports ALT text on images:</p> <p><div class="wiki_image_left"><p></p><img src="Red-Flower.jpg" alt="here is a red flower" /></div></p> <h5><a name="toc-8"></a>Creole 0.4</h5> <p>Tables are done like this:</p> <table> <thead> <tr> <th>header col1</th> <th>header col2</th> </tr> </thead> <tbody> <tr> <td>col1</td> <td>col2</td> </tr> <tr> <td>you</td> <td>can</td> </tr> <tr> <td>also</td> <td>align<br /> it.</td> </tr> </tbody> </table> <p>You can format an address by simply forcing linebreaks:</p> <p>My contact dates:<br /> Pone: xyz<br /> Fax: +45<br /> Mobile: abc</p> <h5><a name="toc-9"></a>Creole 0.5</h5> <table> <thead> <tr> <th>Header title</th> <th>Another header title</th> </tr> </thead> <tbody> <tr> <td><tt> //not italic text// </tt></td> <td><tt> **not bold text** </tt></td> </tr> <tr> <td><em>italic text</em></td> <td><strong> bold text </strong></td> </tr> </tbody> </table> <h5><a name="toc-10"></a>Creole 1.0</h5> <p>If interwiki links are setup in your wiki, this links to the WikiCreole page about Creole 1.0 test cases: <a href="http://WikiCreole%3ACreole1.0TestCases">WikiCreole:Creole1.0TestCases</a>.</p> creole/3 0000644 00000003770 15152661621 0006116 0 ustar 00 <h3><a name="toc-1"></a>In nisi purus, varius in, mollis eget, interdum in, ipsum.</h3> <p>Vivamus lobortis. <strong>Mauris dui dui, rutrum in, egestas nec, porttitor vehicula, risus!</strong> Vivamus aliquam ultrices metus. <em>Donec ultricies, metus eget volutpat condimentum;</em> neque orci mattis dolor, non posuere eros dui et orci. Duis aliquam. Fusce sit amet nisl. Duis tempor dapibus diam? In venenatis congue mi? Aliquam metus erat; facilisis a, suscipit a, pretium vitae; ligula? Ut id metus a pede adipiscing commodo! <strong>Praesent ultricies urna et sapien.</strong> <em>Donec adipiscing.</em> Donec sit amet lacus.</p> <h4><a name="toc-2"></a>**In nisi purus**, //varius in,// mollis eget, interdum in, ipsum.</h4> <p>Duis feugiat ligula ac elit. %!34%!Nulla sed arcu a risus sodales mattis. Etiam magna arcu, accumsan vitae, sodales non, faucibus quis, nunc. Aenean ut elit. Pellentesque malesuada lacus a orci. Suspendisse in erat sed mi porta faucibus. Nullam a nibh. Suspendisse potenti. Nam malesuada lobortis nibh. Ut venenatis, nibh ac convallis iaculis, justo pede tristique sapien, vel ultricies massa diam id leo. Pellentesque ullamcorper condimentum urna. //Proin dui lacus; scelerisque nec, condimentum non, <strong>lobortis ac, felis.</strong></p> <p>//Nullam ac neque. %!4%!<strong>Praesent quis tellus. </strong>Maecenas<strong> et felis vitae lectus porttitor dignissim. Etiam at dui id nibh molestie semper. Sed vulputate nunc et neque. Fusce consectetur elit id leo. <em>Nulla facilisi. </em>Donec vitae nulla ac nisl mollis blandit. //Nulla adipiscing.</strong> Phasellus quis odio sed eros viverra sodales. Suspendisse eget mauris id urna convallis fringilla. Aliquam dolor. Sed commodo. Quisque vestibulum, eros in mollis rutrum, odio risus aliquam turpis; nec convallis ante justo in dui? Pellentesque pharetra venenatis odio. Nulla placerat, libero at lacinia pellentesque; nisi massa sodales risus, at tincidunt orci pede sed ipsum. Etiam massa! Nullam aliquet justo at erat placerat convallis.</p> creole/6 0000644 00000003124 15152661621 0006112 0 ustar 00 <p>Donec sem est, dictum ac, blandit ut, commodo vitae, pede. Proin auctor egestas est. Aliquam fermentum, dui ac malesuada facilisis, mauris felis porttitor turpis, non adipiscing odio mi sit amet felis. Duis dignissim posuere sem. Fusce consequat convallis lectus. Ut suscipit neque sed massa. Etiam suscipit. Sed vitae elit. Nulla non mi. Aliquam risus erat, varius eget, eleifend eget, scelerisque sit amet, enim. Proin venenatis.</p> <ul> <li>Donec ligula enim</li> <li>viverra at</li> <li>ultricies rutrum</li> </ul> <ul> <li>volutpat sed <ul> <li>ligula</li> <li>Aenean laoreet tortor at lorem</li> </ul> </li> <li>Fusce varius nunc quis lacus sodales posuere</li> </ul> <p><strong> Integer laoreet congue ligula</strong></p> <ul> <li>Vestibulum condimentum</li> </ul> <p><strong>dui ac porta imperdiet</strong></p> <p><strong>Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nam accumsan lectus vel sapien. Quisque laoreet lorem non dolor. Ut diam dolor, facilisis non, tempus eu, varius id, nunc. Aliquam sit amet lorem. Cras congue ultricies enim. Nunc vehicula, odio eget volutpat pharetra, leo pede commodo tellus, eu scelerisque erat purus non felis. Sed sed sem eget massa convallis eleifend? Nam tristique. Aliquam justo. Sed risus mi, egestas in, viverra a; tincidunt ac, mauris! Nulla magna. Aenean mauris velit, facilisis ut, condimentum eget, hendrerit ac, sem. Phasellus lorem. Curabitur augue mi; iaculis sit amet, suscipit eget, commodo nec; nibh. Cras pellentesque hendrerit quam. Praesent arcu dui, rhoncus non, feugiat ut, laoreet vitae, velit.</strong></p> creole/5 0000644 00000003051 15152661621 0006110 0 ustar 00 <h3><a name="toc-1"></a>Integer eu leo? \\ Quisque posuere.</h3> <p>Nunc commodo nisi vitae quam. Etiam tincidunt; lectus eu tempus molestie, elit enim auctor tortor, in varius leo mi ac risus. Sed iaculis magna vel libero. Pellentesque iaculis, tellus in ullamcorper tempus, justo sapien scelerisque enim, eu ornare dui neque sed ligula. <br />Vestibulum porta justo a dolor. Duis mollis quam vel sem. Quisque vel arcu. Pellentesque sem. Aliquam adipiscing neque quis turpis. Mauris placerat, elit quis iaculis vehicula, sem nulla imperdiet nunc, in elementum felis lectus non magna. Mauris cursus; odio eu sagittis sodales, nisi nibh pellentesque tortor, ut ultricies lacus tellus non odio. In semper, ligula eu condimentum posuere, sapien tellus blandit quam, dapibus iaculis lacus erat eget ipsum. Duis pulvinar molestie magna. Aliquam bibendum quam ac nulla!</p> <h4><a name="toc-2"></a>Fusce justo. Aliquam felis tellus, tempor vel, congue quis, tempus eu, ipsum. \\</h4> <p><br />Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Morbi sed erat! Vivamus condimentum. Praesent euismod; nibh sed mollis feugiat, erat lorem commodo lectus, vitae tristique erat massa semper diam. Morbi vitae elit. <br />Quisque sagittis leo non odio auctor faucibus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Pellentesque mi pede, lacinia id, commodo faucibus, rhoncus in, nibh. Praesent vestibulum aliquet quam!</p> nwiki/2 0000644 00000001530 15152661621 0005755 0 ustar 00 <h3><a name="toc-1"></a>Links</h3> <h4><a name="toc-2"></a>Internal links</h4> <p>Some <a href="http://links">links</a>. <a href="http://link">Another Link</a>.</p> <h5><a name="toc-3"></a>Anchors</h5> <p>This is an <a href="#External+links">anchor</a> to the external links section.</p> <p>And this is an <a href="http://link#Section">anchor to another page</a>.</p> <h4><a name="toc-4"></a>External links</h4> <p>A link to <a href="http://www.google.com">http://www.google.com</a> , and a link to <a href="http://www.apple.com">apple</a>. </p> <p>The same link to <a href="http://www.apple.com">Apple Corporation</a>.</p> <h4><a name="toc-5"></a>Attachments & images</h4> <p>That's an <a href="attachment.png" class="wiki-attachment">attachment</a>.</p> <p>And that's an <div class="wiki_image_left"><p></p><img src="image.png" alt="image" /></div>.</p> nwiki/4 0000644 00000000331 15152661621 0005755 0 ustar 00 <table> <tbody> <tr> <td>A</td> <td>B</td> </tr> <tr> <td>C</td> <td>D</td> </tr> </tbody> </table> <table> <thead> <tr> <th>A</th> <th>B</th> </tr> </thead> <tbody> <tr> <td>C</td> <td>D</td> </tr> </tbody> </table> nwiki/1 0000644 00000001022 15152661621 0005750 0 ustar 00 <h3><a name="toc-1"></a>Header 1</h3> <p>First paragraph with no formats.</p> <p><strong>This paragraph has bold text.</strong></p> <p>== False header =</p> <p><em>This part of the paragraph is italicized.</em> But not this part.</p> <h4><a name="toc-2"></a>Header 2</h4> <p>Some mix of <em>italics</em> and <strong>bold</strong>, and some <em><strong>italics & bold</strong></em>.</p> <p>And that <em>italics and <strong>both</strong></em>.</p> <p>And this: <em>italics and</em> <em><strong>both</strong></em>.</p> <hr /> <hr /> nwiki/3 0000644 00000000624 15152661621 0005761 0 ustar 00 <h3><a name="toc-1"></a>Lists</h3> <h4><a name="toc-2"></a>Unordered lists</h4> <ul> <li>1 <ul> <li>2</li> </ul> </li> <li>1</li> </ul> <ul> <li>1 <ul> <li>3 <ul> <li><strong>bold</strong></li> </ul> </li> </ul> </li> <li><em>italic</em></li> </ul> <h4><a name="toc-3"></a>Ordered lists</h4> <ol> <li>1 <ol> <li>2</li> </ol> </li> <li>3</li> </ol> <ol> <li>4</li> <li>5 <ol> <li>6</li> </ol> </li> </ol> nwiki/5 0000644 00000000001 15152661621 0005750 0 ustar 00 action_bar.php 0000644 00000007454 15152662033 0007373 0 ustar 00 <?php // This file is part of Moodle - http://moodle.org/ // // Moodle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Moodle is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with Moodle. If not, see <http://www.gnu.org/licenses/>. namespace gradereport_user\output; use moodle_url; use core_grades\output\general_action_bar; /** * Renderable class for the action bar elements in the user report page. * * @package gradereport_user * @copyright 2022 Mihail Geshoski <mihail@moodle.com> * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class action_bar extends \core_grades\output\action_bar { /** @var int|null $userid The user ID. */ protected $userid; /** @var int $userview The user report view mode. */ protected $userview; /** @var int|null $currentgroupid The user report view mode. */ protected $currentgroupid; /** * The class constructor. * * @param \context $context The context object. * @param int $userview The user report view mode. * @param int|null $userid The user ID or 0 if displaying all users. * @param int|null $currentgroupid The ID of the current group. */ public function __construct(\context $context, int $userview, ?int $userid = null, ?int $currentgroupid = null) { parent::__construct($context); $this->userview = $userview; $this->userid = $userid; $this->currentgroupid = $currentgroupid; } /** * Returns the template for the action bar. * * @return string */ public function get_template(): string { return 'gradereport_user/action_bar'; } /** * Export the data for the mustache template. * * @param \renderer_base $output renderer to be used to render the action bar elements. * @return array */ public function export_for_template(\renderer_base $output): array { global $PAGE, $USER; // If in the course context, we should display the general navigation selector in gradebook. $courseid = $this->context->instanceid; // Get the data used to output the general navigation selector. $generalnavselector = new general_action_bar($this->context, new moodle_url('/grade/report/user/index.php', ['id' => $courseid]), 'gradereport', 'user'); $data = $generalnavselector->export_for_template($output); // If the user has the capability to view all grades, display the group selector (if applicable), the user selector // and the view mode selector (if applicable). if (has_capability('moodle/grade:viewall', $this->context)) { $course = get_course($courseid); $gradesrenderer = $PAGE->get_renderer('core_grades'); $userreportrenderer = $PAGE->get_renderer('gradereport_user'); $data['groupselector'] = $gradesrenderer->group_selector($course); $data['userselector'] = $userreportrenderer->users_selector($course, $this->userid, $this->currentgroupid); // Do not output the 'view mode' selector when in zero state or when the current user is viewing its own report. if (!is_null($this->userid) && $USER->id != $this->userid) { $data['viewasselector'] = $userreportrenderer->view_mode_selector($this->userid, $this->userview, $courseid); } } return $data; } }
| ver. 1.4 |
Github
|
.
| PHP 7.4.33 | ���֧ߧ֧�ѧ�ڧ� ����ѧߧڧ��: 0 |
proxy
|
phpinfo
|
���ѧ����ۧܧ�