]> git.agnieray.net Git - galette.git/blob - galette/lib/Galette/Controllers/CrudController.php
83089ac9e20648a864e15f960d291d71c147b363
[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-2023 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-2023 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\Psr7\Request;
41 use Slim\Psr7\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-2023 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 'modals/confirm_removal.html.twig',
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->getHeaderLine('X-Requested-With') === 'XMLHttpRequest') ? '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 entries_sel keys
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 if ($ids === null && method_exists($this, 'getFilterName')) {
200 $filter_name = $this->getFilterName($args);
201 $filters = $this->session->$filter_name;
202 $ids = $filters->selected;
203 }
204
205 //type
206 if (is_array($ids)) {
207 $ids = array_map('intval', $ids);
208 } elseif (is_string($ids)) {
209 $ids = (int)$ids;
210 }
211
212 //add to $args if needed
213 if (is_array($ids)) {
214 $args['ids'] = $ids;
215 } elseif (!isset($args['id']) && $ids) {
216 $args['id'] = $ids;
217 }
218
219 return $ids;
220 }
221
222 /**
223 * Get redirection URI
224 *
225 * @param array $args Route arguments
226 *
227 * @return string
228 */
229 abstract public function redirectUri(array $args);
230
231 /**
232 * Get cancel URI
233 *
234 * @param array $args Route arguments
235 *
236 * @return string
237 */
238 public function cancelUri(array $args)
239 {
240 return $this->redirectUri($args);
241 }
242
243 /**
244 * Get form URI
245 *
246 * @param array $args Route arguments
247 *
248 * @return string
249 */
250 abstract public function formUri(array $args);
251
252 /**
253 * Get confirmation removal page title
254 *
255 * @param array $args Route arguments
256 *
257 * @return string
258 */
259 abstract public function confirmRemoveTitle(array $args);
260
261 /**
262 * Removal
263 *
264 * @param Request $request PSR Request
265 * @param Response $response PSR Response
266 *
267 * @return Response
268 */
269 public function delete(Request $request, Response $response): Response
270 {
271 $post = $request->getParsedBody();
272 $args = $this->getArgs($request);
273 $ajax = isset($post['ajax']) && $post['ajax'] === 'true';
274 $success = false;
275
276 $uri = $post['redirect_uri'] ?? $this->redirectUri($args);
277
278 if (!isset($post['confirm'])) {
279 $this->flash->addMessage(
280 'error_detected',
281 _T("Removal has not been confirmed!")
282 );
283 } else {
284 try {
285 $this->getIdsToRemove($args, $post);
286 $res = $this->doDelete($args, $post);
287 if ($res === true) {
288 $this->flash->addMessage(
289 'success_detected',
290 _T('Successfully deleted!')
291 );
292 $success = true;
293 }
294 } catch (Throwable $e) {
295 Analog::log(
296 'An error occurred on delete | ' . $e->getMessage(),
297 Analog::ERROR
298 );
299
300 $this->flash->addMessage(
301 'error_detected',
302 _T('An error occurred trying to delete :(')
303 );
304
305 $success = false;
306 }
307 }
308
309 if (!$ajax) {
310 return $response
311 ->withStatus(301)
312 ->withHeader('Location', $uri);
313 } else {
314 return $this->withJson($response, ['success' => $success]);
315 }
316 }
317
318 /**
319 * Remove object
320 *
321 * @param array $args Route arguments
322 * @param array $post POST values
323 *
324 * @return boolean
325 */
326 abstract protected function doDelete(array $args, array $post);
327 // /CRUD - Delete
328 }