芝麻web文件管理V1.00
编辑当前文件:/home2/sdektunc/.trash/cepali/privacy/classes/local/request/contextlist.php
. /** * Privacy Fetch Result Set. * * @package core_privacy * @copyright 2018 Andrew Nicols
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ namespace core_privacy\local\request; defined('MOODLE_INTERNAL') || die(); /** * Privacy Fetch Result Set. * * @copyright 2018 Andrew Nicols
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class contextlist extends contextlist_base { /** * Add a set of contexts from SQL. * * The SQL should only return a list of context IDs. * * @param string $sql The SQL which will fetch the list of * context IDs * @param array $params The set of SQL parameters * @return $this */ public function add_from_sql(string $sql, array $params) : contextlist { global $DB; $fields = \context_helper::get_preload_record_columns_sql('ctx'); if ($fieldname = $this->guess_id_field_from_sql($sql)) { if (is_numeric($fieldname)) { $wrapper = " SELECT {$fields} FROM {context} ctx WHERE ctx.id = :fieldvalue"; $params = ['fieldvalue' => $fieldname]; } else { // Able to guess a field name. $wrapper = " SELECT {$fields} FROM {context} ctx JOIN ({$sql}) target ON ctx.id = target.{$fieldname}"; } } else { // No field name available. Fall back on a potentially slower version. $wrapper = " SELECT {$fields} FROM {context} ctx WHERE ctx.id IN ({$sql})"; } $contexts = $DB->get_recordset_sql($wrapper, $params); $contextids = []; foreach ($contexts as $context) { $contextids[] = $context->ctxid; \context_helper::preload_from_record($context); } $contexts->close(); $this->set_contextids(array_merge($this->get_contextids(), $contextids)); return $this; } /** * Adds the system context. * * @return $this */ public function add_system_context() : contextlist { return $this->add_from_sql(SYSCONTEXTID, []); } /** * Adds the user context for a given user. * * @param int $userid * @return $this */ public function add_user_context(int $userid) : contextlist { $sql = "SELECT DISTINCT ctx.id FROM {context} ctx WHERE ctx.contextlevel = :contextlevel AND ctx.instanceid = :instanceid"; return $this->add_from_sql($sql, ['contextlevel' => CONTEXT_USER, 'instanceid' => $userid]); } /** * Adds the user contexts for given users. * * @param array $userids * @return $this */ public function add_user_contexts(array $userids) : contextlist { global $DB; list($useridsql, $useridparams) = $DB->get_in_or_equal($userids, SQL_PARAMS_NAMED); $sql = "SELECT DISTINCT ctx.id FROM {context} ctx WHERE ctx.contextlevel = :contextlevel AND ctx.instanceid $useridsql"; return $this->add_from_sql($sql, ['contextlevel' => CONTEXT_USER] + $useridparams); } /** * Sets the component for this contextlist. * * @param string $component the frankenstyle component name. */ public function set_component($component) { parent::set_component($component); } /** * Guess the name of the contextid field from the supplied SQL. * * @param string $sql The SQL to guess from * @return string The field name or a numeric value representing the context id */ protected function guess_id_field_from_sql(string $sql) : string { // We are not interested in any subquery/view/conditions for the purpose of this method, so // let's reduce the query to the interesting parts by recursively cleaning all // contents within parenthesis. If there are problems (null), we keep the text unmodified. // So just top-level sql will remain after the reduction. $recursiveregexp = '/\((([^()]*|(?R))*)\)/'; $sql = (preg_replace($recursiveregexp, '', $sql) ?: $sql); // Get the list of relevant words from the SQL Query. // We explode the SQL by the space character, then trim any extra whitespace (e.g. newlines), before we filter // empty value, and finally we re-index the array. $sql = rtrim($sql, ';'); $words = array_map('trim', preg_split('/\s+/', $sql)); $words = array_filter($words, function($word) { return $word !== ''; }); $words = array_values($words); $uwords = array_map('strtoupper', $words); // Uppercase all them. // If the query has boolean operators (UNION, it is the only one we support cross-db) // then we cannot guarantee whats coming after the first query, it can be anything. if (array_search('UNION', $uwords)) { return ''; } if ($firstfrom = array_search('FROM', $uwords)) { // Found a FROM keyword. // Select the previous word. $fieldname = $words[$firstfrom - 1]; if (is_numeric($fieldname)) { return $fieldname; } if ($hasdot = strpos($fieldname, '.')) { // This field is against a table alias. Take off the alias. $fieldname = substr($fieldname, $hasdot + 1); } return $fieldname; } else if ((count($words) == 1) && (is_numeric($words[0]))) { // Not a real SQL, just a single numerical value - such as one returned by {@link self::add_system_context()}. return $words[0]; } else if ((count($words) == 2) && (strtoupper($words[0]) === 'SELECT') && (is_numeric($words[1]))) { // SQL returning a constant numerical value. return $words[1]; } return ''; } }