From 4f078f38ae82031070714c7de8f67f7d348455b0 Mon Sep 17 00:00:00 2001 From: Adrian Greeve Date: Thu, 3 Apr 2014 09:22:29 +0800 Subject: [PATCH] MDL-44637 report_eventlist: Created a tool for listing all events. --- lib/classes/plugin_manager.php | 2 +- report/eventlist/classes/filter_form.php | 55 ++++ report/eventlist/classes/list_generator.php | 282 ++++++++++++++++++ report/eventlist/classes/renderer.php | 175 +++++++++++ report/eventlist/eventdetail.php | 140 +++++++++ report/eventlist/index.php | 53 ++++ report/eventlist/lang/en/report_eventlist.php | 59 ++++ report/eventlist/settings.php | 30 ++ report/eventlist/styles.css | 79 +++++ report/eventlist/version.php | 29 ++ ...odle-report_eventlist-eventfilter-debug.js | 262 ++++++++++++++++ ...moodle-report_eventlist-eventfilter-min.js | 1 + .../moodle-report_eventlist-eventfilter.js | 262 ++++++++++++++++ .../eventlist/yui/src/eventfilter/build.json | 10 + .../yui/src/eventfilter/js/eventfilter.js | 247 +++++++++++++++ .../yui/src/eventfilter/meta/eventfilter.json | 13 + 16 files changed, 1698 insertions(+), 1 deletion(-) create mode 100644 report/eventlist/classes/filter_form.php create mode 100644 report/eventlist/classes/list_generator.php create mode 100644 report/eventlist/classes/renderer.php create mode 100644 report/eventlist/eventdetail.php create mode 100644 report/eventlist/index.php create mode 100644 report/eventlist/lang/en/report_eventlist.php create mode 100644 report/eventlist/settings.php create mode 100644 report/eventlist/styles.css create mode 100644 report/eventlist/version.php create mode 100644 report/eventlist/yui/build/moodle-report_eventlist-eventfilter/moodle-report_eventlist-eventfilter-debug.js create mode 100644 report/eventlist/yui/build/moodle-report_eventlist-eventfilter/moodle-report_eventlist-eventfilter-min.js create mode 100644 report/eventlist/yui/build/moodle-report_eventlist-eventfilter/moodle-report_eventlist-eventfilter.js create mode 100644 report/eventlist/yui/src/eventfilter/build.json create mode 100644 report/eventlist/yui/src/eventfilter/js/eventfilter.js create mode 100644 report/eventlist/yui/src/eventfilter/meta/eventfilter.json diff --git a/lib/classes/plugin_manager.php b/lib/classes/plugin_manager.php index a4ebb6bb2c2..78e32ab2f30 100644 --- a/lib/classes/plugin_manager.php +++ b/lib/classes/plugin_manager.php @@ -1102,7 +1102,7 @@ class core_plugin_manager { ), 'report' => array( - 'backups', 'completion', 'configlog', 'courseoverview', + 'backups', 'completion', 'configlog', 'courseoverview', 'eventlist', 'log', 'loglive', 'outline', 'participation', 'progress', 'questioninstances', 'security', 'stats', 'performance' ), diff --git a/report/eventlist/classes/filter_form.php b/report/eventlist/classes/filter_form.php new file mode 100644 index 00000000000..a7ebdc429fc --- /dev/null +++ b/report/eventlist/classes/filter_form.php @@ -0,0 +1,55 @@ +. + +defined('MOODLE_INTERNAL') || die(); + +require_once($CFG->libdir.'/formslib.php'); + +/** + * Event list filter form. + * + * @package report_eventlist + * @copyright 2014 Adrian Greeve + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class report_eventlist_filter_form extends moodleform { + + /** + * Form definition method. + */ + public function definition() { + + $mform = $this->_form; + $mform->disable_form_change_checker(); + $componentarray = $this->_customdata['components']; + $edulevelarray = $this->_customdata['edulevel']; + $crudarray = $this->_customdata['crud']; + + $mform->addElement('header', 'displayinfo', get_string('filter', 'report_eventlist')); + + $mform->addElement('text', 'eventname', get_string('name', 'report_eventlist')); + $mform->setType('eventname', PARAM_RAW); + + $mform->addElement('select', 'eventcomponent', get_string('component', 'report_eventlist'), $componentarray); + $mform->addElement('select', 'eventedulevel', get_string('edulevel', 'report_eventlist'), $edulevelarray); + $mform->addElement('select', 'eventcrud', get_string('crud', 'report_eventlist'), $crudarray); + + $buttonarray = array(); + $buttonarray[] = $mform->createElement('button', 'filterbutton', get_string('filter', 'report_eventlist')); + $buttonarray[] = $mform->createElement('button', 'clearbutton', get_string('clear', 'report_eventlist')); + $mform->addGroup($buttonarray, 'filterbuttons', '', array(' '), false); + } +} diff --git a/report/eventlist/classes/list_generator.php b/report/eventlist/classes/list_generator.php new file mode 100644 index 00000000000..8db4688fdc1 --- /dev/null +++ b/report/eventlist/classes/list_generator.php @@ -0,0 +1,282 @@ +. + +/** + * Event documentation + * + * @package report_eventlist + * @copyright 2014 Adrian Greeve + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +defined('MOODLE_INTERNAL') || die(); + +/** + * Class for returning system event information. + * + * @package report_eventlist + * @copyright 2014 Adrian Greeve + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class report_eventlist_list_generator { + + /** + * Convenience method. Returns all of the core events either with or without details. + * + * @param bool $detail True will return details, but no abstract classes, False will return all events, but no details. + * @return array All events. + */ + public static function get_all_events_list($detail = true) { + return array_merge(self::get_core_events_list($detail), self::get_non_core_event_list($detail)); + } + + /** + * Return all of the core event files. + * + * @param bool $detail True will return details, but no abstract classes, False will return all events, but no details. + * @return array Core events. + */ + public static function get_core_events_list($detail = true) { + global $CFG; + + // Disable developer debugging as deprecated events will fire warnings. + // Setup backup variables to restore the following settings back to what they were when we are finished. + $debuglevel = $CFG->debug; + $debugdisplay = $CFG->debugdisplay; + $debugdeveloper = $CFG->debugdeveloper; + $CFG->debug = 0; + $CFG->debugdisplay = false; + $CFG->debugdeveloper = false; + + $eventinformation = array(); + $directory = $CFG->libdir . '/classes/event'; + $files = self::get_file_list($directory); + + // Remove exceptional events that will cause problems being displayed. + if (isset($files['unknown_logged'])) { + unset($files['unknown_logged']); + } + foreach ($files as $file => $location) { + $functionname = '\\core\\event\\' . $file; + // Check to see if this is actually a valid event. + if (method_exists($functionname, 'get_static_info')) { + if ($detail) { + $ref = new \ReflectionClass($functionname); + if (!$ref->isAbstract() && $file != 'manager') { + $eventinformation = self::format_data($eventinformation, $functionname); + } + } else { + $eventinformation[$functionname] = $file; + } + } + } + // Now enable developer debugging as event information has been retrieved. + $CFG->debug = $debuglevel; + $CFG->debugdisplay = $debugdisplay; + $CFG->debugdeveloper = $debugdeveloper; + return $eventinformation; + } + + /** + * Returns the appropriate string for the CRUD character. + * + * @param string $crudcharacter The CRUD character. + * @return string get_string for the specific CRUD character. + */ + public static function get_crud_string($crudcharacter) { + switch ($crudcharacter) { + case 'c': + return get_string('create', 'report_eventlist'); + break; + + case 'u': + return get_string('update', 'report_eventlist'); + break; + + case 'd': + return get_string('delete', 'report_eventlist'); + break; + + case 'r': + default: + return get_string('read', 'report_eventlist'); + break; + } + } + + /** + * Returns the appropriate string for the event education level. + * + * @param int $edulevel Takes either the edulevel constant or string. + * @return string get_string for the specific education level. + */ + public static function get_edulevel_string($edulevel) { + switch ($edulevel) { + case \core\event\base::LEVEL_PARTICIPATING: + return get_string('participating', 'report_eventlist'); + break; + + case \core\event\base::LEVEL_TEACHING: + return get_string('teaching', 'report_eventlist'); + break; + + case \core\event\base::LEVEL_OTHER: + default: + return get_string('other', 'report_eventlist'); + break; + } + } + + /** + * Returns a list of files (events) with a full directory path for events in a specified directory. + * + * @param string $directory location of files. + * @return array full location of files from the specified directory. + */ + private static function get_file_list($directory) { + global $CFG; + $directoryroot = $CFG->dirroot; + $finaleventfiles = array(); + if (is_dir($directory)) { + if ($handle = opendir($directory)) { + $eventfiles = scandir($directory); + foreach ($eventfiles as $file) { + if ($file != '.' && $file != '..') { + // Ignore the file if it is external to the system. + if (strrpos($directory, $directoryroot) !== false) { + $location = substr($directory, strlen($directoryroot)); + $eventname = substr($file, 0, -4); + $finaleventfiles[$eventname] = $location . '/' . $file; + } + } + } + } + } + return $finaleventfiles; + } + + /** + * This function returns an array of all events for the plugins of the system. + * + * @param bool $detail True will return details, but no abstract classes, False will return all events, but no details. + * @return array A list of events from all plug-ins. + */ + public static function get_non_core_event_list($detail = true) { + global $CFG; + // Disable developer debugging as deprecated events will fire warnings. + // Setup backup variables to restore the following settings back to what they were when we are finished. + $debuglevel = $CFG->debug; + $debugdisplay = $CFG->debugdisplay; + $debugdeveloper = $CFG->debugdeveloper; + $CFG->debug = 0; + $CFG->debugdisplay = false; + $CFG->debugdeveloper = false; + + $noncorepluginlist = array(); + $plugintypes = \core_component::get_plugin_types(); + foreach ($plugintypes as $plugintype => $notused) { + $pluginlist = \core_component::get_plugin_list($plugintype); + foreach ($pluginlist as $plugin => $directory) { + $plugindirectory = $directory . '/classes/event'; + foreach (self::get_file_list($plugindirectory) as $eventname => $notused) { + $plugineventname = '\\' . $plugintype . '_' . $plugin . '\\event\\' . $eventname; + // Check that this is actually an event. + if (method_exists($plugineventname, 'get_static_info')) { + if ($detail) { + $ref = new \ReflectionClass($plugineventname); + if (!$ref->isAbstract() && $plugin != 'legacy') { + $noncorepluginlist = self::format_data($noncorepluginlist, $plugineventname); + } + } else { + $noncorepluginlist[$plugineventname] = $eventname; + } + } + } + } + } + // Now enable developer debugging as event information has been retrieved. + $CFG->debug = $debuglevel; + $CFG->debugdisplay = $debugdisplay; + $CFG->debugdeveloper = $debugdeveloper; + + return $noncorepluginlist; + } + + /** + * Get the full list of observers for the system. + * + * @return array An array of observers in the system. + */ + public static function get_observer_list() { + $events = \core\event\manager::get_all_observers(); + foreach ($events as $key => $observers) { + foreach ($observers as $observerskey => $observer) { + $events[$key][$observerskey]->parentplugin = + \core_plugin_manager::instance()->get_parent_of_subplugin($observer->plugintype); + } + } + return $events; + } + + /** + * Returns the event data list section with url links and other formatting. + * + * @param array $eventdata The event data list section. + * @param string $eventfullpath Full path to the events for this plugin / subplugin. + * @return array The event data list section with additional formatting. + */ + private static function format_data($eventdata, $eventfullpath) { + // Get general event information. + $eventdata[$eventfullpath] = $eventfullpath::get_static_info(); + // Create a link for further event detail. + $url = new \moodle_url('eventdetail.php', array('eventname' => $eventfullpath)); + $link = \html_writer::link($url, $eventfullpath::get_name()); + $eventdata[$eventfullpath]['fulleventname'] = \html_writer::span($link); + $eventdata[$eventfullpath]['fulleventname'] .= \html_writer::empty_tag('br'); + $eventdata[$eventfullpath]['fulleventname'] .= \html_writer::span($eventdata[$eventfullpath]['eventname'], + 'report-eventlist-name'); + + $eventdata[$eventfullpath]['crud'] = self::get_crud_string($eventdata[$eventfullpath]['crud']); + $eventdata[$eventfullpath]['edulevel'] = self::get_edulevel_string($eventdata[$eventfullpath]['edulevel']); + $eventdata[$eventfullpath]['legacyevent'] = $eventfullpath::get_legacy_eventname(); + + // Mess around getting since information. + $ref = new \ReflectionClass($eventdata[$eventfullpath]['eventname']); + $eventdocbloc = $ref->getDocComment(); + $sincepattern = "/since\s*Moodle\s([0-9]+.[0-9]+)/i"; + preg_match($sincepattern, $eventdocbloc, $result); + if (isset($result[1])) { + $eventdata[$eventfullpath]['since'] = $result[1]; + } else { + $eventdata[$eventfullpath]['since'] = null; + } + + // Human readable plugin information to go with the component. + $pluginstring = explode('\\', $eventfullpath); + if ($pluginstring[1] !== 'core') { + $component = $eventdata[$eventfullpath]['component']; + $manager = get_string_manager(); + if ($manager->string_exists('pluginname', $pluginstring[1])) { + $eventdata[$eventfullpath]['component'] = \html_writer::span(get_string('pluginname', $pluginstring[1])); + } + } + + // Unset information that is not currently required. + unset($eventdata[$eventfullpath]['action']); + unset($eventdata[$eventfullpath]['target']); + return $eventdata; + } +} diff --git a/report/eventlist/classes/renderer.php b/report/eventlist/classes/renderer.php new file mode 100644 index 00000000000..fc1cbf1e529 --- /dev/null +++ b/report/eventlist/classes/renderer.php @@ -0,0 +1,175 @@ +. + +/** + * Event report renderer. + * + * @package report_eventlist + * @copyright 2014 Adrian Greeve + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +defined('MOODLE_INTERNAL') || die(); + +/** + * Renderer for event report. + * + * @package report_eventlist + * @copyright 2014 Adrian Greeve + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class report_eventlist_renderer extends plugin_renderer_base { + + /** + * Renders the event list page with filter form and datatable. + * + * @param eventfilter_form $form Event filter form. + * @param array $tabledata An array of event data to be used by the datatable. + * @return string HTML to be displayed. + */ + public function render_event_list($form, $tabledata) { + global $PAGE; + + $title = get_string('pluginname', 'report_eventlist'); + + // Header. + $html = $this->output->header(); + $html .= $this->output->heading($title); + + // Form. + ob_start(); + $form->display(); + $html .= ob_get_contents(); + ob_end_clean(); + + $PAGE->requires->yui_module('moodle-report_eventlist-eventfilter', 'Y.M.report_eventlist.EventFilter.init', + array(array('tabledata' => $tabledata))); + $PAGE->requires->strings_for_js(array( + 'eventname', + 'component', + 'action', + 'crud', + 'edulevel', + 'affectedtable', + 'dname', + 'legacyevent', + 'since' + ), 'report_eventlist'); + $html .= html_writer::start_div('report-eventlist-data-table', array('id' => 'report-eventlist-table')); + $html .= html_writer::end_div(); + + $html .= $this->output->footer(); + return $html; + } + + /** + * Event detail renderer. + * + * @param array $observerlist A list of observers that consume this event. + * @param array $eventinformation A list of information about the event. + * @return string HTML to be displayed. + */ + public function render_event_detail($observerlist, $eventinformation) { + global $PAGE; + + $titlehtml = $this->output->header(); + $titlehtml .= $this->output->heading($eventinformation['title']); + + $html = html_writer::start_tag('dl', array('class' => 'list')); + + $explanation = nl2br($eventinformation['explanation']); + $html .= html_writer::tag('dt', get_string('eventexplanation', 'report_eventlist')); + $html .= html_writer::tag('dd', $explanation); + + if (isset($eventinformation['crud'])) { + $html .= html_writer::tag('dt', get_string('crud', 'report_eventlist')); + $html .= html_writer::tag('dd', $eventinformation['crud']); + } + + if (isset($eventinformation['edulevel'])) { + $html .= html_writer::tag('dt', get_string('edulevel', 'report_eventlist')); + $html .= html_writer::tag('dd', $eventinformation['edulevel']); + } + + if (isset($eventinformation['objecttable'])) { + $html .= html_writer::tag('dt', get_string('affectedtable', 'report_eventlist')); + $html .= html_writer::tag('dd', $eventinformation['objecttable']); + } + + if (isset($eventinformation['legacyevent'])) { + $html .= html_writer::tag('dt', get_string('legacyevent', 'report_eventlist')); + $html .= html_writer::tag('dd', $eventinformation['legacyevent']); + } + + if (isset($eventinformation['parentclass'])) { + $url = new moodle_url('eventdetail.php', array('eventname' => $eventinformation['parentclass'])); + $html .= html_writer::tag('dt', get_string('parentevent', 'report_eventlist')); + $html .= html_writer::tag('dd', html_writer::link($url, $eventinformation['parentclass'])); + } + + if (isset($eventinformation['abstract'])) { + $html .= html_writer::tag('dt', get_string('abstractclass', 'report_eventlist')); + $html .= html_writer::tag('dd', get_string('yes', 'report_eventlist')); + } + + if (isset($eventinformation['typeparameter'])) { + $html .= html_writer::tag('dt', get_string('typedeclaration', 'report_eventlist')); + foreach ($eventinformation['typeparameter'] as $typeparameter) { + $html .= html_writer::tag('dd', $typeparameter); + } + } + + if (isset($eventinformation['otherparameter'])) { + $html .= html_writer::tag('dt', get_string('othereventparameters', 'report_eventlist')); + foreach ($eventinformation['otherparameter'] as $otherparameter) { + $html .= html_writer::tag('dd', $otherparameter); + } + } + + // List observers consuming this event if there are any. + if (!empty($observerlist)) { + $html .= html_writer::tag('dt', get_string('relatedobservers', 'report_eventlist')); + foreach ($observerlist as $observer) { + if ($observer->plugin == 'core') { + $html .= html_writer::tag('dd', $observer->plugin); + } else { + $manager = get_string_manager(); + $pluginstring = $observer->plugintype . '_' . $observer->plugin; + if ($manager->string_exists('pluginname', $pluginstring)) { + if (!empty($observer->parentplugin)) { + $string = get_string('pluginname', $pluginstring) . ' (' . $observer->parentplugin + . ' ' . $pluginstring . ')'; + } else { + $string = get_string('pluginname', $pluginstring) . ' (' . $pluginstring . ')'; + } + } else { + $string = $observer->plugintype . ' ' . $observer->plugin; + } + $html .= html_writer::tag('dd', $string); + } + } + } + $html .= html_writer::end_div(); + $html .= html_writer::end_tag('dl'); + + $pagecontent = new html_table(); + $pagecontent->data = array(array($html)); + $pagehtml = $titlehtml . html_writer::table($pagecontent); + $pagehtml .= $this->output->footer(); + + return $pagehtml; + } +} diff --git a/report/eventlist/eventdetail.php b/report/eventlist/eventdetail.php new file mode 100644 index 00000000000..2949aaf5d69 --- /dev/null +++ b/report/eventlist/eventdetail.php @@ -0,0 +1,140 @@ +. + +/** + * Event developer detail. + * + * @package report_eventlist + * @copyright 2014 Adrian Greeve + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +require_once(__DIR__ . '/../../config.php'); +require_once($CFG->libdir . '/adminlib.php'); + +// Required parameters. +$eventname = required_param('eventname', PARAM_RAW); + +admin_externalpage_setup('reporteventlists'); + +// Retrieve all events in a list. +$completelist = report_eventlist_list_generator::get_all_events_list(false); + +// Check that $eventname is a valid event. +if (!array_key_exists($eventname, $completelist)) { + print_error('errorinvalidevent', 'report_eventlist'); +} + +// Break up the full event name to usable parts. +$component = explode('\\', $eventname); +$directory = core_component::get_component_directory($component[1]); + +// File and directory information. +$directory = $directory . '/classes/event'; +// Verify that the directory is valid. +if (!is_dir($directory)) { + print_error('errorinvaliddirectory', 'report_eventlist'); +} +$filename = end($component); +$eventfiles = $directory . '/' . $filename . '.php'; +$title = $eventname::get_name(); + +// Define event information. +$eventinformation = array('title' => $title); +$eventcontents = file_get_contents($eventfiles); +$eventinformation['filecontents'] = $eventcontents; + +$ref = new \ReflectionClass($eventname); +$eventinformation['explanation'] = $eventname::get_explanation($eventname); +// Get event information nicely if we can. +if (!$ref->isAbstract()) { + $eventinformation = array_merge($eventinformation, $eventname::get_static_info()); + $eventinformation['legacyevent'] = $eventname::get_legacy_eventname(); + $eventinformation['crud'] = report_eventlist_list_generator::get_crud_string($eventinformation['crud']); + $eventinformation['edulevel'] = report_eventlist_list_generator::get_edulevel_string($eventinformation['edulevel']); +} else { + $eventinformation['abstract'] = true; + if ($eventname != '\core\event\base') { + // No choice but to get information the hard way. + // Strip out CRUD information. + $crudpattern = "/(\['crud'\]\s=\s')(\w)/"; + $result = array(); + preg_match($crudpattern, $eventcontents, $result); + if (!empty($result[2])) { + $eventinformation['crud'] = report_eventlist_list_generator::get_crud_string($result[2]); + } + + // Strip out edulevel information. + $edulevelpattern = "/(\['edulevel'\]\s=\sself\:\:)(\w*)/"; + $result = array(); + preg_match($edulevelpattern, $eventcontents, $result); + if (!empty($result[2])) { + $educationlevel = constant('\core\event\base::' . $result[2]); + $eventinformation['edulevel'] = report_eventlist_list_generator::get_edulevel_string($educationlevel); + } + + // Retrieve object table information. + $affectedtablepattern = "/(\['objecttable'\]\s=\s')(\w*)/"; + $result = array(); + preg_match($affectedtablepattern, $eventcontents, $result); + if (!empty($result[2])) { + $eventinformation['objecttable'] = $result[2]; + } + } +} + +// I can't think of a nice way to get the following information. +// Searching to see if @type has been used for the 'other' field in the event. +$othertypepattern = "/(@type\s([\w|\s|.]*))+/"; +$typeparams = array(); +preg_match_all($othertypepattern, $eventcontents, $typeparams); +if (!empty($typeparams[2])) { + $eventinformation['typeparameter'] = array(); + foreach ($typeparams[2] as $typeparameter) { + $eventinformation['typeparameter'][] = $typeparameter; + } +} + +// Retrieving the 'other' event field information. +$otherpattern = "/(\*\s{5}-([\w|\s]*\:[\w|\s|\(|\)|.]*))/"; +$typeparams = array(); +preg_match_all($otherpattern, $eventcontents, $typeparams); +if (!empty($typeparams[2])) { + $eventinformation['otherparameter'] = array(); + foreach ($typeparams[2] as $typeparameter) { + $eventinformation['otherparameter'][] = $typeparameter; + } +} + +// Get parent class information. +if ($parentclass = get_parent_class($eventname)) { + $eventinformation['parentclass'] = '\\' . $parentclass; +} + +// Fetch all the observers to be matched with this event. +$allobserverslist = report_eventlist_list_generator::get_observer_list(); +$observers = array(); + +if (isset($allobserverslist['\\core\\event\\base'])) { + $observers = $allobserverslist['\\core\\event\\base']; +} +if (isset($allobserverslist[$eventname])) { + $observers = array_merge($observers, $allobserverslist[$eventname]); +} + +// OUTPUT. +$renderer = $PAGE->get_renderer('report_eventlist'); +echo $renderer->render_event_detail($observers, $eventinformation); + diff --git a/report/eventlist/index.php b/report/eventlist/index.php new file mode 100644 index 00000000000..9d1e40c4a39 --- /dev/null +++ b/report/eventlist/index.php @@ -0,0 +1,53 @@ +. + +/** + * Event documentation. + * + * @package report_eventlist + * @copyright 2014 Adrian Greeve + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +require_once(__DIR__ . '/../../config.php'); +require_once($CFG->libdir . '/adminlib.php'); + +admin_externalpage_setup('reporteventlists'); + +// Retrieve all events in a list. +$completelist = report_eventlist_list_generator::get_all_events_list(); + +$tabledata = array(); +$components = array('0' => get_string('all', 'report_eventlist')); +$edulevel = array('0' => get_string('all', 'report_eventlist')); +$crud = array('0' => get_string('all', 'report_eventlist')); +foreach ($completelist as $value) { + $components[] = $value['component']; + $edulevel[] = $value['edulevel']; + $crud[] = $value['crud']; + $tabledata[] = (object)$value; +} +$components = array_unique($components); +$edulevel = array_unique($edulevel); +$crud = array_unique($crud); + +// Create the filter form for the table. +$filtersection = new report_eventlist_filter_form(null, array('components' => $components, 'edulevel' => $edulevel, + 'crud' => $crud)); + +// Output. +$renderer = $PAGE->get_renderer('report_eventlist'); +echo $renderer->render_event_list($filtersection, $tabledata); + diff --git a/report/eventlist/lang/en/report_eventlist.php b/report/eventlist/lang/en/report_eventlist.php new file mode 100644 index 00000000000..cd82c8b8391 --- /dev/null +++ b/report/eventlist/lang/en/report_eventlist.php @@ -0,0 +1,59 @@ +. + +/** + * Strings for component 'report_event', language 'en', branch 'MOODLE_27_STABLE' + * + * @package report_eventlist + * @copyright 2014 Adrian Greeve + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +$string['abstractclass'] = 'Abstract class'; +$string['action'] = 'Action'; +$string['affectedtable'] = 'Affected table'; +$string['all'] = 'All'; +$string['clear'] = 'Clear'; +$string['component'] = 'Component'; +$string['create'] = 'create'; +$string['crud'] = 'Database query type'; +$string['delete'] = 'delete'; +$string['details'] = 'Details'; +$string['dname'] = 'Name'; +$string['edulevel'] = 'Education level'; +$string['errorinvalidevent'] = 'The event provided is not a valid event.'; +$string['errorinvaliddirectory'] = 'The event directory does not exist or is invalid.'; +$string['eventcode'] = 'Event Code'; +$string['eventexplanation'] = 'Explanation of the event'; +$string['eventname'] = 'Event name'; +$string['filter'] = 'Filter'; +$string['legacyevent'] = 'Legacy event'; +$string['name'] = 'Name'; +$string['objecttable'] = 'Object table'; +$string['other'] = 'Other'; +$string['otherinformation'] = 'Other information:'; +$string['othereventparameters'] = 'Other event parameters'; +$string['parentevent'] = 'Parent Event'; +$string['participating'] = 'Participating'; +$string['pluginname'] = 'Events list'; +$string['read'] = 'read'; +$string['relatedobservers'] = 'Plugins observering this event'; +$string['since'] = 'Since'; +$string['teaching'] = 'Teaching'; +$string['typedeclaration'] = 'Other event parameters'; +$string['update'] = 'update'; +$string['yes'] = 'yes'; + diff --git a/report/eventlist/settings.php b/report/eventlist/settings.php new file mode 100644 index 00000000000..f8c168654b7 --- /dev/null +++ b/report/eventlist/settings.php @@ -0,0 +1,30 @@ +. + +/** + * Adds the event list link to the admin tree + * + * @package report_eventlist + * @copyright 2014 Adrian Greeve + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +defined('MOODLE_INTERNAL') || die(); + +if ($hassiteconfig) { + $url = $CFG->wwwroot . '/report/eventlist/index.php'; + $ADMIN->add('reports', new admin_externalpage('reporteventlists', get_string('pluginname', 'report_eventlist'), $url)); +} diff --git a/report/eventlist/styles.css b/report/eventlist/styles.css new file mode 100644 index 00000000000..c7b83e8a0e9 --- /dev/null +++ b/report/eventlist/styles.css @@ -0,0 +1,79 @@ +.report-eventlist-name { + color: #888; + font-size: 0.75em; +} + +.report-eventlist-datatable-table > div > table { + width: 100%; +} + +#page-admin-report-eventlist-index dt { + float: left; + clear: left; + text-align: right; + padding-right: 1em; + width: 20em; + +} + +#page-admin-report-eventlist-index dd { + display: block; + float: left; + text-align: left; + margin-left: 0; +} + +#page-admin-report-eventlist-index dd + dd { + clear: left; + margin-left: 21em; +} + +@media (max-width : 767px) { + #page-admin-report-eventlist-index dt { + width: 100%; + text-align: left; + } + + #page-admin-report-eventlist-index dd { + margin-left: 0; + } + + #page-admin-report-eventlist-index dd + dd { + margin-left: 0; + } +} + +#page-admin-report-eventlist-index.dir-rtl dt { + float: right; + clear: right; + text-align: left; + padding-left: 1em; + width: 20em; +} + +#page-admin-report-eventlist-index.dir-rtl dd { + display: block; + float: right; + text-align: right; + margin-right: 0; +} + +#page-admin-report-eventlist-index.dir-rtl dd + dd { + clear: right; + margin-right: 22em; +} + +@media (max-width : 767px) { + #page-admin-report-eventlist-index.dir-rtl dt { + width: 100%; + text-align: right; + } + + #page-admin-report-eventlist-index.dir-rtl dd { + margin-right: 1em; + } + + #page-admin-report-eventlist-index.dir-rtl dd + dd { + margin-right: 1em; + } +} \ No newline at end of file diff --git a/report/eventlist/version.php b/report/eventlist/version.php new file mode 100644 index 00000000000..8e41bf661f7 --- /dev/null +++ b/report/eventlist/version.php @@ -0,0 +1,29 @@ +. + +/** + * Version details. + * + * @package report_eventlist + * @copyright 2014 Adrian Greeve + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +defined('MOODLE_INTERNAL') || die(); + +$plugin->version = 2014032800; // The current plugin version (Date: YYYYMMDDXX). +$plugin->requires = 2014032700; // Requires this Moodle version. +$plugin->component = 'report_eventlist'; // Full name of the plugin (used for diagnostics). diff --git a/report/eventlist/yui/build/moodle-report_eventlist-eventfilter/moodle-report_eventlist-eventfilter-debug.js b/report/eventlist/yui/build/moodle-report_eventlist-eventfilter/moodle-report_eventlist-eventfilter-debug.js new file mode 100644 index 00000000000..08010cef22e --- /dev/null +++ b/report/eventlist/yui/build/moodle-report_eventlist-eventfilter/moodle-report_eventlist-eventfilter-debug.js @@ -0,0 +1,262 @@ +YUI.add('moodle-report_eventlist-eventfilter', function (Y, NAME) { + +/** + * A tool for displaying and filtering system events. + * + * @module moodle-report_eventlist-eventfilter + */ + +/** + * A tool for displaying and filtering system events. + * + * @class M.report_eventlist.EventFilter + * @extends Base + * @constructor + */ +function EventFilter() { + EventFilter.superclass.constructor.apply(this, arguments); +} + +var SELECTORS = { + EVENTNAME: '#id_eventname', + EVENTCOMPONENT: '#id_eventcomponent', + EVENTEDULEVEL: '#id_eventedulevel', + EVENTCRUD: '#id_eventcrud', + FILTERBUTTON : '#id_filterbutton', + CLEARBUTTON : '#id_clearbutton' + }; + +Y.extend(EventFilter, Y.Base, { + + /** + * A reference to the datatable. + * + * @property _table + * @type DataTable + * @private + */ + _table: null, + /** + * A reference to the eventname text element. + * + * @property _eventName + * @type node + * @private + */ + _eventName: null, + /** + * A reference to the component select box element. + * + * @property _component + * @type node + * @private + */ + _component: null, + /** + * A reference to the education level select box element. + * + * @property _eduLevel + * @type node + * @private + */ + _eduLevel: null, + /** + * A reference to the CRUD select box element. + * + * @property _crud + * @type node + * @private + */ + _crud: null, + + /** + * Initializer. + * Basic setup and delegations. + * + * @method initializer + */ + initializer: function() { + + var filterButton = Y.one(SELECTORS.FILTERBUTTON), + clearButton = Y.one(SELECTORS.CLEARBUTTON); + + this._createTable(this.get('tabledata')); + this._eventName = Y.one(SELECTORS.EVENTNAME); + this._component = Y.one(SELECTORS.EVENTCOMPONENT); + this._eduLevel = Y.one(SELECTORS.EVENTEDULEVEL); + this._crud = Y.one(SELECTORS.EVENTCRUD); + + this._eventName.on('valuechange', this._totalFilter, this); + filterButton.on('click', this._totalFilter, this); + clearButton.on('click', this._clearFilter, this); + }, + + /** + * Create the table for displaying all of the event information. + * + * @param {array} tableData Event data for populating the table. + * @method _createTable + * @private + * @chainable + */ + _createTable: function(tableData) { + + var table = new Y.DataTable({ + columns: [ + { + key: "fulleventname", + label: M.util.get_string('eventname', 'report_eventlist'), + allowHTML: true, + sortable: true, + title: M.util.get_string('eventname', 'report_eventlist') + }, { + key: "component", + label: M.util.get_string('component', 'report_eventlist'), + allowHTML: true, + sortable: true, + title: M.util.get_string('component', 'report_eventlist') + }, { + key: "edulevel", + label: M.util.get_string('edulevel', 'report_eventlist'), + sortable: true, + title: M.util.get_string('edulevel', 'report_eventlist') + }, { + key: "crud", + label: M.util.get_string('crud', 'report_eventlist'), + sortable: true, + title: M.util.get_string('crud', 'report_eventlist') + }, { + key: "objecttable", + label: M.util.get_string('affectedtable', 'report_eventlist'), + sortable: true, + title: M.util.get_string('affectedtable', 'report_eventlist') + }, { + key: "since", + label: M.util.get_string('since', 'report_eventlist'), + sortable: true, + title: M.util.get_string('since', 'report_eventlist') + }, { + key: "legacyevent", + label: M.util.get_string('legacyevent', 'report_eventlist'), + sortable: true, + title: M.util.get_string('legacyevent', 'report_eventlist') + } + ], + data: tableData, + strings: { + sortBy: '{title}', + reverseSortBy: '{title}' + } + }); + + // Display the table. + table.render("#report-eventlist-table"); + table.get('boundingBox').addClass('report-eventlist-datatable-table'); + this._table = table; + return this; + }, + + /** + * Filters the entries being displayed in the table. + * + * @method totalFilter + * @private + */ + _totalFilter: function() { + // Get all of the details of the filter elements + var eventNameFilter = this._eventName.get('value').toLowerCase(), + // Component selected text. + componentFilter = this._component.get('options').item(this._component.get('selectedIndex')).get('text').toLowerCase(), + // Component selected value. + componentValue = this._component.get('value'), + // Education level selected text. + eduLevelFilter = this._eduLevel.get('options').item(this._eduLevel.get('selectedIndex')).get('text').toLowerCase(), + // Education level selected value. + eduLevelValue = this._eduLevel.get('value'), + // CRUD selected text. + crudFilter = this._crud.get('options').item(this._crud.get('selectedIndex')).get('text').toLowerCase(), + // CRUD selected value. + crudValue = this._crud.get('value'), + i, + filtered = []; + + // Loop through the rows and put the ones we want into the filter. + for (i = 0; i < this.get('tabledata').length; i++) { + // These variables will either be false or true depending on the statement outcome. + var fullEventText = Y.Node.create(this.get('tabledata')[i].fulleventname).get('text'), + eventNameValue = fullEventText.toLowerCase().indexOf(eventNameFilter) >= 0, + componentFilterValue = this.get('tabledata')[i].component.toLowerCase().indexOf(componentFilter) >= 0, + eduLevelFilterValue = this.get('tabledata')[i].edulevel.toLowerCase().indexOf(eduLevelFilter) >= 0, + crudFilterValue = this.get('tabledata')[i].crud.toLowerCase().indexOf(crudFilter) >= 0; + // If the name field is empty then add to the filter. + if (eventNameFilter === '') { + eventNameValue = true; + } + // If the component is set to 'all' then add to the filter. + if (componentValue === '0') { + componentFilterValue = true; + } + // If the education level is set to 'all' then add to the filter. + if (eduLevelValue === '0') { + eduLevelFilterValue = true; + } + // If the CRUD field is set to 'all' then add to the filter. + if (crudValue === '0') { + crudFilterValue = true; + } + // If any of the Values here is false then don't add to the filter (all must be true). + if (eventNameValue && componentFilterValue && eduLevelFilterValue && crudFilterValue) { + filtered.push(this.get('tabledata')[i]); + } + } + // Display the table again with the new data. + this._table.set('data', filtered); + }, + + /** + * Clears the filtered table data and changes the filter form to default. + * + * @method _clearFilter + * @private + */ + _clearFilter: function() { + // Reset filter form elements + this._eventName.set('value', ''); + this._component.set('value', '0'); + this._eduLevel.set('value', '0'); + this._crud.set('value', '0'); + // Reset the table data back to the original. + this._table.set('data', this.get('tabledata')); + } +}, { + NAME: 'eventFilter', + ATTRS: { + /** + * Data for the table. + * + * @attribute tabledata. + * @type Array + * @writeOnce + */ + tabledata: { + value: null + } + } +}); + +Y.namespace('M.report_eventlist.EventFilter').init = function(config) { + return new EventFilter(config); +}; + + +}, '@VERSION@', { + "requires": [ + "base", + "event", + "node", + "node-event-delegate", + "datatable", + "autocomplete", + "autocomplete-filters" + ] +}); diff --git a/report/eventlist/yui/build/moodle-report_eventlist-eventfilter/moodle-report_eventlist-eventfilter-min.js b/report/eventlist/yui/build/moodle-report_eventlist-eventfilter/moodle-report_eventlist-eventfilter-min.js new file mode 100644 index 00000000000..43f2c3c46ad --- /dev/null +++ b/report/eventlist/yui/build/moodle-report_eventlist-eventfilter/moodle-report_eventlist-eventfilter-min.js @@ -0,0 +1 @@ +YUI.add("moodle-report_eventlist-eventfilter",function(e,t){function n(){n.superclass.constructor.apply(this,arguments)}var r={EVENTNAME:"#id_eventname",EVENTCOMPONENT:"#id_eventcomponent",EVENTEDULEVEL:"#id_eventedulevel",EVENTCRUD:"#id_eventcrud",FILTERBUTTON:"#id_filterbutton",CLEARBUTTON:"#id_clearbutton"};e.extend(n,e.Base,{_table:null,_eventName:null,_component:null,_eduLevel:null,_crud:null,initializer:function(){var t=e.one(r.FILTERBUTTON),n=e.one(r.CLEARBUTTON);this._createTable(this.get("tabledata")),this._eventName=e.one(r.EVENTNAME),this._component=e.one(r.EVENTCOMPONENT),this._eduLevel=e.one(r.EVENTEDULEVEL),this._crud=e.one(r.EVENTCRUD),this._eventName.on("valuechange",this._totalFilter,this),t.on("click",this._totalFilter,this),n.on("click",this._clearFilter,this)},_createTable:function(t){var n=new e.DataTable({columns:[{key:"fulleventname",label:M.util.get_string("eventname","report_eventlist"),allowHTML:!0,sortable:!0,title:M.util.get_string("eventname","report_eventlist")},{key:"component",label:M.util.get_string("component","report_eventlist"),allowHTML:!0,sortable:!0,title:M.util.get_string("component","report_eventlist")},{key:"edulevel",label:M.util.get_string("edulevel","report_eventlist"),sortable:!0,title:M.util.get_string("edulevel","report_eventlist")},{key:"crud",label:M.util.get_string("crud","report_eventlist"),sortable:!0,title:M.util.get_string("crud","report_eventlist")},{key:"objecttable",label:M.util.get_string("affectedtable","report_eventlist"),sortable:!0,title:M.util.get_string("affectedtable","report_eventlist")},{key:"since",label:M.util.get_string("since","report_eventlist"),sortable:!0,title:M.util.get_string("since","report_eventlist")},{key:"legacyevent",label:M.util.get_string("legacyevent","report_eventlist"),sortable:!0,title:M.util.get_string("legacyevent","report_eventlist")}],data:t,strings:{sortBy:"{title}",reverseSortBy:"{title}"}});return n.render("#report-eventlist-table"),n.get("boundingBox").addClass("report-eventlist-datatable-table"),this._table=n,this},_totalFilter:function(){var t=this._eventName.get("value").toLowerCase(),n=this._component.get("options").item(this._component.get("selectedIndex")).get("text").toLowerCase(),r=this._component.get("value"),i=this._eduLevel.get("options").item(this._eduLevel.get("selectedIndex")).get("text").toLowerCase(),s=this._eduLevel.get("value"),o=this._crud.get("options").item(this._crud.get("selectedIndex")).get("text").toLowerCase(),u=this._crud.get("value"),a,f=[];for(a=0;a=0,h=this.get("tabledata")[a].component.toLowerCase().indexOf(n)>=0,p=this.get("tabledata")[a].edulevel.toLowerCase().indexOf(i)>=0,d=this.get("tabledata")[a].crud.toLowerCase().indexOf(o)>=0;t===""&&(c=!0),r==="0"&&(h=!0),s==="0"&&(p=!0),u==="0"&&(d=!0),c&&h&&p&&d&&f.push(this.get("tabledata")[a])}this._table.set("data",f)},_clearFilter:function(){this._eventName.set("value",""),this._component.set("value","0"),this._eduLevel.set("value","0"),this._crud.set("value","0"),this._table.set("data",this.get("tabledata"))}},{NAME:"eventFilter",ATTRS:{tabledata:{value:null}}}),e.namespace("M.report_eventlist.EventFilter").init=function(e){return new n(e)}},"@VERSION@",{requires:["base","event","node","node-event-delegate","datatable","autocomplete","autocomplete-filters"]}); diff --git a/report/eventlist/yui/build/moodle-report_eventlist-eventfilter/moodle-report_eventlist-eventfilter.js b/report/eventlist/yui/build/moodle-report_eventlist-eventfilter/moodle-report_eventlist-eventfilter.js new file mode 100644 index 00000000000..08010cef22e --- /dev/null +++ b/report/eventlist/yui/build/moodle-report_eventlist-eventfilter/moodle-report_eventlist-eventfilter.js @@ -0,0 +1,262 @@ +YUI.add('moodle-report_eventlist-eventfilter', function (Y, NAME) { + +/** + * A tool for displaying and filtering system events. + * + * @module moodle-report_eventlist-eventfilter + */ + +/** + * A tool for displaying and filtering system events. + * + * @class M.report_eventlist.EventFilter + * @extends Base + * @constructor + */ +function EventFilter() { + EventFilter.superclass.constructor.apply(this, arguments); +} + +var SELECTORS = { + EVENTNAME: '#id_eventname', + EVENTCOMPONENT: '#id_eventcomponent', + EVENTEDULEVEL: '#id_eventedulevel', + EVENTCRUD: '#id_eventcrud', + FILTERBUTTON : '#id_filterbutton', + CLEARBUTTON : '#id_clearbutton' + }; + +Y.extend(EventFilter, Y.Base, { + + /** + * A reference to the datatable. + * + * @property _table + * @type DataTable + * @private + */ + _table: null, + /** + * A reference to the eventname text element. + * + * @property _eventName + * @type node + * @private + */ + _eventName: null, + /** + * A reference to the component select box element. + * + * @property _component + * @type node + * @private + */ + _component: null, + /** + * A reference to the education level select box element. + * + * @property _eduLevel + * @type node + * @private + */ + _eduLevel: null, + /** + * A reference to the CRUD select box element. + * + * @property _crud + * @type node + * @private + */ + _crud: null, + + /** + * Initializer. + * Basic setup and delegations. + * + * @method initializer + */ + initializer: function() { + + var filterButton = Y.one(SELECTORS.FILTERBUTTON), + clearButton = Y.one(SELECTORS.CLEARBUTTON); + + this._createTable(this.get('tabledata')); + this._eventName = Y.one(SELECTORS.EVENTNAME); + this._component = Y.one(SELECTORS.EVENTCOMPONENT); + this._eduLevel = Y.one(SELECTORS.EVENTEDULEVEL); + this._crud = Y.one(SELECTORS.EVENTCRUD); + + this._eventName.on('valuechange', this._totalFilter, this); + filterButton.on('click', this._totalFilter, this); + clearButton.on('click', this._clearFilter, this); + }, + + /** + * Create the table for displaying all of the event information. + * + * @param {array} tableData Event data for populating the table. + * @method _createTable + * @private + * @chainable + */ + _createTable: function(tableData) { + + var table = new Y.DataTable({ + columns: [ + { + key: "fulleventname", + label: M.util.get_string('eventname', 'report_eventlist'), + allowHTML: true, + sortable: true, + title: M.util.get_string('eventname', 'report_eventlist') + }, { + key: "component", + label: M.util.get_string('component', 'report_eventlist'), + allowHTML: true, + sortable: true, + title: M.util.get_string('component', 'report_eventlist') + }, { + key: "edulevel", + label: M.util.get_string('edulevel', 'report_eventlist'), + sortable: true, + title: M.util.get_string('edulevel', 'report_eventlist') + }, { + key: "crud", + label: M.util.get_string('crud', 'report_eventlist'), + sortable: true, + title: M.util.get_string('crud', 'report_eventlist') + }, { + key: "objecttable", + label: M.util.get_string('affectedtable', 'report_eventlist'), + sortable: true, + title: M.util.get_string('affectedtable', 'report_eventlist') + }, { + key: "since", + label: M.util.get_string('since', 'report_eventlist'), + sortable: true, + title: M.util.get_string('since', 'report_eventlist') + }, { + key: "legacyevent", + label: M.util.get_string('legacyevent', 'report_eventlist'), + sortable: true, + title: M.util.get_string('legacyevent', 'report_eventlist') + } + ], + data: tableData, + strings: { + sortBy: '{title}', + reverseSortBy: '{title}' + } + }); + + // Display the table. + table.render("#report-eventlist-table"); + table.get('boundingBox').addClass('report-eventlist-datatable-table'); + this._table = table; + return this; + }, + + /** + * Filters the entries being displayed in the table. + * + * @method totalFilter + * @private + */ + _totalFilter: function() { + // Get all of the details of the filter elements + var eventNameFilter = this._eventName.get('value').toLowerCase(), + // Component selected text. + componentFilter = this._component.get('options').item(this._component.get('selectedIndex')).get('text').toLowerCase(), + // Component selected value. + componentValue = this._component.get('value'), + // Education level selected text. + eduLevelFilter = this._eduLevel.get('options').item(this._eduLevel.get('selectedIndex')).get('text').toLowerCase(), + // Education level selected value. + eduLevelValue = this._eduLevel.get('value'), + // CRUD selected text. + crudFilter = this._crud.get('options').item(this._crud.get('selectedIndex')).get('text').toLowerCase(), + // CRUD selected value. + crudValue = this._crud.get('value'), + i, + filtered = []; + + // Loop through the rows and put the ones we want into the filter. + for (i = 0; i < this.get('tabledata').length; i++) { + // These variables will either be false or true depending on the statement outcome. + var fullEventText = Y.Node.create(this.get('tabledata')[i].fulleventname).get('text'), + eventNameValue = fullEventText.toLowerCase().indexOf(eventNameFilter) >= 0, + componentFilterValue = this.get('tabledata')[i].component.toLowerCase().indexOf(componentFilter) >= 0, + eduLevelFilterValue = this.get('tabledata')[i].edulevel.toLowerCase().indexOf(eduLevelFilter) >= 0, + crudFilterValue = this.get('tabledata')[i].crud.toLowerCase().indexOf(crudFilter) >= 0; + // If the name field is empty then add to the filter. + if (eventNameFilter === '') { + eventNameValue = true; + } + // If the component is set to 'all' then add to the filter. + if (componentValue === '0') { + componentFilterValue = true; + } + // If the education level is set to 'all' then add to the filter. + if (eduLevelValue === '0') { + eduLevelFilterValue = true; + } + // If the CRUD field is set to 'all' then add to the filter. + if (crudValue === '0') { + crudFilterValue = true; + } + // If any of the Values here is false then don't add to the filter (all must be true). + if (eventNameValue && componentFilterValue && eduLevelFilterValue && crudFilterValue) { + filtered.push(this.get('tabledata')[i]); + } + } + // Display the table again with the new data. + this._table.set('data', filtered); + }, + + /** + * Clears the filtered table data and changes the filter form to default. + * + * @method _clearFilter + * @private + */ + _clearFilter: function() { + // Reset filter form elements + this._eventName.set('value', ''); + this._component.set('value', '0'); + this._eduLevel.set('value', '0'); + this._crud.set('value', '0'); + // Reset the table data back to the original. + this._table.set('data', this.get('tabledata')); + } +}, { + NAME: 'eventFilter', + ATTRS: { + /** + * Data for the table. + * + * @attribute tabledata. + * @type Array + * @writeOnce + */ + tabledata: { + value: null + } + } +}); + +Y.namespace('M.report_eventlist.EventFilter').init = function(config) { + return new EventFilter(config); +}; + + +}, '@VERSION@', { + "requires": [ + "base", + "event", + "node", + "node-event-delegate", + "datatable", + "autocomplete", + "autocomplete-filters" + ] +}); diff --git a/report/eventlist/yui/src/eventfilter/build.json b/report/eventlist/yui/src/eventfilter/build.json new file mode 100644 index 00000000000..5741b6b7193 --- /dev/null +++ b/report/eventlist/yui/src/eventfilter/build.json @@ -0,0 +1,10 @@ +{ + "name": "moodle-report_eventlist-eventfilter", + "builds": { + "moodle-report_eventlist-eventfilter": { + "jsfiles": [ + "eventfilter.js" + ] + } + } +} \ No newline at end of file diff --git a/report/eventlist/yui/src/eventfilter/js/eventfilter.js b/report/eventlist/yui/src/eventfilter/js/eventfilter.js new file mode 100644 index 00000000000..0bdf024b362 --- /dev/null +++ b/report/eventlist/yui/src/eventfilter/js/eventfilter.js @@ -0,0 +1,247 @@ +/** + * A tool for displaying and filtering system events. + * + * @module moodle-report_eventlist-eventfilter + */ + +/** + * A tool for displaying and filtering system events. + * + * @class M.report_eventlist.EventFilter + * @extends Base + * @constructor + */ +function EventFilter() { + EventFilter.superclass.constructor.apply(this, arguments); +} + +var SELECTORS = { + EVENTNAME: '#id_eventname', + EVENTCOMPONENT: '#id_eventcomponent', + EVENTEDULEVEL: '#id_eventedulevel', + EVENTCRUD: '#id_eventcrud', + FILTERBUTTON : '#id_filterbutton', + CLEARBUTTON : '#id_clearbutton' + }; + +Y.extend(EventFilter, Y.Base, { + + /** + * A reference to the datatable. + * + * @property _table + * @type DataTable + * @private + */ + _table: null, + /** + * A reference to the eventname text element. + * + * @property _eventName + * @type node + * @private + */ + _eventName: null, + /** + * A reference to the component select box element. + * + * @property _component + * @type node + * @private + */ + _component: null, + /** + * A reference to the education level select box element. + * + * @property _eduLevel + * @type node + * @private + */ + _eduLevel: null, + /** + * A reference to the CRUD select box element. + * + * @property _crud + * @type node + * @private + */ + _crud: null, + + /** + * Initializer. + * Basic setup and delegations. + * + * @method initializer + */ + initializer: function() { + + var filterButton = Y.one(SELECTORS.FILTERBUTTON), + clearButton = Y.one(SELECTORS.CLEARBUTTON); + + this._createTable(this.get('tabledata')); + this._eventName = Y.one(SELECTORS.EVENTNAME); + this._component = Y.one(SELECTORS.EVENTCOMPONENT); + this._eduLevel = Y.one(SELECTORS.EVENTEDULEVEL); + this._crud = Y.one(SELECTORS.EVENTCRUD); + + this._eventName.on('valuechange', this._totalFilter, this); + filterButton.on('click', this._totalFilter, this); + clearButton.on('click', this._clearFilter, this); + }, + + /** + * Create the table for displaying all of the event information. + * + * @param {array} tableData Event data for populating the table. + * @method _createTable + * @private + * @chainable + */ + _createTable: function(tableData) { + + var table = new Y.DataTable({ + columns: [ + { + key: "fulleventname", + label: M.util.get_string('eventname', 'report_eventlist'), + allowHTML: true, + sortable: true, + title: M.util.get_string('eventname', 'report_eventlist') + }, { + key: "component", + label: M.util.get_string('component', 'report_eventlist'), + allowHTML: true, + sortable: true, + title: M.util.get_string('component', 'report_eventlist') + }, { + key: "edulevel", + label: M.util.get_string('edulevel', 'report_eventlist'), + sortable: true, + title: M.util.get_string('edulevel', 'report_eventlist') + }, { + key: "crud", + label: M.util.get_string('crud', 'report_eventlist'), + sortable: true, + title: M.util.get_string('crud', 'report_eventlist') + }, { + key: "objecttable", + label: M.util.get_string('affectedtable', 'report_eventlist'), + sortable: true, + title: M.util.get_string('affectedtable', 'report_eventlist') + }, { + key: "since", + label: M.util.get_string('since', 'report_eventlist'), + sortable: true, + title: M.util.get_string('since', 'report_eventlist') + }, { + key: "legacyevent", + label: M.util.get_string('legacyevent', 'report_eventlist'), + sortable: true, + title: M.util.get_string('legacyevent', 'report_eventlist') + } + ], + data: tableData, + strings: { + sortBy: '{title}', + reverseSortBy: '{title}' + } + }); + + // Display the table. + table.render("#report-eventlist-table"); + table.get('boundingBox').addClass('report-eventlist-datatable-table'); + this._table = table; + return this; + }, + + /** + * Filters the entries being displayed in the table. + * + * @method totalFilter + * @private + */ + _totalFilter: function() { + // Get all of the details of the filter elements + var eventNameFilter = this._eventName.get('value').toLowerCase(), + // Component selected text. + componentFilter = this._component.get('options').item(this._component.get('selectedIndex')).get('text').toLowerCase(), + // Component selected value. + componentValue = this._component.get('value'), + // Education level selected text. + eduLevelFilter = this._eduLevel.get('options').item(this._eduLevel.get('selectedIndex')).get('text').toLowerCase(), + // Education level selected value. + eduLevelValue = this._eduLevel.get('value'), + // CRUD selected text. + crudFilter = this._crud.get('options').item(this._crud.get('selectedIndex')).get('text').toLowerCase(), + // CRUD selected value. + crudValue = this._crud.get('value'), + i, + filtered = []; + + // Loop through the rows and put the ones we want into the filter. + for (i = 0; i < this.get('tabledata').length; i++) { + // These variables will either be false or true depending on the statement outcome. + var fullEventText = Y.Node.create(this.get('tabledata')[i].fulleventname).get('text'), + eventNameValue = fullEventText.toLowerCase().indexOf(eventNameFilter) >= 0, + componentFilterValue = this.get('tabledata')[i].component.toLowerCase().indexOf(componentFilter) >= 0, + eduLevelFilterValue = this.get('tabledata')[i].edulevel.toLowerCase().indexOf(eduLevelFilter) >= 0, + crudFilterValue = this.get('tabledata')[i].crud.toLowerCase().indexOf(crudFilter) >= 0; + // If the name field is empty then add to the filter. + if (eventNameFilter === '') { + eventNameValue = true; + } + // If the component is set to 'all' then add to the filter. + if (componentValue === '0') { + componentFilterValue = true; + } + // If the education level is set to 'all' then add to the filter. + if (eduLevelValue === '0') { + eduLevelFilterValue = true; + } + // If the CRUD field is set to 'all' then add to the filter. + if (crudValue === '0') { + crudFilterValue = true; + } + // If any of the Values here is false then don't add to the filter (all must be true). + if (eventNameValue && componentFilterValue && eduLevelFilterValue && crudFilterValue) { + filtered.push(this.get('tabledata')[i]); + } + } + // Display the table again with the new data. + this._table.set('data', filtered); + }, + + /** + * Clears the filtered table data and changes the filter form to default. + * + * @method _clearFilter + * @private + */ + _clearFilter: function() { + // Reset filter form elements + this._eventName.set('value', ''); + this._component.set('value', '0'); + this._eduLevel.set('value', '0'); + this._crud.set('value', '0'); + // Reset the table data back to the original. + this._table.set('data', this.get('tabledata')); + } +}, { + NAME: 'eventFilter', + ATTRS: { + /** + * Data for the table. + * + * @attribute tabledata. + * @type Array + * @writeOnce + */ + tabledata: { + value: null + } + } +}); + +Y.namespace('M.report_eventlist.EventFilter').init = function(config) { + return new EventFilter(config); +}; diff --git a/report/eventlist/yui/src/eventfilter/meta/eventfilter.json b/report/eventlist/yui/src/eventfilter/meta/eventfilter.json new file mode 100644 index 00000000000..72b79b2407a --- /dev/null +++ b/report/eventlist/yui/src/eventfilter/meta/eventfilter.json @@ -0,0 +1,13 @@ +{ + "moodle-report_eventlist-eventfilter": { + "requires": [ + "base", + "event", + "node", + "node-event-delegate", + "datatable", + "autocomplete", + "autocomplete-filters" + ] + } +} \ No newline at end of file