MDL-55494 report_eventlist: ignore only logstore_legacy
[moodle.git] / report / eventlist / classes / list_generator.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  * Event documentation
19  *
20  * @package   report_eventlist
21  * @copyright 2014 Adrian Greeve <adrian@moodle.com>
22  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23  */
25 defined('MOODLE_INTERNAL') || die();
27 /**
28  * Class for returning system event information.
29  *
30  * @package   report_eventlist
31  * @copyright 2014 Adrian Greeve <adrian@moodle.com>
32  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
33  */
34 class report_eventlist_list_generator {
36     /**
37      * Convenience method. Returns all of the core events either with or without details.
38      *
39      * @param bool $detail True will return details, but no abstract classes, False will return all events, but no details.
40      * @return array All events.
41      */
42     public static function get_all_events_list($detail = true) {
43         return array_merge(self::get_core_events_list($detail), self::get_non_core_event_list($detail));
44     }
46     /**
47      * Return all of the core event files.
48      *
49      * @param bool $detail True will return details, but no abstract classes, False will return all events, but no details.
50      * @return array Core events.
51      */
52     public static function get_core_events_list($detail = true) {
53         global $CFG;
55         // Disable developer debugging as deprecated events will fire warnings.
56         // Setup backup variables to restore the following settings back to what they were when we are finished.
57         $debuglevel          = $CFG->debug;
58         $debugdisplay        = $CFG->debugdisplay;
59         $debugdeveloper      = $CFG->debugdeveloper;
60         $CFG->debug          = 0;
61         $CFG->debugdisplay   = false;
62         $CFG->debugdeveloper = false;
64         $eventinformation = array();
65         $directory = $CFG->libdir . '/classes/event';
66         $files = self::get_file_list($directory);
68         // Remove exceptional events that will cause problems being displayed.
69         if (isset($files['unknown_logged'])) {
70             unset($files['unknown_logged']);
71         }
72         foreach ($files as $file => $location) {
73             $functionname = '\\core\\event\\' . $file;
74             // Check to see if this is actually a valid event.
75             if (method_exists($functionname, 'get_static_info')) {
76                 if ($detail) {
77                     $ref = new \ReflectionClass($functionname);
78                     if (!$ref->isAbstract() && $file != 'manager') {
79                         $eventinformation = self::format_data($eventinformation, $functionname);
80                     }
81                 } else {
82                     $eventinformation[$functionname] = $file;
83                 }
84             }
85         }
86         // Now enable developer debugging as event information has been retrieved.
87         $CFG->debug          = $debuglevel;
88         $CFG->debugdisplay   = $debugdisplay;
89         $CFG->debugdeveloper = $debugdeveloper;
90         return $eventinformation;
91     }
93     /**
94      * Returns the appropriate string for the CRUD character.
95      *
96      * @param string $crudcharacter The CRUD character.
97      * @return string get_string for the specific CRUD character.
98      */
99     public static function get_crud_string($crudcharacter) {
100         switch ($crudcharacter) {
101             case 'c':
102                 return get_string('create', 'report_eventlist');
103                 break;
105             case 'u':
106                 return get_string('update', 'report_eventlist');
107                 break;
109             case 'd':
110                 return get_string('delete', 'report_eventlist');
111                 break;
113             case 'r':
114             default:
115                 return get_string('read', 'report_eventlist');
116                 break;
117         }
118     }
120     /**
121      * Returns the appropriate string for the event education level.
122      *
123      * @param int $edulevel Takes either the edulevel constant or string.
124      * @return string get_string for the specific education level.
125      */
126     public static function get_edulevel_string($edulevel) {
127         switch ($edulevel) {
128             case \core\event\base::LEVEL_PARTICIPATING:
129                 return get_string('participating', 'report_eventlist');
130                 break;
132             case \core\event\base::LEVEL_TEACHING:
133                 return get_string('teaching', 'report_eventlist');
134                 break;
136             case \core\event\base::LEVEL_OTHER:
137             default:
138                 return get_string('other', 'report_eventlist');
139                 break;
140         }
141     }
143     /**
144      * Returns a list of files (events) with a full directory path for events in a specified directory.
145      *
146      * @param string $directory location of files.
147      * @return array full location of files from the specified directory.
148      */
149     private static function get_file_list($directory) {
150         global $CFG;
151         $directoryroot = $CFG->dirroot;
152         $finaleventfiles = array();
153         if (is_dir($directory)) {
154             if ($handle = opendir($directory)) {
155                 $eventfiles = scandir($directory);
156                 foreach ($eventfiles as $file) {
157                     if ($file != '.' && $file != '..') {
158                         // Ignore the file if it is external to the system.
159                         if (strrpos($directory, $directoryroot) !== false) {
160                             $location = substr($directory, strlen($directoryroot));
161                             $eventname = substr($file, 0, -4);
162                             $finaleventfiles[$eventname] = $location  . '/' . $file;
163                         }
164                     }
165                 }
166             }
167         }
168         return $finaleventfiles;
169     }
171     /**
172      * This function returns an array of all events for the plugins of the system.
173      *
174      * @param bool $detail True will return details, but no abstract classes, False will return all events, but no details.
175      * @return array A list of events from all plug-ins.
176      */
177     public static function get_non_core_event_list($detail = true) {
178         global $CFG;
179         // Disable developer debugging as deprecated events will fire warnings.
180         // Setup backup variables to restore the following settings back to what they were when we are finished.
181         $debuglevel          = $CFG->debug;
182         $debugdisplay        = $CFG->debugdisplay;
183         $debugdeveloper      = $CFG->debugdeveloper;
184         $CFG->debug          = 0;
185         $CFG->debugdisplay   = false;
186         $CFG->debugdeveloper = false;
188         $noncorepluginlist = array();
189         $plugintypes = \core_component::get_plugin_types();
190         foreach ($plugintypes as $plugintype => $notused) {
191             $pluginlist = \core_component::get_plugin_list($plugintype);
192             foreach ($pluginlist as $plugin => $directory) {
193                 $plugindirectory = $directory . '/classes/event';
194                 foreach (self::get_file_list($plugindirectory) as $eventname => $notused) {
195                     $plugineventname = '\\' . $plugintype . '_' . $plugin . '\\event\\' . $eventname;
196                     // Check that this is actually an event.
197                     if (method_exists($plugineventname, 'get_static_info')) {
198                         if ($detail) {
199                             $ref = new \ReflectionClass($plugineventname);
200                             if (!$ref->isAbstract() && $plugintype . '_' . $plugin !== 'logstore_legacy') {
201                                 $noncorepluginlist = self::format_data($noncorepluginlist, $plugineventname);
202                             }
203                         } else {
204                             $noncorepluginlist[$plugineventname] = $eventname;
205                         }
206                     }
207                 }
208             }
209         }
210         // Now enable developer debugging as event information has been retrieved.
211         $CFG->debug          = $debuglevel;
212         $CFG->debugdisplay   = $debugdisplay;
213         $CFG->debugdeveloper = $debugdeveloper;
215         return $noncorepluginlist;
216     }
218     /**
219      * Get the full list of observers for the system.
220      *
221      * @return array An array of observers in the system.
222      */
223     public static function get_observer_list() {
224         $events = \core\event\manager::get_all_observers();
225         foreach ($events as $key => $observers) {
226             foreach ($observers as $observerskey => $observer) {
227                 $events[$key][$observerskey]->parentplugin =
228                         \core_plugin_manager::instance()->get_parent_of_subplugin($observer->plugintype);
229             }
230         }
231         return $events;
232     }
234     /**
235      * Returns the event data list section with url links and other formatting.
236      *
237      * @param array $eventdata The event data list section.
238      * @param string $eventfullpath Full path to the events for this plugin / subplugin.
239      * @return array The event data list section with additional formatting.
240      */
241     private static function format_data($eventdata, $eventfullpath) {
242         // Get general event information.
243         $eventdata[$eventfullpath] = $eventfullpath::get_static_info();
244         // Create a link for further event detail.
245         $url = new \moodle_url('eventdetail.php', array('eventname' => $eventfullpath));
246         $link = \html_writer::link($url, $eventfullpath::get_name());
247         $eventdata[$eventfullpath]['fulleventname'] = \html_writer::span($link);
248         $eventdata[$eventfullpath]['fulleventname'] .= \html_writer::empty_tag('br');
249         $eventdata[$eventfullpath]['fulleventname'] .= \html_writer::span($eventdata[$eventfullpath]['eventname'],
250                 'report-eventlist-name');
252         $eventdata[$eventfullpath]['crud'] = self::get_crud_string($eventdata[$eventfullpath]['crud']);
253         $eventdata[$eventfullpath]['edulevel'] = self::get_edulevel_string($eventdata[$eventfullpath]['edulevel']);
254         $eventdata[$eventfullpath]['legacyevent'] = $eventfullpath::get_legacy_eventname();
256         // Mess around getting since information.
257         $ref = new \ReflectionClass($eventdata[$eventfullpath]['eventname']);
258         $eventdocbloc = $ref->getDocComment();
259         $sincepattern = "/since\s*Moodle\s([0-9]+.[0-9]+)/i";
260         preg_match($sincepattern, $eventdocbloc, $result);
261         if (isset($result[1])) {
262             $eventdata[$eventfullpath]['since'] = $result[1];
263         } else {
264             $eventdata[$eventfullpath]['since'] = null;
265         }
267         // Human readable plugin information to go with the component.
268         $pluginstring = explode('\\', $eventfullpath);
269         if ($pluginstring[1] !== 'core') {
270             $component = $eventdata[$eventfullpath]['component'];
271             $manager = get_string_manager();
272             if ($manager->string_exists('pluginname', $pluginstring[1])) {
273                 $eventdata[$eventfullpath]['component'] = \html_writer::span(get_string('pluginname', $pluginstring[1]));
274             }
275         }
277         // Raw event data to be used to sort the "Event name" column.
278         $eventdata[$eventfullpath]['raweventname'] = $eventfullpath::get_name() . ' ' . $eventdata[$eventfullpath]['eventname'];
280         // Unset information that is not currently required.
281         unset($eventdata[$eventfullpath]['action']);
282         unset($eventdata[$eventfullpath]['target']);
283         return $eventdata;
284     }