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