Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1441 ariadna 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\route\controller;
18
 
19
use core\form\error_feedback;
20
use core\router;
21
use core\router\route;
22
use core\router\schema\parameters\query_parameter;
23
use core\router\util;
24
use core\url;
25
use core_user;
26
use Psr\Http\Message\ResponseInterface;
27
use Psr\Http\Message\ServerRequestInterface;
28
 
29
/**
30
 * Page Not Found Controller.
31
 *
32
 * @package    core
33
 * @copyright  Andrew Lyons <andrew@nicols.co.uk>
34
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
35
 */
36
class page_not_found_controller {
37
    use \core\router\route_controller;
38
 
39
    /**
40
     * Constructor for the page not found handler.
41
     *
42
     * @param \core\router $router The router.
43
     */
44
    public function __construct(
45
        /** @var router The routing engine */
46
        private router $router,
47
    ) {
48
    }
49
 
50
    /**
51
     * Administer a course.
52
     *
53
     * @param ServerRequestInterface $request
54
     * @param ResponseInterface $response
55
     * @return ResponseInterface
56
     */
57
    #[route(
58
        path: '/error',
59
        method: ['GET', 'POST'],
60
        queryparams: [
61
            new query_parameter(
62
                name: 'code',
63
                type: \core\param::INT,
64
                default: 404,
65
            ),
66
        ],
67
    )]
68
    public function page_not_found_handler(
69
        ServerRequestInterface $request,
70
    ): ResponseInterface {
71
        global $CFG, $PAGE, $OUTPUT, $ME;
72
 
73
        $context = \core\context\system::instance();
74
        $title = get_string('pagenotexisttitle', 'error');
75
        $PAGE->set_url('/error');
76
        $PAGE->set_context($context);
77
        $PAGE->set_title($title);
78
        $PAGE->set_heading($title);
79
        $PAGE->navbar->add($title);
80
 
81
        // This allows the webserver to dictate wether the http status should remain
82
        // what it would have been, or force it to be a 404. Under other conditions
83
        // it could most often be a 403, 405 or a 50x error.
84
        $code = $request->getQueryParams()['code'] ?? 404;
85
        $response = $this->router->get_app()->getResponseFactory()->createResponse($code);
86
 
87
        $mform = $this->get_message_form($response);
88
        if ($mform) {
89
            if ($this->process_message_form($mform)) {
90
                // The form was submitted. Redirect to the home page.
91
                return util::redirect(
92
                    $response,
93
                    new url('/'),
94
                );
95
            }
96
 
97
            // Form not submitted. We need to set the referer and request path because the URI may be different on submission.
98
            $mform->set_data([
99
                'referer' => $request->getHeaderLine('Referer'),
100
                'requested' => $request->getUri()->getPath(),
101
            ]);
102
        }
103
 
104
        $response->getBody()->write($OUTPUT->header());
105
        $response->getBody()->write($OUTPUT->notification(get_string('pagenotexist', 'error', s($ME)), 'error'));
106
        $response->getBody()->write($OUTPUT->supportemail(['class' => 'text-center d-block mb-3 fw-bold']));
107
 
108
        if ($mform) {
109
            $response->getBody()->write(\html_writer::tag('h4', get_string('sendmessage', 'error')));
110
            $response->getBody()->write($mform->render());
111
        } else {
112
            $response->getBody()->write($OUTPUT->continue_button($CFG->wwwroot));
113
        }
114
 
115
        $response->getBody()->write($OUTPUT->footer());
116
 
117
        return $response;
118
    }
119
 
120
    /**
121
     * Get the message form, or null if it should not be displayed.
122
     *
123
     * @param \Psr\Http\Message\ResponseInterface $response
124
     * @return error_feedback|null
125
     */
126
    protected function get_message_form(
127
        ResponseInterface $response,
128
    ): ?\moodleform {
129
        $canmessage = has_capability('moodle/site:senderrormessage', \core\context\system::instance());
130
        $supportuser = core_user::get_support_user();
131
 
132
        // We can only message support if both the user has the capability
133
        // and the support user is a real user.
134
        $canmessage = $canmessage && core_user::is_real_user($supportuser->id);
135
 
136
        if (!$canmessage) {
137
            return null;
138
        }
139
 
140
        return new error_feedback(util::get_path_for_callable([self::class, 'page_not_found_handler'], [], [])->out());
141
    }
142
 
143
    /**
144
     * Process the message form.
145
     *
146
     * If the form was submitted, send the message and return a redirect response.
147
     *
148
     * @param error_feedback $mform
149
     * @return bool
150
     */
151
    protected function process_message_form(
152
        error_feedback $mform,
153
    ): bool {
154
        global $CFG, $USER;
155
        if ($data = $mform->get_data()) {
156
            // Send the message and redirect.
157
            $message = new \core\message\message();
158
            $message->courseid         = SITEID;
159
            $message->component        = 'moodle';
160
            $message->name             = 'errors';
161
            $message->userfrom          = $USER;
162
            $message->userto            = core_user::get_support_user();
163
            $message->subject           = 'Error: ' . $data->referer . ' -> ' . $data->requested;
164
            $message->fullmessage       = $data->text;
165
            $message->fullmessageformat = FORMAT_PLAIN;
166
            $message->fullmessagehtml   = '';
167
            $message->smallmessage      = '';
168
            $message->contexturl = $data->requested;
169
            message_send($message);
170
 
171
            \core\notification::success(get_string('sendmessagesent', 'error', $data->requested));
172
 
173
            return true;
174
        }
175
 
176
        return false;
177
    }
178
}