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 - https://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 <https://www.gnu.org/licenses/>.
16
 
17
namespace core\context;
18
 
19
use core\context;
20
use stdClass;
21
use coding_exception, moodle_url;
22
 
23
/**
24
 * User context class
25
 *
26
 * @package   core_access
27
 * @category  access
28
 * @copyright Petr Skoda
29
 * @license   https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
30
 * @since     Moodle 4.2
31
 */
32
class user extends context {
33
    /** @var int numeric context level value matching legacy CONTEXT_USER */
34
    public const LEVEL = 30;
35
 
36
    /**
37
     * Please use \core\context\user::instance($userid) if you need the instance of context.
38
     * Alternatively if you know only the context id use \core\context::instance_by_id($contextid)
39
     *
40
     * @param stdClass $record
41
     */
42
    protected function __construct(stdClass $record) {
43
        parent::__construct($record);
44
        if ($record->contextlevel != self::LEVEL) {
45
            throw new coding_exception('Invalid $record->contextlevel in core\context\user constructor.');
46
        }
47
    }
48
 
49
    /**
50
     * Returns short context name.
51
     *
52
     * @since Moodle 4.2
53
     *
54
     * @return string
55
     */
56
    public static function get_short_name(): string {
57
        return 'user';
58
    }
59
 
60
    /**
61
     * Returns human readable context level name.
62
     *
63
     * @return string the human readable context level name.
64
     */
65
    public static function get_level_name() {
66
        return get_string('user');
67
    }
68
 
69
    /**
70
     * Returns human readable context identifier.
71
     *
72
     * @param boolean $withprefix whether to prefix the name of the context with User
73
     * @param boolean $short does not apply to user context
74
     * @param boolean $escape does not apply to user context
75
     * @return string the human readable context name.
76
     */
77
    public function get_context_name($withprefix = true, $short = false, $escape = true) {
78
        global $DB;
79
 
80
        $name = '';
81
        if ($user = $DB->get_record('user', array('id' => $this->_instanceid, 'deleted' => 0))) {
82
            if ($withprefix) {
83
                $name = get_string('user').': ';
84
            }
85
            $name .= fullname($user);
86
        }
87
        return $name;
88
    }
89
 
90
    /**
91
     * Returns the most relevant URL for this context.
92
     *
93
     * @return moodle_url
94
     */
95
    public function get_url() {
96
        global $COURSE;
97
 
98
        if ($COURSE->id == SITEID) {
99
            $url = new moodle_url('/user/profile.php', array('id' => $this->_instanceid));
100
        } else {
101
            $url = new moodle_url('/user/view.php', array('id' => $this->_instanceid, 'courseid' => $COURSE->id));
102
        }
103
        return $url;
104
    }
105
 
106
    /**
107
     * Returns list of all possible parent context levels.
108
     * @since Moodle 4.2
109
     *
110
     * @return int[]
111
     */
112
    public static function get_possible_parent_levels(): array {
113
        return [system::LEVEL];
114
    }
115
 
116
    /**
117
     * Returns context instance database name.
118
     *
119
     * @return string|null table name for all levels except system.
120
     */
121
    protected static function get_instance_table(): ?string {
122
        return 'user';
123
    }
124
 
125
    /**
126
     * Returns list of columns that can be used from behat
127
     * to look up context by reference.
128
     *
129
     * @return array list of column names from instance table
130
     */
131
    protected static function get_behat_reference_columns(): array {
132
        return ['username'];
133
    }
134
 
135
    /**
136
     * Returns array of relevant context capability records.
137
     *
138
     * @param string $sort
139
     * @return array
140
     */
141
    public function get_capabilities(string $sort = self::DEFAULT_CAPABILITY_SORT) {
142
        global $DB;
143
 
144
        $extracaps = array('moodle/grade:viewall');
145
        list($extra, $params) = $DB->get_in_or_equal($extracaps, SQL_PARAMS_NAMED, 'cap');
146
 
147
        return $DB->get_records_select('capabilities', "contextlevel = :level OR name {$extra}",
148
            $params + ['level' => self::LEVEL], $sort);
149
    }
150
 
151
    /**
152
     * Returns user context instance.
153
     *
154
     * @param int $userid id from {user} table
155
     * @param int $strictness
156
     * @return user|false context instance
157
     */
158
    public static function instance($userid, $strictness = MUST_EXIST) {
159
        global $DB;
160
 
161
        if ($context = context::cache_get(self::LEVEL, $userid)) {
162
            return $context;
163
        }
164
 
165
        if (!$record = $DB->get_record('context', array('contextlevel' => self::LEVEL, 'instanceid' => $userid))) {
166
            if ($user = $DB->get_record('user', array('id' => $userid, 'deleted' => 0), 'id', $strictness)) {
167
                $record = context::insert_context_record(self::LEVEL, $user->id, '/'.SYSCONTEXTID, 0);
168
            }
169
        }
170
 
171
        if ($record) {
172
            $context = new user($record);
173
            context::cache_add($context);
174
            return $context;
175
        }
176
 
177
        return false;
178
    }
179
 
180
    /**
181
     * Create missing context instances at user context level
182
     */
183
    protected static function create_level_instances() {
184
        global $DB;
185
 
186
        $sql = "SELECT " . self::LEVEL . ", u.id
187
                  FROM {user} u
188
                 WHERE u.deleted = 0
189
                       AND NOT EXISTS (SELECT 'x'
190
                                         FROM {context} cx
191
                                        WHERE u.id = cx.instanceid AND cx.contextlevel=" . self::LEVEL . ")";
192
        $contextdata = $DB->get_recordset_sql($sql);
193
        foreach ($contextdata as $context) {
194
            context::insert_context_record(self::LEVEL, $context->id, null);
195
        }
196
        $contextdata->close();
197
    }
198
 
199
    /**
200
     * Returns sql necessary for purging of stale context instances.
201
     *
202
     * @return string cleanup SQL
203
     */
204
    protected static function get_cleanup_sql() {
205
        $sql = "
206
                  SELECT c.*
207
                    FROM {context} c
208
         LEFT OUTER JOIN {user} u ON (c.instanceid = u.id AND u.deleted = 0)
209
                   WHERE u.id IS NULL AND c.contextlevel = " . self::LEVEL . "
210
               ";
211
 
212
        return $sql;
213
    }
214
 
215
    /**
216
     * Rebuild context paths and depths at user context level.
217
     *
218
     * @param bool $force
219
     */
220
    protected static function build_paths($force) {
221
        global $DB;
222
 
223
        // First update normal users.
224
        $path = $DB->sql_concat('?', 'id');
225
        $pathstart = '/' . SYSCONTEXTID . '/';
226
        $params = array($pathstart);
227
 
228
        if ($force) {
229
            $where = "depth <> 2 OR path IS NULL OR path <> ({$path})";
230
            $params[] = $pathstart;
231
        } else {
232
            $where = "depth = 0 OR path IS NULL";
233
        }
234
 
235
        $sql = "UPDATE {context}
236
                   SET depth = 2,
237
                       path = {$path}
238
                 WHERE contextlevel = " . self::LEVEL . "
239
                   AND ($where)";
240
        $DB->execute($sql, $params);
241
    }
242
}