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 * Class represents a single rule.
19 *
20 * @package    tool_monitor
21 * @copyright  2014 onwards Ankit Agarwal <ankit.agrr@gmail.com>
22 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23 */
24
25namespace tool_monitor;
26
27defined('MOODLE_INTERNAL') || die();
28
29/**
30 * Class represents a single rule.
31 *
32 * @since      Moodle 2.8
33 * @package    tool_monitor
34 * @copyright  2014 onwards Ankit Agarwal <ankit.agrr@gmail.com>
35 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
36 */
37class rule {
38
39    /**
40     * @var \stdClass The rule object form database.
41     */
42    protected $rule;
43
44    /**
45     * Constructor.
46     *
47     * @param \stdClass $rule A rule object from database.
48     */
49    public function __construct($rule) {
50        $this->rule = $rule;
51    }
52
53    /**
54     * Can the user manage this rule? Defaults to $USER.
55     *
56     * @param int $userid Check against this userid.
57     * @return bool true if the current user can manage this rule, else false.
58     */
59    public function can_manage_rule($userid = null) {
60        $courseid = $this->courseid;
61        $context = empty($courseid) ? \context_system::instance() : \context_course::instance($this->courseid);
62        return has_capability('tool/monitor:managerules', $context, $userid);
63    }
64
65    /**
66     * Api to duplicate a rule in a given courseid.
67     *
68     * @param int $finalcourseid Final course id.
69     */
70    public function duplicate_rule($finalcourseid) {
71        $rule = fullclone($this->rule);
72        unset($rule->id);
73        $rule->courseid = $finalcourseid;
74        $time = time();
75        $rule->timecreated = $time;
76        $rule->timemodified = $time;
77        rule_manager::add_rule($rule);
78    }
79
80    /**
81     * Delete this rule.
82     *
83     * Note: It also removes all associated subscriptions.
84     */
85    public function delete_rule() {
86        rule_manager::delete_rule($this->id);
87    }
88
89    /**
90     * Gets the rule subscribe options for a given course and rule.
91     *
92     * Could be a select drop down with a list of possible module
93     * instances or a single link to subscribe if the rule plugin
94     * is not a module.
95     *
96     * @param int $courseid course id
97     *
98     * @return \single_select|\moodle_url|string
99     * @throws \coding_exception
100     */
101    public function get_subscribe_options($courseid) {
102        global $CFG;
103
104        $url = new \moodle_url($CFG->wwwroot. '/admin/tool/monitor/index.php', array(
105            'courseid' => $courseid,
106            'ruleid' => $this->id,
107            'action' => 'subscribe',
108            'sesskey' => sesskey()
109        ));
110
111        if (strpos($this->plugin, 'mod_') !== 0) {
112            return $url;
113
114        } else {
115            // Single select when the plugin is an activity.
116            $options = array();
117            $options[0] = get_string('allmodules', 'tool_monitor');
118
119            if ($courseid == 0) {
120                // They need to be in a course to select module instance.
121                return get_string('selectcourse', 'tool_monitor');
122            }
123
124            // Let them select an instance.
125            $cms = get_fast_modinfo($courseid);
126            $instances = $cms->get_instances_of(str_replace('mod_', '',  $this->plugin));
127            foreach ($instances as $cminfo) {
128                // Don't list instances that are not visible or available to the user.
129                if ($cminfo->uservisible && $cminfo->available) {
130                    $options[$cminfo->id] = $cminfo->get_formatted_name();
131                }
132            }
133
134            return new \single_select($url, 'cmid', $options);
135        }
136    }
137
138    /**
139     * Subscribe an user to this rule.
140     *
141     * @param int $courseid Course id.
142     * @param int $cmid Course module id.
143     * @param int $userid User id.
144     *
145     * @throws \coding_exception
146     */
147    public function subscribe_user($courseid, $cmid, $userid = 0) {
148        global $USER;
149
150        if ($this->courseid != $courseid && $this->courseid != 0) {
151            // Trying to subscribe to a rule that belongs to a different course. Should never happen.
152            throw new \coding_exception('Can not subscribe to rules from a different course');
153        }
154        if ($cmid !== 0) {
155            $cms = get_fast_modinfo($courseid);
156            $cminfo = $cms->get_cm($cmid);
157            if (!$cminfo->uservisible || !$cminfo->available) {
158                // Trying to subscribe to a hidden or restricted cm. Should never happen.
159                throw new \coding_exception('You cannot do that');
160            }
161        }
162        $userid = empty($userid) ? $USER->id : $userid;
163
164        subscription_manager::create_subscription($this->id, $courseid, $cmid, $userid);
165    }
166
167    /**
168     * Magic get method.
169     *
170     * @param string $prop property to get.
171     *
172     * @return mixed
173     * @throws \coding_exception
174     */
175    public function __get($prop) {
176        if (property_exists($this->rule, $prop)) {
177            return $this->rule->$prop;
178        }
179        throw new \coding_exception('Property "' . $prop . '" doesn\'t exist');
180    }
181
182    /**
183     * Return the rule data to be used while setting mform.
184     *
185     * @throws \coding_exception
186     */
187    public function get_mform_set_data() {
188        if (!empty($this->rule)) {
189            $rule = fullclone($this->rule);
190            $rule->description = array('text' => $rule->description, 'format' => $rule->descriptionformat);
191            $rule->template = array('text' => $rule->template, 'format' => $rule->templateformat);
192            return $rule;
193        }
194        throw new \coding_exception('Invalid call to get_mform_set_data.');
195    }
196
197    /**
198     * Method to get event name.
199     *
200     * @return string
201     * @throws \coding_exception
202     */
203    public function get_event_name() {
204        $eventclass = $this->eventname;
205        if (class_exists($eventclass)) {
206            return $eventclass::get_name_with_info();
207        }
208        return get_string('eventnotfound', 'tool_monitor');
209    }
210
211    /**
212     * Get filter description.
213     *
214     * @return string
215     */
216    public function get_filters_description() {
217        $a = new \stdClass();
218        $a->freq = $this->frequency;
219        $mins = $this->timewindow / MINSECS; // Convert seconds to minutes.
220        $a->mins = $mins;
221        return get_string('freqdesc', 'tool_monitor', $a);
222    }
223
224    /**
225     * Get properly formatted name of the course associated.
226     *
227     * @param \context $context context where this name would be displayed.
228     * @return string The course fullname.
229     */
230    public function get_course_name($context) {
231        $courseid = $this->courseid;
232        if (empty($courseid)) {
233            return get_string('site');
234        } else {
235            $course = get_course($courseid);
236            return format_string($course->fullname, true, array('context' => $context));
237        }
238    }
239
240    /**
241     * Get properly formatted name of the rule associated.
242     *
243     * @param \context $context context where this name would be displayed.
244     * @return string Formatted name of the rule.
245     */
246    public function get_name(\context $context) {
247        return format_text($this->name, FORMAT_HTML, array('context' => $context));
248    }
249
250    /**
251     * Get properly formatted description of the rule associated.
252     *
253     * @param \context $context context where this description would be displayed.
254     * @return string Formatted description of the rule.
255     */
256    public function get_description(\context $context) {
257        return format_text($this->description, $this->descriptionformat, array('context' => $context));
258    }
259
260    /**
261     * Get name of the plugin associated with this rule
262     *
263     * @return string Plugin name.
264     */
265    public function get_plugin_name() {
266        if ($this->plugin === 'core') {
267            $string = get_string('core', 'tool_monitor');
268        } else if (get_string_manager()->string_exists('pluginname', $this->plugin)) {
269            $string = get_string('pluginname', $this->plugin);
270        } else {
271            $string = $this->plugin;
272        }
273        return $string;
274    }
275}
276