MDL-65032 mod_forum: Updates based on Jun's feedback
[moodle.git] / mod / forum / classes / local / vaults / db_table_vault.php
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/>.
17 /**
18  * Abstract class for loading records from the DB.
19  *
20  * @package    mod_forum
21  * @copyright  2019 Ryan Wyllie <ryan@moodle.com>
22  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23  */
25 namespace mod_forum\local\vaults;
27 defined('MOODLE_INTERNAL') || die();
29 use mod_forum\local\factories\entity as entity_factory;
30 use moodle_database;
32 /**
33  * Abstract class for loading records from the DB.
34  *
35  * @copyright  2019 Ryan Wyllie <ryan@moodle.com>
36  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
37  */
38 abstract class db_table_vault {
39     /** @var moodle_database $db A moodle database */
40     private $db;
41     /** @var entity_factory $entityfactory Entity factory */
42     private $entityfactory;
43     /** @var legacy_factor $legacyfactory Entity->legacy factory */
44     private $legacyfactory;
46     /**
47      * Constructor.
48      *
49      * @param moodle_database $db A moodle database
50      * @param entity_factory $entityfactory Entity factory
51      * @param object $legacyfactory Legacy factory
52      */
53     public function __construct(
54         moodle_database $db,
55         entity_factory $entityfactory,
56         object $legacyfactory
57     ) {
58         $this->db = $db;
59         $this->entityfactory = $entityfactory;
60         $this->legacyfactory = $legacyfactory;
61     }
63     /**
64      * Get the table alias.
65      *
66      * @return string
67      */
68     abstract protected function get_table_alias() : string;
70     /**
71      * Build the SQL to be used in get_records_sql.
72      *
73      * @param string|null $wheresql Where conditions for the SQL
74      * @param string|null $sortsql Order by conditions for the SQL
75      * @return string
76      */
77     abstract protected function generate_get_records_sql(string $wheresql = null, string $sortsql = null) : string;
79     /**
80      * Convert the DB records into entities. The list of records will have been
81      * passed through any preprocessors that may be defined before being given to
82      * this function.
83      *
84      * Each result will from the list will be an associative array where the key
85      * is set to the identifier given to the preprocessor and the result is the value
86      * generated by the preprocessor.
87      *
88      * All results will have a 'record' key who's value is the original DB record.
89      *
90      * @param array $results The DB records
91      */
92     abstract protected function from_db_records(array $results);
94     /**
95      * Get the list of preprocessors to run on the DB record results. The preprocessors
96      * should be defined using an associative array. The key used to identify the
97      * preprocessor in this list will be used to identify the value of that preprocessor
98      * in the list of results when passed to the from_db_records function.
99      *
100      * @return array
101      */
102     protected function get_preprocessors() : array {
103         return [];
104     }
106     /**
107      * Get the moodle database.
108      *
109      * @return moodle_database
110      */
111     protected function get_db() : moodle_database {
112         return $this->db;
113     }
115     /**
116      * Get the entity factory.
117      *
118      * @return entity_factory
119      */
120     protected function get_entity_factory() : entity_factory {
121         return $this->entityfactory;
122     }
124     /**
125      * Get the legacy factory
126      *
127      * @return object
128      */
129     protected function get_legacy_factory() {
130         return $this->legacyfactory;
131     }
133     /**
134      * Execute the defined preprocessors on the DB record results and then convert
135      * them into entities.
136      *
137      * @param stdClass[] $records List of DB results
138      * @return array
139      */
140     protected function transform_db_records_to_entities(array $records) {
141         $preprocessors = $this->get_preprocessors();
142         $result = array_map(function($record) {
143             return ['record' => $record];
144         }, $records);
146         $result = array_reduce(array_keys($preprocessors), function($carry, $preprocessor) use ($records, $preprocessors) {
147             $step = $preprocessors[$preprocessor];
148             $dependencies = $step->execute($records);
150             foreach ($dependencies as $index => $dependency) {
151                 // Add the new dependency to the list.
152                 $carry[$index] = array_merge($carry[$index], [$preprocessor => $dependency]);
153             }
155             return $carry;
156         }, $result);
158         return $this->from_db_records($result);
159     }
161     /**
162      * Get the entity for the given id.
163      *
164      * @param int $id Identifier for the entity
165      * @return object|null
166      */
167     public function get_from_id(int $id) {
168         $records = $this->get_from_ids([$id]);
169         return count($records) ? array_shift($records) : null;
170     }
172     /**
173      * Get the list of entities for the given ids.
174      *
175      * @param int[] $ids Identifiers
176      * @return array
177      */
178     public function get_from_ids(array $ids) {
179         $alias = $this->get_table_alias();
180         list($insql, $params) = $this->get_db()->get_in_or_equal($ids);
181         $wheresql = $alias . '.id ' . $insql;
182         $sql = $this->generate_get_records_sql($wheresql);
183         $records = $this->get_db()->get_records_sql($sql, $params);
185         return $this->transform_db_records_to_entities($records);
186     }