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