MDL-67585 core_course: add hook get_all_content_items
[moodle.git] / course / classes / local / service / content_item_service.php
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/>.
17 /**
18  * Contains the content_item_service class.
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\service;
27 defined('MOODLE_INTERNAL') || die();
29 use core_course\local\exporters\course_content_items_exporter;
30 use core_course\local\repository\content_item_readonly_repository_interface;
32 /**
33  * The content_item_service class, providing the api for interacting with content items.
34  *
35  * @copyright  2020 Jake Dallimore <jrhdallimore@gmail.com>
36  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
37  */
38 class content_item_service {
40     /** @var content_item_readonly_repository_interface $repository a repository for content items. */
41     private $repository;
43     /**
44      * The content_item_service constructor.
45      *
46      * @param content_item_readonly_repository_interface $repository a content item repository.
47      */
48     public function __construct(content_item_readonly_repository_interface $repository) {
49         $this->repository = $repository;
50     }
52     /**
53      * Get all content items which may be added to courses, irrespective of course caps, for site admin views, etc.
54      *
55      * @return array the array of exported content items.
56      */
57     public function get_all_content_items(): array {
58         global $PAGE;
59         $allcontentitems = $this->repository->find_all();
61         // Export the objects to get the formatted objects for transfer/display.
62         $ciexporter = new course_content_items_exporter(
63             $allcontentitems,
64             ['context' => \context_system::instance()]
65         );
66         $exported = $ciexporter->export($PAGE->get_renderer('core'));
68         // Sort by title for return.
69         usort($exported->content_items, function($a, $b) {
70             return $a->title > $b->title;
71         });
73         return $exported->content_items;
74     }
76     /**
77      * Return a representation of the available content items, for a user in a course.
78      *
79      * @param \stdClass $user the user to check access for.
80      * @param \stdClass $course the course to scope the content items to.
81      * @param array $linkparams the desired section to return to.
82      * @return \stdClass[] the content items, scoped to a course.
83      */
84     public function get_content_items_for_user_in_course(\stdClass $user, \stdClass $course, array $linkparams = []): array {
85         global $PAGE;
87         if (!has_capability('moodle/course:manageactivities', \context_course::instance($course->id), $user)) {
88             return [];
89         }
91         // Get all the visible content items.
92         $allcontentitems = $this->repository->find_all_for_course($course, $user);
94         // Content items can only originate from modules or submodules.
95         $pluginmanager = \core_plugin_manager::instance();
96         $components = \core_component::get_component_list();
97         $parents = [];
98         foreach ($allcontentitems as $contentitem) {
99             if (!in_array($contentitem->get_component_name(), array_keys($components['mod']))) {
100                 // It could be a subplugin.
101                 $info = $pluginmanager->get_plugin_info($contentitem->get_component_name());
102                 if (!is_null($info)) {
103                     $parent = $info->get_parent_plugin();
104                     if ($parent != false) {
105                         if (in_array($parent, array_keys($components['mod']))) {
106                             $parents[$contentitem->get_component_name()] = $parent;
107                             continue;
108                         }
109                     }
110                 }
111                 throw new \moodle_exception('Only modules and submodules can generate content items. \''
112                     . $contentitem->get_component_name() . '\' is neither.');
113             }
114             $parents[$contentitem->get_component_name()] = $contentitem->get_component_name();
115         }
117         // Now, check access to these items for the user.
118         $availablecontentitems = array_filter($allcontentitems, function($contentitem) use ($course, $user, $parents) {
119             // Check the parent module access for the user.
120             return course_allowed_module($course, explode('_', $parents[$contentitem->get_component_name()])[1], $user);
121         });
123         // Add the link params to the link, if any have been provided.
124         if (!empty($linkparams)) {
125             $availablecontentitems = array_map(function ($item) use ($linkparams) {
126                 $item->get_link()->params($linkparams);
127                 return $item;
128             }, $availablecontentitems);
129         }
131         // Export the objects to get the formatted objects for transfer/display.
132         $ciexporter = new course_content_items_exporter(
133             $availablecontentitems,
134             ['context' => \context_course::instance($course->id)]
135         );
136         $exported = $ciexporter->export($PAGE->get_renderer('course'));
138         // Sort by title for return.
139         usort($exported->content_items, function($a, $b) {
140             return $a->title > $b->title;
141         });
143         return $exported->content_items;
144     }