See Release Notes
Long Term Support Release
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 declare(strict_types=1); 18 19 namespace core_reportbuilder\local\helpers; 20 21 use core_text; 22 23 /** 24 * This class handles the setting and retrieving of a users' filter values for given reports 25 * 26 * It is currently using the user preference API as a storage mechanism 27 * 28 * @package core_reportbuilder 29 * @copyright 2021 Paul Holden <paulh@moodle.com> 30 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 31 */ 32 class user_filter_manager { 33 34 /** @var int The size of each chunk, matching the maximum length of a single user preference */ 35 private const PREFERENCE_CHUNK_SIZE = 1333; 36 37 /** @var string The prefix used to name the stored user preferences */ 38 private const PREFERENCE_NAME_PREFIX = 'reportbuilder-report-'; 39 40 /** 41 * Generate user preference name for given report 42 * 43 * @param int $reportid 44 * @param int $index 45 * @return string 46 */ 47 private static function user_preference_name(int $reportid, int $index): string { 48 return static::PREFERENCE_NAME_PREFIX . "{$reportid}-{$index}"; 49 } 50 51 /** 52 * Set user filters for given report 53 * 54 * @param int $reportid 55 * @param array $values 56 * @param int|null $userid 57 * @return bool 58 */ 59 public static function set(int $reportid, array $values, int $userid = null): bool { 60 $jsonvalues = json_encode($values); 61 62 $jsonchunks = str_split($jsonvalues, static::PREFERENCE_CHUNK_SIZE); 63 foreach ($jsonchunks as $index => $jsonchunk) { 64 $userpreference = static::user_preference_name($reportid, $index); 65 set_user_preference($userpreference, $jsonchunk, $userid); 66 } 67 68 // Ensure any subsequent preferences are reset (to account for number of chunks decreasing). 69 static::reset_all($reportid, $userid, $index + 1); 70 71 return true; 72 } 73 74 /** 75 * Get user filters for given report 76 * 77 * @param int $reportid 78 * @param int|null $userid 79 * @return array 80 */ 81 public static function get(int $reportid, int $userid = null): array { 82 $jsonvalues = ''; 83 $index = 0; 84 85 // We'll repeatedly append chunks to our JSON string, until we hit one that is below the maximum length. 86 do { 87 $userpreference = static::user_preference_name($reportid, $index++); 88 $jsonchunk = get_user_preferences($userpreference, '', $userid); 89 $jsonvalues .= $jsonchunk; 90 } while (core_text::strlen($jsonchunk) === static::PREFERENCE_CHUNK_SIZE); 91 92 return (array) json_decode($jsonvalues); 93 } 94 95 /** 96 * Merge individual user filter values for given report 97 * 98 * @param int $reportid 99 * @param array $values 100 * @param int|null $userid 101 * @return bool 102 */ 103 public static function merge(int $reportid, array $values, int $userid = null): bool { 104 $existing = static::get($reportid, $userid); 105 106 return static::set($reportid, array_merge($existing, $values), $userid); 107 } 108 109 /** 110 * Reset all user filters for given report 111 * 112 * @param int $reportid 113 * @param int|null $userid 114 * @param int $index If specified, then preferences will be reset starting from this index 115 * @return bool 116 */ 117 public static function reset_all(int $reportid, int $userid = null, int $index = 0): bool { 118 // We'll repeatedly retrieve and reset preferences, until we hit one that is below the maximum length. 119 do { 120 $userpreference = static::user_preference_name($reportid, $index++); 121 $jsonchunk = get_user_preferences($userpreference, '', $userid); 122 unset_user_preference($userpreference, $userid); 123 } while (core_text::strlen($jsonchunk) === static::PREFERENCE_CHUNK_SIZE); 124 125 return true; 126 } 127 128 /** 129 * Reset single user filter for given report 130 * 131 * @param int $reportid 132 * @param string $uniqueidentifier 133 * @param int|null $userid 134 * @return bool 135 */ 136 public static function reset_single(int $reportid, string $uniqueidentifier, int $userid = null): bool { 137 $originalvalues = static::get($reportid, $userid); 138 139 // Remove any filters whose name is prefixed by given identifier. 140 $values = array_filter($originalvalues, static function(string $filterkey) use ($uniqueidentifier): bool { 141 return core_text::strpos($filterkey, $uniqueidentifier) !== 0; 142 }, ARRAY_FILTER_USE_KEY); 143 144 return static::set($reportid, $values, $userid); 145 } 146 147 /** 148 * Get all report filters for given user 149 * 150 * This is primarily designed for the privacy provider, and allows us to preserve all the preference logic within this class. 151 * 152 * @param int $userid 153 * @return array 154 */ 155 public static function get_all_for_user(int $userid): array { 156 global $DB; 157 $prefs = []; 158 159 // We need to locate the first preference chunk of all report filters. 160 $select = 'userid = :userid AND ' . $DB->sql_like('name', ':namelike'); 161 $params = [ 162 'userid' => $userid, 163 'namelike' => $DB->sql_like_escape(static::PREFERENCE_NAME_PREFIX) . '%-0', 164 ]; 165 $preferences = $DB->get_fieldset_select('user_preferences', 'name', $select, $params); 166 167 // Retrieve all found filters. 168 foreach ($preferences as $preference) { 169 preg_match('/^' . static::PREFERENCE_NAME_PREFIX . '(?<reportid>\d+)\-/', $preference, $matches); 170 $prefs[static::PREFERENCE_NAME_PREFIX . $matches['reportid']] = static::get((int) $matches['reportid'], $userid); 171 } 172 173 return $prefs; 174 } 175 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body