Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 4.3.x will end 7 October 2024 (12 months).
  • Bug fixes for security issues in 4.3.x will end 21 April 2025 (18 months).
  • PHP version: minimum PHP 8.0.0 Note: minimum PHP version has increased since Moodle 4.1. PHP 8.2.x is supported too.

Differences Between: [Versions 310 and 403] [Versions 39 and 403]

   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   * Abstract event factory.
  19   *
  20   * @package    core_calendar
  21   * @copyright  2017 Cameron Ball <cameron@cameron1729.xyz>
  22   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  23   */
  24  
  25  namespace core_calendar\local\event\factories;
  26  
  27  defined('MOODLE_INTERNAL') || die();
  28  
  29  use core_calendar\local\event\entities\event;
  30  use core_calendar\local\event\entities\repeat_event_collection;
  31  use core_calendar\local\event\exceptions\invalid_callback_exception;
  32  use core_calendar\local\event\proxies\cm_info_proxy;
  33  use core_calendar\local\event\proxies\coursecat_proxy;
  34  use core_calendar\local\event\proxies\std_proxy;
  35  use core_calendar\local\event\value_objects\event_description;
  36  use core_calendar\local\event\value_objects\event_times;
  37  use core_calendar\local\event\entities\event_interface;
  38  
  39  /**
  40   * Abstract factory for creating calendar events.
  41   *
  42   * @copyright 2017 Cameron Ball <cameron@cameron1729.xyz>
  43   * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  44   */
  45  abstract class event_abstract_factory implements event_factory_interface {
  46      /**
  47       * @var callable $actioncallbackapplier Function to apply component action callbacks.
  48       */
  49      protected $actioncallbackapplier;
  50  
  51      /**
  52       * @var callable $visibilitycallbackapplier Function to apply component visibility callbacks.
  53       */
  54      protected $visibilitycallbackapplier;
  55  
  56      /**
  57       * @var array Course cache for use with get_course_cached.
  58       */
  59      protected $coursecachereference;
  60  
  61      /**
  62       * @var array Module cache reference for use with get_module_cached.
  63       */
  64      protected $modulecachereference;
  65  
  66      /**
  67       * @var callable Bail out check for create_instance.
  68       */
  69      protected $bailoutcheck;
  70  
  71      /**
  72       * Applies component actions to the event.
  73       *
  74       * @param event_interface $event The event to be updated.
  75       * @return event_interface The potentially modified event.
  76       */
  77      protected abstract function apply_component_action(event_interface $event);
  78  
  79      /**
  80       * Exposes the event (or not).
  81       *
  82       * @param event_interface $event The event to potentially expose.
  83       * @return event_interface|null The exposed event or null.
  84       */
  85      protected abstract function expose_event(event_interface $event);
  86  
  87      /**
  88       * Constructor.
  89       *
  90       * @param callable $actioncallbackapplier     Function to apply component action callbacks.
  91       * @param callable $visibilitycallbackapplier Function to apply component visibility callbacks.
  92       * @param callable $bailoutcheck              Function to test if we can return null early.
  93       * @param array    $coursecachereference      Cache to use with get_course_cached.
  94       * @param array    $modulecachereference      Cache to use with get_module_cached.
  95       */
  96      public function __construct(
  97          callable $actioncallbackapplier,
  98          callable $visibilitycallbackapplier,
  99          callable $bailoutcheck,
 100          array &$coursecachereference,
 101          array &$modulecachereference
 102      ) {
 103          $this->actioncallbackapplier = $actioncallbackapplier;
 104          $this->visibilitycallbackapplier = $visibilitycallbackapplier;
 105          $this->bailoutcheck = $bailoutcheck;
 106          $this->coursecachereference = &$coursecachereference;
 107          $this->modulecachereference = &$modulecachereference;
 108      }
 109  
 110      public function create_instance(\stdClass $dbrow) {
 111          if ($dbrow->modulename && $dbrow->instance && $dbrow->courseid == 0) {
 112              // Some events (for example user overrides) may contain module instance but not course id. Find course id.
 113              $cm = calendar_get_module_cached($this->modulecachereference, $dbrow->modulename, $dbrow->instance);
 114              $dbrow->courseid = $cm->course;
 115          }
 116  
 117          $bailcheck = $this->bailoutcheck;
 118          $bail = $bailcheck($dbrow);
 119  
 120          if (!is_bool($bail)) {
 121              throw new invalid_callback_exception(
 122                  'Bail check must return true or false'
 123              );
 124          }
 125  
 126          if ($bail) {
 127              return null;
 128          }
 129  
 130          $category = null;
 131          $course = null;
 132          $group = null;
 133          $user = null;
 134          $module = null;
 135          $subscription = null;
 136          $component = null;
 137  
 138          if ($dbrow->modulename && $dbrow->instance) {
 139              $module = new cm_info_proxy($dbrow->modulename, $dbrow->instance, $dbrow->courseid);
 140          }
 141  
 142          if ($dbrow->categoryid) {
 143              $category = new coursecat_proxy($dbrow->categoryid);
 144          }
 145  
 146          $course = new std_proxy($dbrow->courseid, function($id) {
 147              return calendar_get_course_cached($this->coursecachereference, $id);
 148          });
 149  
 150          if ($dbrow->groupid) {
 151              $group = new std_proxy($dbrow->groupid, function($id) {
 152                  return calendar_get_group_cached($id);
 153              });
 154          }
 155  
 156          if ($dbrow->userid) {
 157              $user = new std_proxy($dbrow->userid, function($id) {
 158                  global $DB;
 159                  return $DB->get_record('user', ['id' => $id]);
 160              });
 161          }
 162  
 163          if ($dbrow->subscriptionid) {
 164              $subscription = new std_proxy($dbrow->subscriptionid, function($id) {
 165                  return calendar_get_subscription($id);
 166              });
 167          }
 168  
 169          if (!empty($dbrow->repeatid)) {
 170              $repeatcollection = new repeat_event_collection($dbrow, $this);
 171          } else {
 172              $repeatcollection = null;
 173          }
 174  
 175          if (!empty($dbrow->component)) {
 176              $component = $dbrow->component;
 177          }
 178  
 179          $event = new event(
 180              $dbrow->id,
 181              $dbrow->name,
 182              new event_description($dbrow->description, $dbrow->format),
 183              $category,
 184              $course,
 185              $group,
 186              $user,
 187              $repeatcollection,
 188              $module,
 189              $dbrow->eventtype,
 190              new event_times(
 191                  (new \DateTimeImmutable())->setTimestamp($dbrow->timestart),
 192                  (new \DateTimeImmutable())->setTimestamp($dbrow->timestart + $dbrow->timeduration),
 193                  (new \DateTimeImmutable())->setTimestamp($dbrow->timesort ? $dbrow->timesort : $dbrow->timestart),
 194                  (new \DateTimeImmutable())->setTimestamp($dbrow->timemodified),
 195                  (new \DateTimeImmutable())->setTimestamp($dbrow->timesort ? usergetmidnight($dbrow->timesort) : 0)
 196              ),
 197              !empty($dbrow->visible),
 198              $subscription,
 199              $dbrow->location,
 200              $component
 201          );
 202  
 203          $isactionevent = !empty($dbrow->type) && $dbrow->type == CALENDAR_EVENT_TYPE_ACTION;
 204  
 205          return $isactionevent ? $this->expose_event($this->apply_component_action($event)) : $event;
 206      }
 207  }