MDL-67585 core_course: add exporter for course content items
authorJake Dallimore <jake@moodle.com>
Tue, 21 Jan 2020 03:04:54 +0000 (11:04 +0800)
committerJake Dallimore <jake@moodle.com>
Thu, 20 Feb 2020 01:28:57 +0000 (09:28 +0800)
An exporter will allow let us add calculated fields like 'favourited'
to the data being transferred.

course/classes/local/exporters/course_content_item_exporter.php [new file with mode: 0644]
course/classes/local/exporters/course_content_items_exporter.php [new file with mode: 0644]
course/tests/exporters_content_item_test.php [new file with mode: 0644]
course/tests/exporters_content_items_test.php [new file with mode: 0644]

diff --git a/course/classes/local/exporters/course_content_item_exporter.php b/course/classes/local/exporters/course_content_item_exporter.php
new file mode 100644 (file)
index 0000000..855a2eb
--- /dev/null
@@ -0,0 +1,123 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * Contains the course_content_item_exporter class.
+ *
+ * @package    core
+ * @subpackage course
+ * @copyright  2020 Jake Dallimore <jrhdallimore@gmail.com>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+namespace core_course\local\exporters;
+
+defined('MOODLE_INTERNAL') || die();
+
+use core\external\exporter;
+use core_course\local\entity\content_item;
+
+/**
+ * The course_content_item_exporter class.
+ *
+ * @copyright  2020 Jake Dallimore <jrhdallimore@gmail.com>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class course_content_item_exporter extends exporter {
+
+    /** @var content_item $contentitem the content_item to export. */
+    private $contentitem;
+
+    /**
+     * The course_content_item_exporter constructor.
+     *
+     * @param content_item $contentitem the content item to export.
+     * @param array $related the array of related objects used during export.
+     */
+    public function __construct(content_item $contentitem, array $related = []) {
+        $this->contentitem = $contentitem;
+
+        return parent::__construct($contentitem, $related);
+    }
+
+    /**
+     * Definition of all properties originating in the export target, \core_course\local\entity\content_item.
+     *
+     * @return array The array of property values, indexed by name.
+     */
+    protected static function define_properties() {
+        return [
+            'id' => ['type' => PARAM_INT, 'description' => 'The id of the content item'],
+            'name' => ['type' => PARAM_TEXT, 'description' => 'Name of the content item'],
+            'title' => ['type' => PARAM_TEXT, 'description' => 'The string title of the content item, human readable'],
+            'link' => ['type' => PARAM_URL, 'description' => 'The link to the content item creation page'],
+            'icon' => ['type' => PARAM_RAW, 'description' => 'Html containing the icon for the content item'],
+            'help' => ['type' => PARAM_RAW, 'description' => 'Html description / help for the content item'],
+            'archetype' => ['type' => PARAM_RAW, 'description' => 'The archetype of the module exposing the content item'],
+            'componentname' => ['type' => PARAM_TEXT, 'description' => 'The name of the component exposing the content item'],
+        ];
+    }
+
+    /**
+     * Definition of all properties which are either calculated or originate in a related domain object.
+     *
+     * @return array The array of property values, indexed by name.
+     */
+    protected static function define_other_properties() {
+        // This will hold user-dependant properties such as whether the item is starred or recommended.
+        return [];
+    }
+
+    /**
+     * Get ALL properties for the content_item DTO being exported.
+     *
+     * These properties are a mix of:
+     * - readonly properties of the primary object (content_item) being exported.
+     * - calculated values
+     * - properties originating from the related domain objects.
+     *
+     * Normally, those properties defined in get_properties() are added to the export automatically as part of the superclass code,
+     * provided they are public properties on the export target. In this case, the export target is content_item, which doesn't
+     * provide public access to its properties, so those are fetched via their respective getters here.
+     *
+     * @param \renderer_base $output
+     * @return array The array of property values, indexed by name.
+     */
+    protected function get_other_values(\renderer_base $output) {
+        $properties = [
+            'id' => $this->contentitem->get_id(),
+            'name' => $this->contentitem->get_name(),
+            'title' => $this->contentitem->get_title()->get_value(),
+            'link' => $this->contentitem->get_link()->out(false),
+            'icon' => $this->contentitem->get_icon(),
+            'help' => $this->contentitem->get_help(),
+            'archetype' => $this->contentitem->get_archetype(),
+            'componentname' => $this->contentitem->get_component_name(),
+        ];
+
+        return $properties;
+    }
+
+    /**
+     * Define the list of related objects, used by this exporter.
+     *
+     * @return array the list of related objects.
+     */
+    protected static function define_related(): array {
+        return [
+            'context' => 'context'
+        ];
+    }
+}
diff --git a/course/classes/local/exporters/course_content_items_exporter.php b/course/classes/local/exporters/course_content_items_exporter.php
new file mode 100644 (file)
index 0000000..177e49f
--- /dev/null
@@ -0,0 +1,104 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * Contains the course_content_items_exporter class.
+ *
+ * @package    core
+ * @subpackage course
+ * @copyright  2020 Jake Dallimore <jrhdallimore@gmail.com>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+namespace core_course\local\exporters;
+
+defined('MOODLE_INTERNAL') || die();
+
+use core\external\exporter;
+use core_course\local\entity\content_item;
+
+/**
+ * The course_content_items_exporter class.
+ *
+ * @copyright  2020 Jake Dallimore <jrhdallimore@gmail.com>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class course_content_items_exporter extends exporter {
+
+    /** @var content_item[] the array of content items. */
+    private $contentitems;
+
+    /**
+     * The course_content_items_exporter constructor.
+     *
+     * @param array $contentitems the array of \core_course\local\entity\content_item objects to export.
+     * @param array $related any related objects, see define_related for what's expected.
+     */
+    public function __construct(array $contentitems, array $related) {
+        $this->contentitems = $contentitems;
+
+        parent::__construct($contentitems, $related);
+    }
+
+    /**
+     * Return the properties defining this export.
+     *
+     * @return array the array of properties.
+     */
+    public static function define_properties() {
+        return [
+            'content_items' => [
+                'type' => course_content_item_exporter::read_properties_definition(),
+                'multiple' => true
+            ]
+        ];
+    }
+
+    /**
+     * Generate and return the data for this export.
+     *
+     * @param \renderer_base $output
+     * @return array the array of course content_items
+     */
+    protected function get_other_values(\renderer_base $output) {
+
+        $contentitemexport = function(content_item $contentitem) use ($output) {
+            $exporter = new course_content_item_exporter(
+                $contentitem,
+                [
+                    'context' => $this->related['context']
+                ]
+            );
+            return $exporter->export($output);
+        };
+
+        $exportedcontentitems = array_map($contentitemexport, $this->contentitems);
+
+        return [
+            'content_items' => $exportedcontentitems
+        ];
+    }
+
+    /**
+     * Define the list of related objects, used by this exporter.
+     *
+     * @return array the list of related objects.
+     */
+    protected static function define_related() {
+        return [
+            'context' => '\context'
+        ];
+    }
+}
diff --git a/course/tests/exporters_content_item_test.php b/course/tests/exporters_content_item_test.php
new file mode 100644 (file)
index 0000000..32c0018
--- /dev/null
@@ -0,0 +1,74 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * Contains the tests for the course_content_item_exporter class.
+ *
+ * @package    core
+ * @subpackage course
+ * @copyright  2020 Jake Dallimore <jrhdallimore@gmail.com>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+namespace tests\core_course;
+
+defined('MOODLE_INTERNAL') || die();
+
+use core_course\local\exporters\course_content_item_exporter;
+use core_course\local\repository\content_item_readonly_repository;
+
+/**
+ * The tests for the course_content_item_exporter class.
+ *
+ * @copyright  2020 Jake Dallimore <jrhdallimore@gmail.com>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class exporters_course_content_item_testcase extends \advanced_testcase {
+
+    /**
+     * Test confirming a content_item can be exported for a course.
+     */
+    public function test_export_course_content_item() {
+        $this->resetAfterTest();
+        global $PAGE;
+
+        $course = $this->getDataGenerator()->create_course();
+        $user = $this->getDataGenerator()->create_and_enrol($course, 'editingteacher');
+        $cir = new content_item_readonly_repository();
+        $contentitems = $cir->find_all_for_course($course, $user);
+        $contentitem = array_shift($contentitems);
+
+        $ciexporter = new course_content_item_exporter($contentitem, ['context' => \context_course::instance($course->id)]);
+        $renderer = $PAGE->get_renderer('core');
+        $exporteditem = $ciexporter->export($renderer);
+
+        $this->assertObjectHasAttribute('id', $exporteditem);
+        $this->assertEquals($exporteditem->id, $contentitem->get_id());
+        $this->assertObjectHasAttribute('name', $exporteditem);
+        $this->assertEquals($exporteditem->name, $contentitem->get_name());
+        $this->assertObjectHasAttribute('title', $exporteditem);
+        $this->assertEquals($exporteditem->title, $contentitem->get_title()->get_value());
+        $this->assertObjectHasAttribute('link', $exporteditem);
+        $this->assertEquals($exporteditem->link, $contentitem->get_link()->out(false));
+        $this->assertObjectHasAttribute('icon', $exporteditem);
+        $this->assertEquals($exporteditem->icon, $contentitem->get_icon());
+        $this->assertObjectHasAttribute('help', $exporteditem);
+        $this->assertEquals($exporteditem->help, $contentitem->get_help());
+        $this->assertObjectHasAttribute('archetype', $exporteditem);
+        $this->assertEquals($exporteditem->archetype, $contentitem->get_archetype());
+        $this->assertObjectHasAttribute('componentname', $exporteditem);
+        $this->assertEquals($exporteditem->componentname, $contentitem->get_component_name());
+    }
+}
diff --git a/course/tests/exporters_content_items_test.php b/course/tests/exporters_content_items_test.php
new file mode 100644 (file)
index 0000000..0e6065a
--- /dev/null
@@ -0,0 +1,68 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * Contains the tests for the course_content_items_exporter class.
+ *
+ * @package    core
+ * @subpackage course
+ * @copyright  2020 Jake Dallimore <jrhdallimore@gmail.com>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+namespace tests\core_course;
+
+defined('MOODLE_INTERNAL') || die();
+
+use core_course\local\exporters\course_content_items_exporter;
+use core_course\local\repository\content_item_readonly_repository;
+
+/**
+ * The tests for the course_content_items_exporter class.
+ *
+ * @copyright  2020 Jake Dallimore <jrhdallimore@gmail.com>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class exporters_course_content_items_testcase extends \advanced_testcase {
+
+    /**
+     * Test confirming the collection of content_items can be exported for a course.
+     */
+    public function test_export_course_content_items() {
+        $this->resetAfterTest();
+        global $PAGE;
+
+        $course = $this->getDataGenerator()->create_course();
+        $user = $this->getDataGenerator()->create_and_enrol($course, 'editingteacher');
+        $cir = new content_item_readonly_repository();
+        $contentitems = $cir->find_all_for_course($course, $user);
+
+        $ciexporter = new course_content_items_exporter($contentitems, ['context' => \context_course::instance($course->id)]);
+        $renderer = $PAGE->get_renderer('core');
+        $exportedcontentitems = $ciexporter->export($renderer);
+
+        $this->assertObjectHasAttribute('content_items', $exportedcontentitems);
+        foreach ($exportedcontentitems->content_items as $key => $dto) {
+            $this->assertObjectHasAttribute('id', $dto);
+            $this->assertObjectHasAttribute('name', $dto);
+            $this->assertObjectHasAttribute('title', $dto);
+            $this->assertObjectHasAttribute('link', $dto);
+            $this->assertObjectHasAttribute('icon', $dto);
+            $this->assertObjectHasAttribute('help', $dto);
+            $this->assertObjectHasAttribute('archetype', $dto);
+            $this->assertObjectHasAttribute('componentname', $dto);
+        }
+    }
+}