TrackingIdGenerator working. Stubbed out todo list for rest of creating ticket
This commit is contained in:
parent
7e966b93a5
commit
65b10bae3c
@ -40,5 +40,23 @@ class CreateTicketByCustomerModel {
|
|||||||
*/
|
*/
|
||||||
public $customFields;
|
public $customFields;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var double[]|null
|
||||||
|
*/
|
||||||
public $location;
|
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 $ticketRequest CreateTicketByCustomerModel
|
||||||
* @param $heskSettings array HESK settings
|
* @param $heskSettings array HESK settings
|
||||||
* @param $modsForHeskSettings array Mods for HESK settings
|
* @param $modsForHeskSettings array Mods for HESK settings
|
||||||
* @throws ValidationException When a required field in $ticket_request is missing
|
* @throws ValidationException When a required field in $ticket_request is missing
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
function createTicketByCustomer($ticketRequest, $heskSettings, $modsForHeskSettings, $userContext) {
|
function createTicketByCustomer($ticketRequest, $heskSettings, $modsForHeskSettings, $userContext) {
|
||||||
$validationModel = $this->validate($ticketRequest, false, $heskSettings, $modsForHeskSettings, $userContext);
|
$validationModel = $this->validate($ticketRequest, false, $heskSettings, $modsForHeskSettings, $userContext);
|
||||||
@ -47,6 +50,25 @@ class TicketCreator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create the ticket
|
// 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;
|
namespace BusinessLogic\Tickets;
|
||||||
|
|
||||||
|
|
||||||
|
use BusinessLogic\Tickets\Exceptions\UnableToGenerateTrackingIdException;
|
||||||
|
use DataAccess\Tickets\TicketGateway;
|
||||||
|
|
||||||
class TrackingIdGenerator {
|
class TrackingIdGenerator {
|
||||||
|
/**
|
||||||
|
* @var $ticketGateway TicketGateway
|
||||||
|
*/
|
||||||
private $ticketGateway;
|
private $ticketGateway;
|
||||||
|
|
||||||
function __construct($ticketGateway) {
|
function __construct($ticketGateway) {
|
||||||
$this->ticketGateway = $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;
|
use DataAccess\CommonDao;
|
||||||
|
|
||||||
class TicketGateway extends CommonDao {
|
class TicketGateway extends CommonDao {
|
||||||
|
/**
|
||||||
|
* @param $id int
|
||||||
|
* @param $heskSettings array
|
||||||
|
* @return Ticket|null
|
||||||
|
*/
|
||||||
function getTicketById($id, $heskSettings) {
|
function getTicketById($id, $heskSettings) {
|
||||||
$this->init();
|
$this->init();
|
||||||
|
|
||||||
$rs = hesk_dbQuery("SELECT * FROM `" . hesk_dbEscape($heskSettings['db_pfix']) . "tickets` WHERE `id` = " . intval($id));
|
$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);
|
$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);
|
$ticket = Ticket::fromDatabaseRow($row, $linkedTicketsRs, $heskSettings);
|
||||||
|
|
||||||
@ -21,16 +31,55 @@ class TicketGateway extends CommonDao {
|
|||||||
return $ticket;
|
return $ticket;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $emailAddress string
|
||||||
|
* @param $heskSettings array
|
||||||
|
* @return array|null
|
||||||
|
*/
|
||||||
function getTicketsByEmail($emailAddress, $heskSettings) {
|
function getTicketsByEmail($emailAddress, $heskSettings) {
|
||||||
|
$this->init();
|
||||||
|
|
||||||
$rs = hesk_dbQuery("SELECT * FROM `" . hesk_dbEscape($heskSettings['db_pfix']) . "tickets`
|
$rs = hesk_dbQuery("SELECT * FROM `" . hesk_dbEscape($heskSettings['db_pfix']) . "tickets`
|
||||||
WHERE `email` = '" . hesk_dbEscape($emailAddress) . "'");
|
WHERE `email` = '" . hesk_dbEscape($emailAddress) . "'");
|
||||||
|
|
||||||
|
if (hesk_dbNumRows($rs) === 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
$tickets = array();
|
$tickets = array();
|
||||||
|
|
||||||
while ($row = hesk_dbFetchAssoc($rs)) {
|
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;
|
namespace BusinessLogic\Tickets;
|
||||||
|
|
||||||
|
|
||||||
|
use BusinessLogic\Tickets\Exceptions\UnableToGenerateTrackingIdException;
|
||||||
use DataAccess\Tickets\TicketGateway;
|
use DataAccess\Tickets\TicketGateway;
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
@ -18,6 +19,9 @@ class TrackingIdGeneratorTest extends TestCase {
|
|||||||
*/
|
*/
|
||||||
private $ticketGateway;
|
private $ticketGateway;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var $trackingIdGenerator TrackingIdGenerator
|
||||||
|
*/
|
||||||
private $trackingIdGenerator;
|
private $trackingIdGenerator;
|
||||||
|
|
||||||
function setUp() {
|
function setUp() {
|
||||||
@ -28,10 +32,35 @@ class TrackingIdGeneratorTest extends TestCase {
|
|||||||
|
|
||||||
function testItReturnsTrackingIdInTheProperFormat() {
|
function testItReturnsTrackingIdInTheProperFormat() {
|
||||||
//-- Arrange
|
//-- Arrange
|
||||||
$format = '';
|
$this->ticketGateway->method('getTicketByTrackingId')
|
||||||
|
->willReturn(null);
|
||||||
|
$acceptableCharacters = '[AEUYBDGHJLMNPQRSTVWXZ123456789]';
|
||||||
|
$format = "/^{$acceptableCharacters}{3}-{$acceptableCharacters}{3}-{$acceptableCharacters}{4}$/";
|
||||||
|
|
||||||
//-- Act
|
//-- Act
|
||||||
|
$trackingId = $this->trackingIdGenerator->generateTrackingId(array());
|
||||||
|
|
||||||
//-- Assert
|
//-- 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…
x
Reference in New Issue
Block a user