From 86f1fb3ca23232259e92eea6fa998027868ec114 Mon Sep 17 00:00:00 2001 From: Mike Koch Date: Wed, 27 Dec 2017 22:00:30 -0500 Subject: [PATCH] Slowly working on moving more API endpoints --- admin/calendar.php | 16 +++--- .../Calendar/CalendarHandler.php | 31 ++++++++++- .../Calendar/SearchEventsFilter.php | 9 ++++ api/BusinessLogic/Tickets/TicketEditor.php | 21 ++++++++ .../Calendar/CalendarController.php | 33 ++++++++---- .../Tickets/StaffTicketController.php | 11 ++++ api/DataAccess/Calendar/CalendarGateway.php | 51 ++++++++++++++++--- api/index.php | 2 +- js/calendar/mods-for-hesk-calendar.js | 20 +++++--- 9 files changed, 157 insertions(+), 37 deletions(-) diff --git a/admin/calendar.php b/admin/calendar.php index 679bfd21..905cc81d 100644 --- a/admin/calendar.php +++ b/admin/calendar.php @@ -282,10 +282,10 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
@@ -453,10 +453,10 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
diff --git a/api/BusinessLogic/Calendar/CalendarHandler.php b/api/BusinessLogic/Calendar/CalendarHandler.php index 7f327997..5347eaf1 100644 --- a/api/BusinessLogic/Calendar/CalendarHandler.php +++ b/api/BusinessLogic/Calendar/CalendarHandler.php @@ -3,7 +3,10 @@ namespace BusinessLogic\Calendar; +use BusinessLogic\Exceptions\ApiFriendlyException; +use BusinessLogic\Security\UserContext; use DataAccess\Calendar\CalendarGateway; +use PHPUnit\Runner\Exception; class CalendarHandler extends \BaseClass { private $calendarGateway; @@ -12,11 +15,35 @@ class CalendarHandler extends \BaseClass { $this->calendarGateway = $calendarGateway; } - public function getEventsForStaff($startTime, $endTime, $searchEventsFilter, $heskSettings) { - return $this->calendarGateway->getEventsForStaff($startTime, $endTime, $searchEventsFilter, $heskSettings); + public function getEventsForStaff($searchEventsFilter, $heskSettings) { + return $this->calendarGateway->getEventsForStaff($searchEventsFilter, $heskSettings); } + /** + * @param $calendarEvent CalendarEvent + * @param $userContext UserContext + * @param $heskSettings array + * @return CalendarEvent + * @throws \Exception If more than one event is returned for the given ID + */ public function updateEvent($calendarEvent, $userContext, $heskSettings) { $this->calendarGateway->updateEvent($calendarEvent, $userContext, $heskSettings); + + $eventFilter = new SearchEventsFilter(); + $eventFilter->eventId = $calendarEvent->id; + $eventFilter->reminderUserId = $userContext->id; + + $events = $this->calendarGateway->getEventsForStaff($eventFilter, $heskSettings); + + if (count($events) !== 1) { + throw new \Exception("Expected exactly 1 event, found: " . count($events)); + } + + return $events[0]; + } + + + public function createEvent($calendarEvent, $userContext, $heskSettings) { + return $this->calendarGateway->createEvent($calendarEvent, $userContext, $heskSettings); } } \ No newline at end of file diff --git a/api/BusinessLogic/Calendar/SearchEventsFilter.php b/api/BusinessLogic/Calendar/SearchEventsFilter.php index 1a509f9f..72e31b3d 100644 --- a/api/BusinessLogic/Calendar/SearchEventsFilter.php +++ b/api/BusinessLogic/Calendar/SearchEventsFilter.php @@ -4,6 +4,15 @@ namespace BusinessLogic\Calendar; class SearchEventsFilter { + /* @var $startTime int|null */ + public $startTime; + + /* @var $endTime int|null */ + public $endTime; + + /* @var $id int|null */ + public $eventId; + /* @var $categories int[]|null */ public $categories; diff --git a/api/BusinessLogic/Tickets/TicketEditor.php b/api/BusinessLogic/Tickets/TicketEditor.php index e15b33d9..5b6e2f7d 100644 --- a/api/BusinessLogic/Tickets/TicketEditor.php +++ b/api/BusinessLogic/Tickets/TicketEditor.php @@ -135,4 +135,25 @@ class TicketEditor extends \BaseClass { throw new ValidationException($validationModel); } } + + /** + * @param $id int + * @param $dueDate string + * @param $userContext UserContext + * @param $heskSettings array + * @throws ApiFriendlyException If ticket does not exist or if the user cannot edit the ticket + */ + function updateDueDate($id, $dueDate, $userContext, $heskSettings) { + $ticket = $this->ticketGateway->getTicketById($id, $heskSettings); + + if ($ticket === null) { + throw new ApiFriendlyException("Please enter a valid ticket ID.", "Ticket Not Found!", 400); + } + + if (!$this->userToTicketChecker->isTicketAccessibleToUser($userContext, $ticket, $heskSettings, array(UserPrivilege::CAN_EDIT_TICKETS))) { + throw new ApiFriendlyException("User " . $userContext->id . " does not have permission to edit ticket " . $id, "Access Denied", 403); + } + + // TODO Do it + } } \ No newline at end of file diff --git a/api/Controllers/Calendar/CalendarController.php b/api/Controllers/Calendar/CalendarController.php index 1a180fc1..2e30c0b1 100644 --- a/api/Controllers/Calendar/CalendarController.php +++ b/api/Controllers/Calendar/CalendarController.php @@ -32,18 +32,20 @@ class CalendarController extends \BaseClass { $calendarHandler = $applicationContext->get(CalendarHandler::clazz()); $searchEventsFilter = new SearchEventsFilter(); + $searchEventsFilter->startTime = $startTime; + $searchEventsFilter->endTime = $endTime; $searchEventsFilter->reminderUserId = $userContext->id; $searchEventsFilter->includeTicketsAssignedToOthers = in_array(UserPrivilege::CAN_VIEW_ASSIGNED_TO_OTHER, $userContext->permissions); $searchEventsFilter->includeUnassignedTickets = in_array(UserPrivilege::CAN_VIEW_UNASSIGNED, $userContext->permissions); $searchEventsFilter->includeTickets = true; $searchEventsFilter->categories = $userContext->admin ? null : $userContext->categories; - $events = $calendarHandler->getEventsForStaff($startTime, $endTime, $searchEventsFilter, $hesk_settings); + $events = $calendarHandler->getEventsForStaff($searchEventsFilter, $hesk_settings); return output($events); } - function put($id) { + function post() { /* @var $userContext UserContext */ global $applicationContext, $hesk_settings, $userContext; @@ -53,25 +55,36 @@ class CalendarController extends \BaseClass { /* @var $calendarHandler CalendarHandler */ $calendarHandler = $applicationContext->get(CalendarHandler::clazz()); + } + + function put($id) { + /* @var $userContext UserContext */ + global $applicationContext, $hesk_settings, $userContext; + + $json = JsonRetriever::getJsonData(); + + $event = $this->transformJson($json, $id); + + /* @var $calendarHandler CalendarHandler */ + $calendarHandler = $applicationContext->get(CalendarHandler::clazz()); return output($calendarHandler->updateEvent($event, $userContext, $hesk_settings)); } - private function transformJson($json, $creating = false) { + private function transformJson($json, $id = null) { $event = new CalendarEvent(); - if ($creating) { - $event->id = Helpers::safeArrayGet($json, 'id'); - } - - $event->startTime = date('Y-m-d H:i:s', Helpers::safeArrayGet($json, 'startTime')); - $event->endTime = date('Y-m-d H:i:s', Helpers::safeArrayGet($json, 'endTime')); - $event->allDay = Helpers::safeArrayGet($json, 'allDay') === 'true'; + $event->id = $id; + $event->startTime = date('Y-m-d H:i:s', strtotime(Helpers::safeArrayGet($json, 'startTime'))); + $event->endTime = date('Y-m-d H:i:s', strtotime(Helpers::safeArrayGet($json, 'endTime'))); + $event->allDay = Helpers::safeArrayGet($json, 'allDay'); $event->title = Helpers::safeArrayGet($json, 'title'); $event->location = Helpers::safeArrayGet($json, 'location'); $event->comments = Helpers::safeArrayGet($json, 'comments'); $event->categoryId = Helpers::safeArrayGet($json, 'categoryId'); $event->reminderValue = Helpers::safeArrayGet($json, 'reminderValue'); $event->reminderUnits = ReminderUnit::getByName(Helpers::safeArrayGet($json, 'reminderUnits')); + + return $event; } } \ No newline at end of file diff --git a/api/Controllers/Tickets/StaffTicketController.php b/api/Controllers/Tickets/StaffTicketController.php index 023f5352..ea4761a1 100644 --- a/api/Controllers/Tickets/StaffTicketController.php +++ b/api/Controllers/Tickets/StaffTicketController.php @@ -4,6 +4,7 @@ namespace Controllers\Tickets; use BusinessLogic\Helpers; +use BusinessLogic\Security\UserContext; use BusinessLogic\Tickets\EditTicketModel; use BusinessLogic\Tickets\TicketDeleter; use BusinessLogic\Tickets\TicketEditor; @@ -45,6 +46,16 @@ class StaffTicketController extends \BaseClass { return; } + static function updateDueDate($id) { + /* @var $userContext UserContext */ + global $applicationContext, $userContext, $hesk_settings; + + /* @var $ticketEditor TicketEditor */ + $ticketEditor = $applicationContext->get(TicketEditor::clazz()); + + + } + private function getEditTicketModel($id, $jsonRequest) { $editTicketModel = new EditTicketModel(); $editTicketModel->id = $id; diff --git a/api/DataAccess/Calendar/CalendarGateway.php b/api/DataAccess/Calendar/CalendarGateway.php index 9367dbb7..a644370d 100644 --- a/api/DataAccess/Calendar/CalendarGateway.php +++ b/api/DataAccess/Calendar/CalendarGateway.php @@ -11,23 +11,19 @@ use BusinessLogic\Calendar\TicketEvent; use BusinessLogic\Security\UserContext; use Core\Constants\Priority; use DataAccess\CommonDao; +use DataAccess\Logging\LoggingGateway; class CalendarGateway extends CommonDao { /** - * @param $startTime int - * @param $endTime int * @param $searchEventsFilter SearchEventsFilter * @param $heskSettings array * @return AbstractEvent[] */ - public function getEventsForStaff($startTime, $endTime, $searchEventsFilter, $heskSettings) { + public function getEventsForStaff($searchEventsFilter, $heskSettings) { $this->init(); $events = array(); - $startTimeSql = "CONVERT_TZ(FROM_UNIXTIME(" . hesk_dbEscape($startTime) . " / 1000), @@session.time_zone, '+00:00')"; - $endTimeSql = "CONVERT_TZ(FROM_UNIXTIME(" . hesk_dbEscape($endTime) . " / 1000), @@session.time_zone, '+00:00')"; - // EVENTS $sql = "SELECT `events`.*, `categories`.`name` AS `category_name`, `categories`.`background_color` AS `background_color`, `categories`.`foreground_color` AS `foreground_color`, `categories`.`display_border_outline` AS `display_border`, @@ -38,9 +34,21 @@ class CalendarGateway extends CommonDao { LEFT JOIN `" . hesk_dbEscape($heskSettings['db_pfix']) . "calendar_event_reminder` AS `reminders` ON `reminders`.`user_id` = " . intval($searchEventsFilter->reminderUserId) . " AND `reminders`.`event_id` = `events`.`id` - WHERE NOT (`end` < {$startTimeSql} OR `start` > {$endTimeSql}) + WHERE 1=1"; + + if ($searchEventsFilter->startTime !== null && $searchEventsFilter->endTime !== null) { + $startTimeSql = "CONVERT_TZ(FROM_UNIXTIME(" . hesk_dbEscape($searchEventsFilter->startTime) . " / 1000), @@session.time_zone, '+00:00')"; + $endTimeSql = "CONVERT_TZ(FROM_UNIXTIME(" . hesk_dbEscape($searchEventsFilter->endTime) . " / 1000), @@session.time_zone, '+00:00')"; + + + $sql .= " AND NOT (`end` < {$startTimeSql} OR `start` > {$endTimeSql}) AND `categories`.`usage` <> 1 AND `categories`.`type` = '0'"; + } + + if ($searchEventsFilter->eventId !== null) { + $sql .= " AND `events`.`id` = " . intval($searchEventsFilter->eventId); + } if (!empty($searchEventsFilter->categories)) { $categoriesAsString = implode(',', $searchEventsFilter->categories); @@ -130,6 +138,33 @@ class CalendarGateway extends CommonDao { return $events; } + /** + * @param $event CalendarEvent + * @param $userContext UserContext + * @param $heskSettings array + * @return CalendarEvent + */ + public function createEvent($event, $userContext, $heskSettings) { + $this->init(); + + hesk_dbQuery("INSERT INTO `" . hesk_dbEscape($heskSettings['db_pfix']) . "calendar_event` (`start`, `end`, `all_day`, `name`, + `location`, `comments`, `category`) VALUES ('" . hesk_dbEscape($event->startTime) . "', '" . hesk_dbEscape($event->endTime) . "', + '" . ($event->allDay ? 1 : 0) . "', '" . hesk_dbEscape(addslashes($event->title)) . "', + '" . hesk_dbEscape(addslashes($event->location)) . "', '". hesk_dbEscape(addslashes($event->comments)) . "', " . intval($event->categoryId) . ")"); + + $event->id = hesk_dbInsertID(); + + if ($event->reminderValue !== null) { + hesk_dbQuery("INSERT INTO `" . hesk_dbEscape($heskSettings['db_pfix']) . "calendar_event_reminder` (`user_id`, `event_id`, + `amount`, `unit`) VALUES (" . intval($userContext->id) . ", " . intval($event->id) . ", " . intval($event->reminderValue) . ", + " . intval($event->reminderUnits) . ")"); + } + + $this->close(); + + return $event; + } + /** * @param $event CalendarEvent * @param $userContext UserContext @@ -143,7 +178,7 @@ class CalendarGateway extends CommonDao { . hesk_dbEscape(addslashes($event->title)) . "', `location` = '" . hesk_dbEscape(addslashes($event->location)) . "', `comments` = '" . hesk_dbEscape(addslashes($event->comments)) . "', `category` = " . intval($event->categoryId) . " WHERE `id` = " . intval($event->id); - if ($event->reminderValue != null) { + if ($event->reminderValue !== null) { $delete_sql = "DELETE FROM `" . hesk_dbEscape($heskSettings['db_pfix']) . "calendar_event_reminder` WHERE `event_id` = " . intval($event->id) . " AND `user_id` = " . intval($userContext->id); hesk_dbQuery($delete_sql); diff --git a/api/index.php b/api/index.php index d833c236..00bd9af3 100644 --- a/api/index.php +++ b/api/index.php @@ -203,7 +203,7 @@ Link::all(array( // Settings '/v1/settings' => action(\Controllers\Settings\SettingsController::clazz(), RequestMethod::all()), // Calendar - '/v1/calendar/events/staff' => action(\Controllers\Calendar\CalendarController::clazz(), array(RequestMethod::GET), SecurityHandler::INTERNAL_OR_AUTH_TOKEN), + '/v1/calendar/events/staff' => action(\Controllers\Calendar\CalendarController::clazz(), array(RequestMethod::GET, RequestMethod::POST), SecurityHandler::INTERNAL_OR_AUTH_TOKEN), '/v1/calendar/events/staff/{i}' => action(\Controllers\Calendar\CalendarController::clazz(), array(RequestMethod::PUT), SecurityHandler::INTERNAL_OR_AUTH_TOKEN), /* Internal use only routes */ diff --git a/js/calendar/mods-for-hesk-calendar.js b/js/calendar/mods-for-hesk-calendar.js index 88197f4f..1ccfe7eb 100644 --- a/js/calendar/mods-for-hesk-calendar.js +++ b/js/calendar/mods-for-hesk-calendar.js @@ -204,7 +204,6 @@ $(document).ready(function() { allDay: allDay, comments: $createForm.find('textarea[name="comments"]').val(), categoryId: $createForm.find('select[name="category"]').val(), - action: 'create', type: 'CALENDAR', backgroundColor: $createForm.find('select[name="category"] :selected').attr('data-background-color'), foregroundColor: $createForm.find('select[name="category"] :selected').attr('data-foreground-color'), @@ -216,8 +215,10 @@ $(document).ready(function() { $.ajax({ method: 'POST', - url: heskPath + 'internal-api/admin/calendar/', - data: data, + url: heskPath + 'api/v1/calendar/events/staff', + data: JSON.stringify(data), + contentType: 'json', + headers: { 'X-Internal-Call': true }, success: function(id) { addToCalendar(id, data, $('#lang_event_created').text()); $('#create-event-modal').modal('hide'); @@ -245,7 +246,6 @@ $(document).ready(function() { } var data = { - id: $form.find('input[name="id"]').val(), title: $form.find('input[name="name"]').val(), location: $form.find('input[name="location"]').val(), startTime: moment(start).format(dateFormat), @@ -257,15 +257,19 @@ $(document).ready(function() { foregroundColor: $form.find('select[name="category"] :selected').attr('data-foreground-color'), displayBorder: $form.find('select[name="category"] :selected').attr('data-display-border'), categoryName: $form.find('select[name="category"] :selected').text().trim(), - action: 'update', reminderValue: $form.find('input[name="reminder-value"]').val(), reminderUnits: $form.find('select[name="reminder-unit"]').val() }; $.ajax({ method: 'POST', - url: heskPath + 'internal-api/admin/calendar/', - data: data, + url: heskPath + 'api/v1/calendar/events/staff/' + $form.find('input[name="id"]').val(), + data: JSON.stringify(data), + contentType: 'json', + headers: { + 'X-Internal-Call': true, + 'X-HTTP-Method-Override': 'PUT' + }, success: function() { removeFromCalendar(data.id); addToCalendar(data.id, data, $('#lang_event_updated').text()); @@ -291,7 +295,7 @@ function removeFromCalendar(id) { } function buildEvent(id, dbObject) { - if (dbObject.type == 'TICKET') { + if (dbObject.type === 'TICKET') { return { title: dbObject.title, subject: dbObject.subject,