PluginProbe ʕ •ᴥ•ʔ
VikAppointments Services Booking Calendar / trunk
VikAppointments Services Booking Calendar vtrunk
trunk 1.2.17 1.2.18 1.2.19
vikappointments / admin / controllers / service.php
vikappointments / admin / controllers Last commit date
analytics.php 4 years ago apiban.php 4 years ago apilog.php 4 years ago apiplugin.php 4 years ago apiuser.php 4 years ago backup.php 4 years ago calendar.php 4 years ago city.php 4 years ago closure.php 1 month ago configapp.php 4 years ago configcldays.php 2 years ago configcron.php 4 years ago configemp.php 4 years ago configsmsapi.php 4 years ago configuration.php 1 month ago conversion.php 1 year ago country.php 4 years ago coupon.php 4 years ago coupongroup.php 4 years ago cronjob.php 2 years ago cronjoblog.php 4 years ago customer.php 4 months ago customf.php 1 year ago dashboard.php 4 years ago emplocwdays.php 4 years ago employee.php 1 year ago emprates.php 4 years ago export.php 4 years ago exportres.php 4 years ago file.php 4 months ago findreservation.php 1 month ago group.php 4 years ago import.php 4 years ago index.html 4 years ago invoice.php 1 month ago langcustomf.php 4 years ago langemployee.php 4 years ago langgroup.php 4 years ago langmedia.php 4 years ago langoption.php 4 years ago langoptiongroup.php 4 years ago langpackage.php 4 years ago langpackgroup.php 4 years ago langpayment.php 4 years ago langservice.php 4 years ago langstatuscode.php 4 years ago langsubscr.php 4 years ago langtax.php 4 years ago location.php 4 years ago mailtext.php 2 years ago makerecurrence.php 1 month ago media.php 4 years ago multiorder.php 4 years ago option.php 4 months ago optiongroup.php 4 years ago package.php 2 years ago packgroup.php 4 years ago packorder.php 1 year ago payment.php 4 years ago rate.php 4 years ago reportsemp.php 4 years ago reportsser.php 4 years ago reservation.php 1 month ago restriction.php 4 years ago review.php 4 years ago service.php 1 year ago serworkday.php 4 months ago state.php 4 years ago statuscode.php 4 years ago subscription.php 4 years ago subscrorder.php 4 years ago tag.php 4 years ago tax.php 4 years ago usernote.php 4 years ago waitinglist.php 4 years ago webhook.php 4 years ago wizard.php 1 year ago
service.php
571 lines
1 <?php
2 /**
3 * @package VikAppointments
4 * @subpackage core
5 * @author E4J s.r.l.
6 * @copyright Copyright (C) 2021 E4J s.r.l. All Rights Reserved.
7 * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL
8 * @link https://vikwp.com
9 */
10
11 // No direct access
12 defined('ABSPATH') or die('No script kiddies please!');
13
14 VAPLoader::import('libraries.mvc.controllers.admin');
15
16 /**
17 * VikAppointments service controller.
18 *
19 * @since 1.7
20 */
21 class VikAppointmentsControllerService extends VAPControllerAdmin
22 {
23 /**
24 * Task used to access the creation page of a new record.
25 *
26 * @return boolean
27 */
28 public function add()
29 {
30 $app = JFactory::getApplication();
31 $user = JFactory::getUser();
32
33 $data = array();
34 $id_group = $app->input->getInt('id_group', 0);
35
36 if ($id_group > 0)
37 {
38 $data['id_group'] = $id_group;
39 }
40
41 // unset user state for being recovered again
42 $app->setUserState('vap.service.data', $data);
43
44 // check user permissions
45 if (!$user->authorise('core.create', 'com_vikappointments') || !$user->authorise('core.access.services', 'com_vikappointments'))
46 {
47 // back to main list, not authorised to create records
48 $app->enqueueMessage(JText::translate('JERROR_ALERTNOAUTHOR'), 'error');
49 $this->cancel();
50
51 return false;
52 }
53
54 $this->setRedirect('index.php?option=com_vikappointments&view=manageservice');
55
56 return true;
57 }
58
59 /**
60 * Task used to access the management page of an existing record.
61 *
62 * @return boolean
63 */
64 public function edit()
65 {
66 $app = JFactory::getApplication();
67 $user = JFactory::getUser();
68
69 // unset user state for being recovered again
70 $app->setUserState('vap.service.data', array());
71
72 // check user permissions
73 if (!$user->authorise('core.edit', 'com_vikappointments') || !$user->authorise('core.access.services', 'com_vikappointments'))
74 {
75 // back to main list, not authorised to edit records
76 $app->enqueueMessage(JText::translate('JERROR_ALERTNOAUTHOR'), 'error');
77 $this->cancel();
78
79 return false;
80 }
81
82 $cid = $app->input->getUint('cid', array(0));
83
84 $this->setRedirect('index.php?option=com_vikappointments&view=manageservice&cid[]=' . $cid[0]);
85
86 return true;
87 }
88
89 /**
90 * Task used to save the record data set in the request.
91 * After saving, the user is redirected to the main list.
92 *
93 * @return void
94 */
95 public function saveclose()
96 {
97 if ($this->save())
98 {
99 $this->cancel();
100 }
101 }
102
103 /**
104 * Task used to save the record data set in the request.
105 * After saving, the user is redirected to the creation
106 * page of a new record.
107 *
108 * @return void
109 */
110 public function savenew()
111 {
112 if ($this->save())
113 {
114 $this->setRedirect('index.php?option=com_vikappointments&task=service.add');
115 }
116 }
117
118 /**
119 * Task used to save the record data as a copy of the current item.
120 * After saving, the user is redirected to the management
121 * page of the record that has been saved.
122 *
123 * @return void
124 */
125 public function savecopy()
126 {
127 $this->save(true);
128 }
129
130 /**
131 * Task used to save the record data set in the request.
132 * After saving, the user is redirected to the management
133 * page of the record that has been saved.
134 *
135 * @param boolean $copy True to save the record as a copy.
136 *
137 * @return boolean
138 */
139 public function save($copy = false)
140 {
141 $app = JFactory::getApplication();
142 $input = $app->input;
143 $user = JFactory::getUser();
144
145 /**
146 * Added token validation.
147 *
148 * @since 1.7
149 */
150 if (!JSession::checkToken())
151 {
152 // back to main list, missing CSRF-proof token
153 $app->enqueueMessage(JText::translate('JINVALID_TOKEN'), 'error');
154 $this->cancel();
155
156 return false;
157 }
158
159 $args = array();
160 $args['name'] = $input->getString('name', '');
161 $args['alias'] = $input->getString('alias', '');
162 $args['description'] = JComponentHelper::filterText($input->getRaw('description', ''));
163 $args['duration'] = $input->getUint('duration', 0);
164 $args['sleep'] = $input->getInt('sleep', 0);
165 $args['interval'] = $input->getUint('interval', 1);
166 $args['minrestr'] = $input->getInt('minrestr', 0);
167 $args['mindate'] = $input->getInt('mindate', 0);
168 $args['maxdate'] = $input->getInt('maxdate', 0);
169 $args['price'] = $input->getFloat('price', 0);
170 $args['id_tax'] = $input->getFloat('id_tax', 0);
171 $args['max_capacity'] = $input->getUint('max_capacity', 1);
172 $args['max_per_res'] = $input->getUint('max_per_res', 1);
173 $args['min_per_res'] = $input->getUint('min_per_res', 1);
174 $args['priceperpeople'] = $input->getUint('priceperpeople', 0);
175 $args['app_per_slot'] = $input->getUint('app_per_slot', 0);
176 $args['published'] = $input->getUint('published', 0);
177 $args['quick_contact'] = $input->getUint('quick_contact', 0);
178 $args['choose_emp'] = $input->getUint('choose_emp', 0);
179 $args['random_emp'] = $input->getUint('random_emp', 0);
180 $args['has_own_cal'] = $input->getUint('has_own_cal', 0);
181 $args['checkout_selection'] = $input->getUint('checkout_selection', 0);
182 $args['display_seats'] = $input->getUint('display_seats', 0);
183 $args['use_recurrence'] = $input->getUint('use_recurrence', 0);
184 $args['enablezip'] = $input->getUint('enablezip', 0);
185 $args['image'] = $input->getString('image', '');
186 $args['layout'] = $input->getString('layout', 'default-layout');
187 $args['start_publishing'] = $input->getString('start_publishing', '');
188 $args['end_publishing'] = $input->getString('end_publishing', '');
189 $args['level'] = $input->getUint('level', 0);
190 $args['id_group'] = $input->getUint('id_group', 0);
191 $args['attachments'] = $input->getString('attachments', array());
192 $args['metadata'] = $input->get('metadata', array(), 'array');
193 $args['id'] = $input->getUint('id', 0);
194
195 if ($args['layout'] === 'custom')
196 {
197 $args['layout'] = $input->getString('layout_class_sfx', '');
198 }
199
200 if ($copy)
201 {
202 // unset ID to create a copy
203 $args['id'] = 0;
204 }
205
206 $rule = 'core.' . ($args['id'] > 0 ? 'edit' : 'create');
207
208 // check user permissions
209 if (!$user->authorise($rule, 'com_vikappointments') || !$user->authorise('core.access.services', 'com_vikappointments'))
210 {
211 // back to main list, not authorised to create/edit records
212 $app->enqueueMessage(JText::translate('JERROR_ALERTNOAUTHOR'), 'error');
213 $this->cancel();
214
215 return false;
216 }
217
218 /**
219 * Try to auto-create a new group before saving the service.
220 *
221 * @since 1.7
222 */
223 if ($args['id_group'] == 0 && ($group_name = $input->getString('group_name')))
224 {
225 // make sure the user is authorised
226 if ($user->authorise('core.create', 'com_vikappointments') && $user->authorise('core.access.groups', 'com_vikappointments'))
227 {
228 $group = $this->getModel('group');
229
230 // attempt to save group
231 $id_group = $group->save(array('name' => $group_name));
232
233 if ($id_group)
234 {
235 // overwrite the group ID
236 $args['id_group'] = $id_group;
237 }
238 }
239 }
240
241 /**
242 * Convert timestamp from local timezone to UTC.
243 *
244 * @since 1.7
245 */
246 $args['start_publishing'] = VAPDateHelper::getSqlDateLocale($args['start_publishing']);
247 $args['end_publishing'] = VAPDateHelper::getSqlDateLocale($args['end_publishing']);
248
249 // get service model
250 $service = $this->getModel();
251
252 // try to save arguments
253 $id = $service->save($args);
254
255 if (!$id)
256 {
257 // get string error
258 $error = $service->getError(null, true);
259
260 // display error message
261 $app->enqueueMessage(JText::sprintf('JLIB_APPLICATION_ERROR_SAVE_FAILED', $error), 'error');
262
263 $url = 'index.php?option=com_vikappointments&view=manageservice';
264
265 if ($args['id'])
266 {
267 $url .= '&cid[]=' . $args['id'];
268 }
269
270 // redirect to new/edit page
271 $this->setRedirect($url);
272
273 return false;
274 }
275
276 // get save data
277 $data = $service->getData();
278
279 // get service-option relation model
280 $optModel = $this->getModel('seroptassoc');
281
282 if (!$copy)
283 {
284 // load deleted options
285 $opt_deleted = $input->get('option_deleted', array(), 'uint');
286
287 // delete options before save the other ones
288 $optModel->delete($opt_deleted);
289
290 // load new options
291 $opt_ids = $input->get('id_option', array(), 'uint');
292 }
293 else
294 {
295 // We are saving as copy, so we don't need to delete the specified options.
296 // Load the option IDs from a different pool.
297 $opt_ids = $input->get('id_option_copy', array(), 'uint');
298 }
299
300 foreach ($opt_ids as $opt_id)
301 {
302 $src = array();
303 $src['id_service'] = $id;
304 $src['id_option'] = $opt_id;
305
306 // attempt to save the relation
307 $optModel->save($src);
308 }
309
310 // get service-employee relation model
311 $empModel = $this->getModel('serempassoc');
312
313 // load deleted employees
314 $emp_deleted = $input->get('employee_deleted', array(), 'uint');
315
316 // delete employees before save the other ones
317 $empModel->delete($emp_deleted);
318
319 // load employee details
320 $emp_json = $input->get('employee_json', array(), 'array');
321
322 foreach ($emp_json as $i => $json)
323 {
324 // decode the employee data
325 $src = json_decode($json, true);
326
327 if ($copy)
328 {
329 // unset ID to create a copy
330 $src['id'] = 0;
331 }
332
333 // always specify the service ID
334 $src['id_service'] = $id;
335 // set up the ordering
336 $src['ordering'] = $i + 1;
337
338 if ($src['global'])
339 {
340 // overwrite with default service settings
341 $src['rate'] = $data['price'];
342 $src['duration'] = $data['duration'];
343 $src['sleep'] = $data['sleep'];
344 $src['description'] = '';
345 }
346
347 // attempt to save the service
348 $empModel->save($src);
349 }
350
351 // display generic successful message
352 $app->enqueueMessage(JText::translate('JLIB_APPLICATION_SAVE_SUCCESS'));
353
354 // redirect to edit page
355 $this->setRedirect('index.php?option=com_vikappointments&task=service.edit&cid[]=' . $id);
356
357 return true;
358 }
359
360 /**
361 * Deletes a list of records set in the request.
362 *
363 * @return boolean
364 */
365 public function delete()
366 {
367 $app = JFactory::getApplication();
368 $user = JFactory::getUser();
369
370 /**
371 * Added token validation.
372 * Both GET and POST are supported.
373 *
374 * @since 1.7
375 */
376 if (!JSession::checkToken() && !JSession::checkToken('get'))
377 {
378 // back to main list, missing CSRF-proof token
379 $app->enqueueMessage(JText::translate('JINVALID_TOKEN'), 'error');
380 $this->cancel();
381
382 return false;
383 }
384
385 $cid = $app->input->get('cid', array(), 'uint');
386
387 // check user permissions
388 if (!$user->authorise('core.delete', 'com_vikappointments') || !$user->authorise('core.access.services', 'com_vikappointments'))
389 {
390 // back to main list, not authorised to delete records
391 $app->enqueueMessage(JText::translate('JERROR_ALERTNOAUTHOR'), 'error');
392 $this->cancel();
393
394 return false;
395 }
396
397 // delete selected records
398 $this->getModel()->delete($cid);
399
400 // back to main list
401 $this->cancel();
402
403 return true;
404 }
405
406 /**
407 * Publishes the selected records.
408 *
409 * @return boolean
410 */
411 public function publish()
412 {
413 $app = JFactory::getApplication();
414 $user = JFactory::getUser();
415
416 /**
417 * Added token validation.
418 * Both GET and POST are supported.
419 *
420 * @since 1.7
421 */
422 if (!JSession::checkToken() && !JSession::checkToken('get'))
423 {
424 // back to main list, missing CSRF-proof token
425 $app->enqueueMessage(JText::translate('JINVALID_TOKEN'), 'error');
426 $this->cancel();
427
428 return false;
429 }
430
431 $cid = $app->input->get('cid', array(), 'uint');
432 $task = $app->input->get('task', null);
433
434 $state = $task == 'unpublish' ? 0 : 1;
435
436 // check user permissions
437 if (!$user->authorise('core.edit.state', 'com_vikappointments') || !$user->authorise('core.access.services', 'com_vikappointments'))
438 {
439 // back to main list, not authorised to edit records
440 $app->enqueueMessage(JText::translate('JERROR_ALERTNOAUTHOR'), 'error');
441 $this->cancel();
442
443 return false;
444 }
445
446 // change state of selected records
447 $this->getModel()->publish($cid, $state);
448
449 // back to main list
450 $this->cancel();
451
452 return true;
453 }
454
455 /**
456 * Redirects the users to the main records list.
457 *
458 * @return void
459 */
460 public function cancel()
461 {
462 $this->setRedirect('index.php?option=com_vikappointments&view=services');
463 }
464
465 /**
466 * AJAX end-point used to obtain all the employees assigned to the given service.
467 * The task expects the following parameters to be set in request.
468 *
469 * @param integer id_ser The service ID.
470 * @param boolean all True to return all the employees.
471 * False to obtain only the employees listed in the front-end.
472 *
473 * @return void
474 */
475 public function employeesajax()
476 {
477 $input = JFactory::getApplication()->input;
478
479 /**
480 * Added token validation.
481 *
482 * @since 1.7
483 */
484 if (!JSession::checkToken())
485 {
486 // missing CSRF-proof token
487 UIErrorFactory::raiseError(403, JText::translate('JINVALID_TOKEN'));
488 }
489
490 $id_ser = $input->getUint('id_ser', 0);
491 $all = $input->getBool('all', false);
492
493 // negate ALL because the model expects a "strict" argument
494 $employees = $this->getModel()->getEmployees($id_ser, !$all);
495
496 // send resulting object to caller
497 $this->sendJSON($employees);
498 }
499
500 /**
501 * AJAX end-point used to calculate the average price of the services.
502 * The task expects the following parameters to be set in request.
503 *
504 * @param array cid A list of services IDs.
505 *
506 * @return void
507 */
508 public function avgajax()
509 {
510 $input = JFactory::getApplication()->input;
511
512 /**
513 * Added token validation.
514 *
515 * @since 1.7
516 */
517 if (!JSession::checkToken())
518 {
519 // missing CSRF-proof token
520 UIErrorFactory::raiseError(403, JText::translate('JINVALID_TOKEN'));
521 }
522
523 $ids = $input->getUint('cid', array());
524
525 // calculate the average price of the specified services
526 $avg = $this->getModel()->getAveragePrice($ids);
527
528 // send resulting amount to caller
529 $this->sendJSON($avg);
530 }
531
532 /**
533 * AJAX end-point used to change the thumb color of the given service.
534 * The task expects the following parameters to be set in request.
535 *
536 * @param integer id The service ID.
537 * @param string color The hex color.
538 *
539 * @return void
540 */
541 public function changecolorajax()
542 {
543 $input = JFactory::getApplication()->input;
544
545 /**
546 * Added token validation.
547 *
548 * @since 1.7
549 */
550 if (!JSession::checkToken())
551 {
552 // missing CSRF-proof token
553 UIErrorFactory::raiseError(403, JText::translate('JINVALID_TOKEN'));
554 }
555
556 $args = array();
557 $args['id'] = $input->getUint('id', 0);
558 $args['color'] = $input->getString('color', '');
559
560 // get service model
561 $model = $this->getModel();
562
563 // update service color without taking care
564 // of any possible errors
565 $model->save($args);
566
567 // send response to caller
568 $this->sendJSON(1);
569 }
570 }
571