]> git.agnieray.net Git - galette.git/blob - galette/lib/Galette/Repository/SavedSearches.php
a607bcae5cdc357eb4fcec124adce0a8b7865335
[galette.git] / galette / lib / Galette / Repository / SavedSearches.php
1 <?php
2
3 /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
4
5 /**
6 * Saved searches
7 *
8 * PHP version 5
9 *
10 * Copyright © 2019 The Galette Team
11 *
12 * This file is part of Galette (http://galette.tuxfamily.org).
13 *
14 * Galette is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation, either version 3 of the License, or
17 * (at your option) any later version.
18 *
19 * Galette is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with Galette. If not, see <http://www.gnu.org/licenses/>.
26 *
27 * @category Repository
28 * @package Galette
29 *
30 * @author Johan Cwiklinski <johan@x-tnd.be>
31 * @copyright 2019 The Galette Team
32 * @license http://www.gnu.org/licenses/gpl-3.0.html GPL License 3.0 or (at your option) any later version
33 * @link http://galette.tuxfamily.org
34 * @since 2019-09-21
35 */
36
37 namespace Galette\Repository;
38
39 use Throwable;
40 use Analog\Analog;
41 use Laminas\Db\Sql\Expression;
42 use Galette\Core\Db;
43 use Galette\Core\Login;
44 use Galette\Core\History;
45 use Galette\Entity\SavedSearch;
46 use Galette\Filters\SavedSearchesList;
47 use Galette\Entity\Adherent;
48
49 /**
50 * Saved searches
51 *
52 * @category Repository
53 * @name SavedSearches
54 * @package Galette
55 * @author Johan Cwiklinski <johan@x-tnd.be>
56 * @copyright 2019 The Galette Team
57 * @license http://www.gnu.org/licenses/gpl-3.0.html GPL License 3.0 or (at your option) any later version
58 * @link http://galette.tuxfamily.org
59 * @since 2019-09-21
60 */
61 class SavedSearches
62 {
63 public const TABLE = SavedSearch::TABLE;
64 public const PK = SavedSearch::PK;
65
66 private $count = null;
67
68 /**
69 * Default constructor
70 *
71 * @param Db $zdb Database
72 * @param Login $login Login
73 * @param SavedSearchesList $filters Filtering
74 */
75 public function __construct(Db $zdb, Login $login, $filters = null)
76 {
77 $this->zdb = $zdb;
78 $this->login = $login;
79
80 if ($filters === null) {
81 $this->filters = new SavedSearchesList();
82 } else {
83 $this->filters = $filters;
84 }
85 }
86
87 /**
88 * Get saved searches list
89 *
90 * @param bool $as_search return the results as an array of
91 * SavedSearch object.
92 * @param array $fields field(s) name(s) to get. Should be a string or
93 * an array. If null, all fields will be
94 * returned
95 * @param boolean $count true if we want to count
96 *
97 * @return SavedSearch[]|ResultSet
98 */
99 public function getList($as_search = false, $fields = null, $count = true)
100 {
101 try {
102 $select = $this->buildSelect($fields, $count);
103 $this->filters->setLimits($select);
104
105 $searches = array();
106 $results = $this->zdb->execute($select);
107 if ($as_search) {
108 foreach ($results as $row) {
109 $searches[] = new SavedSearch($this->zdb, $this->login, $row);
110 }
111 } else {
112 $searches = $results;
113 }
114 return $searches;
115 } catch (Throwable $e) {
116 Analog::log(
117 'Cannot list saved searches | ' . $e->getMessage(),
118 Analog::WARNING
119 );
120 throw $e;
121 }
122 }
123
124 /**
125 * Builds the SELECT statement
126 *
127 * @param array $fields fields list to retrieve
128 * @param bool $count true if we want to count members
129 * (not applicable from static calls), defaults to false
130 *
131 * @return string SELECT statement
132 */
133 private function buildSelect($fields, $count = false)
134 {
135 try {
136 $fieldsList = ($fields != null)
137 ? ((!is_array($fields) || count($fields) < 1) ? (array)'*'
138 : implode(', ', $fields)) : (array)'*';
139
140 $select = $this->zdb->select(self::TABLE, 's');
141 $select->columns($fieldsList);
142 if (0 === $this->login->id) {
143 $select->where->isNull(Adherent::PK);
144 } else {
145 $select->where([Adherent::PK => $this->login->id]);
146 }
147
148 $select->order(self::buildOrderClause());
149
150 if ($count) {
151 $this->proceedCount($select);
152 }
153
154 return $select;
155 } catch (Throwable $e) {
156 Analog::log(
157 'Cannot build SELECT clause for saved searches | ' . $e->getMessage(),
158 Analog::WARNING
159 );
160 return false;
161 }
162 }
163
164 /**
165 * Count searches from the query
166 *
167 * @param Select $select Original select
168 *
169 * @return void
170 */
171 private function proceedCount($select)
172 {
173 try {
174 $countSelect = clone $select;
175 $countSelect->reset($countSelect::COLUMNS);
176 $countSelect->reset($countSelect::JOINS);
177 $countSelect->reset($countSelect::ORDER);
178 $countSelect->columns(
179 array(
180 self::PK => new Expression('COUNT(' . self::PK . ')')
181 )
182 );
183
184 $results = $this->zdb->execute($countSelect);
185 $result = $results->current();
186
187 $k = self::PK;
188 $this->count = $result->$k;
189
190 if ($this->count > 0) {
191 $this->filters->setCounter($this->count);
192 }
193 } catch (Throwable $e) {
194 Analog::log(
195 'Cannot count saved searches | ' . $e->getMessage(),
196 Analog::WARNING
197 );
198 return false;
199 }
200 }
201
202 /**
203 * Builds the order clause
204 *
205 * @return string SQL ORDER clause
206 */
207 private function buildOrderClause()
208 {
209 $order = array();
210 $order[] = $this->filters->orderby . ' ' . $this->filters->ordered;
211
212 return $order;
213 }
214
215 /**
216 * Get count for current query
217 *
218 * @return int
219 */
220 public function getCount()
221 {
222 return $this->count;
223 }
224
225 /**
226 * Remove specified searches
227 *
228 * @param integer|array $ids Searches identifiers to delete
229 * @param History $hist History
230 * @param boolean $transaction True to begin a database transaction
231 *
232 * @return boolean
233 */
234 public function remove($ids, History $hist, $transaction = true)
235 {
236 $list = array();
237 if (is_numeric($ids)) {
238 //we've got only one identifier
239 $list[] = $ids;
240 } else {
241 $list = $ids;
242 }
243
244 if (is_array($list)) {
245 $res = true;
246 try {
247 if ($transaction) {
248 $this->zdb->connection->beginTransaction();
249 }
250 $select = $this->zdb->select(self::TABLE);
251 $select->where->in(self::PK, $list);
252 $searches = $this->zdb->execute($select);
253 foreach ($searches as $search) {
254 $s = new SavedSearch($this->zdb, $this->login, $search);
255 $res = $s->remove(false);
256 if ($res === false) {
257 throw new \Exception();
258 }
259 }
260 if ($transaction) {
261 $this->zdb->connection->commit();
262 }
263 $hist->add(
264 str_replace(
265 '%list',
266 print_r($list, true),
267 _T("Searches deleted (%list)")
268 )
269 );
270 return true;
271 } catch (Throwable $e) {
272 if ($transaction) {
273 $this->zdb->connection->rollBack();
274 }
275 Analog::log(
276 'An error occurred trying to remove searches | ' .
277 $e->getMessage(),
278 Analog::ERROR
279 );
280 return false;
281 }
282 } else {
283 //not numeric and not an array: incorrect.
284 Analog::log(
285 'Asking to remove searches, but without providing an array or a single numeric value.',
286 Analog::WARNING
287 );
288 return false;
289 }
290 }
291 }