Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 4.1.x will end 13 November 2023 (12 months).
  • Bug fixes for security issues in 4.1.x will end 10 November 2025 (36 months).
  • PHP version: minimum PHP 7.4.0 Note: minimum PHP version has increased since Moodle 4.0. PHP 8.0.x is supported too.

Differences Between: [Versions 310 and 401] [Versions 311 and 401] [Versions 39 and 401] [Versions 400 and 401]

   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  /**
  18   * Base implementation of a userlist.
  19   *
  20   * @package    core_privacy
  21   * @copyright  2018 Andrew Nicols <andrew@nicols.co.uk>
  22   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  23   */
  24  
  25  namespace core_privacy\local\request;
  26  
  27  defined('MOODLE_INTERNAL') || die();
  28  
  29  /**
  30   * Base implementation of a userlist used to store a set of users.
  31   *
  32   * @copyright  2018 Andrew Nicols <andrew@nicols.co.uk>
  33   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  34   */
  35  abstract class userlist_base implements
  36          // Implement an Iterator to fetch the Context objects.
  37          \Iterator,
  38  
  39          // Implement the Countable interface to allow the number of returned results to be queried easily.
  40          \Countable {
  41  
  42      /**
  43       * @var array List of user IDs.
  44       *
  45       * Note: this must not be updated using set_userids only as this
  46       * ensures uniqueness.
  47       */
  48      private $userids = [];
  49  
  50      /**
  51       * @var string component the frankenstyle component name.
  52       */
  53      protected $component = '';
  54  
  55      /**
  56       * @var int Current position of the iterator.
  57       */
  58      protected $iteratorposition = 0;
  59  
  60      /** @var \context The context that this userlist belongs to */
  61      protected $context;
  62  
  63      /**
  64       * Constructor to create a new userlist.
  65       *
  66       * @param   \context    $context
  67       * @param   string      $component
  68       */
  69      public function __construct(\context $context, string $component) {
  70          $this->context = $context;
  71          $this->set_component($component);
  72      }
  73  
  74      /**
  75       * Set the userids.
  76       *
  77       * @param   array   $userids The list of users.
  78       * @return  $this
  79       */
  80      protected function set_userids(array $userids) : userlist_base {
  81          $this->userids = array_values(array_unique($userids));
  82  
  83          return $this;
  84      }
  85  
  86      /**
  87       * Add a set of additional userids.
  88       *
  89       * @param   array   $userids The list of users.
  90       * @return  $this
  91       */
  92      protected function add_userids(array $userids) : userlist_base {
  93          $this->set_userids(array_merge($this->get_userids(), $userids));
  94  
  95          return $this;
  96      }
  97  
  98      /**
  99       * Get the list of user IDs that relate to this request.
 100       *
 101       * @return  int[]
 102       */
 103      public function get_userids() : array {
 104          return $this->userids;
 105      }
 106  
 107      /**
 108       * Get the complete list of user objects that relate to this request.
 109       *
 110       * @return  \stdClass[]
 111       */
 112      public function get_users() : array {
 113          $users = [];
 114          foreach ($this->userids as $userid) {
 115              if ($user = \core_user::get_user($userid)) {
 116                  $users[] = $user;
 117              }
 118          }
 119  
 120          return $users;
 121      }
 122  
 123      /**
 124       * Sets the component for this userlist.
 125       *
 126       * @param string $component the frankenstyle component name.
 127       * @return  $this
 128       */
 129      protected function set_component($component) : userlist_base {
 130          $this->component = $component;
 131  
 132          return $this;
 133      }
 134  
 135      /**
 136       * Get the name of the component to which this userlist belongs.
 137       *
 138       * @return string the component name associated with this userlist.
 139       */
 140      public function get_component() : string {
 141          return $this->component;
 142      }
 143  
 144      /**
 145       * Return the current user.
 146       *
 147       * @return  \user
 148       */
 149      #[\ReturnTypeWillChange]
 150      public function current() {
 151          $user = \core_user::get_user($this->userids[$this->iteratorposition]);
 152  
 153          if (false === $user) {
 154              // This user was not found.
 155              unset($this->userids[$this->iteratorposition]);
 156  
 157              // Check to see if there are any more users left.
 158              if ($this->count()) {
 159                  // Move the pointer to the next record and try again.
 160                  $this->next();
 161                  $user = $this->current();
 162              } else {
 163                  // There are no more context ids left.
 164                  return null;
 165              }
 166          }
 167  
 168          return $user;
 169      }
 170  
 171      /**
 172       * Return the key of the current element.
 173       *
 174       * @return  mixed
 175       */
 176      #[\ReturnTypeWillChange]
 177      public function key() {
 178          return $this->iteratorposition;
 179      }
 180  
 181      /**
 182       * Move to the next user in the list.
 183       */
 184      public function next(): void {
 185          ++$this->iteratorposition;
 186      }
 187  
 188      /**
 189       * Check if the current position is valid.
 190       *
 191       * @return  bool
 192       */
 193      public function valid(): bool {
 194          return isset($this->userids[$this->iteratorposition]) && $this->current();
 195      }
 196  
 197      /**
 198       * Rewind to the first found user.
 199       *
 200       * The list of users is uniqued during the rewind.
 201       * The rewind is called at the start of most iterations.
 202       */
 203      public function rewind(): void {
 204          $this->iteratorposition = 0;
 205      }
 206  
 207      /**
 208       * Return the number of users.
 209       */
 210      public function count(): int {
 211          return count($this->userids);
 212      }
 213  
 214      /**
 215       * Get the context for this userlist
 216       *
 217       * @return  \context
 218       */
 219      public function get_context() : \context {
 220          return $this->context;
 221      }
 222  }