From 7f6e3eefd1f9c4696674e93aa6b123334498e201 Mon Sep 17 00:00:00 2001 From: Frederic Massart Date: Tue, 1 Oct 2013 13:48:35 +0800 Subject: [PATCH] MDL-40060 mod_book: Replace add_to_log with events --- mod/book/classes/event/chapter_created.php | 88 +++++++ mod/book/classes/event/chapter_deleted.php | 100 ++++++++ mod/book/classes/event/chapter_updated.php | 88 +++++++ mod/book/classes/event/chapter_viewed.php | 97 ++++++++ .../classes/event/course_module_viewed.php | 97 ++++++++ .../classes/event/instances_list_viewed.php | 73 ++++++ mod/book/delete.php | 20 +- mod/book/edit.php | 16 +- mod/book/index.php | 6 +- mod/book/lang/en/book.php | 8 +- mod/book/move.php | 9 + mod/book/show.php | 16 ++ mod/book/tests/events_test.php | 224 ++++++++++++++++++ .../classes/event/book_exported.php | 85 +++++++ mod/book/tool/exportimscp/index.php | 8 +- .../lang/en/booktool_exportimscp.php | 1 + .../tool/exportimscp/tests/events_test.php | 72 ++++++ mod/book/tool/importhtml/locallib.php | 8 +- .../importhtml/tests/fixtures/chapters.zip | Bin 0 -> 1567 bytes .../tool/importhtml/tests/locallib_test.php | 76 ++++++ .../tool/print/classes/event/book_printed.php | 85 +++++++ .../print/classes/event/chapter_printed.php | 85 +++++++ mod/book/tool/print/index.php | 17 +- .../tool/print/lang/en/booktool_print.php | 2 + mod/book/tool/print/tests/events_test.php | 103 ++++++++ mod/book/view.php | 17 +- 26 files changed, 1389 insertions(+), 12 deletions(-) create mode 100644 mod/book/classes/event/chapter_created.php create mode 100644 mod/book/classes/event/chapter_deleted.php create mode 100644 mod/book/classes/event/chapter_updated.php create mode 100644 mod/book/classes/event/chapter_viewed.php create mode 100644 mod/book/classes/event/course_module_viewed.php create mode 100644 mod/book/classes/event/instances_list_viewed.php create mode 100644 mod/book/tests/events_test.php create mode 100644 mod/book/tool/exportimscp/classes/event/book_exported.php create mode 100644 mod/book/tool/exportimscp/tests/events_test.php create mode 100644 mod/book/tool/importhtml/tests/fixtures/chapters.zip create mode 100644 mod/book/tool/importhtml/tests/locallib_test.php create mode 100644 mod/book/tool/print/classes/event/book_printed.php create mode 100644 mod/book/tool/print/classes/event/chapter_printed.php create mode 100644 mod/book/tool/print/tests/events_test.php diff --git a/mod/book/classes/event/chapter_created.php b/mod/book/classes/event/chapter_created.php new file mode 100644 index 00000000000..a107bd8b90b --- /dev/null +++ b/mod/book/classes/event/chapter_created.php @@ -0,0 +1,88 @@ +. + +/** + * mod_book chapter created event. + * + * @package mod_book + * @copyright 2013 Frédéric Massart + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +namespace mod_book\event; +defined('MOODLE_INTERNAL') || die(); + +/** + * mod_book chapter created event class. + * + * @package mod_book + * @copyright 2013 Frédéric Massart + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class chapter_created extends \core\event\base { + + /** + * Returns description of what happened. + * + * @return string + */ + public function get_description() { + return "The chapter $this->objectid of the book $this->context->instanceid has been created."; + } + + /** + * Return the legacy event log data. + * + * @return array|null + */ + protected function get_legacy_logdata() { + return array($this->courseid, 'book', 'add chapter', 'view.php?id=' . $this->context->instanceid . '&chapterid=' . + $this->objectid, $this->objectid, $this->context->instanceid); + } + + /** + * Return localised event name. + * + * @return string + */ + public static function get_name() { + return get_string('event_chapter_created', 'mod_book'); + } + + /** + * Get URL related to the action. + * + * @return \moodle_url + */ + public function get_url() { + return new \moodle_url('/mod/book/view.php', array( + 'id' => $this->context->instanceid, + 'chapterid' => $this->objectid + )); + } + + /** + * Init method. + * + * @return void + */ + protected function init() { + $this->data['crud'] = 'c'; + $this->data['level'] = self::LEVEL_TEACHING; + $this->data['objecttable'] = 'book_chapters'; + } + +} diff --git a/mod/book/classes/event/chapter_deleted.php b/mod/book/classes/event/chapter_deleted.php new file mode 100644 index 00000000000..43595e12dcf --- /dev/null +++ b/mod/book/classes/event/chapter_deleted.php @@ -0,0 +1,100 @@ +. + +/** + * mod_book chapter deleted event. + * + * @package mod_book + * @copyright 2013 Frédéric Massart + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +namespace mod_book\event; +defined('MOODLE_INTERNAL') || die(); + +/** + * mod_book chapter deleted event class. + * + * @package mod_book + * @copyright 2013 Frédéric Massart + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class chapter_deleted extends \core\event\base { + + /** + * Legacy log data. + * + * @var array + */ + protected $legacylogdata; + + /** + * Returns description of what happened. + * + * @return string + */ + public function get_description() { + return "The chapter $this->objectid of the book $this->context->instanceid has been deleted."; + } + + /** + * Return the legacy event log data. + * + * @return array|null + */ + protected function get_legacy_logdata() { + return $this->legacylogdata; + } + + /** + * Return localised event name. + * + * @return string + */ + public static function get_name() { + return get_string('event_chapter_deleted', 'mod_book'); + } + + /** + * Get URL related to the action. + * + * @return \moodle_url + */ + public function get_url() { + return new \moodle_url('/mod/book/view.php', array('id' => $this->context->instanceid)); + } + + /** + * Init method. + * + * @return void + */ + protected function init() { + $this->data['crud'] = 'd'; + $this->data['level'] = self::LEVEL_TEACHING; + $this->data['objecttable'] = 'book_chapters'; + } + + /** + * Set the legacy event log data. + * + * @return array|null + */ + public function set_legacy_logdata($legacydata) { + $this->legacylogdata = $legacydata; + } + +} diff --git a/mod/book/classes/event/chapter_updated.php b/mod/book/classes/event/chapter_updated.php new file mode 100644 index 00000000000..559da1f4ac0 --- /dev/null +++ b/mod/book/classes/event/chapter_updated.php @@ -0,0 +1,88 @@ +. + +/** + * mod_book chapter updated event. + * + * @package mod_book + * @copyright 2013 Frédéric Massart + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +namespace mod_book\event; +defined('MOODLE_INTERNAL') || die(); + +/** + * mod_book chapter updated event class. + * + * @package mod_book + * @copyright 2013 Frédéric Massart + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class chapter_updated extends \core\event\base { + + /** + * Returns description of what happened. + * + * @return string + */ + public function get_description() { + return "The chapter $this->objectid of the book $this->context->instanceid has been updated."; + } + + /** + * Return the legacy event log data. + * + * @return array|null + */ + protected function get_legacy_logdata() { + return array($this->courseid, 'book', 'update chapter', 'view.php?id=' . $this->context->instanceid . '&chapterid=' . + $this->objectid, $this->objectid, $this->context->instanceid); + } + + /** + * Return localised event name. + * + * @return string + */ + public static function get_name() { + return get_string('event_chapter_updated', 'mod_book'); + } + + /** + * Get URL related to the action. + * + * @return \moodle_url + */ + public function get_url() { + return new \moodle_url('/mod/book/view.php', array( + 'id' => $this->context->instanceid, + 'chapterid' => $this->objectid + )); + } + + /** + * Init method. + * + * @return void + */ + protected function init() { + $this->data['crud'] = 'u'; + $this->data['level'] = self::LEVEL_TEACHING; + $this->data['objecttable'] = 'book_chapters'; + } + +} diff --git a/mod/book/classes/event/chapter_viewed.php b/mod/book/classes/event/chapter_viewed.php new file mode 100644 index 00000000000..35010b8601d --- /dev/null +++ b/mod/book/classes/event/chapter_viewed.php @@ -0,0 +1,97 @@ +. + +/** + * mod_book chapter viewed event. + * + * @package mod_book + * @copyright 2013 Frédéric Massart + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +namespace mod_book\event; +defined('MOODLE_INTERNAL') || die(); + +/** + * mod_book chapter viewed event class. + * + * @package mod_book + * @copyright 2013 Frédéric Massart + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class chapter_viewed extends \core\event\content_viewed { + + /** + * Returns description of what happened. + * + * @return string + */ + public function get_description() { + return "The user $this->userid has viewed the chapter $this->objectid of book module $this->context->instanceid"; + } + + /** + * Return the legacy event log data. + * + * @return array|null + */ + protected function get_legacy_logdata() { + return array($this->courseid, 'book', 'view chapter', 'view.php?id=' . $this->context->instanceid . + '&chapterid=' . $this->objectid, $this->objectid, $this->context->instanceid); + } + + /** + * Return localised event name. + * + * @return string + */ + public static function get_name() { + return get_string('event_chapter_viewed', 'mod_book'); + } + + /** + * Get URL related to the action. + * + * @return \moodle_url + */ + public function get_url() { + return new \moodle_url('/mod/book/view.php', array('id' => $this->context->instanceid, 'chapterid' => $this->objectid)); + } + + /** + * Init method. + * + * @return void + */ + protected function init() { + $this->data['crud'] = 'r'; + $this->data['level'] = self::LEVEL_PARTICIPATING; + $this->data['objecttable'] = 'book_chapters'; + } + + /** + * Custom validation. + * + * @throws \coding_exception + * @return void + */ + protected function validate_data() { + // Hack to please the parent class. 'view chapter' was the key used in old add_to_log(). + $this->data['other']['content'] = 'view chapter'; + parent::validate_data(); + } + +} diff --git a/mod/book/classes/event/course_module_viewed.php b/mod/book/classes/event/course_module_viewed.php new file mode 100644 index 00000000000..e7118362c04 --- /dev/null +++ b/mod/book/classes/event/course_module_viewed.php @@ -0,0 +1,97 @@ +. + +/** + * mod_book course module viewed event. + * + * @package mod_book + * @copyright 2013 Frédéric Massart + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +namespace mod_book\event; +defined('MOODLE_INTERNAL') || die(); + +/** + * mod_book course module viewed event class. + * + * @package mod_book + * @copyright 2013 Frédéric Massart + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class course_module_viewed extends \core\event\content_viewed { + + /** + * Returns description of what happened. + * + * @return string + */ + public function get_description() { + return "The user $this->userid has viewed the book $this->objectid."; + } + + /** + * Return the legacy event log data. + * + * @return array|null + */ + protected function get_legacy_logdata() { + return array($this->courseid, 'book', 'view', 'view.php?id=' . $this->context->instanceid, $this->objectid, + $this->context->instanceid); + } + + /** + * Return localised event name. + * + * @return string + */ + public static function get_name() { + return get_string('event_course_module_viewed', 'mod_book'); + } + + /** + * Get URL related to the action. + * + * @return \moodle_url + */ + public function get_url() { + return new \moodle_url('/mod/book/view.php', array('id' => $this->context->instanceid)); + } + + /** + * Init method. + * + * @return void + */ + protected function init() { + $this->data['crud'] = 'r'; + $this->data['level'] = self::LEVEL_PARTICIPATING; + $this->data['objecttable'] = 'book'; + } + + /** + * Custom validation. + * + * @throws \coding_exception + * @return void + */ + protected function validate_data() { + // Hack to please the parent class. 'view' was the key used in old add_to_log(). + $this->data['other']['content'] = 'view'; + parent::validate_data(); + } + +} diff --git a/mod/book/classes/event/instances_list_viewed.php b/mod/book/classes/event/instances_list_viewed.php new file mode 100644 index 00000000000..3630e41b714 --- /dev/null +++ b/mod/book/classes/event/instances_list_viewed.php @@ -0,0 +1,73 @@ +. + +/** + * mod_book instances list viewed event. + * + * @package mod_book + * @copyright 2013 Frédéric Massart + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +namespace mod_book\event; +defined('MOODLE_INTERNAL') || die(); + +/** + * mod_book instances list viewed event class. + * + * @package mod_book + * @copyright 2013 Frédéric Massart + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class instances_list_viewed extends \core\event\course_module_instances_list_viewed { + + /** + * Returns description of what happened. + * + * @return string + */ + public function get_description() { + return "User $this->userid viewed the list of book activities in the course $this->courseid."; + } + + /** + * Return the legacy event log data. + * + * @return array|null + */ + protected function get_legacy_logdata() { + return array($this->courseid, 'book', 'view all', 'index.php?id=' . $this->courseid, ''); + } + + /** + * Return localised event name. + * + * @return string + */ + public static function get_name() { + return get_string('event_instances_list_viewed', 'mod_book'); + } + + /** + * Get URL related to the action + * + * @return \moodle_url + */ + public function get_url() { + return new \moodle_url('/mod/book/index.php', array('id' => $this->courseid)); + } + +} diff --git a/mod/book/delete.php b/mod/book/delete.php index b93b56d3f4c..02ce6a0f316 100644 --- a/mod/book/delete.php +++ b/mod/book/delete.php @@ -52,7 +52,7 @@ $PAGE->set_heading($course->fullname); if ($confirm) { // the operation was confirmed. $fs = get_file_storage(); if (!$chapter->subchapter) { // Delete all its sub-chapters if any - $chapters = $DB->get_records('book_chapters', array('bookid'=>$book->id), 'pagenum', 'id, subchapter'); + $chapters = $DB->get_recordset('book_chapters', array('bookid'=>$book->id), 'pagenum'); $found = false; foreach ($chapters as $ch) { if ($ch->id == $chapter->id) { @@ -60,16 +60,32 @@ if ($confirm) { // the operation was confirmed. } else if ($found and $ch->subchapter) { $fs->delete_area_files($context->id, 'mod_book', 'chapter', $ch->id); $DB->delete_records('book_chapters', array('id'=>$ch->id)); + + $params = array( + 'context' => $context, + 'objectid' => $ch->id + ); + $event = \mod_book\event\chapter_deleted::create($params); + $event->add_record_snapshot('book_chapters', $ch); + $event->trigger(); } else if ($found) { break; } } + $chapters->close(); } $fs->delete_area_files($context->id, 'mod_book', 'chapter', $chapter->id); $DB->delete_records('book_chapters', array('id'=>$chapter->id)); add_to_log($course->id, 'course', 'update mod', '../mod/book/view.php?id='.$cm->id, 'book '.$book->id); - add_to_log($course->id, 'book', 'update', 'view.php?id='.$cm->id, $book->id, $cm->id); + $params = array( + 'context' => $context, + 'objectid' => $chapter->id + ); + $event = \mod_book\event\chapter_deleted::create($params); + $event->add_record_snapshot('book_chapters', $chapter); + $event->set_legacy_logdata(array($course->id, 'book', 'update', 'view.php?id='.$cm->id, $book->id, $cm->id)); + $event->trigger(); book_preload_chapters($book); // Fix structure. $DB->set_field('book', 'revision', $book->revision+1, array('id'=>$book->id)); diff --git a/mod/book/edit.php b/mod/book/edit.php index 28c8ddde484..773216554be 100644 --- a/mod/book/edit.php +++ b/mod/book/edit.php @@ -76,7 +76,13 @@ if ($mform->is_cancelled()) { $DB->set_field('book', 'revision', $book->revision+1, array('id'=>$book->id)); add_to_log($course->id, 'course', 'update mod', '../mod/book/view.php?id='.$cm->id, 'book '.$book->id); - add_to_log($course->id, 'book', 'update chapter', 'view.php?id='.$cm->id.'&chapterid='.$data->id, $data->id, $cm->id); + $params = array( + 'context' => $context, + 'objectid' => $data->id + ); + $event = \mod_book\event\chapter_updated::create($params); + $event->add_record_snapshot('book_chapters', $data); + $event->trigger(); } else { // adding new chapter @@ -102,7 +108,13 @@ if ($mform->is_cancelled()) { $DB->set_field('book', 'revision', $book->revision+1, array('id'=>$book->id)); add_to_log($course->id, 'course', 'update mod', '../mod/book/view.php?id='.$cm->id, 'book '.$book->id); - add_to_log($course->id, 'book', 'add chapter', 'view.php?id='.$cm->id.'&chapterid='.$data->id, $data->id, $cm->id); + $params = array( + 'context' => $context, + 'objectid' => $data->id + ); + $event = \mod_book\event\chapter_created::create($params); + $event->add_record_snapshot('book_chapters', $data); + $event->trigger(); } book_preload_chapters($book); // fix structure diff --git a/mod/book/index.php b/mod/book/index.php index 75461889413..db47dd62569 100644 --- a/mod/book/index.php +++ b/mod/book/index.php @@ -48,7 +48,11 @@ $PAGE->set_heading($course->fullname); $PAGE->navbar->add($strbooks); echo $OUTPUT->header(); -add_to_log($course->id, 'book', 'view all', 'index.php?id='.$course->id, ''); +$params = array( + 'context' => context_course::instance($course->id) +); +$event = \mod_book\event\instances_list_viewed::create($params); +$event->trigger(); // Get all the appropriate data if (!$books = get_all_instances_in_course('book', $course)) { diff --git a/mod/book/lang/en/book.php b/mod/book/lang/en/book.php index e15de109d5b..4acbc52620f 100644 --- a/mod/book/lang/en/book.php +++ b/mod/book/lang/en/book.php @@ -43,9 +43,15 @@ $string['customtitles_help'] = 'Normally the chapter title is displayed in the t If the custom titles checkbox is ticked, the chapter title is NOT displayed as a heading above the content. A different title (perhaps longer than the chapter title) may be entered as part of the content.'; $string['chapters'] = 'Chapters'; -$string['editingchapter'] = 'Editing chapter'; $string['chaptertitle'] = 'Chapter title'; $string['content'] = 'Content'; +$string['editingchapter'] = 'Editing chapter'; +$string['event_chapter_created'] = 'Chapter created'; +$string['event_chapter_deleted'] = 'Chapter deleted'; +$string['event_chapter_updated'] = 'Chapter updated'; +$string['event_chapter_viewed'] = 'Chapter viewed'; +$string['event_instances_list_viewed'] = 'Instances list viewed'; +$string['event_course_module_viewed'] = 'Course module viewed'; $string['subchapter'] = 'Subchapter'; $string['nocontent'] = 'No content has been added to this book yet.'; $string['numbering'] = 'Chapter formatting'; diff --git a/mod/book/move.php b/mod/book/move.php index 7ae229b27f9..dc6a05f80a7 100644 --- a/mod/book/move.php +++ b/mod/book/move.php @@ -173,10 +173,19 @@ if (!$nothing) { foreach ($newchapters as $ch) { $ch->pagenum = $i; $DB->update_record('book_chapters', $ch); + + $params = array( + 'context' => $context, + 'objectid' => $ch->id + ); + $event = \mod_book\event\chapter_updated::create($params); + $event->trigger(); + $i++; } } +// MDL-39963 Decide what to do with those logs. add_to_log($course->id, 'course', 'update mod', '../mod/book/view.php?id='.$cm->id, 'book '.$book->id); add_to_log($course->id, 'book', 'update', 'view.php?id='.$cm->id, $book->id, $cm->id); diff --git a/mod/book/show.php b/mod/book/show.php index 7af7de22dba..21372f89b3d 100644 --- a/mod/book/show.php +++ b/mod/book/show.php @@ -47,6 +47,13 @@ $chapter->hidden = $chapter->hidden ? 0 : 1; // Update record. $DB->update_record('book_chapters', $chapter); +$params = array( + 'context' => $context, + 'objectid' => $chapter->id +); +$event = \mod_book\event\chapter_updated::create($params); +$event->add_record_snapshot('book_chapters', $chapter); +$event->trigger(); // Change visibility of subchapters too. if (!$chapter->subchapter) { @@ -58,12 +65,21 @@ if (!$chapter->subchapter) { } else if ($found and $ch->subchapter) { $ch->hidden = $chapter->hidden; $DB->update_record('book_chapters', $ch); + + $params = array( + 'context' => $context, + 'objectid' => $ch->id + ); + $event = \mod_book\event\chapter_updated::create($params); + $event->trigger(); + } else if ($found) { break; } } } +// MDL-39963 Decide what to do with those logs. add_to_log($course->id, 'course', 'update mod', '../mod/book/view.php?id='.$cm->id, 'book '.$book->id); add_to_log($course->id, 'book', 'update', 'view.php?id='.$cm->id, $book->id, $cm->id); diff --git a/mod/book/tests/events_test.php b/mod/book/tests/events_test.php new file mode 100644 index 00000000000..d53db31529d --- /dev/null +++ b/mod/book/tests/events_test.php @@ -0,0 +1,224 @@ +. + +/** + * Events tests. + * + * @package mod_book + * @category phpunit + * @copyright 2013 Frédéric Massart + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +defined('MOODLE_INTERNAL') || die(); +global $CFG; + +/** + * Events tests class. + * + * @package mod_book + * @category phpunit + * @copyright 2013 Frédéric Massart + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class mod_book_events_testcase extends advanced_testcase { + + public function setUp() { + $this->resetAfterTest(); + } + + public function test_chapter_created() { + // There is no proper API to call to generate chapters for a book, so what we are + // doing here is simply making sure that the events returns the right information. + + $course = $this->getDataGenerator()->create_course(); + $book = $this->getDataGenerator()->create_module('book', array('course' => $course->id)); + $bookgenerator = $this->getDataGenerator()->get_plugin_generator('mod_book'); + + $chapter = $bookgenerator->create_chapter(array('bookid' => $book->id)); + + $params = array( + 'context' => context_module::instance($book->cmid), + 'objectid' => $chapter->id + ); + $event = \mod_book\event\chapter_created::create($params); + + // Triggering and capturing the event. + $sink = $this->redirectEvents(); + $event->trigger(); + $events = $sink->get_events(); + $this->assertCount(1, $events); + $event = reset($events); + + // Checking that the event contains the expected values. + $this->assertInstanceOf('\mod_book\event\chapter_created', $event); + $this->assertEquals(context_module::instance($book->id), $event->get_context()); + $this->assertEquals($chapter->id, $event->objectid); + $expected = array($course->id, 'book', 'add chapter', 'view.php?id='.$book->cmid.'&chapterid='.$chapter->id, + $chapter->id, $book->cmid); + $this->assertEventLegacyLogData($expected, $event); + } + + public function test_chapter_updated() { + // There is no proper API to call to generate chapters for a book, so what we are + // doing here is simply making sure that the events returns the right information. + + $course = $this->getDataGenerator()->create_course(); + $book = $this->getDataGenerator()->create_module('book', array('course' => $course->id)); + $bookgenerator = $this->getDataGenerator()->get_plugin_generator('mod_book'); + + $chapter = $bookgenerator->create_chapter(array('bookid' => $book->id)); + + $params = array( + 'context' => context_module::instance($book->cmid), + 'objectid' => $chapter->id + ); + $event = \mod_book\event\chapter_updated::create($params); + + // Triggering and capturing the event. + $sink = $this->redirectEvents(); + $event->trigger(); + $events = $sink->get_events(); + $this->assertCount(1, $events); + $event = reset($events); + + // Checking that the event contains the expected values. + $this->assertInstanceOf('\mod_book\event\chapter_updated', $event); + $this->assertEquals(context_module::instance($book->id), $event->get_context()); + $this->assertEquals($chapter->id, $event->objectid); + $expected = array($course->id, 'book', 'update chapter', 'view.php?id='.$book->cmid.'&chapterid='.$chapter->id, + $chapter->id, $book->cmid); + $this->assertEventLegacyLogData($expected, $event); + } + + public function test_chapter_deleted() { + // There is no proper API to call to delete chapters for a book, so what we are + // doing here is simply making sure that the events returns the right information. + + $course = $this->getDataGenerator()->create_course(); + $book = $this->getDataGenerator()->create_module('book', array('course' => $course->id)); + $bookgenerator = $this->getDataGenerator()->get_plugin_generator('mod_book'); + + $chapter = $bookgenerator->create_chapter(array('bookid' => $book->id)); + + $params = array( + 'context' => context_module::instance($book->cmid), + 'objectid' => $chapter->id + ); + $event = \mod_book\event\chapter_deleted::create($params); + $event->add_record_snapshot('book_chapters', $chapter); + $event->set_legacy_logdata(array('1', 2, false)); + + // Triggering and capturing the event. + $sink = $this->redirectEvents(); + $event->trigger(); + $events = $sink->get_events(); + $this->assertCount(1, $events); + $event = reset($events); + + // Checking that the event contains the expected values. + $this->assertInstanceOf('\mod_book\event\chapter_deleted', $event); + $this->assertEquals(context_module::instance($book->id), $event->get_context()); + $this->assertEquals($chapter->id, $event->objectid); + $this->assertEquals($chapter, $event->get_record_snapshot('book_chapters', $chapter->id)); + $this->assertEventLegacyLogData(array('1', 2, false), $event); + } + + public function test_instances_list_viewed() { + // There is no proper API to call to trigger this event, so what we are + // doing here is simply making sure that the events returns the right information. + + $course = $this->getDataGenerator()->create_course(); + $params = array( + 'context' => context_course::instance($course->id) + ); + $event = \mod_book\event\instances_list_viewed::create($params); + + // Triggering and capturing the event. + $sink = $this->redirectEvents(); + $event->trigger(); + $events = $sink->get_events(); + $this->assertCount(1, $events); + $event = reset($events); + + // Checking that the event contains the expected values. + $this->assertInstanceOf('\mod_book\event\instances_list_viewed', $event); + $this->assertEquals(context_course::instance($course->id), $event->get_context()); + $expected = array($course->id, 'book', 'view all', 'index.php?id='.$course->id, ''); + $this->assertEventLegacyLogData($expected, $event); + } + + public function test_course_module_viewed() { + // There is no proper API to call to trigger this event, so what we are + // doing here is simply making sure that the events returns the right information. + + $course = $this->getDataGenerator()->create_course(); + $book = $this->getDataGenerator()->create_module('book', array('course' => $course->id)); + + $params = array( + 'context' => context_module::instance($book->cmid), + 'objectid' => $book->id + ); + $event = \mod_book\event\course_module_viewed::create($params); + + // Triggering and capturing the event. + $sink = $this->redirectEvents(); + $event->trigger(); + $events = $sink->get_events(); + $this->assertCount(1, $events); + $event = reset($events); + + // Checking that the event contains the expected values. + $this->assertInstanceOf('\mod_book\event\course_module_viewed', $event); + $this->assertEquals(context_module::instance($book->cmid), $event->get_context()); + $this->assertEquals($book->id, $event->objectid); + $expected = array($course->id, 'book', 'view', 'view.php?id=' . $book->cmid, $book->id, $book->cmid); + $this->assertEventLegacyLogData($expected, $event); + } + + public function test_chapter_viewed() { + // There is no proper API to call to trigger this event, so what we are + // doing here is simply making sure that the events returns the right information. + + $course = $this->getDataGenerator()->create_course(); + $book = $this->getDataGenerator()->create_module('book', array('course' => $course->id)); + $bookgenerator = $this->getDataGenerator()->get_plugin_generator('mod_book'); + + $chapter = $bookgenerator->create_chapter(array('bookid' => $book->id)); + + $params = array( + 'context' => context_module::instance($book->cmid), + 'objectid' => $chapter->id + ); + $event = \mod_book\event\chapter_viewed::create($params); + + // Triggering and capturing the event. + $sink = $this->redirectEvents(); + $event->trigger(); + $events = $sink->get_events(); + $this->assertCount(1, $events); + $event = reset($events); + + // Checking that the event contains the expected values. + $this->assertInstanceOf('\mod_book\event\chapter_viewed', $event); + $this->assertEquals(context_module::instance($book->cmid), $event->get_context()); + $this->assertEquals($chapter->id, $event->objectid); + $expected = array($course->id, 'book', 'view chapter', 'view.php?id=' . $book->cmid . '&chapterid=' . + $chapter->id, $chapter->id, $book->cmid); + $this->assertEventLegacyLogData($expected, $event); + } + +} diff --git a/mod/book/tool/exportimscp/classes/event/book_exported.php b/mod/book/tool/exportimscp/classes/event/book_exported.php new file mode 100644 index 00000000000..556ca970fad --- /dev/null +++ b/mod/book/tool/exportimscp/classes/event/book_exported.php @@ -0,0 +1,85 @@ +. + +/** + * booktool_exportimscp book exported event. + * + * @package booktool_exportimscp + * @copyright 2013 Frédéric Massart + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +namespace booktool_exportimscp\event; +defined('MOODLE_INTERNAL') || die(); + +/** + * booktool_exportimscp book exported event class. + * + * @package booktool_exportimscp + * @copyright 2013 Frédéric Massart + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class book_exported extends \core\event\base { + + /** + * Returns description of what happened. + * + * @return string + */ + public function get_description() { + return "The user $this->userid has exported the book $this->objectid."; + } + + /** + * Return the legacy event log data. + * + * @return array|null + */ + protected function get_legacy_logdata() { + return array($this->courseid, 'book', 'exportimscp', 'tool/exportimscp/index.php?id=' . $this->context->instanceid, + $this->objectid, $this->context->instanceid); + } + + /** + * Return localised event name. + * + * @return string + */ + public static function get_name() { + return get_string('event_book_exported', 'booktool_exportimscp'); + } + + /** + * Get URL related to the action. + * + * @return \moodle_url + */ + public function get_url() { + return new \moodle_url('/mod/book/view.php', array('id' => $this->context->instanceid)); + } + + /** + * Init method. + * + * @return void + */ + protected function init() { + $this->data['crud'] = 'r'; + $this->data['level'] = self::LEVEL_OTHER; + $this->data['objecttable'] = 'book'; + } + +} diff --git a/mod/book/tool/exportimscp/index.php b/mod/book/tool/exportimscp/index.php index 29418edffd4..d12aa42465d 100644 --- a/mod/book/tool/exportimscp/index.php +++ b/mod/book/tool/exportimscp/index.php @@ -43,7 +43,13 @@ $context = context_module::instance($cm->id); require_capability('mod/book:read', $context); require_capability('booktool/exportimscp:export', $context); -add_to_log($course->id, 'book', 'exportimscp', 'tool/exportimscp/index.php?id='.$cm->id, $book->id, $cm->id); +$params = array( + 'context' => $context, + 'objectid' => $book->id +); +$event = \booktool_exportimscp\event\book_exported::create($params); +$event->add_record_snapshot('book', $book); +$event->trigger(); $file = booktool_exportimscp_build_package($book, $context); diff --git a/mod/book/tool/exportimscp/lang/en/booktool_exportimscp.php b/mod/book/tool/exportimscp/lang/en/booktool_exportimscp.php index 558469f8c9e..28daab04f43 100644 --- a/mod/book/tool/exportimscp/lang/en/booktool_exportimscp.php +++ b/mod/book/tool/exportimscp/lang/en/booktool_exportimscp.php @@ -24,6 +24,7 @@ defined('MOODLE_INTERNAL') || die; +$string['event_book_exported'] = 'Book exported'; $string['exportimscp:export'] = 'Export book as IMS content package'; $string['generateimscp'] = 'Generate IMS CP'; $string['nochapters'] = 'No book chapters found, so unable to export to IMS CP.'; diff --git a/mod/book/tool/exportimscp/tests/events_test.php b/mod/book/tool/exportimscp/tests/events_test.php new file mode 100644 index 00000000000..9ca78a2e606 --- /dev/null +++ b/mod/book/tool/exportimscp/tests/events_test.php @@ -0,0 +1,72 @@ +. + +/** + * Events tests. + * + * @package booktool_exportimscp + * @category phpunit + * @copyright 2013 Frédéric Massart + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +defined('MOODLE_INTERNAL') || die(); +global $CFG; + +/** + * Events tests class. + * + * @package booktool_exportimscp + * @category phpunit + * @copyright 2013 Frédéric Massart + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class booktool_exportimscp_events_testcase extends advanced_testcase { + + public function setUp() { + $this->resetAfterTest(); + } + + public function test_book_exported() { + // There is no proper API to call to test the event, so what we are + // doing here is simply making sure that the events returns the right information. + + $course = $this->getDataGenerator()->create_course(); + $book = $this->getDataGenerator()->create_module('book', array('course' => $course->id)); + + $params = array( + 'context' => context_module::instance($book->cmid), + 'objectid' => $book->id + ); + $event = \booktool_exportimscp\event\book_exported::create($params); + + // Triggering and capturing the event. + $sink = $this->redirectEvents(); + $event->trigger(); + $events = $sink->get_events(); + $this->assertCount(1, $events); + $event = reset($events); + + // Checking that the event contains the expected values. + $this->assertInstanceOf('\booktool_exportimscp\event\book_exported', $event); + $this->assertEquals(context_module::instance($book->cmid), $event->get_context()); + $this->assertEquals($book->id, $event->objectid); + $expected = array($course->id, 'book', 'exportimscp', 'tool/exportimscp/index.php?id=' . $book->cmid, + $book->id, $book->cmid); + $this->assertEventLegacyLogData($expected, $event); + } + +} diff --git a/mod/book/tool/importhtml/locallib.php b/mod/book/tool/importhtml/locallib.php index 34a317a98b6..d61a40962f9 100644 --- a/mod/book/tool/importhtml/locallib.php +++ b/mod/book/tool/importhtml/locallib.php @@ -84,7 +84,13 @@ function toolbook_importhtml_import_chapters($package, $type, $book, $context, $ $chapter->id = $DB->insert_record('book_chapters', $chapter); $chapters[$chapter->id] = $chapter; - add_to_log($book->course, 'book', 'add chapter', 'view.php?id='.$context->instanceid.'&chapterid='.$chapter->id, $chapter->id, $context->instanceid); + $params = array( + 'context' => $context, + 'objectid' => $chapter->id + ); + $event = \mod_book\event\chapter_created::create($params); + $event->add_record_snapshot('book_chapters', $chapter); + $event->trigger(); } } } diff --git a/mod/book/tool/importhtml/tests/fixtures/chapters.zip b/mod/book/tool/importhtml/tests/fixtures/chapters.zip new file mode 100644 index 0000000000000000000000000000000000000000..7d8b9452b815bb3e042dc281839a644daf22bd63 GIT binary patch literal 1567 zcmWIWW@Zs#W?Z~XM0z^qc?BjhC&{_ProPJ6)8-VmdI?_Qa$zUq_RVsVio*~$`-y& zKmN|-!K`b_f@i9nUM_q3G41Khk1^imXz~x#Rey*n~N`L zOl}pQo39@r!J8Asx7_*ap@4~{6BzxAS-bLfC#Zed&h%I2k@ecYTbq)YV9Ygr~h_Dx9>LJJ;U2Y&m0mrmfJyHR@B=MZME6`(MMZY<0Qz_f<#H9kLNSS~@*%zr&%rR{30RAHg-;CRIL7$5VQ|8(mH8G7MHs=Gbb)TTrzkgGaWV zfr~S>-)pgtSX{|Id&fkR4Vjj6_(HjzU9UN^*_;*C*!8w)=7o5!FU1|_w|sjp)c5kS zZP<5ygx{Tje*f4idkLH0lW_QbzDqc!gjuh$bf(rg!&TrH~K`1`pvF!2_4O<#PG)g&#tQA}N0MY=_`V~k+wL(e@WUbh88CWOS)>puM2h)nk xbIAI!rBsCeXG{qFh;)mrA6slA^gjZY`B3{IaUbB#$_A2V1wuoh<8H8kcmU>ESGxcJ literal 0 HcmV?d00001 diff --git a/mod/book/tool/importhtml/tests/locallib_test.php b/mod/book/tool/importhtml/tests/locallib_test.php new file mode 100644 index 00000000000..71909ab98c8 --- /dev/null +++ b/mod/book/tool/importhtml/tests/locallib_test.php @@ -0,0 +1,76 @@ +. + +/** + * booktool_importhtml tests. + * + * @package booktool_importhtml + * @category phpunit + * @copyright 2013 Frédéric Massart + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +defined('MOODLE_INTERNAL') || die(); +global $CFG; + +require_once($CFG->dirroot.'/mod/book/tool/importhtml/locallib.php'); + +/** + * booktool_importhtml tests class. + * + * @package booktool_importhtml + * @category phpunit + * @copyright 2013 Frédéric Massart + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class booktool_importhtml_locallib_testcase extends advanced_testcase { + + public function setUp() { + $this->resetAfterTest(); + } + + public function test_import_chapters_events() { + $course = $this->getDataGenerator()->create_course(); + $book = $this->getDataGenerator()->create_module('book', array('course' => $course->id)); + $context = context_module::instance($book->cmid); + + $record = new stdClass(); + $record->contextid = $context->id; + $record->component = 'phpunit'; + $record->filearea = 'test'; + $record->itemid = 0; + $record->filepath = '/'; + $record->filename = 'chapters.zip'; + + $fs = get_file_storage(); + $file = $fs->create_file_from_pathname($record, __DIR__ . '/fixtures/chapters.zip'); + + // Importing the chapters. + $sink = $this->redirectEvents(); + toolbook_importhtml_import_chapters($file, 2, $book, $context, false); + $events = $sink->get_events(); + + // Checking the results. + $this->assertCount(5, $events); + foreach ($events as $event) { + $this->assertInstanceOf('\mod_book\event\chapter_created', $event); + $this->assertEquals($context, $event->get_context()); + $chapter = $event->get_record_snapshot('book_chapters', $event->objectid); + $this->assertNotEmpty($chapter); + } + } + +} diff --git a/mod/book/tool/print/classes/event/book_printed.php b/mod/book/tool/print/classes/event/book_printed.php new file mode 100644 index 00000000000..642881f398f --- /dev/null +++ b/mod/book/tool/print/classes/event/book_printed.php @@ -0,0 +1,85 @@ +. + +/** + * booktool_print book printed event. + * + * @package booktool_print + * @copyright 2013 Frédéric Massart + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +namespace booktool_print\event; +defined('MOODLE_INTERNAL') || die(); + +/** + * booktool_print book printed event class. + * + * @package booktool_print + * @copyright 2013 Frédéric Massart + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class book_printed extends \core\event\base { + + /** + * Returns description of what happened. + * + * @return string + */ + public function get_description() { + return "The user $this->userid has printed the book $this->objectid."; + } + + /** + * Return the legacy event log data. + * + * @return array|null + */ + protected function get_legacy_logdata() { + return array($this->courseid, 'book', 'print', 'tool/print/index.php?id=' . $this->context->instanceid, + $this->objectid, $this->context->instanceid); + } + + /** + * Return localised event name. + * + * @return string + */ + public static function get_name() { + return get_string('event_book_printed', 'booktool_print'); + } + + /** + * Get URL related to the action. + * + * @return \moodle_url + */ + public function get_url() { + return new \moodle_url('/mod/book/tool/print/index.php', array('id' => $this->context->instanceid)); + } + + /** + * Init method. + * + * @return void + */ + protected function init() { + $this->data['crud'] = 'r'; + $this->data['level'] = self::LEVEL_PARTICIPATING; + $this->data['objecttable'] = 'book'; + } + +} diff --git a/mod/book/tool/print/classes/event/chapter_printed.php b/mod/book/tool/print/classes/event/chapter_printed.php new file mode 100644 index 00000000000..83104242261 --- /dev/null +++ b/mod/book/tool/print/classes/event/chapter_printed.php @@ -0,0 +1,85 @@ +. + +/** + * booktool_print chapter printed event. + * + * @package booktool_print + * @copyright 2013 Frédéric Massart + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +namespace booktool_print\event; +defined('MOODLE_INTERNAL') || die(); + +/** + * booktool_print chapter printed event class. + * + * @package booktool_print + * @copyright 2013 Frédéric Massart + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class chapter_printed extends \core\event\base { + + /** + * Returns description of what happened. + * + * @return string + */ + public function get_description() { + return "The user $this->userid has printed the chapter $this->objectid of the book module $this->context->instanceid."; + } + + /** + * Return the legacy event log data. + * + * @return array|null + */ + protected function get_legacy_logdata() { + return array($this->courseid, 'book', 'print chapter', 'tool/print/index.php?id=' . $this->context->instanceid . + '&chapterid=' . $this->objectid, $this->objectid, $this->context->instanceid); + } + + /** + * Return localised event name. + * + * @return string + */ + public static function get_name() { + return get_string('event_chapter_printed', 'booktool_print'); + } + + /** + * Get URL related to the action. + * + * @return \moodle_url + */ + public function get_url() { + return new \moodle_url('/mod/book/tool/print/index.php', array('id' => $this->context->instanceid)); + } + + /** + * Init method. + * + * @return void + */ + protected function init() { + $this->data['crud'] = 'r'; + $this->data['level'] = self::LEVEL_PARTICIPATING; + $this->data['objecttable'] = 'book'; + } + +} diff --git a/mod/book/tool/print/index.php b/mod/book/tool/print/index.php index 2fc3d1292a4..9997117cdef 100644 --- a/mod/book/tool/print/index.php +++ b/mod/book/tool/print/index.php @@ -77,7 +77,13 @@ if ($chapter) { require_capability('mod/book:viewhiddenchapters', $context); } - add_to_log($course->id, 'book', 'print chapter', 'tool/print/index.php?id='.$cm->id.'&chapterid='.$chapter->id, $chapter->id, $cm->id); + $params = array( + 'context' => $context, + 'objectid' => $chapter->id + ); + $event = \booktool_print\event\chapter_printed::create($params); + $event->add_record_snapshot('book_chapters', $chapter); + $event->trigger(); // page header ?> @@ -123,7 +129,14 @@ if ($chapter) { echo ' '; } else { - add_to_log($course->id, 'book', 'print', 'tool/print/index.php?id='.$cm->id, $book->id, $cm->id); + $params = array( + 'context' => $context, + 'objectid' => $book->id + ); + $event = \booktool_print\event\book_printed::create($params); + $event->add_record_snapshot('book', $book); + $event->trigger(); + $allchapters = $DB->get_records('book_chapters', array('bookid'=>$book->id), 'pagenum'); $book->intro = file_rewrite_pluginfile_urls($book->intro, 'pluginfile.php', $context->id, 'mod_book', 'intro', null); diff --git a/mod/book/tool/print/lang/en/booktool_print.php b/mod/book/tool/print/lang/en/booktool_print.php index a2b1e9554e3..d5f24fde312 100644 --- a/mod/book/tool/print/lang/en/booktool_print.php +++ b/mod/book/tool/print/lang/en/booktool_print.php @@ -24,6 +24,8 @@ defined('MOODLE_INTERNAL') || die; +$string['event_book_printed'] = 'Book printed'; +$string['event_chapter_printed'] = 'Chapter printed'; $string['pluginname'] = 'Book printing'; $string['printbook'] = 'Print book'; $string['printchapter'] = 'Print this chapter'; diff --git a/mod/book/tool/print/tests/events_test.php b/mod/book/tool/print/tests/events_test.php new file mode 100644 index 00000000000..82620fdf433 --- /dev/null +++ b/mod/book/tool/print/tests/events_test.php @@ -0,0 +1,103 @@ +. + +/** + * Events tests. + * + * @package booktool_print + * @category phpunit + * @copyright 2013 Frédéric Massart + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +defined('MOODLE_INTERNAL') || die(); +global $CFG; + +/** + * Events tests class. + * + * @package booktool_print + * @category phpunit + * @copyright 2013 Frédéric Massart + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class booktool_print_events_testcase extends advanced_testcase { + + public function setUp() { + $this->resetAfterTest(); + } + + public function test_book_printed() { + // There is no proper API to call to test the event, so what we are + // doing here is simply making sure that the events returns the right information. + + $course = $this->getDataGenerator()->create_course(); + $book = $this->getDataGenerator()->create_module('book', array('course' => $course->id)); + + $params = array( + 'context' => context_module::instance($book->cmid), + 'objectid' => $book->id + ); + $event = \booktool_print\event\book_printed::create($params); + + // Triggering and capturing the event. + $sink = $this->redirectEvents(); + $event->trigger(); + $events = $sink->get_events(); + $this->assertCount(1, $events); + $event = reset($events); + + // Checking that the event contains the expected values. + $this->assertInstanceOf('\booktool_print\event\book_printed', $event); + $this->assertEquals(context_module::instance($book->cmid), $event->get_context()); + $this->assertEquals($book->id, $event->objectid); + $expected = array($course->id, 'book', 'print', 'tool/print/index.php?id=' . $book->cmid, $book->id, $book->cmid); + $this->assertEventLegacyLogData($expected, $event); + } + + + public function test_chapter_printed() { + // There is no proper API to call to test the event, so what we are + // doing here is simply making sure that the events returns the right information. + + $course = $this->getDataGenerator()->create_course(); + $book = $this->getDataGenerator()->create_module('book', array('course' => $course->id)); + $bookgenerator = $this->getDataGenerator()->get_plugin_generator('mod_book'); + $chapter = $bookgenerator->create_chapter(array('bookid' => $book->id)); + + $params = array( + 'context' => context_module::instance($book->cmid), + 'objectid' => $chapter->id + ); + $event = \booktool_print\event\chapter_printed::create($params); + + // Triggering and capturing the event. + $sink = $this->redirectEvents(); + $event->trigger(); + $events = $sink->get_events(); + $this->assertCount(1, $events); + $event = reset($events); + + // Checking that the event contains the expected values. + $this->assertInstanceOf('\booktool_print\event\chapter_printed', $event); + $this->assertEquals(context_module::instance($book->cmid), $event->get_context()); + $this->assertEquals($chapter->id, $event->objectid); + $expected = array($course->id, 'book', 'print chapter', 'tool/print/index.php?id=' . $book->cmid . + '&chapterid=' . $chapter->id, $chapter->id, $book->cmid); + $this->assertEventLegacyLogData($expected, $event); + } + +} diff --git a/mod/book/view.php b/mod/book/view.php index 549c0219291..0f3901df820 100644 --- a/mod/book/view.php +++ b/mod/book/view.php @@ -75,7 +75,14 @@ if ($allowedit and !$chapters) { } // Check chapterid and read chapter data if ($chapterid == '0') { // Go to first chapter if no given. - add_to_log($course->id, 'book', 'view', 'view.php?id='.$cm->id, $book->id, $cm->id); + $params = array( + 'context' => $context, + 'objectid' => $book->id + ); + $event = \mod_book\event\course_module_viewed::create($params); + $event->add_record_snapshot('book', $book); + $event->trigger(); + foreach ($chapters as $ch) { if ($edit) { $chapterid = $ch->id; @@ -110,7 +117,13 @@ unset($chapterid); // Security checks END. -add_to_log($course->id, 'book', 'view chapter', 'view.php?id='.$cm->id.'&chapterid='.$chapter->id, $chapter->id, $cm->id); +$params = array( + 'context' => $context, + 'objectid' => $chapter->id +); +$event = \mod_book\event\chapter_viewed::create($params); +$event->add_record_snapshot('book_chapters', $chapter); +$event->trigger(); // Read standard strings. $strbooks = get_string('modulenameplural', 'mod_book');