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 * Classes representing JS event handlers, used by output components.
19 *
20 * Please see http://docs.moodle.org/en/Developement:How_Moodle_outputs_HTML
21 * for an overview.
22 *
23 * @package core
24 * @category output
25 * @copyright 2009 Nicolas Connault
26 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
27 */
28
29defined('MOODLE_INTERNAL') || die();
30
31/**
32 * Helper class used by other components that involve an action on the page (URL or JS).
33 *
34 * @copyright 2009 Nicolas Connault
35 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
36 * @since Moodle 2.0
37 * @package core
38 * @category output
39 */
40class component_action implements templatable {
41
42    /**
43     * @var string $event The DOM event that will trigger this action when caught
44     */
45    public $event;
46
47    /**
48     * @var string A function name to call when the button is clicked
49     * The JS function you create must have two arguments:
50     *      1. The event object
51     *      2. An object/array of arguments ($jsfunctionargs)
52     */
53    public $jsfunction = false;
54
55    /**
56     * @var array An array of arguments to pass to the JS function
57     */
58    public $jsfunctionargs = array();
59
60    /**
61     * Constructor
62     * @param string $event DOM event
63     * @param string $jsfunction An optional JS function. Required if jsfunctionargs is given
64     * @param array $jsfunctionargs An array of arguments to pass to the jsfunction
65     */
66    public function __construct($event, $jsfunction, $jsfunctionargs=array()) {
67        $this->event = $event;
68
69        $this->jsfunction = $jsfunction;
70        $this->jsfunctionargs = $jsfunctionargs;
71
72        if (!empty($this->jsfunctionargs)) {
73            if (empty($this->jsfunction)) {
74                throw new coding_exception('The component_action object needs a jsfunction value to pass the jsfunctionargs to.');
75            }
76        }
77    }
78
79    /**
80     * Export for template.
81     *
82     * @param renderer_base $output The renderer.
83     * @return stdClass
84     */
85    public function export_for_template(renderer_base $output) {
86        $args = !empty($this->jsfunctionargs) ? json_encode($this->jsfunctionargs) : false;
87        return (object) [
88            'event' => $this->event,
89            'jsfunction' => $this->jsfunction,
90            'jsfunctionargs' => $args,
91        ];
92    }
93}
94
95
96/**
97 * Confirm action
98 *
99 * @copyright 2009 Nicolas Connault
100 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
101 * @since Moodle 2.0
102 * @package core
103 * @category output
104 */
105class confirm_action extends component_action {
106    /**
107     * Constructs the confirm action object
108     *
109     * @param string $message The message to display to the user when they are shown
110     *    the confirm dialogue.
111     * @param string $callback Deprecated since 2.7
112     * @param string $continuelabel The string to use for he continue button
113     * @param string $cancellabel The string to use for the cancel button
114     */
115    public function __construct($message, $callback = null, $continuelabel = null, $cancellabel = null) {
116        if ($callback !== null) {
117            debugging('The callback argument to new confirm_action() has been deprecated.' .
118                    ' If you need to use a callback, please write Javascript to use moodle-core-notification-confirmation ' .
119                    'and attach to the provided events.',
120                    DEBUG_DEVELOPER);
121        }
122        parent::__construct('click', 'M.util.show_confirm_dialog', array(
123                'message' => $message,
124                'continuelabel' => $continuelabel, 'cancellabel' => $cancellabel));
125    }
126}
127
128
129/**
130 * Component action for a popup window.
131 *
132 * @copyright 2009 Nicolas Connault
133 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
134 * @since Moodle 2.0
135 * @package core
136 * @category output
137 */
138class popup_action extends component_action {
139
140    /**
141     * @var string The JS function to call for the popup
142     */
143    public $jsfunction = 'openpopup';
144
145    /**
146     * @var array An array of parameters that will be passed to the openpopup JS function
147     */
148    public $params = array(
149            'height' =>  400,
150            'width' => 500,
151            'top' => 0,
152            'left' => 0,
153            'menubar' => false,
154            'location' => false,
155            'scrollbars' => true,
156            'resizable' => true,
157            'toolbar' => true,
158            'status' => true,
159            'directories' => false,
160            'fullscreen' => false,
161            'dependent' => true);
162
163    /**
164     * Constructor
165     *
166     * @param string $event DOM event
167     * @param moodle_url|string $url A moodle_url object, required if no jsfunction is given
168     * @param string $name The JS function to call for the popup (default 'popup')
169     * @param array  $params An array of popup parameters
170     */
171    public function __construct($event, $url, $name='popup', $params=array()) {
172        global $CFG;
173        $this->name = $name;
174
175        $url = new moodle_url($url);
176
177        if ($this->name) {
178            $_name = $this->name;
179            if (($_name = preg_replace("/\s/", '_', $_name)) != $this->name) {
180                throw new coding_exception('The $name of a popup window shouldn\'t contain spaces - string modified. '. $this->name .' changed to '. $_name);
181                $this->name = $_name;
182            }
183        } else {
184            $this->name = 'popup';
185        }
186
187        foreach ($this->params as $var => $val) {
188            if (array_key_exists($var, $params)) {
189                $this->params[$var] = $params[$var];
190            }
191        }
192
193        $attributes = array('url' => $url->out(false), 'name' => $name, 'options' => $this->get_js_options($params));
194        if (!empty($params['fullscreen'])) {
195            $attributes['fullscreen'] = 1;
196        }
197        parent::__construct($event, $this->jsfunction, $attributes);
198    }
199
200    /**
201     * Returns a string of concatenated option->value pairs used by JS to call the popup window,
202     * based on this object's variables
203     *
204     * @return string String of option->value pairs for JS popup function.
205     */
206    public function get_js_options() {
207        $jsoptions = '';
208
209        foreach ($this->params as $var => $val) {
210            if (is_string($val) || is_int($val)) {
211                $jsoptions .= "$var=$val,";
212            } elseif (is_bool($val)) {
213                $jsoptions .= ($val) ? "$var," : "$var=0,";
214            }
215        }
216
217        $jsoptions = substr($jsoptions, 0, strlen($jsoptions) - 1);
218
219        return $jsoptions;
220    }
221}
222