From c26db927990320baaa47caba253ff9a46098e2ef Mon Sep 17 00:00:00 2001 From: Mike Koch Date: Thu, 27 Apr 2017 22:04:28 -0400 Subject: [PATCH] Add edit ticket endpoint --- api/BusinessLogic/Tickets/EditTicketModel.php | 30 ++++ api/BusinessLogic/Tickets/TicketEditor.php | 128 ++++++++++++++++++ api/DataAccess/Tickets/TicketGateway.php | 35 +++++ 3 files changed, 193 insertions(+) create mode 100644 api/BusinessLogic/Tickets/EditTicketModel.php create mode 100644 api/BusinessLogic/Tickets/TicketEditor.php diff --git a/api/BusinessLogic/Tickets/EditTicketModel.php b/api/BusinessLogic/Tickets/EditTicketModel.php new file mode 100644 index 00000000..d36aa1b9 --- /dev/null +++ b/api/BusinessLogic/Tickets/EditTicketModel.php @@ -0,0 +1,30 @@ +ticketGateway = $ticketGateway; + $this->userToTicketChecker = $userToTicketChecker; + } + + + /** + * @param $editTicketModel EditTicketModel + * @param $userContext UserContext + * @param $heskSettings array + * @throws ApiFriendlyException When the ticket isn't found for the ID + * @throws \Exception When the user doesn't have access to the ticket + */ + // TODO Unit Tests + function editTicket($editTicketModel, $userContext, $heskSettings) { + $ticket = $this->ticketGateway->getTicketById($editTicketModel->id, $heskSettings); + + if ($ticket === null) { + throw new ApiFriendlyException("Ticket with ID {$editTicketModel->id} not found!", "Ticket not found", 404); + } + + if (!$this->userToTicketChecker->isTicketAccessibleToUser($userContext, $ticket, $heskSettings, array(UserPrivilege::CAN_EDIT_TICKETS))) { + throw new \Exception("User does not have access to ticket {$editTicketModel->id}"); + } + + $this->validate($editTicketModel, $ticket->categoryId, $heskSettings); + } + + /** + * @param $editTicketModel EditTicketModel + * @param $categoryId int + * @param $heskSettings array + * @throws ValidationException When validation fails + */ + private function validate($editTicketModel, $categoryId, $heskSettings) { + $validationModel = new ValidationModel(); + + if ($editTicketModel->name === null || trim($editTicketModel->name) === '') { + $validationModel->errorKeys[] = 'NO_NAME'; + } + + if (!Validators::validateEmail($editTicketModel->email, $heskSettings['multi_eml'], false)) { + $validationModel->errorKeys[] = 'INVALID_OR_MISSING_EMAIL'; + } + + if ($heskSettings['require_subject'] === 1 && + ($editTicketModel->subject === NULL || $editTicketModel->subject === '')) { + $validationModel->errorKeys[] = 'SUBJECT_REQUIRED'; + } + + if ($heskSettings['require_message'] === 1 && + ($editTicketModel->message === NULL || $editTicketModel->message === '')) { + $validationModel->errorKeys[] = 'MESSAGE_REQUIRED'; + } + + foreach ($heskSettings['custom_fields'] as $key => $value) { + $customFieldNumber = intval(str_replace('custom', '', $key)); + + //TODO test this + if (!array_key_exists($customFieldNumber, $editTicketModel->customFields)) { + continue; + } + + if ($value['use'] == 1 && CustomFieldValidator::isCustomFieldInCategory($customFieldNumber, intval($categoryId), false, $heskSettings)) { + $custom_field_value = $editTicketModel->customFields[$customFieldNumber]; + if (empty($custom_field_value)) { + $validationModel->errorKeys[] = "CUSTOM_FIELD_{$customFieldNumber}_INVALID::NO_VALUE"; + continue; + } + switch($value['type']) { + case CustomField::DATE: + if (!preg_match("/^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$/", $custom_field_value)) { + $validationModel->errorKeys[] = 'CUSTOM_FIELD_' . $customFieldNumber . '_INVALID::INVALID_DATE'; + } else { + // Actually validate based on range + $date = strtotime($custom_field_value . ' t00:00:00'); + $dmin = strlen($value['value']['dmin']) ? strtotime($value['value']['dmin'] . ' t00:00:00') : false; + $dmax = strlen($value['value']['dmax']) ? strtotime($value['value']['dmax'] . ' t00:00:00') : false; + + if ($dmin && $dmin > $date) { + $validationModel->errorKeys[] = 'CUSTOM_FIELD_' . $customFieldNumber . '_INVALID::DATE_BEFORE_MIN::MIN:' . date('Y-m-d', $dmin) . '::ENTERED:' . date('Y-m-d', $date); + } elseif ($dmax && $dmax < $date) { + $validationModel->errorKeys[] = 'CUSTOM_FIELD_' . $customFieldNumber . '_INVALID::DATE_AFTER_MAX::MAX:' . date('Y-m-d', $dmax) . '::ENTERED:' . date('Y-m-d', $date); + } + } + break; + case CustomField::EMAIL: + if (!Validators::validateEmail($custom_field_value, $value['value']['multiple'], false)) { + $validationModel->errorKeys[] = "CUSTOM_FIELD_{$customFieldNumber}_INVALID::INVALID_EMAIL"; + } + break; + } + } + } + + if ($editTicketModel->language === null || + $editTicketModel->language === '') { + $validationModel->errorKeys[] = 'MISSING_LANGUAGE'; + } + + if (count($validationModel->errorKeys) > 0) { + throw new ValidationException($validationModel); + } + } +} \ No newline at end of file diff --git a/api/DataAccess/Tickets/TicketGateway.php b/api/DataAccess/Tickets/TicketGateway.php index 7a940bc8..6556cb5a 100644 --- a/api/DataAccess/Tickets/TicketGateway.php +++ b/api/DataAccess/Tickets/TicketGateway.php @@ -305,4 +305,39 @@ class TicketGateway extends CommonDao { $this->close(); } + + /** + * @param $ticket Ticket + * @param $heskSettings array + */ + function updateBasicTicketInfo($ticket, $heskSettings) { + $this->init(); + + // Escaped vars + $subject = hesk_dbEscape($ticket->subject); + $message = hesk_dbEscape($ticket->message); + $language = hesk_dbEscape($ticket->language); + $name = hesk_dbEscape($ticket->name); + $email = hesk_dbEscape($ticket->email); + + // Prepare SQL for custom fields + $customSql = ''; + + for ($i=1; $i<=50; $i++) + { + $customSql .= ", `custom{$i}` = '" . (isset($ticket->customFields[$i]) ? hesk_dbEscape($ticket->customFields[$i]) : '') . "'"; + } + + hesk_dbQuery("UPDATE `" . hesk_dbEscape($heskSettings['db_pfix']) . "tickets` + SET `subject` = {$subject}, + `message` = {$message}, + `language` = {$language}, + `name` = {$name}, + `email` = {$email}, + `html` = " . ($ticket->usesHtml ? 1 : 0) . " + {$customSql} + WHERE `id` = " . intval($ticket->id)); + + $this->close(); + } } \ No newline at end of file