MDL-67585 core_course: add hook get_all_content_items
[moodle.git] / course / classes / local / service / content_item_service.php
CommitLineData
dd494a41
JD
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 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 */
25namespace core_course\local\service;
26
27defined('MOODLE_INTERNAL') || die();
28
29use core_course\local\exporters\course_content_items_exporter;
30use core_course\local\repository\content_item_readonly_repository_interface;
31
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 */
38class content_item_service {
39
40 /** @var content_item_readonly_repository_interface $repository a repository for content items. */
41 private $repository;
42
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 }
51
57dfcf95
JD
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();
60
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'));
67
68 // Sort by title for return.
69 usort($exported->content_items, function($a, $b) {
70 return $a->title > $b->title;
71 });
72
73 return $exported->content_items;
74 }
75
dd494a41
JD
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;
86
87 if (!has_capability('moodle/course:manageactivities', \context_course::instance($course->id), $user)) {
88 return [];
89 }
90
91 // Get all the visible content items.
92 $allcontentitems = $this->repository->find_all_for_course($course, $user);
93
39b9e293
JD
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 }
116
dd494a41 117 // Now, check access to these items for the user.
39b9e293 118 $availablecontentitems = array_filter($allcontentitems, function($contentitem) use ($course, $user, $parents) {
dd494a41 119 // Check the parent module access for the user.
39b9e293 120 return course_allowed_module($course, explode('_', $parents[$contentitem->get_component_name()])[1], $user);
dd494a41
JD
121 });
122
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 }
130
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'));
137
138 // Sort by title for return.
139 usort($exported->content_items, function($a, $b) {
140 return $a->title > $b->title;
141 });
142
143 return $exported->content_items;
144 }
145}