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.
   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   * Expiry Data.
  19   *
  20   * @package    tool_dataprivacy
  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  namespace tool_dataprivacy;
  25  
  26  use core_privacy\manager;
  27  
  28  defined('MOODLE_INTERNAL') || die();
  29  
  30  /**
  31   * Expiry Data.
  32   *
  33   * @copyright  2018 Andrew Nicols <andrew@nicols.co.uk>
  34   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  35   */
  36  class expiry_info {
  37  
  38      /** @var bool Whether this context is fully expired */
  39      protected $fullyexpired = false;
  40  
  41      /** @var bool Whether the default expiry value of this purpose has been reached */
  42      protected $defaultexpiryreached = false;
  43  
  44      /** @var bool Whether the default purpose is protected */
  45      protected $defaultprotected = false;
  46  
  47      /** @var int[] List of expires roles */
  48      protected $expired = [];
  49  
  50      /** @var int[] List of unexpires roles */
  51      protected $unexpired = [];
  52  
  53      /** @var int[] List of unexpired roles which are also protected */
  54      protected $protectedroles = [];
  55  
  56      /**
  57       * Constructor for the expiry_info class.
  58       *
  59       * @param   bool    $default Whether the default expiry period for this context has been reached.
  60       * @param   bool    $defaultprotected Whether the default expiry is protected.
  61       * @param   int[]   $expired A list of roles in this context which have explicitly expired.
  62       * @param   int[]   $unexpired A list of roles in this context which have not yet expired.
  63       * @param   int[]   $protectedroles A list of unexpired roles in this context which are protected.
  64       */
  65      public function __construct(bool $default, bool $defaultprotected, array $expired, array $unexpired, array $protectedroles) {
  66          $this->defaultexpiryreached = $default;
  67          $this->defaultprotected = $defaultprotected;
  68          $this->expired = $expired;
  69          $this->unexpired = $unexpired;
  70          $this->protectedroles = $protectedroles;
  71      }
  72  
  73      /**
  74       * Whether this context has 'fully' expired.
  75       * That is to say that the default retention period has been reached, and that there are no unexpired roles.
  76       *
  77       * @return  bool
  78       */
  79      public function is_fully_expired() : bool {
  80          return $this->defaultexpiryreached && empty($this->unexpired);
  81      }
  82  
  83      /**
  84       * Whether any part of this context has expired.
  85       *
  86       * @return  bool
  87       */
  88      public function is_any_expired() : bool {
  89          if ($this->is_fully_expired()) {
  90              return true;
  91          }
  92  
  93          if (!empty($this->get_expired_roles())) {
  94              return true;
  95          }
  96  
  97          if ($this->is_default_expired()) {
  98              return true;
  99          }
 100  
 101          return false;
 102      }
 103  
 104      /**
 105       * Get the list of explicitly expired role IDs.
 106       * Note: This does not list roles which have been expired via the default retention policy being reached.
 107       *
 108       * @return  int[]
 109       */
 110      public function get_expired_roles() : array {
 111          if ($this->is_default_expired()) {
 112              return [];
 113          }
 114          return $this->expired;
 115      }
 116  
 117      /**
 118       * Check whether the specified role is explicitly expired.
 119       * Note: This does not list roles which have been expired via the default retention policy being reached.
 120       *
 121       * @param   int $roleid
 122       * @return  bool
 123       */
 124      public function is_role_expired(int $roleid) : bool {
 125          return false !== array_search($roleid, $this->expired);
 126      }
 127  
 128      /**
 129       * Whether the default retention policy has been reached.
 130       *
 131       * @return  bool
 132       */
 133      public function is_default_expired() : bool {
 134          return $this->defaultexpiryreached;
 135      }
 136  
 137      /**
 138       * Whether the default purpose is protected.
 139       *
 140       * @return  bool
 141       */
 142      public function is_default_protected() : bool {
 143          return $this->defaultprotected;
 144      }
 145  
 146      /**
 147       * Get the list of unexpired role IDs.
 148       *
 149       * @return  int[]
 150       */
 151      public function get_unexpired_roles() : array {
 152          return $this->unexpired;
 153      }
 154  
 155      /**
 156       * Get the list of unexpired protected roles.
 157       *
 158       * @return  int[]
 159       */
 160      public function get_unexpired_protected_roles() : array {
 161          return array_keys(array_filter($this->protectedroles));
 162      }
 163  
 164      /**
 165       * Get a list of all overridden roles which are unprotected.
 166       * @return  int[]
 167       */
 168      public function get_unprotected_overridden_roles() : array {
 169          $allroles = array_merge($this->expired, $this->unexpired);
 170  
 171          return array_diff($allroles, $this->protectedroles);
 172      }
 173  
 174      /**
 175       * Merge this expiry_info object with another belonging to a child context in order to set the 'safest' heritage.
 176       *
 177       * It is not possible to delete any part of a context that is not deleted by a parent.
 178       * So if a course's retention policy has been reached, then only parts where the children have also expired can be
 179       * deleted.
 180       *
 181       * @param   expiry_info $child The child record to merge with.
 182       * @return  $this
 183       */
 184      public function merge_with_child(expiry_info $child) : expiry_info {
 185          if ($child->is_fully_expired()) {
 186              return $this;
 187          }
 188  
 189          // If the child is not fully expired, then none of the parents can be either.
 190          $this->fullyexpired = false;
 191  
 192          // Remove any role in this node which is not expired in the child.
 193          foreach ($this->expired as $key => $roleid) {
 194              if (!$child->is_role_expired($roleid)) {
 195                  unset($this->expired[$key]);
 196              }
 197          }
 198  
 199          array_merge($this->unexpired, $child->get_unexpired_roles());
 200  
 201          if (!$child->is_default_expired()) {
 202              $this->defaultexpiryreached = false;
 203          }
 204  
 205          return $this;
 206      }
 207  }