TrackingIdGenerator working. Stubbed out todo list for rest of creating ticket

remotes/upstream/api-rewrite
Mike Koch 7 years ago
parent 7e966b93a5
commit 65b10bae3c

@ -40,5 +40,23 @@ class CreateTicketByCustomerModel {
*/
public $customFields;
/**
* @var double[]|null
*/
public $location;
/**
* @var int[]|null
*/
public $suggestedKnowledgebaseArticleIds;
/**
* @var string|null
*/
public $userAgent;
/**
* @var int[]|null
*/
public $screenResolution;
}

@ -0,0 +1,12 @@
<?php
namespace BusinessLogic\Tickets\Exceptions;
use Exception;
class UnableToGenerateTrackingIdException extends Exception {
public function __construct() {
parent::__construct("Error generating a unique ticket ID.");
}
}

@ -32,10 +32,13 @@ class TicketCreator {
}
/**
* Ticket attachments are <b>NOT</b> handled here!
*
* @param $ticketRequest CreateTicketByCustomerModel
* @param $heskSettings array HESK settings
* @param $modsForHeskSettings array Mods for HESK settings
* @throws ValidationException When a required field in $ticket_request is missing
*
*/
function createTicketByCustomer($ticketRequest, $heskSettings, $modsForHeskSettings, $userContext) {
$validationModel = $this->validate($ticketRequest, false, $heskSettings, $modsForHeskSettings, $userContext);
@ -47,6 +50,25 @@ class TicketCreator {
}
// Create the ticket
//-- TODO Get tracking ID
//-- TODO handle message
//-- TODO suggested kb articles
//-- TODO autoassign logic
//-- TODO latitude/longitude
//-- TODO HTML flag
//-- TODO Screen res / user agent
//-- TODO Should ticket validation exist?
//-- TODO Create the ticket
//-- TODO return the freshly created ticket. Any extra stuff the web side does will be handled in submit_ticket.php
}
/**

@ -3,14 +3,134 @@
namespace BusinessLogic\Tickets;
use BusinessLogic\Tickets\Exceptions\UnableToGenerateTrackingIdException;
use DataAccess\Tickets\TicketGateway;
class TrackingIdGenerator {
/**
* @var $ticketGateway TicketGateway
*/
private $ticketGateway;
function __construct($ticketGateway) {
$this->ticketGateway = $ticketGateway;
}
function generateTrackingId() {
/**
* @param $heskSettings array
* @return string
*/
function generateTrackingId($heskSettings) {
$acceptableCharacters = 'AEUYBDGHJLMNPQRSTVWXZ123456789';
/* Generate raw ID */
$trackingId = '';
/* Let's avoid duplicate ticket ID's, try up to 3 times */
for ($i = 1; $i <= 3; $i++) {
for ($i = 0; $i < 10; $i++) {
$trackingId .= $acceptableCharacters[mt_rand(0, 29)];
}
$trackingId = $this->formatTrackingId($trackingId);
/* Check for duplicate IDs */
$ticket = $this->ticketGateway->getTicketByTrackingId($trackingId, $heskSettings);
if ($ticket === null) {
return $trackingId;
}
/* A duplicate ID has been found! Let's try again (up to 2 more) */
$trackingId = '';
}
/* No valid tracking ID, try one more time with microtime() */
$trackingId = $acceptableCharacters[mt_rand(0, 29)];
$trackingId .= $acceptableCharacters[mt_rand(0, 29)];
$trackingId .= $acceptableCharacters[mt_rand(0, 29)];
$trackingId .= $acceptableCharacters[mt_rand(0, 29)];
$trackingId .= $acceptableCharacters[mt_rand(0, 29)];
$trackingId .= substr(microtime(), -5);
/* Format the ID to the correct shape and check wording */
$trackingId = $this->formatTrackingId($trackingId);
$ticket = $this->ticketGateway->getTicketByTrackingId($trackingId, $heskSettings);
if ($ticket === null) {
return $trackingId;
}
throw new UnableToGenerateTrackingIdException();
}
/**
* @param $id string
* @return string
*/
private function formatTrackingId($id) {
$acceptableCharacters = 'AEUYBDGHJLMNPQRSTVWXZ123456789';
$replace = $acceptableCharacters[mt_rand(0, 29)];
$replace .= mt_rand(1, 9);
$replace .= $acceptableCharacters[mt_rand(0, 29)];
/*
Remove 3 letter bad words from ID
Possiblitiy: 1:27,000
*/
$remove = array(
'ASS',
'CUM',
'FAG',
'FUK',
'GAY',
'SEX',
'TIT',
'XXX',
);
$id = str_replace($remove, $replace, $id);
/*
Remove 4 letter bad words from ID
Possiblitiy: 1:810,000
*/
$remove = array(
'ANAL',
'ANUS',
'BUTT',
'CAWK',
'CLIT',
'COCK',
'CRAP',
'CUNT',
'DICK',
'DYKE',
'FART',
'FUCK',
'JAPS',
'JERK',
'JIZZ',
'KNOB',
'PISS',
'POOP',
'SHIT',
'SLUT',
'SUCK',
'TURD',
// Also, remove words that are known to trigger mod_security
'WGET',
);
$replace .= mt_rand(1, 9);
$id = str_replace($remove, $replace, $id);
/* Format the ID string into XXX-XXX-XXXX format for easier readability */
$id = $id[0] . $id[1] . $id[2] . '-' . $id[3] . $id[4] . $id[5] . '-' . $id[6] . $id[7] . $id[8] . $id[9];
return $id;
}
}

@ -7,12 +7,22 @@ use BusinessLogic\Tickets\Ticket;
use DataAccess\CommonDao;
class TicketGateway extends CommonDao {
/**
* @param $id int
* @param $heskSettings array
* @return Ticket|null
*/
function getTicketById($id, $heskSettings) {
$this->init();
$rs = hesk_dbQuery("SELECT * FROM `" . hesk_dbEscape($heskSettings['db_pfix']) . "tickets` WHERE `id` = " . intval($id));
if (hesk_dbNumRows($rs) === 0) {
return null;
}
$row = hesk_dbFetchAssoc($rs);
$linkedTicketsRs = hesk_dbQuery("SELECT * FROM `hesk_tickets` WHERE `parent` = " . intval($id));
$linkedTicketsRs = hesk_dbQuery("SELECT * FROM `" . hesk_dbEscape($heskSettings['db_pfix']) . "tickets` WHERE `parent` = " . intval($id));
$ticket = Ticket::fromDatabaseRow($row, $linkedTicketsRs, $heskSettings);
@ -21,16 +31,55 @@ class TicketGateway extends CommonDao {
return $ticket;
}
/**
* @param $emailAddress string
* @param $heskSettings array
* @return array|null
*/
function getTicketsByEmail($emailAddress, $heskSettings) {
$this->init();
$rs = hesk_dbQuery("SELECT * FROM `" . hesk_dbEscape($heskSettings['db_pfix']) . "tickets`
WHERE `email` = '" . hesk_dbEscape($emailAddress) . "'");
if (hesk_dbNumRows($rs) === 0) {
return null;
}
$tickets = array();
while ($row = hesk_dbFetchAssoc($rs)) {
$ticket = new Ticket();
$linkedTicketsRs =
hesk_dbQuery("SELECT * FROM `" . hesk_dbEscape($heskSettings['db_pfix']) . "tickets` WHERE `parent` = " . intval($row['id']));
//-- TODO Finish this!
$tickets[] = Ticket::fromDatabaseRow($row, $linkedTicketsRs, $heskSettings);
}
$this->close();
return $tickets;
}
/**
* @param $trackingId string
* @param $heskSettings array
* @return Ticket|null
*/
function getTicketByTrackingId($trackingId, $heskSettings) {
$this->init();
$rs = hesk_dbQuery("SELECT * FROM `" . hesk_dbEscape($heskSettings['db_pfix']) . "tickets` WHERE `id` = " . intval($trackingId));
if (hesk_dbNumRows($rs) === 0) {
return null;
}
$row = hesk_dbFetchAssoc($rs);
$linkedTicketsRs = hesk_dbQuery("SELECT * FROM `" . hesk_dbEscape($heskSettings['db_pfix']) . "tickets` WHERE `parent` = " . intval($trackingId));
$ticket = Ticket::fromDatabaseRow($row, $linkedTicketsRs, $heskSettings);
$this->close();
return $ticket;
}
}

@ -9,6 +9,7 @@
namespace BusinessLogic\Tickets;
use BusinessLogic\Tickets\Exceptions\UnableToGenerateTrackingIdException;
use DataAccess\Tickets\TicketGateway;
use PHPUnit\Framework\TestCase;
@ -18,6 +19,9 @@ class TrackingIdGeneratorTest extends TestCase {
*/
private $ticketGateway;
/**
* @var $trackingIdGenerator TrackingIdGenerator
*/
private $trackingIdGenerator;
function setUp() {
@ -28,10 +32,35 @@ class TrackingIdGeneratorTest extends TestCase {
function testItReturnsTrackingIdInTheProperFormat() {
//-- Arrange
$format = '';
$this->ticketGateway->method('getTicketByTrackingId')
->willReturn(null);
$acceptableCharacters = '[AEUYBDGHJLMNPQRSTVWXZ123456789]';
$format = "/^{$acceptableCharacters}{3}-{$acceptableCharacters}{3}-{$acceptableCharacters}{4}$/";
//-- Act
$trackingId = $this->trackingIdGenerator->generateTrackingId(array());
//-- Assert
$this->assertThat($trackingId, $this->matchesRegularExpression($format));
}
function testItThrowsAnExceptionWhenItWasUnableToGenerateAValidTrackingId() {
//-- Arrange
$exceptionThrown = false;
$this->ticketGateway->method('getTicketByTrackingId')
->willReturn(new Ticket());
//-- Act
try {
$this->trackingIdGenerator->generateTrackingId(array());
} catch (UnableToGenerateTrackingIdException $e) {
//-- Assert (1/2)
$exceptionThrown = true;
}
//-- Assert (2/2)
$this->assertThat($exceptionThrown, $this->isTrue());
}
//-- Trying to test the database logic is tricky, so no tests here.
}

Loading…
Cancel
Save