MDL-57750 calendar: add event vault

Part of MDL-55611 epic.
This commit is contained in:
Ryan Wyllie
2017-04-03 11:36:07 +08:00
committed by Damyon Wiese
parent 5b3c691fd5
commit 84d865d69b
8 changed files with 450 additions and 0 deletions
@@ -33,6 +33,7 @@ defined('MOODLE_INTERNAL') || die();
use core_calendar\action_factory;
use core_calendar\local\event\factories\action_event_factory;
use core_calendar\local\event\factories\event_factory;
use core_calendar\local\event\factories\event_vault_factory;
use core_calendar\local\event\mappers\event_mapper;
use core_calendar\local\interfaces\event_interface;
@@ -63,6 +64,11 @@ class core_container {
*/
protected static $actionfactory;
/**
* @var event_vault $eventvault Event vault.
*/
private static $eventvault;
/**
* Initialises the dependency graph if it hasn't yet been.
*/
@@ -93,6 +99,11 @@ class core_container {
}
);
}
if (empty(self::$eventvault)) {
$vaultfactory = new event_vault_factory();
self::$eventvault = $vaultfactory->create_instance(self::$eventfactory);
}
}
/**
@@ -114,4 +125,14 @@ class core_container {
self::init();
return self::$eventmapper;
}
/**
* Return an event vault.
*
* @return event_vault
*/
public static function get_event_vault() {
self::init();
return self::$eventvault;
}
}
@@ -0,0 +1,174 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Event vault class
*
* @package core_calendar
* @copyright 2017 Ryan Wyllie <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core_calendar\local\event\data_access;
use core_calendar\local\event\exceptions\limit_invalid_parameter_exception;
use core_calendar\local\event\exceptions\timesort_invalid_parameter_exception;
use core_calendar\local\interfaces\action_event_interface;
use core_calendar\local\interfaces\event_interface;
use core_calendar\local\interfaces\event_factory_interface;
use core_calendar\local\interfaces\event_vault_interface;
/**
* This class will handle interacting with the database layer to retrieve
* the records. This is required to house the complex logic required for
* pagination because it's not a one-to-one mapping between database records
* and users.
*
* This is a repository. It's called a vault to reduce confusion because
* Moodle has already taken the name repository. Vault is cooler anyway.
*
* @copyright 2017 Ryan Wyllie <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class event_vault implements event_vault_interface {
private $factory;
/**
* Create an event vault.
*
* @param event_factory_interface $factory An event factory
*/
public function __construct(event_factory_interface $factory) {
$this->factory = $factory;
}
/**
* Retrieve an event for the given id.
*
* @param in $id The event id
* @return event_interface
*/
public function get_event_by_id(int $id) {
global $DB;
if ($record = $DB->get_record('event', ['id' => $id])) {
return $this->transform_from_database_record($record);
} else {
return false;
}
}
/**
* Retrieve an array of events for the given user and time constraints.
*
* @param \stdClass $user The user for whom the events belong
* @param int|null $timesortfrom Events with timesort from this value (inclusive)
* @param int|null $timesortto Events with timesort until this value (inclusive)
* @param event_interface|null $afterevent Only return events after this one
* @param int $limitnum Return at most this number of events
* @return action_event_interface
*/
public function get_action_events_by_timesort(
\stdClass $user,
int $timesortfrom = null,
int $timesortto = null,
event_interface $afterevent = null,
int $limitnum = 20
) {
global $DB;
if (is_null($timesortfrom) && is_null($timesortto)) {
throw new timesort_invalid_parameter_exception("Must provide a timesort to and/or from value");
}
if ($limitnum < 1 || $limitnum > 50) {
throw new limit_invalid_parameter_exception("Limit must be between 1 and 50 (inclusive)");
}
$params = ['type' => CALENDAR_EVENT_TYPE_ACTION];
$where = ['type = :type'];
if ($timesortfrom) {
$where[] = 'timesort >= :timesortfrom';
$params['timesortfrom'] = $timesortfrom;
}
if ($timesortto) {
$where[] = 'timesort <= :timesortto';
$params['timesortto'] = $timesortto;
}
if (!is_null($afterevent)) {
$where[] = 'id > :id';
$params['id'] = $afterevent->get_id();
}
$sql = sprintf("SELECT * FROM {event} WHERE %s ORDER BY timesort ASC, id ASC",
implode(' AND ', $where));
$offset = 0;
$events = [];
// We need to continue to pull records from the database until we reach
// the requested amount of events because not all records in the database
// will be visible for the current user.
while ($records = array_values($DB->get_records_sql($sql, $params, $offset, $limitnum))) {
foreach ($records as $record) {
if ($event = $this->transform_from_database_record($record)) {
if ($event instanceof action_event_interface) {
$events[] = $event;
}
if (count($events) == $limitnum) {
// We've got all of the events so break both loops.
break 2;
}
}
}
$offset += $limitnum;
}
return $events;
}
/**
* Create an event from a database record.
*
* @param \stdClass $record The database record
* @return event_interface|false
*/
private function transform_from_database_record(\stdClass $record) {
return $this->factory->create_instance($record);
}
/**
* Create an array of events from an array of database records.
*
* @param array $records The database records
* @return array
*/
private function transform_from_database_records(array $records) {
$events = [];
foreach ($records as $record) {
if ($event = $this->transform_from_database_record($record)) {
$events[] = $event;
}
}
return $events;
}
}
@@ -0,0 +1,36 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* General invalid parameter exception.
*
* @package core_calendar
* @copyright 2017 Ryan Wyllie <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core_calendar\local\event\exceptions;
defined('MOODLE_INTERNAL') || die();
/**
* General invalid parameter exception.
*
* @copyright 2017 Ryan Wyllie <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class invalid_parameter_exception extends \moodle_exception {
}
@@ -0,0 +1,36 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Invalid limit parameter exception.
*
* @package core_calendar
* @copyright 2017 Ryan Wyllie <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core_calendar\local\event\exceptions;
defined('MOODLE_INTERNAL') || die();
/**
* Invalid limit parameter exception.
*
* @copyright 2017 Ryan Wyllie <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class limit_invalid_parameter_exception extends invalid_parameter_exception {
}
@@ -0,0 +1,36 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Invalid timesort parameter exception.
*
* @package core_calendar
* @copyright 2017 Ryan Wyllie <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core_calendar\local\event\exceptions;
defined('MOODLE_INTERNAL') || die();
/**
* Invalid timesort parameter exception.
*
* @copyright 2017 Ryan Wyllie <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class timesort_invalid_parameter_exception extends invalid_parameter_exception {
}
@@ -0,0 +1,47 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Event vault factory class
*
* @package core_calendar
* @copyright 2017 Ryan Wyllie <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core_calendar\local\event\factories;
use core_calendar\local\event\data_access\event_vault;
use core_calendar\local\interfaces\event_factory_interface;
use core_calendar\local\interfaces\event_vault_factory_interface;
/**
* Event vault factory class
*
* @copyright 2017 Ryan Wyllie <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class event_vault_factory implements event_vault_factory_interface {
/**
* Creates an instance of an event vault
*
* @param event_factory_interface $eventfactory The event factory
* @return event_vault_interface
*/
public function create_instance(event_factory_interface $eventfactory) {
return new event_vault($eventfactory);
}
}
@@ -0,0 +1,41 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Event vault factory interface
*
* @package core_calendar
* @copyright 2017 Ryan Wyllie <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core_calendar\local\interfaces;
/**
* Interface for an event vault factory class
*
* @copyright 2017 Ryan Wyllie <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
interface event_vault_factory_interface {
/**
* Creates an instance of an event vault
*
* @param event_factory_interface $eventfactory The event factory
* @return event_vault_interface
*/
public function create_instance(event_factory_interface $eventfactory);
}
@@ -0,0 +1,59 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Event vault interface
*
* @package core_calendar
* @copyright 2017 Ryan Wyllie <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core_calendar\local\interfaces;
/**
* Interface for an event vault class
*
* @copyright 2017 Ryan Wyllie <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
interface event_vault_interface {
/**
* Retrieve an event for the given id.
*
* @param in $id The event id
* @return event_interface|false
*/
public function get_event_by_id(int $id);
/**
* Retrieve an array of events for the given user and time constraints.
*
* @param \stdClass $user The user for whom the events belong
* @param int $timesortfrom Events with timesort from this value (inclusive)
* @param int $timesortto Events with timesort until this value (inclusive)
* @param event_interface $afterevent Only return events after this one
* @param int $limitnum Return at most this number of events
* @return event_interface
*/
public function get_action_events_by_timesort(
\stdClass $user,
int $timesortfrom,
int $timesortto,
event_interface $afterevent,
int $limitnum
);
}