28399e23f1bc3782435a7db222add7e553b747a5
[moodle.git] / calendar / classes / external / day_exporter.php
1 <?php
2 // This file is part of Moodle - http://moodle.org/
3 //
4 // Moodle is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // Moodle is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
17 /**
18  * Contains event class for displaying the day view.
19  *
20  * @package   core_calendar
21  * @copyright 2017 Andrew Nicols <andrew@nicols.co.uk>
22  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23  */
25 namespace core_calendar\external;
27 defined('MOODLE_INTERNAL') || die();
29 require_once($CFG->dirroot . '/calendar/lib.php');
31 use core\external\exporter;
32 use renderer_base;
33 use moodle_url;
35 /**
36  * Class for displaying the day view.
37  *
38  * @package   core_calendar
39  * @copyright 2017 Andrew Nicols <andrew@nicols.co.uk>
40  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
41  */
42 class day_exporter extends exporter {
44     /**
45      * @var \calendar_information $calendar The calendar being displayed.
46      */
47     protected $calendar;
49     /**
50      * @var moodle_url
51      */
52     protected $url;
53     /**
54      * Constructor.
55      *
56      * @param \calendar_information $calendar The calendar information for the period being displayed
57      * @param mixed $data Either an stdClass or an array of values.
58      * @param array $related Related objects.
59      */
60     public function __construct(\calendar_information $calendar, $data, $related) {
61         $this->calendar = $calendar;
63         $url = new moodle_url('/calendar/view.php', [
64                 'view' => 'day',
65                 'time' => $calendar->time,
66             ]);
68         if ($this->calendar->course && SITEID !== $this->calendar->course->id) {
69             $url->param('course', $this->calendar->course->id);
70         } else if ($this->calendar->categoryid) {
71             $url->param('category', $this->calendar->categoryid);
72         }
74         $this->url = $url;
76         parent::__construct($data, $related);
77     }
79     /**
80      * Return the list of properties.
81      *
82      * @return array
83      */
84     protected static function define_properties() {
85         // These are the default properties as returned by getuserdate()
86         // but without the formatted month and week names.
87         return [
88             'seconds' => [
89                 'type' => PARAM_INT,
90             ],
91             'minutes' => [
92                 'type' => PARAM_INT,
93             ],
94             'hours' => [
95                 'type' => PARAM_INT,
96             ],
97             'mday' => [
98                 'type' => PARAM_INT,
99             ],
100             'wday' => [
101                 'type' => PARAM_INT,
102             ],
103             'year' => [
104                 'type' => PARAM_INT,
105             ],
106             'yday' => [
107                 'type' => PARAM_INT,
108             ],
109         ];
110     }
112     /**
113      * Return the list of additional properties.
114      *
115      * @return array
116      */
117     protected static function define_other_properties() {
118         return [
119             'timestamp' => [
120                 'type' => PARAM_INT,
121             ],
122             'neweventtimestamp' => [
123                 'type' => PARAM_INT,
124             ],
125             'viewdaylink' => [
126                 'type' => PARAM_URL,
127                 'optional' => true,
128             ],
129             'events' => [
130                 'type' => calendar_event_exporter::read_properties_definition(),
131                 'multiple' => true,
132             ],
133             'hasevents' => [
134                 'type' => PARAM_BOOL,
135                 'default' => false,
136             ],
137             'calendareventtypes' => [
138                 'type' => PARAM_RAW,
139                 'multiple' => true,
140             ],
141             'previousperiod' => [
142                 'type' => PARAM_INT,
143             ],
144             'nextperiod' => [
145                 'type' => PARAM_INT,
146             ],
147             'navigation' => [
148                 'type' => PARAM_RAW,
149             ],
150             'popovertitle' => [
151                 'type' => PARAM_RAW,
152                 'default' => '',
153             ],
154             'haslastdayofevent' => [
155                 'type' => PARAM_BOOL,
156                 'default' => false,
157             ],
158             'new_event_button' => [
159                 'type' => PARAM_RAW,
160             ],
161         ];
162     }
164     /**
165      * Get the additional values to inject while exporting.
166      *
167      * @param renderer_base $output The renderer.
168      * @return array Keys are the property names, values are their values.
169      */
170     protected function get_other_values(renderer_base $output) {
171         $daytimestamp = $this->calendar->time;
172         $timestamp = $this->data[0];
173         // Need to account for user's timezone.
174         $usernow = usergetdate(time());
175         $today = new \DateTimeImmutable();
176         // The start time should use the day's date but the current
177         // time of the day (adjusted for user's timezone).
178         $neweventstarttime = $today->setTimestamp($timestamp)->setTime(
179             $usernow['hours'],
180             $usernow['minutes'],
181             $usernow['seconds']
182         );
184         $return = [
185             'timestamp' => $timestamp,
186             'neweventtimestamp' => $neweventstarttime->getTimestamp(),
187             'previousperiod' => $this->get_previous_day_timestamp($daytimestamp),
188             'nextperiod' => $this->get_next_day_timestamp($daytimestamp),
189             'navigation' => $this->get_navigation(),
190             'new_event_button' => $this->get_new_event_button(),
191             'viewdaylink' => $this->url->out(false),
192         ];
195         $cache = $this->related['cache'];
196         $eventexporters = array_map(function($event) use ($cache, $output) {
197             $context = $cache->get_context($event);
198             $course = $cache->get_course($event);
199             $exporter = new calendar_event_exporter($event, [
200                 'context' => $context,
201                 'course' => $course,
202                 'daylink' => $this->url,
203                 'type' => $this->related['type'],
204                 'today' => $this->data[0],
205             ]);
207             return $exporter;
208         }, $this->related['events']);
210         $return['events'] = array_map(function($exporter) use ($output) {
211             return $exporter->export($output);
212         }, $eventexporters);
214         $return['hasevents'] = !empty($return['events']);
216         $return['calendareventtypes'] = array_map(function($exporter) {
217             return $exporter->get_calendar_event_type();
218         }, $eventexporters);
219         $return['calendareventtypes'] = array_values(array_unique($return['calendareventtypes']));
221         $return['haslastdayofevent'] = false;
222         foreach ($return['events'] as $event) {
223             if ($event->islastday) {
224                 $return['haslastdayofevent'] = true;
225                 break;
226             }
227         }
229         return $return;
230     }
232     /**
233      * Returns a list of objects that are related.
234      *
235      * @return array
236      */
237     protected static function define_related() {
238         return [
239             'events' => '\core_calendar\local\event\entities\event_interface[]',
240             'cache' => '\core_calendar\external\events_related_objects_cache',
241             'type' => '\core_calendar\type_base',
242         ];
243     }
245     /**
246      * Get the previous day timestamp.
247      *
248      * @param int $daytimestamp The current day timestamp.
249      * @return int The previous day timestamp.
250      */
251     protected function get_previous_day_timestamp($daytimestamp) {
252         return $this->related['type']->get_prev_day($daytimestamp);
253     }
255     /**
256      * Get the next day timestamp.
257      *
258      * @param int $daytimestamp The current day timestamp.
259      * @return int The next day timestamp.
260      */
261     protected function get_next_day_timestamp($daytimestamp) {
262         return $this->related['type']->get_next_day($daytimestamp);
263     }
265     /**
266      * Get the calendar navigation controls.
267      *
268      * @return string The html code to the calendar top navigation.
269      */
270     protected function get_navigation() {
271         return calendar_top_controls('day', [
272             'id' => $this->calendar->courseid,
273             'time' => $this->calendar->time,
274         ]);
275     }
277     /**
278      * Get the course filter selector.
279      *
280      * This is a temporary solution, this code will be removed by MDL-60096.
281      *
282      * @return string The html code for the course filter selector.
283      */
284     protected function get_new_event_button() {
285         // TODO remove this code on MDL-60096.
286         $output = \html_writer::start_tag('div', array('class' => 'buttons'));
287         $output .= \html_writer::start_tag('form',
288                 array('action' => CALENDAR_URL . 'event.php', 'method' => 'get'));
289         $output .= \html_writer::start_tag('div');
290         $output .= \html_writer::empty_tag('input',
291                 array('type' => 'hidden', 'name' => 'action', 'value' => 'new'));
292         $output .= \html_writer::empty_tag('input',
293                 array('type' => 'hidden', 'name' => 'course', 'value' => $this->calendar->courseid));
294         $output .= \html_writer::empty_tag('input',
295                 array('type' => 'hidden', 'name' => 'time', 'value' => $this->calendar->time));
296         $attributes = array('type' => 'submit', 'value' => get_string('newevent', 'calendar'),
297             'class' => 'btn btn-secondary');
298         $output .= \html_writer::empty_tag('input', $attributes);
299         $output .= \html_writer::end_tag('div');
300         $output .= \html_writer::end_tag('form');
301         $output .= \html_writer::end_tag('div');
302         return $output;
303     }