Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 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
namespace core;
18
 
19
/**
20
 * User Alert notifications.
21
 *
22
 * @package    core
23
 * @copyright  2016 Andrew Nicols <andrew@nicols.co.uk>
24
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
25
 */
26
 
27
use stdClass;
28
 
29
defined('MOODLE_INTERNAL') || die();
30
 
31
class notification {
32
    /**
33
     * A notification of level 'success'.
34
     */
35
    const SUCCESS = 'success';
36
 
37
    /**
38
     * A notification of level 'warning'.
39
     */
40
    const WARNING = 'warning';
41
 
42
    /**
43
     * A notification of level 'info'.
44
     */
45
    const INFO = 'info';
46
 
47
    /**
48
     * A notification of level 'error'.
49
     */
50
    const ERROR = 'error';
51
 
52
    /**
53
     * Add a message to the session notification stack.
54
     *
55
     * @param string $message The message to add to the stack
56
     * @param string $level   The type of message to add to the stack
57
     */
58
    public static function add($message, $level = null) {
59
        global $PAGE, $SESSION;
60
 
61
        if ($PAGE && ($PAGE->state === \moodle_page::STATE_IN_BODY
62
           || $PAGE->state === \moodle_page::STATE_DONE)) {
63
            // Currently in the page body - just render and exit immediately.
64
            // We insert some code to immediately insert this into the user-notifications created by the header.
65
            $id = uniqid();
66
            echo \html_writer::span(
67
                $PAGE->get_renderer('core')->render(new \core\output\notification($message, $level)),
68
                '', array('id' => $id));
69
 
70
            // Insert this JS here using a script directly rather than waiting for the page footer to load to avoid
71
            // ensure that the message is added to the user-notifications section as soon as possible after it is created.
72
            echo \html_writer::script(
73
                    "(function() {" .
74
                        "var notificationHolder = document.getElementById('user-notifications');" .
75
                        "if (!notificationHolder) { return; }" .
76
                        "var thisNotification = document.getElementById('{$id}');" .
77
                        "if (!thisNotification) { return; }" .
78
                        "notificationHolder.appendChild(thisNotification.firstChild);" .
79
                        "thisNotification.remove();" .
80
                    "})();"
81
                );
82
            return;
83
        }
84
 
85
        // Add the notification directly to the session.
86
        // This will either be fetched in the header, or by JS in the footer.
87
        if (!isset($SESSION->notifications) || !array($SESSION->notifications)) {
88
            // Initialise $SESSION if necessary.
89
            if (!is_object($SESSION)) {
90
                $SESSION = new stdClass();
91
            }
92
            $SESSION->notifications = [];
93
        }
94
        $SESSION->notifications[] = (object) array(
95
            'message'   => $message,
96
            'type'      => $level,
97
        );
98
    }
99
 
100
    /**
101
     * @param string[] $icon The icon to use. Required keys are 'pix' and 'component'.
102
     * @param string $message The message to display.
103
     * @param array $actions An array of action links
104
     * @param string $region Optional region name
105
     * @throws \coding_exception
106
     */
107
    public static function add_call_to_action(array $icon, string $message, array $actions, string $region = ''): void {
108
        global $OUTPUT, $PAGE;
109
 
110
        $context = new stdClass();
111
        $context->icon = $icon;
112
        $context->message = $message;
113
        $context->region = $region;
114
 
115
        $context->actions = array_map(function($action) {
116
            $data = [];
117
            foreach ($action['data'] as $name => $value) {
118
                $data[] = ['name' => $name, 'value' => $value];
119
            }
120
            $action['data'] = $data;
121
 
122
            return $action;
123
        }, $actions);
124
 
125
        $notification = $OUTPUT->render_from_template('core/local/notification/cta', $context);
126
 
127
        if ($PAGE && $PAGE->state === \moodle_page::STATE_IN_BODY) {
128
            $id = uniqid();
129
            echo \html_writer::span($notification, '', ['id' => $id]);
130
            echo \html_writer::script(
131
                    "(function() {" .
132
                    "var notificationHolder = document.getElementById('user-notifications');" .
133
                    "if (!notificationHolder) { return; }" .
134
                    "var thisNotification = document.getElementById('{$id}');" .
135
                    "if (!thisNotification) { return; }" .
136
                    "notificationHolder.insertBefore(thisNotification.firstChild, notificationHolder.firstChild);" .
137
                    "thisNotification.remove();" .
138
                    "})();"
139
            );
140
        } else {
141
            throw new \coding_exception('You are calling add_call_to_action() either too early or too late.');
142
        }
143
    }
144
 
145
    /**
146
     * Fetch all of the notifications in the stack and clear the stack.
147
     *
148
     * @return \core\output\notification[] All of the notifications in the stack
149
     */
150
    public static function fetch() {
151
        global $SESSION;
152
 
153
        if (!isset($SESSION) || !isset($SESSION->notifications)) {
154
            return [];
155
        }
156
 
157
        $notifications = $SESSION->notifications;
158
        unset($SESSION->notifications);
159
 
160
        $renderables = [];
161
        foreach ($notifications as $notification) {
162
            $renderable = new \core\output\notification($notification->message, $notification->type);
163
            $renderables[] = $renderable;
164
        }
165
 
166
        return $renderables;
167
    }
168
 
169
    /**
170
     * Fetch all of the notifications in the stack and clear the stack.
171
     *
172
     * @return array All of the notifications in the stack
173
     */
174
    public static function fetch_as_array(\renderer_base $renderer) {
175
        $notifications = [];
176
        foreach (self::fetch() as $notification) {
177
            $notifications[] = [
178
                'template'  => $notification->get_template_name(),
179
                'variables' => $notification->export_for_template($renderer),
180
            ];
181
        }
182
        return $notifications;
183
    }
184
 
185
    /**
186
     * Add a success message to the notification stack.
187
     *
188
     * @param string $message The message to add to the stack
189
     */
190
    public static function success($message) {
191
        return self::add($message, self::SUCCESS);
192
    }
193
 
194
    /**
195
     * Add a info message to the notification stack.
196
     *
197
     * @param string $message The message to add to the stack
198
     */
199
    public static function info($message) {
200
        return self::add($message, self::INFO);
201
    }
202
 
203
    /**
204
     * Add a warning message to the notification stack.
205
     *
206
     * @param string $message The message to add to the stack
207
     */
208
    public static function warning($message) {
209
        return self::add($message, self::WARNING);
210
    }
211
 
212
    /**
213
     * Add a error message to the notification stack.
214
     *
215
     * @param string $message The message to add to the stack
216
     */
217
    public static function error($message) {
218
        return self::add($message, self::ERROR);
219
    }
220
}