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/>.
16
17/**
18 * Allows the user to manage calendar subscriptions.
19 *
20 * @copyright 2012 Jonathan Harker
21 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
22 * @package calendar
23 */
24namespace core_calendar\local\event\forms;
25
26defined('MOODLE_INTERNAL') || die();
27
28require_once($CFG->libdir . '/formslib.php');
29
30/**
31 * Form for adding a subscription to a Moodle course calendar.
32 * @copyright 2012 Jonathan Harker
33 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
34 */
35class managesubscriptions extends \moodleform {
36
37    use eventtype;
38
39    /**
40     * Defines the form used to add calendar subscriptions.
41     */
42    public function definition() {
43        global $PAGE;
44        $mform = $this->_form;
45        $eventtypes = calendar_get_allowed_event_types();
46        if (in_array(true, $eventtypes, true) === false) {
47            print_error('nopermissiontoupdatecalendar');
48        }
49
50        $mform->addElement('header', 'addsubscriptionform', get_string('importcalendarheading', 'calendar'));
51
52        // Name.
53        $mform->addElement('text', 'name', get_string('subscriptionname', 'calendar'), array('maxsize' => '255', 'size' => '40'));
54        $mform->addRule('name', get_string('required'), 'required');
55        $mform->setType('name', PARAM_TEXT);
56
57        // Import from (url | importfile).
58        $mform->addElement('html', get_string('importfrominstructions', 'calendar'));
59        $choices = array(CALENDAR_IMPORT_FROM_FILE => get_string('importfromfile', 'calendar'),
60            CALENDAR_IMPORT_FROM_URL  => get_string('importfromurl',  'calendar'));
61        $mform->addElement('select', 'importfrom', get_string('importcalendarfrom', 'calendar'), $choices);
62        $mform->setDefault('importfrom', CALENDAR_IMPORT_FROM_URL);
63
64        // URL.
65        $mform->addElement('text', 'url', get_string('importfromurl', 'calendar'), array('maxsize' => '255', 'size' => '50'));
66        // Cannot set as PARAM_URL since we need to allow webcal:// protocol.
67        $mform->setType('url', PARAM_RAW);
68        $mform->setForceLtr('url');
69
70        // Poll interval
71        $choices = calendar_get_pollinterval_choices();
72        $mform->addElement('select', 'pollinterval', get_string('pollinterval', 'calendar'), $choices);
73        $mform->setDefault('pollinterval', 604800);
74        $mform->addHelpButton('pollinterval', 'pollinterval', 'calendar');
75        $mform->setType('pollinterval', PARAM_INT);
76
77        // Import file
78        $mform->addElement('filepicker', 'importfile', get_string('importfromfile', 'calendar'), null, array('accepted_types' => '.ics'));
79
80        // Disable appropriate elements depending on import from value.
81        $mform->hideIf('pollinterval', 'importfrom', 'eq', CALENDAR_IMPORT_FROM_FILE);
82        $mform->hideIf('url',  'importfrom', 'eq', CALENDAR_IMPORT_FROM_FILE);
83        $mform->hideIf('importfile', 'importfrom', 'eq', CALENDAR_IMPORT_FROM_URL);
84
85        // Add the select elements for the available event types.
86        $this->add_event_type_elements($mform, $eventtypes);
87
88        // Eventtype: 0 = user, 1 = site, anything else = course ID.
89        $mform->addElement('submit', 'add', get_string('add'));
90
91        // Add the javascript required to enhance this mform.
92        $PAGE->requires->js_call_amd('core_calendar/event_form', 'init', [$mform->getAttribute('id')]);
93    }
94
95    /**
96     * Validates the returned data.
97     *
98     * @param array $data
99     * @param array $files
100     * @return array
101     */
102    public function validation($data, $files) {
103        global $USER;
104
105        $errors = parent::validation($data, $files);
106
107        $eventtype = isset($data['eventtype']) ? $data['eventtype'] : null;
108        $coursekey = ($eventtype == 'group') ? 'groupcourseid' : 'courseid';
109        $courseid = (!empty($data[$coursekey])) ? $data[$coursekey] : null;
110        $eventtypes = calendar_get_allowed_event_types($courseid);
111
112        if (empty($eventtype) || !isset($eventtypes[$eventtype])) {
113            $errors['eventtype'] = get_string('invalideventtype', 'calendar');
114        }
115
116        if ($data['importfrom'] == CALENDAR_IMPORT_FROM_FILE) {
117            if (empty($data['importfile'])) {
118                $errors['importfile'] = get_string('errorrequiredurlorfile', 'calendar');
119            } else {
120                // Make sure the file area is not empty and contains only one file.
121                $draftitemid = $data['importfile'];
122                $fs = get_file_storage();
123                $usercontext = \context_user::instance($USER->id);
124                $files = $fs->get_area_files($usercontext->id, 'user', 'draft', $draftitemid, 'id DESC', false);
125                if (count($files) !== 1) {
126                    $errors['importfile'] = get_string('errorrequiredurlorfile', 'calendar');
127                }
128            }
129        } else if (($data['importfrom'] == CALENDAR_IMPORT_FROM_URL)) {
130            // Clean input calendar url.
131            $url = clean_param($data['url'], PARAM_URL);
132            try {
133                calendar_get_icalendar($url);
134            } catch (\moodle_exception $e) {
135                $errors['url']  = get_string('errorinvalidicalurl', 'calendar');
136            }
137        } else {
138            // Shouldn't happen.
139            $errors['url'] = get_string('errorrequiredurlorfile', 'calendar');
140        }
141
142        return $errors;
143    }
144
145    public function definition_after_data() {
146        $mform =& $this->_form;
147
148        $mform->applyFilter('url', static::class . '::strip_webcal');
149        $mform->applyFilter('url', 'trim');
150    }
151
152    /**
153     * Replace webcal:// urls with http:// as
154     * curl does not understand this protocol
155     *
156     * @param string @url url to examine
157     * @return string url with webcal:// replaced
158     */
159    public static function strip_webcal($url) {
160        if (strpos($url, 'webcal://') === 0) {
161            $url = str_replace('webcal://', 'http://', $url);
162        }
163        return $url;
164    }
165}
166