]> git.agnieray.net Git - galette.git/blob - galette/lib/Galette/Controllers/CrudController.php
Fix IDs checks
[galette.git] / galette / lib / Galette / Controllers / CrudController.php
1 <?php
2
3 /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
4
5 /**
6 * Galette CRUD controller
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 Entity
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 Available since 0.9.4dev - 2019-12-08
35 */
36
37 namespace Galette\Controllers;
38
39 use Throwable;
40 use Slim\Http\Request;
41 use Slim\Http\Response;
42 use Analog\Analog;
43
44 /**
45 * Galette CRUD controller
46 *
47 * @category Controllers
48 * @name CrudController
49 * @package Galette
50 * @author Johan Cwiklinski <johan@x-tnd.be>
51 * @copyright 2019 The Galette Team
52 * @license http://www.gnu.org/licenses/gpl-3.0.html GPL License 3.0 or (at your option) any later version
53 * @link http://galette.tuxfamily.org
54 * @since Available since 0.9.4dev - 2019-12-08
55 */
56
57 abstract class CrudController extends AbstractController
58 {
59 // CRUD - Create
60
61 /**
62 * Add page
63 *
64 * @param Request $request PSR Request
65 * @param Response $response PSR Response
66 *
67 * @return Response
68 */
69 abstract public function add(Request $request, Response $response): Response;
70
71 /**
72 * Add action
73 *
74 * @param Request $request PSR Request
75 * @param Response $response PSR Response
76 *
77 * @return Response
78 */
79 abstract public function doAdd(Request $request, Response $response): Response;
80
81 // /CRUD - Create
82 // CRUD - Read
83
84 /**
85 * List page
86 *
87 * @param Request $request PSR Request
88 * @param Response $response PSR Response
89 * @param string $option One of 'page' or 'order'
90 * @param string|integer $value Value of the option
91 *
92 * @return Response
93 */
94 abstract public function list(Request $request, Response $response, $option = null, $value = null): Response;
95
96 /**
97 * List filtering
98 *
99 * @param Request $request PSR Request
100 * @param Response $response PSR Response
101 *
102 * @return Response
103 */
104 abstract public function filter(Request $request, Response $response): Response;
105
106 // /CRUD - Read
107 // CRUD - Update
108
109 /**
110 * Edit page
111 *
112 * @param Request $request PSR Request
113 * @param Response $response PSR Response
114 * @param integer $id Record id
115 *
116 * @return Response
117 */
118 abstract public function edit(Request $request, Response $response, int $id): Response;
119
120 /**
121 * Edit action
122 *
123 * @param Request $request PSR Request
124 * @param Response $response PSR Response
125 * @param integer $id Record id
126 *
127 * @return Response
128 */
129 abstract public function doEdit(Request $request, Response $response, int $id): Response;
130
131 // /CRUD - Update
132 // CRUD - Delete
133
134 /**
135 * Removal confirmation
136 *
137 * @param Request $request PSR Request
138 * @param Response $response PSR Response
139 *
140 * @return Response
141 */
142 public function confirmDelete(Request $request, Response $response): Response
143 {
144 // display page
145 $this->view->render(
146 $response,
147 'confirm_removal.tpl',
148 $this->getconfirmDeleteParams($request)
149 );
150 return $response;
151 }
152
153 /**
154 * Removal confirmation parameters, can be overriden
155 *
156 * @param Request $request PSR Request
157 *
158 * @return array
159 */
160 protected function getconfirmDeleteParams(Request $request): array
161 {
162 $args = $this->getArgs($request);
163 $post = $request->getParsedBody();
164 $data = [
165 'id' => $this->getIdsToRemove($args, $post),
166 'redirect_uri' => $this->redirectUri($args)
167 ];
168
169 return [
170 'mode' => $request->isXhr() ? 'ajax' : '',
171 'page_title' => $this->confirmRemoveTitle($args),
172 'form_url' => $this->formUri($args),
173 'cancel_uri' => $this->cancelUri($args),
174 'data' => $data
175 ];
176 }
177
178 /**
179 * Get ID to remove
180 *
181 * In simple cases, we get the ID in the route arguments; but for
182 * batchs, it should be found elsewhere.
183 * In post values, we look for id key, as well as all {sthing}_sel keys (like members_sel or contrib_sel)
184 *
185 * @param array $args Request arguments
186 * @param array $post POST values
187 *
188 * @return null|integer|integer[]
189 */
190 protected function getIdsToRemove(&$args, $post)
191 {
192 $ids = null;
193 if (isset($post['id'])) {
194 $ids = $post['id'];
195 } elseif (isset($args['id'])) {
196 $ids = $args['id'];
197 }
198
199 //look for {sthing}_sel as multiple ids selection (members_sel, contrib_sel, and so on)
200 if (is_array($post) && count($post)) {
201 $selecteds = preg_grep('/.+_sel$/', array_keys($post));
202 if (count($selecteds) == 1 && !isset($args['id'])) {
203 $ids = $post[array_shift($selecteds)];
204 } elseif (count($selecteds) > 1) {
205 //maybe an error to have multiple {type}_sel in same post request.
206 Analog::log(
207 'Several {sthing}_sel variables in same post request should be avoid.',
208 ANalog::WARNING
209 );
210 }
211 }
212
213 //type
214 if (is_array($ids)) {
215 $ids = array_map('intval', $ids);
216 } elseif (is_string($ids)) {
217 $ids = (int)$ids;
218 }
219
220 //add to $args if needed
221 if (is_array($ids)) {
222 $args['ids'] = $ids;
223 } elseif (!isset($args['id']) && $ids) {
224 $args['id'] = $ids;
225 }
226
227 return $ids;
228 }
229
230 /**
231 * Get redirection URI
232 *
233 * @param array $args Route arguments
234 *
235 * @return string
236 */
237 abstract public function redirectUri(array $args);
238
239 /**
240 * Get cancel URI
241 *
242 * @param array $args Route arguments
243 *
244 * @return string
245 */
246 public function cancelUri(array $args)
247 {
248 return $this->redirectUri($args);
249 }
250
251 /**
252 * Get form URI
253 *
254 * @param array $args Route arguments
255 *
256 * @return string
257 */
258 abstract public function formUri(array $args);
259
260 /**
261 * Get confirmation removal page title
262 *
263 * @param array $args Route arguments
264 *
265 * @return string
266 */
267 abstract public function confirmRemoveTitle(array $args);
268
269 /**
270 * Removal
271 *
272 * @param Request $request PSR Request
273 * @param Response $response PSR Response
274 *
275 * @return Response
276 */
277 public function delete(Request $request, Response $response): Response
278 {
279 $post = $request->getParsedBody();
280 $args = $this->getArgs($request);
281 $ajax = isset($post['ajax']) && $post['ajax'] === 'true';
282 $success = false;
283
284 $uri = $post['redirect_uri'] ?? $this->redirectUri($args);
285
286 if (!isset($post['confirm'])) {
287 $this->flash->addMessage(
288 'error_detected',
289 _T("Removal has not been confirmed!")
290 );
291 } else {
292 try {
293 $ids = $this->getIdsToRemove($args, $post);
294
295 $res = $this->doDelete($args, $post);
296 if ($res === true) {
297 $this->flash->addMessage(
298 'success_detected',
299 _T('Successfully deleted!')
300 );
301 $success = true;
302 }
303 } catch (Throwable $e) {
304 Analog::log(
305 'An error occurred on delete | ' . $e->getMessage(),
306 Analog::ERROR
307 );
308
309 $this->flash->addMessage(
310 'error_detected',
311 _T('An error occurred trying to delete :(')
312 );
313
314 $success = false;
315 }
316 }
317
318 if (!$ajax) {
319 return $response
320 ->withStatus(301)
321 ->withHeader('Location', $uri);
322 } else {
323 return $response->withJson(
324 [
325 'success' => $success
326 ]
327 );
328 }
329 }
330
331 /**
332 * Remove object
333 *
334 * @param array $args Route arguments
335 * @param array $post POST values
336 *
337 * @return boolean
338 */
339 abstract protected function doDelete(array $args, array $post);
340 // /CRUD - Delete
341 }