See Release Notes
Long Term Support Release
Differences Between: [Versions 310 and 401] [Versions 311 and 401] [Versions 39 and 401] [Versions 400 and 401]
1 <?php 2 // This file is part of Moodle - http://moodle.org/ 3 // 4 // Moodle is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // Moodle is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 16 17 /** 18 * Contains class content_item_repository, for fetching content_items. 19 * 20 * @package core 21 * @subpackage course 22 * @copyright 2020 Jake Dallimore <jrhdallimore@gmail.com> 23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 24 */ 25 namespace core_course\local\repository; 26 27 defined('MOODLE_INTERNAL') || die(); 28 29 use core_component; 30 use core_course\local\entity\content_item; 31 use core_course\local\entity\lang_string_title; 32 use core_course\local\entity\string_title; 33 34 /** 35 * The class content_item_repository, for reading content_items. 36 * 37 * @copyright 2020 Jake Dallimore <jrhdallimore@gmail.com> 38 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 39 */ 40 class content_item_readonly_repository implements content_item_readonly_repository_interface { 41 /** 42 * Get the help string for content items representing core modules. 43 * 44 * @param string $modname the module name. 45 * @return string the help string, including help link. 46 */ 47 private function get_core_module_help_string(string $modname): string { 48 global $OUTPUT; 49 50 $help = ''; 51 $sm = get_string_manager(); 52 if ($sm->string_exists('modulename_help', $modname)) { 53 $help = get_string('modulename_help', $modname); 54 if ($sm->string_exists('modulename_link', $modname)) { // Link to further info in Moodle docs. 55 $link = get_string('modulename_link', $modname); 56 $linktext = get_string('morehelp'); 57 $arialabel = get_string('morehelpaboutmodule', '', get_string('modulename', $modname)); 58 $doclink = $OUTPUT->doc_link($link, $linktext, true, ['aria-label' => $arialabel]); 59 $help .= \html_writer::tag('div', $doclink, ['class' => 'helpdoclink']); 60 } 61 } 62 return $help; 63 } 64 65 /** 66 * Helper to get the contentitems from all subplugin hooks for a given module plugin. 67 * 68 * @param string $parentpluginname the name of the module plugin to check subplugins for. 69 * @param content_item $modulecontentitem the content item of the module plugin, to pass to the hooks. 70 * @param \stdClass $user the user object to pass to subplugins. 71 * @return array the array of content items. 72 */ 73 private function get_subplugin_course_content_items(string $parentpluginname, content_item $modulecontentitem, 74 \stdClass $user): array { 75 76 $contentitems = []; 77 $pluginmanager = \core_plugin_manager::instance(); 78 foreach ($pluginmanager->get_subplugins_of_plugin($parentpluginname) as $subpluginname => $subplugin) { 79 // Call the hook, but with a copy of the module content item data. 80 $spcontentitems = component_callback($subpluginname, 'get_course_content_items', [$modulecontentitem, $user], null); 81 if (!is_null($spcontentitems)) { 82 foreach ($spcontentitems as $spcontentitem) { 83 $contentitems[] = $spcontentitem; 84 } 85 } 86 } 87 return $contentitems; 88 } 89 90 /** 91 * Get all the content items for a subplugin. 92 * 93 * @param string $parentpluginname 94 * @param content_item $modulecontentitem 95 * @return array 96 */ 97 private function get_subplugin_all_content_items(string $parentpluginname, content_item $modulecontentitem): array { 98 $contentitems = []; 99 $pluginmanager = \core_plugin_manager::instance(); 100 foreach ($pluginmanager->get_subplugins_of_plugin($parentpluginname) as $subpluginname => $subplugin) { 101 // Call the hook, but with a copy of the module content item data. 102 $spcontentitems = component_callback($subpluginname, 'get_all_content_items', [$modulecontentitem], null); 103 if (!is_null($spcontentitems)) { 104 foreach ($spcontentitems as $spcontentitem) { 105 $contentitems[] = $spcontentitem; 106 } 107 } 108 } 109 return $contentitems; 110 } 111 112 /** 113 * Find all the available content items, not restricted to course or user. 114 * 115 * @return array the array of content items. 116 */ 117 public function find_all(): array { 118 global $OUTPUT, $DB, $CFG; 119 120 // Get all modules so we know which plugins are enabled and able to add content. 121 // Only module plugins may add content items. 122 $modules = $DB->get_records('modules', ['visible' => 1]); 123 $return = []; 124 125 // Now, generate the content_items. 126 foreach ($modules as $modid => $mod) { 127 // Exclude modules if the code doesn't exist. 128 if (!file_exists("$CFG->dirroot/mod/$mod->name/lib.php")) { 129 continue; 130 } 131 // Create the content item for the module itself. 132 // If the module chooses to implement the hook, this may be thrown away. 133 $help = $this->get_core_module_help_string($mod->name); 134 $archetype = plugin_supports('mod', $mod->name, FEATURE_MOD_ARCHETYPE, MOD_ARCHETYPE_OTHER); 135 $purpose = plugin_supports('mod', $mod->name, FEATURE_MOD_PURPOSE, MOD_PURPOSE_OTHER); 136 137 $contentitem = new content_item( 138 $mod->id, 139 $mod->name, 140 new lang_string_title("modulename", $mod->name), 141 new \moodle_url(''), // No course scope, so just an empty link. 142 $OUTPUT->pix_icon('monologo', '', $mod->name, ['class' => 'icon activityicon']), 143 $help, 144 $archetype, 145 'mod_' . $mod->name, 146 $purpose, 147 ); 148 149 $modcontentitemreference = clone($contentitem); 150 151 if (component_callback_exists('mod_' . $mod->name, 'get_all_content_items')) { 152 // Call the module hooks for this module. 153 $plugincontentitems = component_callback('mod_' . $mod->name, 'get_all_content_items', 154 [$modcontentitemreference], []); 155 if (!empty($plugincontentitems)) { 156 array_push($return, ...$plugincontentitems); 157 } 158 159 // Now, get those for subplugins of the module. 160 $subplugincontentitems = $this->get_subplugin_all_content_items('mod_' . $mod->name, $modcontentitemreference); 161 if (!empty($subplugincontentitems)) { 162 array_push($return, ...$subplugincontentitems); 163 } 164 } else { 165 // Neither callback was found, so just use the default module content item. 166 $return[] = $contentitem; 167 } 168 } 169 return $return; 170 } 171 172 /** 173 * Get the list of potential content items for the given course. 174 * 175 * @param \stdClass $course the course 176 * @param \stdClass $user the user, to pass to plugins implementing callbacks. 177 * @return array the array of content_item objects 178 */ 179 public function find_all_for_course(\stdClass $course, \stdClass $user): array { 180 global $OUTPUT, $DB, $CFG; 181 182 // Get all modules so we know which plugins are enabled and able to add content. 183 // Only module plugins may add content items. 184 $modules = $DB->get_records('modules', ['visible' => 1]); 185 $return = []; 186 187 // Now, generate the content_items. 188 foreach ($modules as $modid => $mod) { 189 // Exclude modules if the code doesn't exist. 190 if (!file_exists("$CFG->dirroot/mod/$mod->name/lib.php")) { 191 continue; 192 } 193 // Create the content item for the module itself. 194 // If the module chooses to implement the hook, this may be thrown away. 195 $help = $this->get_core_module_help_string($mod->name); 196 $archetype = plugin_supports('mod', $mod->name, FEATURE_MOD_ARCHETYPE, MOD_ARCHETYPE_OTHER); 197 $purpose = plugin_supports('mod', $mod->name, FEATURE_MOD_PURPOSE, MOD_PURPOSE_OTHER); 198 199 $icon = 'monologo'; 200 // Quick check for monologo icons. 201 // Plugins that don't have monologo icons will be displayed as is and CSS filter will not be applied. 202 $hasmonologoicons = core_component::has_monologo_icon('mod', $mod->name); 203 $iconclass = ''; 204 if (!$hasmonologoicons) { 205 $iconclass = 'nofilter'; 206 } 207 $contentitem = new content_item( 208 $mod->id, 209 $mod->name, 210 new lang_string_title("modulename", $mod->name), 211 new \moodle_url('/course/mod.php', ['id' => $course->id, 'add' => $mod->name]), 212 $OUTPUT->pix_icon($icon, '', $mod->name, ['class' => "activityicon $iconclass"]), 213 $help, 214 $archetype, 215 'mod_' . $mod->name, 216 $purpose, 217 ); 218 219 $modcontentitemreference = clone($contentitem); 220 221 if (component_callback_exists('mod_' . $mod->name, 'get_course_content_items')) { 222 // Call the module hooks for this module. 223 $plugincontentitems = component_callback('mod_' . $mod->name, 'get_course_content_items', 224 [$modcontentitemreference, $user, $course], []); 225 if (!empty($plugincontentitems)) { 226 array_push($return, ...$plugincontentitems); 227 } 228 229 // Now, get those for subplugins of the module. 230 $subpluginitems = $this->get_subplugin_course_content_items('mod_' . $mod->name, $modcontentitemreference, $user); 231 if (!empty($subpluginitems)) { 232 array_push($return, ...$subpluginitems); 233 } 234 235 } else { 236 // Callback was not found, so just use the default module content item. 237 $return[] = $contentitem; 238 } 239 } 240 241 return $return; 242 } 243 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body