PluginProbe ʕ •ᴥ•ʔ
Booking for Appointments and Events Calendar – Amelia / 2.0.2
Booking for Appointments and Events Calendar – Amelia v2.0.2
2.4.3 2.4.2 2.4.1 2.4 trunk 1.2.1 1.2.10 1.2.11 1.2.12 1.2.13 1.2.14 1.2.15 1.2.16 1.2.17 1.2.18 1.2.19 1.2.2 1.2.20 1.2.21 1.2.22 1.2.23 1.2.24 1.2.25 1.2.26 1.2.27 1.2.28 1.2.29 1.2.3 1.2.30 1.2.31 1.2.32 1.2.33 1.2.34 1.2.35 1.2.36 1.2.37 1.2.38 1.2.4 1.2.5 1.2.6 1.2.7 1.2.8 1.2.9 2.0 2.0.1 2.0.2 2.1 2.1.1 2.1.2 2.1.3 2.2 2.2.1 2.3
ameliabooking / src / Application / Controller / Controller.php
ameliabooking / src / Application / Controller Last commit date
Bookable 6 months ago Booking 6 months ago Calendar 6 months ago Entities 4 years ago Import 4 years ago Notification 6 months ago Payment 6 months ago QrCode 7 months ago Settings 6 months ago Square 6 months ago Stash 4 years ago Stats 6 months ago Test 2 years ago User 6 months ago WhatsNew 6 months ago Controller.php 5 months ago
Controller.php
324 lines
1 <?php
2
3 namespace AmeliaBooking\Application\Controller;
4
5 use AmeliaBooking\Application\Commands\Command;
6 use AmeliaBooking\Application\Services\User\UserApplicationService;
7 use AmeliaBooking\Domain\Services\DateTime\DateTimeService;
8 use AmeliaBooking\Domain\Services\Permissions\PermissionsService;
9 use AmeliaBooking\Domain\Services\Settings\SettingsService;
10 use AmeliaBooking\Infrastructure\Common\Container;
11 use AmeliaBooking\Domain\Events\DomainEventBus;
12 use AmeliaBooking\Application\Commands\CommandResult;
13 use AmeliaBooking\Infrastructure\WP\SettingsService\SettingsStorage;
14 use AmeliaBooking\Domain\Common\Exceptions\CustomException;
15 use League\Tactician\CommandBus;
16 use Slim\Http\Request;
17 use Slim\Http\Response;
18
19 /**
20 * Class Controller
21 *
22 * @package AmeliaBooking\Application\Controller
23 */
24 abstract class Controller
25 {
26 public const STATUS_OK = 200;
27 public const STATUS_REDIRECT = 302;
28 public const STATUS_FORBIDDEN = 403;
29 public const STATUS_NOT_FOUNT = 404;
30 public const STATUS_CONFLICT = 409;
31 public const STATUS_INTERNAL_SERVER_ERROR = 500;
32
33 /**
34 * @var CommandBus
35 */
36 protected $commandBus;
37 /**
38 * @var DomainEventBus
39 */
40 protected $eventBus;
41
42 /**
43 * @var PermissionsService
44 */
45 protected $permissionsService;
46 protected $allowedFields = [
47 'ameliaNonce',
48 'wpAmeliaNonce',
49 ];
50
51 protected $sendJustData = false;
52 /**
53 * @var UserApplicationService
54 */
55 private $userApplicationService;
56
57 /**
58 * Base Controller constructor.
59 *
60 * @param Container $container
61 * @param bool $fromApi
62 */
63 public function __construct(Container $container, $fromApi = false)
64 {
65 $this->commandBus = $container->getCommandBus();
66 $this->eventBus = $container->getEventBus();
67 $this->permissionsService = $fromApi ? $container->getApiPermissionsService() : $container->getPermissionsService();
68 $this->userApplicationService = $fromApi ? $container->getApiUserApplicationService() : $container->getUserApplicationService();
69 }
70
71 /**
72 * @param Request $request
73 * @param $args
74 *
75 * @return mixed
76 */
77 abstract protected function instantiateCommand(Request $request, $args);
78
79 /**
80 * Emit a success domain event, do nothing by default
81 *
82 * @param DomainEventBus $eventBus
83 *
84 * @param CommandResult $result
85 *
86 * @return void
87 */
88 protected function emitSuccessEvent(DomainEventBus $eventBus, CommandResult $result)
89 {
90 }
91
92 /**
93 * Emit a failure domain event, do nothing by default
94 *
95 * @param DomainEventBus $eventBus
96 *
97 * @param CommandResult $data
98 *
99 * @return null
100 */
101 protected function emitFailureEvent(DomainEventBus $eventBus, CommandResult $data)
102 {
103 return null;
104 }
105
106 /**
107 * @param Request $request
108 * @param Response $response
109 * @param $args
110 *
111 * @return Response
112 * @throws \InvalidArgumentException
113 * @throws \RuntimeException
114 */
115 public function __invoke(Request $request, Response $response, $args, $validApiCall = false)
116 {
117 /** @var Command $command */
118 $command = $this->instantiateCommand($request, $args);
119
120 /** @var SettingsService $settingsService */
121 $settingsService = new SettingsService(new SettingsStorage());
122
123 if (!$validApiCall && !$command->validateNonce($request)) {
124 return $response->withStatus(self::STATUS_FORBIDDEN);
125 }
126
127 $command->setPermissionService($this->permissionsService);
128 $command->setUserApplicationService($this->userApplicationService);
129
130 try {
131 /** @var CommandResult $commandResult */
132 $commandResult = $this->commandBus->handle($command);
133 } catch (CustomException $e) {
134 $response = $response->withHeader('Content-Type', 'application/json;charset=utf-8');
135 $response = $response->withStatus(self::STATUS_INTERNAL_SERVER_ERROR);
136
137 $response = $response->write(
138 json_encode(
139 [
140 'data' => [
141 'message' => $e->getMessage()
142 ]
143 ]
144 )
145 );
146
147 return $response;
148 }
149
150 if ($commandResult->getResult() === CommandResult::RESULT_ERROR) {
151 if ($settingsService->getSetting('activation', 'responseErrorAsConflict')) {
152 $commandResult->setResult(CommandResult::RESULT_CONFLICT);
153 }
154 }
155
156 if ($commandResult->getUrl() !== null) {
157 $this->emitSuccessEvent($this->eventBus, $commandResult);
158
159 /** @var Response $response */
160 $response = $response->withHeader('Location', $commandResult->getUrl());
161 $response = $response->withStatus(self::STATUS_REDIRECT);
162
163 return $response;
164 }
165
166 if ($commandResult->hasAttachment() === false) {
167 $responseBody = [
168 'message' => $commandResult->getMessage(),
169 'data' => $commandResult->getData()
170 ];
171
172 $this->emitSuccessEvent($this->eventBus, $commandResult);
173
174 switch ($commandResult->getResult()) {
175 case (CommandResult::RESULT_SUCCESS):
176 $response = $response->withStatus(self::STATUS_OK);
177
178 break;
179 case (CommandResult::RESULT_CONFLICT):
180 $response = $response->withStatus(self::STATUS_CONFLICT);
181
182 break;
183 default:
184 $response = $response->withStatus(self::STATUS_INTERNAL_SERVER_ERROR);
185
186 break;
187 }
188
189 /** @var Response $response */
190 $response = $response->withHeader('Content-Type', 'application/json;charset=utf-8');
191 $response = $response->write(
192 $this->sendJustData ? $commandResult->getData() :
193 json_encode(
194 $commandResult->hasDataInResponse() ?
195 $responseBody : array_merge($responseBody, ['data' => []])
196 )
197 );
198 }
199
200 if (($file = $commandResult->getFile()) !== null) {
201 /** @var Response $response */
202 $response = $response->withHeader('Content-Type', $file['type']);
203 $response = $response->withHeader('Content-Disposition', 'inline; filename=' . '"' . $file['name'] . '"');
204 $response = $response->withHeader('Cache-Control', 'max-age=0');
205
206 if (array_key_exists('size', $file)) {
207 $response = $response->withHeader('Content-Length', $file['size']);
208 }
209
210 $response = $response->write($file['content']);
211 }
212
213 return $response;
214 }
215
216 /**
217 * @param Command $command
218 * @param $requestBody
219 */
220 protected function setCommandFields($command, $requestBody)
221 {
222 foreach ($this->allowedFields as $field) {
223 if (!isset($requestBody[$field])) {
224 continue;
225 }
226 $command->setField($field, $requestBody[$field]);
227 }
228 }
229
230 /**
231 * @param mixed $params
232 * @param array $keys
233 */
234 protected function setArrayParams(&$params, $keys = [])
235 {
236 $names = array_merge([
237 'customers',
238 'categories',
239 'services',
240 'packages',
241 'employees',
242 'providers',
243 'providerIds',
244 'locations',
245 'locationIds',
246 'events',
247 'tag',
248 'dates',
249 'types',
250 'fields',
251 'statuses',
252 'stats',
253 'bookingTypes',
254 ], $keys);
255
256 foreach ($names as $name) {
257 if (!empty($params[$name])) {
258 $params[$name] = is_array($params[$name]) ? $params[$name] : explode(',', $params[$name]);
259 }
260 }
261
262 if (isset($params['dates'][0])) {
263 $params['dates'][0] = preg_match("/^\d{4}-\d{2}-\d{2}$/", $params['dates'][0]) ?
264 $params['dates'][0] : DateTimeService::getNowDate();
265 }
266
267 if (isset($params['dates'][1]) && $params['dates'][1]) {
268 $params['dates'][1] = preg_match("/^\d{4}-\d{2}-\d{2}$/", $params['dates'][1]) ?
269 $params['dates'][1] : DateTimeService::getNowDate();
270 }
271
272 if (isset($params['date'])) {
273 $params['date'] = preg_match("/^\d{4}-\d{2}-\d{2}$/", $params['date']) ?
274 $params['date'] : DateTimeService::getNowDate();
275 }
276 }
277
278 /**
279 * @param array $data
280 * @param string $field
281 * @param string $translationField
282 *
283 * @return void
284 */
285 private function filterField(&$data, $field, $translationField)
286 {
287 if (!empty($data[$field])) {
288 global $allowedposttags;
289
290 $data[$field] = wp_kses($data[$field], $allowedposttags);
291
292 if (!empty($data['translations']) && ($translations = json_decode($data['translations'], true)) !== null) {
293 if (!empty($translations[$translationField])) {
294 foreach ($translations[$translationField] as $lang => $translation) {
295 $translations[$translationField][$lang] = wp_kses(
296 $translations[$translationField][$lang],
297 $allowedposttags
298 );
299 }
300
301 $data['translations'] = json_encode($translations);
302 }
303 }
304 }
305 }
306
307 /**
308 * @param array $requestBody
309 *
310 * @return void
311 */
312 protected function filter(&$requestBody)
313 {
314 if (!current_user_can('unfiltered_html') && $requestBody) {
315 $this->filterField($requestBody, 'description', 'description');
316 $this->filterField($requestBody, 'label', 'name');
317
318 foreach (!empty($requestBody['extras']) ? $requestBody['extras'] : [] as $index => $extra) {
319 $this->filterField($requestBody['extras'][$index], 'description', 'description');
320 }
321 }
322 }
323 }
324