MDL-37624 calendar: Added location support
authorMichael Hawkins <michaelh@moodle.com>
Thu, 24 May 2018 01:44:54 +0000 (09:44 +0800)
committerMichael Hawkins <michaelh@moodle.com>
Fri, 29 Jun 2018 02:46:54 +0000 (10:46 +0800)
39 files changed:
backup/moodle2/backup_stepslib.php
backup/moodle2/restore_stepslib.php
calendar/classes/external/event_exporter_base.php
calendar/classes/local/event/entities/action_event.php
calendar/classes/local/event/entities/event.php
calendar/classes/local/event/entities/event_interface.php
calendar/classes/local/event/factories/event_abstract_factory.php
calendar/classes/local/event/forms/create.php
calendar/classes/local/event/mappers/event_mapper.php
calendar/classes/privacy/provider.php
calendar/export_execute.php
calendar/lib.php
calendar/templates/event_item.mustache
calendar/templates/event_summary_body.mustache
calendar/tests/action_event_test.php
calendar/tests/behat/calendar.feature
calendar/tests/behat/calendar_import.feature
calendar/tests/container_test.php
calendar/tests/event_factory_test.php
calendar/tests/event_mapper_test.php
calendar/tests/event_test.php
calendar/tests/externallib_test.php
calendar/tests/fixtures/import.ics
calendar/tests/helpers.php
calendar/tests/lib_test.php
calendar/tests/local_api_test.php
calendar/tests/raw_event_retrieval_strategy_test.php
calendar/tests/repeat_event_collection_test.php
lib/classes/output/icon_system_fontawesome.php
lib/db/install.xml
lib/db/upgrade.php
pix/i/location.png [new file with mode: 0644]
pix/i/location.svg [new file with mode: 0644]
theme/boost/scss/moodle/calendar.scss
theme/bootstrapbase/less/moodle/calendar.less
theme/bootstrapbase/style/moodle.css
theme/bootstrapbase/templates/core_calendar/event_item.mustache [new file with mode: 0644]
theme/bootstrapbase/templates/core_calendar/event_summary_body.mustache
version.php

index a2f922a..3793d9b 100644 (file)
@@ -865,7 +865,7 @@ class backup_calendarevents_structure_step extends backup_structure_step {
                 'name', 'description', 'format', 'courseid', 'groupid', 'userid',
                 'repeatid', 'modulename', 'instance', 'type', 'eventtype', 'timestart',
                 'timeduration', 'timesort', 'visible', 'uuid', 'sequence', 'timemodified',
-                'priority'));
+                'priority', 'location'));
 
         // Build the tree
         $events->add_child($event);
index 56ca4d8..8443174 100644 (file)
@@ -2725,7 +2725,8 @@ class restore_calendarevents_structure_step extends restore_structure_step {
                 'uuid'           => $data->uuid,
                 'sequence'       => $data->sequence,
                 'timemodified'   => $data->timemodified,
-                'priority'       => isset($data->priority) ? $data->priority : null);
+                'priority'       => isset($data->priority) ? $data->priority : null,
+                'location'       => isset($data->location) ? $data->location : null);
         if ($this->name == 'activity_calendar') {
             $params['instance'] = $this->task->get_activityid();
         } else {
index a6bef22..ab3f5ca 100644 (file)
@@ -79,6 +79,7 @@ class event_exporter_base extends exporter {
             $event->get_id()
         );
         $data->descriptionformat = $event->get_description()->get_format();
+        $data->location = htmlspecialchars($event->get_location());
         $data->groupid = $groupid;
         $data->userid = $userid;
         $data->categoryid = $categoryid;
@@ -123,6 +124,12 @@ class event_exporter_base extends exporter {
                 'default' => null,
                 'null' => NULL_ALLOWED
             ],
+            'location' => [
+                'type' => PARAM_RAW_TRIMMED,
+                'optional' => true,
+                'default' => null,
+                'null' => NULL_ALLOWED
+            ],
             'categoryid' => [
                 'type' => PARAM_INT,
                 'optional' => true,
index ad1d98c..6c8b0f1 100644 (file)
@@ -78,6 +78,10 @@ class action_event implements action_event_interface {
         return $this->event->get_description();
     }
 
+    public function get_location() {
+        return $this->event->get_location();
+    }
+
     public function get_category() {
         return $this->event->get_category();
     }
index 2f5ea39..fdfee97 100644 (file)
@@ -52,6 +52,11 @@ class event implements event_interface {
      */
     protected $description;
 
+    /**
+     * @var string $location Location of this event.
+     */
+    protected $location;
+
     /**
      * @var proxy_interface $category Category for this event.
      */
@@ -118,6 +123,7 @@ class event implements event_interface {
      * @param times_interface            $times          The times associated with the event.
      * @param bool                       $visible        The event's visibility. True for visible, false for invisible.
      * @param proxy_interface            $subscription   The event's subscription.
+     * @param string                     $location       The event's location.
      */
     public function __construct(
         $id,
@@ -132,11 +138,13 @@ class event implements event_interface {
         $type,
         times_interface $times,
         $visible,
-        proxy_interface $subscription = null
+        proxy_interface $subscription = null,
+        $location = null
     ) {
         $this->id = $id;
         $this->name = $name;
         $this->description = $description;
+        $this->location = $location;
         $this->category = $category;
         $this->course = $course;
         $this->group = $group;
@@ -161,6 +169,10 @@ class event implements event_interface {
         return $this->description;
     }
 
+    public function get_location() {
+        return $this->location;
+    }
+
     public function get_category() {
         return $this->category;
     }
index 0e2de4f..5561f62 100644 (file)
@@ -56,6 +56,13 @@ interface event_interface {
      */
     public function get_description();
 
+    /**
+     * Get the event's location.
+     *
+     * @return location_interface
+     */
+    public function get_location();
+
     /**
      * Get the category object associated with the event.
      *
index 9574f7f..807ecad 100644 (file)
@@ -189,7 +189,8 @@ abstract class event_abstract_factory implements event_factory_interface {
                 (new \DateTimeImmutable())->setTimestamp($dbrow->timemodified)
             ),
             !empty($dbrow->visible),
-            $subscription
+            $subscription,
+            $dbrow->location
         );
 
         $isactionevent = !empty($dbrow->type) && $dbrow->type == CALENDAR_EVENT_TYPE_ACTION;
index 1e36407..6697a37 100644 (file)
@@ -98,6 +98,10 @@ class create extends \moodleform {
         $mform->setType('description', PARAM_RAW);
         $mform->setAdvanced('description');
 
+        $mform->addElement('text', 'location', get_string('location', 'moodle'), 'size="50"');
+        $mform->setType('location', PARAM_RAW_TRIMMED);
+        $mform->setAdvanced('location');
+
         // Add the variety of elements allowed for selecting event duration.
         $this->add_event_duration_elements($mform);
 
index 214983f..5600ec7 100644 (file)
@@ -68,6 +68,7 @@ class event_mapper implements event_mapper_interface {
                 'id' => $coalesce('id'),
                 'name' => $coalesce('name'),
                 'description' => $coalesce('description'),
+                'location' => $coalesce('location'),
                 'format' => $coalesce('format'),
                 'categoryid' => $coalesce('categoryid'),
                 'courseid' => $coalesce('courseid'),
@@ -119,6 +120,7 @@ class event_mapper implements event_mapper_interface {
             'name'             => $event->get_name(),
             'description'      => $event->get_description()->get_value(),
             'format'           => $event->get_description()->get_format(),
+            'location'         => $event->get_location(),
             'courseid'         => $event->get_course() ? $event->get_course()->get('id') : null,
             'categoryid'       => $event->get_category() ? $event->get_category()->get('id') : null,
             'groupid'          => $event->get_group() ? $event->get_group()->get('id') : null,
index 4fc58de..3332421 100644 (file)
@@ -273,6 +273,7 @@ class provider implements
                 $eventdetails = (object) [
                     'name' => $event->name,
                     'description' => $event->description,
+                    'location' => $event->location,
                     'eventtype' => $event->eventtype,
                     'timestart' => transform::datetime($event->timestart),
                     'timeduration' => $event->timeduration
@@ -456,6 +457,7 @@ class provider implements
                        details.id as eventid,
                        details.name as name,
                        details.description as description,
+                       details.location as location,
                        details.eventtype as eventtype,
                        details.timestart as timestart,
                        details.timeduration as timeduration
index ca162a2..53bd01d 100644 (file)
@@ -211,6 +211,11 @@ foreach($events as $event) {
 
     $ev->add_property('class', 'PUBLIC'); // PUBLIC / PRIVATE / CONFIDENTIAL
     $ev->add_property('last-modified', Bennu::timestamp_to_datetime($event->timemodified));
+
+    if (!empty($event->location)) {
+        $ev->add_property('location', $event->location);
+    }
+
     $ev->add_property('dtstamp', Bennu::timestamp_to_datetime()); // now
     if ($event->timeduration > 0) {
         //dtend is better than duration, because it works in Microsoft Outlook and works better in Korganizer
index 0f684dd..60d3d0f 100644 (file)
@@ -2912,6 +2912,8 @@ function calendar_add_icalendar_event($event, $unused = null, $subscriptionid, $
         \core_date::set_default_server_timezone();
     }
 
+    $eventrecord->location = empty($event->properties['LOCATION'][0]->value) ? '' :
+            str_replace('\\', '', $event->properties['LOCATION'][0]->value);
     $eventrecord->uuid = $event->properties['UID'][0]->value;
     $eventrecord->timemodified = time();
 
index 91d0751..157a652 100644 (file)
                     </a>
                 {{/canedit}}
             </div>
-            {{#icon}}{{#pix}} {{key}}, {{component}}, {{alttext}} {{/pix}}{{/icon}}
-            <h3 class="name d-inline-block">{{name}}</h3>
-            <span class="date pull-xs-right m-r-1">{{{formattedtime}}}</span>
+            {{#icon}}<div class="d-inline-block mt-1 align-top">{{#pix}} {{key}}, {{component}}, {{alttext}} {{/pix}}</div>{{/icon}}
+            <div class="d-inline-block">
+                <h3 class="name d-inline-block">{{name}}</h3>
+                <span class="date pull-xs-right m-r-1">{{{formattedtime}}}</span>
+                <div class="location">{{#location}}{{{location}}}{{/location}}</div>
+            </div>
         </div>
         <div class="description card-block calendar_event_{{eventtype}}">
             <p>{{{description}}}</p>
index de5424e..576ffbe 100644 (file)
@@ -23,6 +23,7 @@
     {
         "timestart": 1490320388,
         "description": "An random event description",
+        "location": "13th floor, building 42",
         "eventtype": "User",
         "source": "Ical imported",
         "groupname": "Group 1"
             <div class="description-content col-xs-11">{{{.}}}</div>
         </div>
         {{/description}}
+        {{#location}}
+        <div class="row m-t-1">
+            <div class="col-xs-1">{{#pix}} i/location, core, {{#str}} location {{/str}} {{/pix}}</div>
+            <div class="location-content col-xs-11">{{{.}}}</div>
+        </div>
+        {{/location}}
         {{#isactionevent}}
         <div class="row m-t-1">
             <div class="col-xs-1">{{#pix}} i/courseevent, core, {{#str}} course {{/str}} {{/pix}}</div>
index acb8643..d6ae9f6 100644 (file)
@@ -108,6 +108,10 @@ class core_calendar_action_event_test_event implements event_interface {
         return new event_description('asdf', 1);
     }
 
+    public function get_location() {
+        return 'Cube office';
+    }
+
     public function get_category() {
         return new \stdClass();
     }
index e0e7850..6d5a602 100644 (file)
@@ -38,6 +38,7 @@ Feature: Perform basic calendar functionality
       | Type of event | site |
       | Event title | Really awesome event! |
       | Description | Come join this awesome event, sucka! |
+      | Location | Cube office |
     And I log out
     And I log in as "student1"
     And I am on "Course 1" course homepage
@@ -56,6 +57,7 @@ Feature: Perform basic calendar functionality
       | Course        | Course 1 |
       | Event title | Really awesome event! |
       | Description | Come join this awesome event, sucka! |
+      | Location | Cube office |
     And I log out
     And I log in as "student1"
     When I am on "Course 1" course homepage
@@ -77,6 +79,7 @@ Feature: Perform basic calendar functionality
       | Group         | Group 1 |
       | Event title | Really awesome event! |
       | Description | Come join this awesome event |
+      | Location | Cube office |
     And I log out
     And I log in as "student1"
     When I am on "Course 1" course homepage
@@ -90,6 +93,7 @@ Feature: Perform basic calendar functionality
       | Type of event | user |
       | Event title | Really awesome event! |
       | Description | Come join this awesome event, sucka! |
+      | Location | Cube office |
     And I log out
     And I log in as "student1"
     When I am on "Course 1" course homepage
@@ -118,6 +122,7 @@ Feature: Perform basic calendar functionality
       | Type of event | user |
       | Event title | Really awesome event! |
       | Description | Come join this awesome event, sucka! |
+      | Location | Cube office |
     And I am on "Course 1" course homepage
     When I follow "This month"
     And I click on "Really awesome event!" "link"
@@ -125,6 +130,7 @@ Feature: Perform basic calendar functionality
     And I set the following fields to these values:
       | Event title | Mediocre event :( |
       | Description | Wait, this event isn't that great. |
+      | Location | The park |
     And I press "Save"
     Then I should see "Mediocre event"
 
index 6930b1e..c56e4d1 100644 (file)
@@ -35,6 +35,7 @@ Feature: Import and edit calendar events
     And I set the following fields to these values:
       | Event title    | Event on 2-20-2017 |
       | Description    | Event on 2-20-2017 |
+      | Location       | Some place |
       | timestart[day] | 20 |
     And I press "Save"
     When I view the calendar for "2" "2017"
index 8439caa..011464b 100644 (file)
@@ -100,6 +100,7 @@ class core_calendar_container_testcase extends advanced_testcase {
         $this->assertEquals($dbrow->description, $event->get_description()->get_value());
         $this->assertEquals($dbrow->format, $event->get_description()->get_format());
         $this->assertEquals($dbrow->courseid, $event->get_course()->get('id'));
+        $this->assertEquals($dbrow->location, $event->get_location());
 
         if ($dbrow->groupid == 0) {
             $this->assertNull($event->get_group());
@@ -337,6 +338,7 @@ class core_calendar_container_testcase extends advanced_testcase {
         $event = new \stdClass();
         $event->name = 'An event';
         $event->description = 'Event description';
+        $event->location = 'Event location';
         $event->format = FORMAT_HTML;
         $event->eventtype = \core_completion\api::COMPLETION_EVENT_TYPE_DATE_COMPLETION_EXPECTED;
         $event->userid = 1;
@@ -386,6 +388,7 @@ class core_calendar_container_testcase extends advanced_testcase {
         $event = new \stdClass();
         $event->name = 'An event';
         $event->description = 'Event description';
+        $event->location = 'Event location';
         $event->format = FORMAT_HTML;
         $event->eventtype = 'close';
         $event->userid = $user->id;
@@ -490,7 +493,8 @@ class core_calendar_container_testcase extends advanced_testcase {
                     'timesort' => 1486396800,
                     'visible' => 1,
                     'timemodified' => 1485793098,
-                    'subscriptionid' => null
+                    'subscriptionid' => null,
+                    'location' => 'Test location',
                 ]
             ],
 
@@ -512,7 +516,8 @@ class core_calendar_container_testcase extends advanced_testcase {
                     'timesort' => 1486396800,
                     'visible' => 1,
                     'timemodified' => 1485793098,
-                    'subscriptionid' => null
+                    'subscriptionid' => null,
+                    'location' => 'Test location',
                 ]
             ]
         ];
@@ -567,7 +572,8 @@ class core_calendar_container_testcase extends advanced_testcase {
             'timesort' => 1486396800,
             'visible' => 1,
             'timemodified' => 1485793098,
-            'subscriptionid' => null
+            'subscriptionid' => null,
+            'location' => 'Test location',
         ];
 
         foreach ((array) $skeleton as $key => $value) {
index e2bf0bf..abf40ea 100644 (file)
@@ -128,7 +128,8 @@ class core_calendar_event_factory_testcase extends advanced_testcase {
                 'timemodified' => 123456789,
                 'timesort' => 123456789,
                 'visible' => 1,
-                'subscriptionid' => 1
+                'subscriptionid' => 1,
+                'location' => 'Test location',
             ]
         );
     }
@@ -177,7 +178,8 @@ class core_calendar_event_factory_testcase extends advanced_testcase {
                 'timemodified' => 123456789,
                 'timesort' => 123456789,
                 'visible' => 1,
-                'subscriptionid' => 1
+                'subscriptionid' => 1,
+                'location' => 'Test location',
             ]
         );
     }
@@ -226,7 +228,8 @@ class core_calendar_event_factory_testcase extends advanced_testcase {
                 'timemodified' => 123456789,
                 'timesort' => 123456789,
                 'visible' => 1,
-                'subscriptionid' => 1
+                'subscriptionid' => 1,
+                'location' => 'Test location',
             ]
         );
     }
@@ -275,7 +278,8 @@ class core_calendar_event_factory_testcase extends advanced_testcase {
                 'timemodified' => 123456789,
                 'timesort' => 123456789,
                 'visible' => 1,
-                'subscriptionid' => 1
+                'subscriptionid' => 1,
+                'location' => 'Test location',
             ]
         );
 
@@ -330,7 +334,8 @@ class core_calendar_event_factory_testcase extends advanced_testcase {
                 'timemodified' => 123456789,
                 'timesort' => 123456789,
                 'visible' => 1,
-                'subscriptionid' => 1
+                'subscriptionid' => 1,
+                'location' => 'Test location',
             ]
         );
 
@@ -364,7 +369,8 @@ class core_calendar_event_factory_testcase extends advanced_testcase {
                     'timemodified' => 123456789,
                     'timesort' => 123456789,
                     'visible' => true,
-                    'subscriptionid' => 1
+                    'subscriptionid' => 1,
+                    'location' => 'Test location',
                 ],
                 'actioncallbackapplier' => function(event_interface $event) {
                     $event->testattribute = 'Hello';
@@ -398,7 +404,8 @@ class core_calendar_event_factory_testcase extends advanced_testcase {
                     'timemodified' => 123456789,
                     'timesort' => 123456789,
                     'visible' => true,
-                    'subscriptionid' => 1
+                    'subscriptionid' => 1,
+                    'location' => 'Test location',
                 ],
                 'actioncallbackapplier' => function(event_interface $event) {
                     $event->testattribute = 'Hello';
@@ -432,7 +439,8 @@ class core_calendar_event_factory_testcase extends advanced_testcase {
                     'timemodified' => 123456789,
                     'timesort' => 123456789,
                     'visible' => true,
-                    'subscriptionid' => 1
+                    'subscriptionid' => 1,
+                    'location' => 'Test location',
                 ],
                 'actioncallbackapplier' => function(event_interface $event) {
                     $event->testattribute = 'Hello';
index 47f3f4b..d59bccc 100644 (file)
@@ -203,6 +203,10 @@ class event_mapper_test_action_event implements action_event_interface {
         return $this->event->get_description();
     }
 
+    public function get_location() {
+        return $this->event->get_location();
+    }
+
     public function get_category() {
         return $this->event->get_category();
     }
@@ -293,7 +297,7 @@ class event_mapper_test_event implements event_interface {
     /**
      * Constructor.
      *
-     * @param calendar_event $legacyevent Legacy event to exctract IDs etc from.
+     * @param calendar_event $legacyevent Legacy event to extract IDs etc from.
      */
     public function __construct($legacyevent = null) {
         if ($legacyevent) {
@@ -322,6 +326,10 @@ class event_mapper_test_event implements event_interface {
         return new event_description('asdf', 1);
     }
 
+    public function get_location() {
+        return 'Cube office';
+    }
+
     public function get_category() {
         return $this->categoryproxy;
     }
index 8b28046..3a70913 100644 (file)
@@ -58,7 +58,8 @@ class core_calendar_event_testcase extends advanced_testcase {
             $constructorparams['type'],
             $constructorparams['times'],
             $constructorparams['visible'],
-            $constructorparams['subscription']
+            $constructorparams['subscription'],
+            $constructorparams['location']
         );
 
         foreach ($constructorparams as $name => $value) {
@@ -98,7 +99,8 @@ class core_calendar_event_testcase extends advanced_testcase {
                         (new \DateTimeImmutable())->setTimestamp(time())
                     ),
                     'visible' => true,
-                    'subscription' => new std_proxy(1, $lamecallable)
+                    'subscription' => new std_proxy(1, $lamecallable),
+                    'location' => 'Test',
                 ]
             ],
         ];
index 9fcf147..28b42d3 100644 (file)
@@ -1516,6 +1516,7 @@ class core_calendar_externallib_testcase extends externallib_advanced_testcase {
                 'text' => '',
                 'format' => 1,
             ],
+            'location' => 'Test',
             'duration' => 1,
             'timedurationuntil' => [
                 'day' => $timedurationuntil->format('j'),
@@ -1574,6 +1575,7 @@ class core_calendar_externallib_testcase extends externallib_advanced_testcase {
                 'format' => 1,
                 'itemid' => 0
             ],
+            'location' => 'Test',
             'duration' => 1,
             'timedurationuntil' => [
                 'day' => $timedurationuntil->format('j'),
@@ -1637,6 +1639,7 @@ class core_calendar_externallib_testcase extends externallib_advanced_testcase {
                 'text' => '',
                 'format' => 1,
             ],
+            'location' => 'Test',
             'duration' => 1,
             'timedurationuntil' => [
                 'day' => $timedurationuntil->format('j'),
@@ -1698,6 +1701,7 @@ class core_calendar_externallib_testcase extends externallib_advanced_testcase {
                 'format' => 1,
                 'itemid' => 0
             ],
+            'location' => 'Test',
             'duration' => 1,
             'timedurationuntil' => [
                 'day' => $timedurationuntil->format('j'),
@@ -1762,6 +1766,7 @@ class core_calendar_externallib_testcase extends externallib_advanced_testcase {
                 'text' => '',
                 'format' => 1,
             ],
+            'location' => 'Test',
             'duration' => 1,
             'timedurationuntil' => [
                 'day' => $timedurationuntil->format('j'),
@@ -1826,6 +1831,7 @@ class core_calendar_externallib_testcase extends externallib_advanced_testcase {
                 'format' => 1,
                 'itemid' => 0,
             ],
+            'location' => 'Test',
             'duration' => 1,
             'timedurationuntil' => [
                 'day' => $timedurationuntil->format('j'),
@@ -1894,6 +1900,7 @@ class core_calendar_externallib_testcase extends externallib_advanced_testcase {
                 'text' => '',
                 'format' => 1,
             ],
+            'location' => 'Test',
             'duration' => 1,
             'timedurationuntil' => [
                 'day' => $timedurationuntil->format('j'),
@@ -1959,6 +1966,7 @@ class core_calendar_externallib_testcase extends externallib_advanced_testcase {
                 'text' => '',
                 'format' => 1,
             ],
+            'location' => 'Test',
             'duration' => 1,
             'timedurationuntil' => [
                 'day' => $timedurationuntil->format('j'),
@@ -2026,6 +2034,7 @@ class core_calendar_externallib_testcase extends externallib_advanced_testcase {
                 'format' => 1,
                 'itemid' => 0
             ],
+            'location' => 'Test',
             'duration' => 1,
             'timedurationuntil' => [
                 'day' => $timedurationuntil->format('j'),
@@ -2098,6 +2107,7 @@ class core_calendar_externallib_testcase extends externallib_advanced_testcase {
                 'format' => 1,
                 'itemid' => 0
             ],
+            'location' => 'Test',
             'duration' => 1,
             'timedurationuntil' => [
                 'day' => $timedurationuntil->format('j'),
@@ -2171,6 +2181,7 @@ class core_calendar_externallib_testcase extends externallib_advanced_testcase {
                 'format' => 1,
                 'itemid' => 0
             ],
+            'location' => 'Test',
             'duration' => 1,
             'timedurationuntil' => [
                 'day' => $timedurationuntil->format('j'),
@@ -2243,6 +2254,7 @@ class core_calendar_externallib_testcase extends externallib_advanced_testcase {
                 'text' => '',
                 'format' => 1,
             ],
+            'location' => 'Test',
             'duration' => 1,
             'timedurationuntil' => [
                 'day' => $timedurationuntil->format('j'),
index d414e63..5ccd189 100644 (file)
@@ -18,6 +18,7 @@ SUMMARY:Event on 2-25-2017
 DESCRIPTION:Event on 2-25-2017
 CLASS:PUBLIC
 LAST-MODIFIED:20170226T014258Z
+LOCATION:Some place
 DTSTAMP:20170226T014355Z
 DTSTART;VALUE=DATE:20170224
 DTEND;VALUE=DATE:20170225
index aa53fd4..92f2e2e 100644 (file)
@@ -136,7 +136,8 @@ class action_event_test_factory implements event_factory_interface {
                 (new \DateTimeImmutable())->setTimestamp($record->timemodified)
             ),
             !empty($record->visible),
-            $subscription
+            $subscription,
+            $record->location
         );
 
         $action = new action(
index 6c6e753..bf8b6ca 100644 (file)
@@ -61,6 +61,7 @@ class core_calendar_lib_testcase extends advanced_testcase {
             [
                 'name' => 'Start of assignment',
                 'description' => '',
+                'location' => 'Test',
                 'format' => 1,
                 'courseid' => $course->id,
                 'groupid' => 0,
@@ -74,6 +75,7 @@ class core_calendar_lib_testcase extends advanced_testcase {
             ], [
                 'name' => 'Start of lesson',
                 'description' => '',
+                'location' => 'Test',
                 'format' => 1,
                 'courseid' => $course->id,
                 'groupid' => 0,
@@ -272,6 +274,7 @@ class core_calendar_lib_testcase extends advanced_testcase {
             [
                 'name' => 'Assignment 1 due date',
                 'description' => '',
+                'location' => 'Test',
                 'format' => 0,
                 'courseid' => $course->id,
                 'groupid' => 0,
@@ -285,6 +288,7 @@ class core_calendar_lib_testcase extends advanced_testcase {
             ], [
                 'name' => 'Assignment 1 due date - User override',
                 'description' => '',
+                'location' => 'Test',
                 'format' => 1,
                 'courseid' => 0,
                 'groupid' => 0,
@@ -299,6 +303,7 @@ class core_calendar_lib_testcase extends advanced_testcase {
             ], [
                 'name' => 'Assignment 1 due date - Group A override',
                 'description' => '',
+                'location' => 'Test',
                 'format' => 1,
                 'courseid' => $course->id,
                 'groupid' => $group1->id,
@@ -313,6 +318,7 @@ class core_calendar_lib_testcase extends advanced_testcase {
             ], [
                 'name' => 'Assignment 1 due date - Group B override',
                 'description' => '',
+                'location' => 'Test',
                 'format' => 1,
                 'courseid' => $course->id,
                 'groupid' => $group2->id,
@@ -372,6 +378,7 @@ class core_calendar_lib_testcase extends advanced_testcase {
             [
                 'name' => 'Repeating site event',
                 'description' => '',
+                'location' => 'Test',
                 'format' => 1,
                 'courseid' => SITEID,
                 'groupid' => 0,
@@ -387,6 +394,7 @@ class core_calendar_lib_testcase extends advanced_testcase {
             [
                 'name' => 'Repeating site event',
                 'description' => '',
+                'location' => 'Test',
                 'format' => 1,
                 'courseid' => SITEID,
                 'groupid' => 0,
index ff2e065..a6466dc 100644 (file)
@@ -662,6 +662,7 @@ class core_calendar_local_api_testcase extends advanced_testcase {
             [
                 'name' => 'Start of assignment',
                 'description' => '',
+                'location' => 'Test',
                 'format' => 1,
                 'courseid' => $course->id,
                 'groupid' => 0,
@@ -675,6 +676,7 @@ class core_calendar_local_api_testcase extends advanced_testcase {
             ], [
                 'name' => 'Start of lesson',
                 'description' => '',
+                'location' => 'Test',
                 'format' => 1,
                 'courseid' => $course->id,
                 'groupid' => 0,
@@ -754,6 +756,7 @@ class core_calendar_local_api_testcase extends advanced_testcase {
             [
                 'name' => 'Assignment 1 due date',
                 'description' => '',
+                'location' => 'Test',
                 'format' => 0,
                 'courseid' => $course->id,
                 'groupid' => 0,
@@ -767,6 +770,7 @@ class core_calendar_local_api_testcase extends advanced_testcase {
             ], [
                 'name' => 'Assignment 1 due date - User override',
                 'description' => '',
+                'location' => 'Test',
                 'format' => 1,
                 'courseid' => 0,
                 'groupid' => 0,
@@ -781,6 +785,7 @@ class core_calendar_local_api_testcase extends advanced_testcase {
             ], [
                 'name' => 'Assignment 1 due date - Group A override',
                 'description' => '',
+                'location' => 'Test',
                 'format' => 1,
                 'courseid' => $course->id,
                 'groupid' => $group1->id,
@@ -795,6 +800,7 @@ class core_calendar_local_api_testcase extends advanced_testcase {
             ], [
                 'name' => 'Assignment 1 due date - Group B override',
                 'description' => '',
+                'location' => 'Test',
                 'format' => 1,
                 'courseid' => $course->id,
                 'groupid' => $group2->id,
@@ -854,6 +860,7 @@ class core_calendar_local_api_testcase extends advanced_testcase {
             [
                 'name' => 'Repeating site event',
                 'description' => '',
+                'location' => 'Test',
                 'format' => 1,
                 'courseid' => SITEID,
                 'groupid' => 0,
@@ -869,6 +876,7 @@ class core_calendar_local_api_testcase extends advanced_testcase {
             [
                 'name' => 'Repeating site event',
                 'description' => '',
+                'location' => 'Test',
                 'format' => 1,
                 'courseid' => SITEID,
                 'groupid' => 0,
index 9d8b137..1a927c2 100644 (file)
@@ -53,6 +53,7 @@ class core_calendar_raw_event_retrieval_strategy_testcase extends advanced_testc
             [
                 'name' => 'Start of assignment',
                 'description' => '',
+                'location' => 'Test',
                 'format' => 1,
                 'courseid' => $course->id,
                 'groupid' => 0,
@@ -66,6 +67,7 @@ class core_calendar_raw_event_retrieval_strategy_testcase extends advanced_testc
             ], [
                 'name' => 'Start of lesson',
                 'description' => '',
+                'location' => 'Test',
                 'format' => 1,
                 'courseid' => $course->id,
                 'groupid' => 0,
@@ -144,6 +146,7 @@ class core_calendar_raw_event_retrieval_strategy_testcase extends advanced_testc
             [
                 'name' => 'Assignment 1 due date',
                 'description' => '',
+                'location' => 'Test',
                 'format' => 0,
                 'courseid' => $course->id,
                 'groupid' => 0,
@@ -157,6 +160,7 @@ class core_calendar_raw_event_retrieval_strategy_testcase extends advanced_testc
             ], [
                 'name' => 'Assignment 1 due date - User override',
                 'description' => '',
+                'location' => 'Test',
                 'format' => 1,
                 'courseid' => 0,
                 'groupid' => 0,
@@ -171,6 +175,7 @@ class core_calendar_raw_event_retrieval_strategy_testcase extends advanced_testc
             ], [
                 'name' => 'Assignment 1 due date - Group A override',
                 'description' => '',
+                'location' => 'Test',
                 'format' => 1,
                 'courseid' => $course->id,
                 'groupid' => $group1->id,
@@ -185,6 +190,7 @@ class core_calendar_raw_event_retrieval_strategy_testcase extends advanced_testc
             ], [
                 'name' => 'Assignment 1 due date - Group B override',
                 'description' => '',
+                'location' => 'Test',
                 'format' => 1,
                 'courseid' => $course->id,
                 'groupid' => $group2->id,
@@ -240,6 +246,7 @@ class core_calendar_raw_event_retrieval_strategy_testcase extends advanced_testc
             [
                 'name' => 'Repeating site event',
                 'description' => '',
+                'location' => 'Test',
                 'format' => 1,
                 'courseid' => SITEID,
                 'groupid' => 0,
@@ -255,6 +262,7 @@ class core_calendar_raw_event_retrieval_strategy_testcase extends advanced_testc
             [
                 'name' => 'Repeating site event',
                 'description' => '',
+                'location' => 'Test',
                 'format' => 1,
                 'courseid' => SITEID,
                 'groupid' => 0,
@@ -294,6 +302,7 @@ class core_calendar_raw_event_retrieval_strategy_testcase extends advanced_testc
                 'name' => 'E1',
                 'eventtype' => 'category',
                 'description' => '',
+                'location' => 'Test',
                 'format' => 1,
                 'categoryid' => $category1->id,
                 'userid' => 2,
@@ -303,6 +312,7 @@ class core_calendar_raw_event_retrieval_strategy_testcase extends advanced_testc
                 'name' => 'E2',
                 'eventtype' => 'category',
                 'description' => '',
+                'location' => 'Test',
                 'format' => 1,
                 'categoryid' => $category2->id,
                 'userid' => 2,
@@ -342,4 +352,3 @@ class core_calendar_raw_event_retrieval_strategy_testcase extends advanced_testc
         $this->assertCount(2, $events);
     }
 }
-
index 98c1c0b..7d335ea 100644 (file)
@@ -204,7 +204,8 @@ class core_calendar_repeat_event_collection_event_test_factory implements event_
                 (new \DateTimeImmutable())->setTimestamp($dbrow->timemodified)
             ),
             !empty($dbrow->visible),
-            new std_proxy($dbrow->subscriptionid, $identity)
+            new std_proxy($dbrow->subscriptionid, $identity),
+            $dbrow->location
         );
     }
 }
index 71d15a6..75abeda 100644 (file)
@@ -243,6 +243,7 @@ class icon_system_fontawesome extends icon_system_font {
             'core:i/item' => 'fa-circle',
             'core:i/loading' => 'fa-circle-o-notch fa-spin',
             'core:i/loading_small' => 'fa-circle-o-notch fa-spin',
+            'core:i/location' => 'fa-map-marker',
             'core:i/lock' => 'fa-lock',
             'core:i/log' => 'fa-list-alt',
             'core:i/mahara_host' => 'fa-id-badge',
index b9b9003..e453f28 100644 (file)
         <FIELD NAME="timemodified" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
         <FIELD NAME="subscriptionid" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false" COMMENT="The event_subscription id this event is associated with."/>
         <FIELD NAME="priority" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false" COMMENT="The event's display priority. For multiple events with the same module name, instance and eventtype (e.g. for group overrides), the one with the higher priority will be displayed."/>
+        <FIELD NAME="location" TYPE="text" NOTNULL="false" SEQUENCE="false" COMMENT="Meeting Location"/>
       </FIELDS>
       <KEYS>
         <KEY NAME="primary" TYPE="primary" FIELDS="id"/>
index cc7edbd..ce13b24 100644 (file)
@@ -2233,5 +2233,19 @@ function xmldb_main_upgrade($oldversion) {
     // Automatically generated Moodle v3.5.0 release upgrade line.
     // Put any upgrade step following this.
 
+    if ($oldversion < 2018062800.01) {
+        // Define field location to be added to event.
+        $table = new xmldb_table('event');
+        $field = new xmldb_field('location', XMLDB_TYPE_TEXT, null, null, null, null, null, 'priority');
+
+        // Conditionally launch add field location.
+        if (!$dbman->field_exists($table, $field)) {
+            $dbman->add_field($table, $field);
+        }
+
+        // Main savepoint reached.
+        upgrade_main_savepoint(true, 2018062800.01);
+    }
+
     return true;
 }
diff --git a/pix/i/location.png b/pix/i/location.png
new file mode 100644 (file)
index 0000000..e9fa8a1
Binary files /dev/null and b/pix/i/location.png differ
diff --git a/pix/i/location.svg b/pix/i/location.svg
new file mode 100644 (file)
index 0000000..937f449
--- /dev/null
@@ -0,0 +1,3 @@
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [\r
+       <!ENTITY ns_flows "http://ns.adobe.com/Flows/1.0/">\r
+]><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" preserveAspectRatio="xMinYMid meet" overflow="visible"><path d="M14.7 12.3c0-.1 0-.1 0 0 .2-.4.4-.6.5-.9 0-.1 0-.1.1-.2.1-.3.3-.6.4-1v-.1c.1-.3.1-.6.2-.9v-.3c0-.3.1-.7.1-1 0-4.4-3.6-8-8-8C3.6 0 0 3.6 0 8c0 4.4 3.4 8 7.8 8H9c.2 0 .4 0 .5-.1.7-.1 1.3-.4 1.9-.7.7-.3 1.3-.7 1.8-1.2.6-.6 1.1-1.1 1.5-1.7zm-5 1.4c-.1 0-.1-.1-.2-.1-.3-.1-.7-.2-.8-.5v-.4c0-.1.2-.2.2-.3 0-.1-.1-.3-.1-.4 0-.1 0-.3.1-.4.1-.1.3-.8.5-.6 0 0 .3.2.5.3.1 0 .2 0 .4-.1h.4c.1 0 .2.1.3.1.1 0 .3 0 .4-.1.3 0 .3.1.5.3.1 0 .3 0 .4.1.2.1.1.1.2.3l.1.1c-.9.7-1.8 1.4-2.9 1.7zM3.2 5c0-.2-.1-.3-.1-.5.9-1.2 2.3-2.1 3.8-2.4l-.1.1c-.1.3.5 0 .6.2 0 .1-.3.1-.3.1h-.4c0 .1-.1.2-.2.3 0 .1-.2.2-.2.4 0 .3.4.4.6.4.2 0 .3-.1.5 0 .2 0 0 .2.2.2.1-.1.1-.2.2-.3.1-.2.2-.3.1-.4 0-.1-.1 0-.1-.1l.1-.1v-.3h.8c.1.1 0 .2.2.1 0-.1.1-.3.2-.3s.2.1.3.2c.1.1.2.1.3.2 0 .1 0 .2.1.3.2-.1.4-.2.5 0 .2.2 0 .5-.2.6-.3.2-.5.1-.7.2-.2.1-.3.3-.4.5.1-.1.4-.3.6-.3.2 0 .3.2.4.2.1 0 .6-.1.4.1-.1.1-.3.2-.4.3 0 .1-.3-.1-.5 0-.1 0-.1.3-.2.4-.1.2-.4.4-.5.7 0 .1.1.3 0 .4 0 .2-.1.2-.3.3-.1.1-.3.3-.3.6s.3.5.3.8c-.3 0-.3-.2-.5-.5s-.5-.1-.8 0c-.1.1-.2.2-.4.3-.2 0-.1-.1-.1-.2s-.1-.2-.2-.1c-.1 0-.1.2-.1.3 0 .5-.6 1.1 0 1.4.3.1.6.1.8-.1.1-.2.3-.4.6-.4 0 .2-.2.5-.2.7.1.2.5 0 .7.1.3.1 0 .5.3.7.2.1-.4.3-.7-.1-.2-.3-.4-.3-.7-.4-.3-.1-.4 0-.7 0-.3 0-.6-.1-.8-.2-.2-.1-.3-.4-.5-.5l-.3-.3c-.1-.1-.2-.2-.2-.3-.2-.1-.1-.6-.4-.6 0 .3.2.5.3.7.1.1.1.2.2.3 0 .1.1.2.1.3h-.1c-.2-.1-.5-.3-.6-.5-.2-.2-.3-.4-.4-.7-.1-.2-.1-.5-.2-.7-.2-.2-.4-.4-.4-.6 0-.2.1-.5.1-.7.1-.3 0-.5-.1-.8zm5.5-2.8c-.1 0-.3-.1-.4-.1-.1 0-.2-.1-.2-.1h.6c.1.2.3.3 0 .2z" fill="#999"/></svg>
\ No newline at end of file
index 8c88d89..97a40a0 100644 (file)
@@ -238,8 +238,15 @@ $calendarEventUserColor: #dce7ec !default; // Pale blue.
             }
         }
 
-        .event .card-header img {
-            vertical-align: baseline;
+        .event {
+            .card-header img {
+                vertical-align: baseline;
+            }
+
+            .location {
+                word-break: break-all;
+                overflow-wrap: break-word;
+            }
         }
 
     }
@@ -426,4 +433,8 @@ table.calendartable caption {
             margin: 0;
         }
     }
+
+    .location-content {
+        overflow-wrap: break-word;
+    }
 }
index a201ecc..d8e50ce 100644 (file)
                 .side {
                     width: 22px;
                 }
+                .location {
+                    clear: both;
+                    word-break: break-all;
+                    overflow-wrap: break-word;
+                }
                 .description {
                     background-color: @white;
                     clear: both;
             margin: 0;
         }
     }
+
+    .location-content {
+        overflow-wrap: break-word;
+    }
 }
index ce1163d..c5a4a99 100644 (file)
@@ -5790,6 +5790,11 @@ img.iconsmall {
 .path-calendar .maincalendar .eventlist .event .side {
   width: 22px;
 }
+.path-calendar .maincalendar .eventlist .event .location {
+  clear: both;
+  word-break: break-all;
+  overflow-wrap: break-word;
+}
 .path-calendar .maincalendar .eventlist .event .description {
   background-color: #fff;
   clear: both;
@@ -5915,6 +5920,9 @@ img.iconsmall {
 .summary-modal-container .description-content > p {
   margin: 0;
 }
+.summary-modal-container .location-content {
+  overflow-wrap: break-word;
+}
 /* course.less */
 /* COURSE CONTENT */
 /* stylelint-disable unit-blacklist */
diff --git a/theme/bootstrapbase/templates/core_calendar/event_item.mustache b/theme/bootstrapbase/templates/core_calendar/event_item.mustache
new file mode 100644 (file)
index 0000000..8fde5ed
--- /dev/null
@@ -0,0 +1,77 @@
+{{!
+    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/>.
+}}
+{{!
+    @template calendar/event_item
+
+    Calendar event item.
+
+    The purpose of this template is to render the event item.
+
+    Classes required for JS:
+    * none
+
+    Data attributes required for JS:
+    * none
+
+    Example context (json):
+    {
+    }
+}}
+<div{{!
+    }} data-type="event"{{!
+    }} data-course-id="{{course.id}}"{{!
+    }} data-event-id="{{id}}"{{!
+    }} class="event"{{!
+    }} data-eventtype-{{calendareventtype}}="1"{{!
+    }} data-event-title="{{name}}"{{!
+    }} data-event-count="{{eventcount}}"{{!
+    }}>
+    <div class="card">
+        <div class="box card-header clearfix p-y-1">
+            <div class="commands pull-xs-right">
+                {{#canedit}}
+                    {{#candelete}}
+                        <a href="{{deleteurl}}" data-action="delete">
+                            {{#pix}}t/delete, core, {{#str}}delete{{/str}}{{/pix}}
+                        </a>
+                    {{/candelete}}
+                    <a href="{{editurl}}" data-action="edit">
+                        {{#pix}}t/edit, core, {{#str}}edit{{/str}}{{/pix}}
+                    </a>
+                {{/canedit}}
+            </div>
+            {{#icon}}{{#pix}} {{key}}, {{component}}, {{alttext}} {{/pix}}{{/icon}}
+            <h3 class="name d-inline-block">{{name}}</h3>
+            <span class="date pull-xs-right m-r-1">{{{formattedtime}}}</span>
+            <div class="location">{{#location}}{{{location}}}{{/location}}</div>
+        </div>
+        <div class="description card-block calendar_event_{{eventtype}}">
+            <p>{{{description}}}</p>
+            {{#iscourseevent}}
+                <div><a href="{{url}}">{{course.fullname}}</a></div>
+            {{/iscourseevent}}
+            {{> core_calendar/event_subscription}}
+            {{#isactionevent}}
+                <a href="{{url}}">{{#str}} gotoactivity, core_calendar {{/str}}</a>
+            {{/isactionevent}}
+            {{#groupname}}
+                <div><a href="{{url}}">{{{course.fullname}}}</a></div>
+                <div>{{{groupname}}}</div>
+            {{/groupname}}
+        </div>
+    </div>
+</div>
\ No newline at end of file
index 980e2d2..56370e0 100644 (file)
@@ -23,6 +23,7 @@
     {
         "timestart": 1490320388,
         "description": "An random event description",
+        "location": "13th floor, building 42",
         "eventtype": "User",
         "source": "Ical imported",
         "groupname": "Group 1"
             <div class="description-content span11">{{{.}}}</div>
         </div>
         {{/description}}
+        {{#location}}
+        <div class="row-fluid m-t-1">
+            <div class="span1">{{#pix}} i/location, core, {{#str}} location {{/str}} {{/pix}}</div>
+            <div class="location-content span11">{{{.}}}</div>
+        </div>
+        {{/location}}
         {{#isactionevent}}
         <div class="row-fluid m-t-1">
             <div class="span1">{{#pix}} i/courseevent, core, {{#str}} course {{/str}} {{/pix}}</div>
index d6966f3..f21cafb 100644 (file)
@@ -29,7 +29,7 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$version  = 2018062800.00;              // YYYYMMDD      = weekly release date of this DEV branch.
+$version  = 2018062800.01;              // YYYYMMDD      = weekly release date of this DEV branch.
                                         //         RR    = release increments - 00 in DEV branches.
                                         //           .XX = incremental changes.