diff --git a/api/BusinessLogic/Emails/EmailSenderHelper.php b/api/BusinessLogic/Emails/EmailSenderHelper.php index 1724dc25..b02453ab 100644 --- a/api/BusinessLogic/Emails/EmailSenderHelper.php +++ b/api/BusinessLogic/Emails/EmailSenderHelper.php @@ -29,13 +29,15 @@ class EmailSenderHelper { /** * @param $templateId int the EmailTemplateRetriever::TEMPLATE_NAME - * @param $languageCode string the language code that matches the language folder + * @param $language string the language name * @param $addressees Addressees the addressees. **cc and bcc addresses from custom fields will be added here!** * @param $ticket Ticket * @param $heskSettings array * @param $modsForHeskSettings array */ - function sendEmailForTicket($templateId, $languageCode, $addressees, $ticket, $heskSettings, $modsForHeskSettings) { + function sendEmailForTicket($templateId, $language, $addressees, $ticket, $heskSettings, $modsForHeskSettings) { + $languageCode = $heskSettings['languages'][$language]['folder']; + $parsedTemplate = $this->emailTemplateParser->getFormattedEmailForLanguage($templateId, $languageCode, $ticket, $heskSettings, $modsForHeskSettings); diff --git a/api/BusinessLogic/Tickets/TicketCreator.php b/api/BusinessLogic/Tickets/TicketCreator.php index 25e4ba22..46a17589 100644 --- a/api/BusinessLogic/Tickets/TicketCreator.php +++ b/api/BusinessLogic/Tickets/TicketCreator.php @@ -2,9 +2,12 @@ namespace BusinessLogic\Tickets; +use BusinessLogic\Emails\Addressees; use BusinessLogic\Emails\EmailSenderHelper; +use BusinessLogic\Emails\EmailTemplateRetriever; use BusinessLogic\Exceptions\ValidationException; use BusinessLogic\Statuses\DefaultStatusForAction; +use DataAccess\Security\UserGateway; use DataAccess\Statuses\StatusGateway; use DataAccess\Tickets\TicketGateway; @@ -44,8 +47,13 @@ class TicketCreator { */ private $emailSenderHelper; + /** + * @var $userGateway UserGateway + */ + private $userGateway; + function __construct($newTicketValidator, $trackingIdGenerator, $autoassigner, - $statusGateway, $ticketGateway, $verifiedEmailChecker, $emailSenderHelper) { + $statusGateway, $ticketGateway, $verifiedEmailChecker, $emailSenderHelper, $userGateway) { $this->newTicketValidator = $newTicketValidator; $this->trackingIdGenerator = $trackingIdGenerator; $this->autoassigner = $autoassigner; @@ -53,6 +61,7 @@ class TicketCreator { $this->ticketGateway = $ticketGateway; $this->verifiedEmailChecker = $verifiedEmailChecker; $this->emailSenderHelper = $emailSenderHelper; + $this->userGateway = $userGateway; } /** @@ -126,6 +135,31 @@ class TicketCreator { $ticket->timeWorked = '00:00:00'; $ticket->lastReplier = 0; + $addressees = new Addressees(); + $addressees->to = $this->getAddressees($ticket->email); + + if ($ticketRequest->sendEmailToCustomer) { + $this->emailSenderHelper->sendEmailForTicket(EmailTemplateRetriever::NEW_TICKET, $ticketRequest->language, $addressees, $ticket, $heskSettings, $modsForHeskSettings); + } + + if ($ticket->ownerId !== null) { + $ownerEmail = $this->userGateway->getEmailForId($ticket->ownerId, $heskSettings); + + $addressees = new Addressees(); + $addressees->to = array($ownerEmail); + $this->emailSenderHelper->sendEmailForTicket(EmailTemplateRetriever::TICKET_ASSIGNED_TO_YOU, $ticketRequest->language, $addressees, $ticket, $heskSettings, $modsForHeskSettings); + } + return $ticket; } + + private function getAddressees($emailAddress) { + if ($emailAddress === null) { + return null; + } + + $emails = str_replace(';', ',', $emailAddress); + + return explode(',', $emails); + } } \ No newline at end of file diff --git a/api/DataAccess/Security/UserGateway.php b/api/DataAccess/Security/UserGateway.php index b44be8b5..be6e43ff 100644 --- a/api/DataAccess/Security/UserGateway.php +++ b/api/DataAccess/Security/UserGateway.php @@ -46,4 +46,19 @@ class UserGateway extends CommonDao { return $row['name']; } + + // TODO Replace this with a basic User retriever + function getEmailForId($id, $heskSettings) { + $this->init(); + + $rs = hesk_dbQuery("SELECT `email` FROM `" . hesk_dbEscape($heskSettings['db_pfix']) . "users` WHERE `id` = " . intval($id)); + + if (hesk_dbNumRows($rs) === 0) { + return null; + } + + $row = hesk_dbFetchAssoc($rs); + + return $row['email']; + } } \ No newline at end of file diff --git a/api/Tests/BusinessLogic/Emails/EmailSenderHelperTest.php b/api/Tests/BusinessLogic/Emails/EmailSenderHelperTest.php index 050abcb3..c9d5c0cb 100644 --- a/api/Tests/BusinessLogic/Emails/EmailSenderHelperTest.php +++ b/api/Tests/BusinessLogic/Emails/EmailSenderHelperTest.php @@ -42,6 +42,9 @@ class EmailSenderHelperTest extends TestCase { $this->basicEmailSender = $this->createMock(BasicEmailSender::class); $this->mailgunEmailSender = $this->createMock(MailgunEmailSender::class); $this->heskSettings = array( + 'languages' => array( + 'English' => array('folder' => 'en') + ), 'custom_fields' => array() ); $this->modsForHeskSettings = array( @@ -67,7 +70,7 @@ class EmailSenderHelperTest extends TestCase { ->with($templateId, $languageCode, $ticket, $this->heskSettings, $this->modsForHeskSettings); //-- Act - $this->emailSenderHelper->sendEmailForTicket($templateId, $languageCode, new Addressees(), $ticket, $this->heskSettings, $this->modsForHeskSettings); + $this->emailSenderHelper->sendEmailForTicket($templateId, 'English', new Addressees(), $ticket, $this->heskSettings, $this->modsForHeskSettings); } function testItSendsTheEmailThroughTheMailgunEmailSender() { @@ -95,7 +98,7 @@ class EmailSenderHelperTest extends TestCase { ->with($expectedEmailBuilder, $this->heskSettings, $this->modsForHeskSettings, true); //-- Act - $this->emailSenderHelper->sendEmailForTicket(EmailTemplateRetriever::NEW_NOTE, 'en', $addressees, new Ticket(), $this->heskSettings, $this->modsForHeskSettings); + $this->emailSenderHelper->sendEmailForTicket(EmailTemplateRetriever::NEW_NOTE, 'English', $addressees, new Ticket(), $this->heskSettings, $this->modsForHeskSettings); } function testItSendsTheEmailThroughTheBasicEmailSender() { @@ -123,6 +126,6 @@ class EmailSenderHelperTest extends TestCase { ->with($expectedEmailBuilder, $this->heskSettings, $this->modsForHeskSettings, true); //-- Act - $this->emailSenderHelper->sendEmailForTicket(EmailTemplateRetriever::NEW_NOTE, 'en', $addressees, new Ticket(), $this->heskSettings, $this->modsForHeskSettings); + $this->emailSenderHelper->sendEmailForTicket(EmailTemplateRetriever::NEW_NOTE, 'English', $addressees, new Ticket(), $this->heskSettings, $this->modsForHeskSettings); } } diff --git a/api/Tests/BusinessLogic/Tickets/TicketCreatorTests/CreateTicketForCustomerTest.php b/api/Tests/BusinessLogic/Tickets/TicketCreatorTests/CreateTicketForCustomerTest.php index 65e8110b..23ab848c 100644 --- a/api/Tests/BusinessLogic/Tickets/TicketCreatorTests/CreateTicketForCustomerTest.php +++ b/api/Tests/BusinessLogic/Tickets/TicketCreatorTests/CreateTicketForCustomerTest.php @@ -116,7 +116,7 @@ class CreateTicketTest extends TestCase { 'require_subject' => 1, 'require_message' => 1, 'custom_fields' => array(), - 'autoassign' => 0, + 'autoassign' => 0 ); $this->modsForHeskSettings = array( 'customer_email_verification_required' => false @@ -260,12 +260,42 @@ class CreateTicketTest extends TestCase { function testItSendsAnEmailToTheCustomerWhenTheTicketIsCreated() { //-- Arrange $this->ticketRequest->sendEmailToCustomer = true; + $this->ticketRequest->language = 'English'; $expectedAddressees = new Addressees(); - $expectedAddressees->to = $this->ticketRequest->email; + $expectedAddressees->to = array($this->ticketRequest->email); //-- Assert $this->emailSenderHelper->expects($this->once())->method('sendEmailForTicket') - ->with(EmailTemplateRetriever::NEW_TICKET, 'en', $this->anything(), $this->heskSettings, $this->modsForHeskSettings); + ->with(EmailTemplateRetriever::NEW_TICKET, 'English', $expectedAddressees, $this->anything(), $this->heskSettings, $this->modsForHeskSettings); + + //-- Act + $this->ticketCreator->createTicketByCustomer($this->ticketRequest, $this->heskSettings, $this->modsForHeskSettings, $this->userContext); + } + + function testItDoesNotSendsAnEmailToTheCustomerWhenTheTicketIsCreatedAndSendToCustomerIsFalse() { + //-- Arrange + $this->ticketRequest->sendEmailToCustomer = false; + $this->ticketRequest->language = 'English'; + $expectedAddressees = new Addressees(); + $expectedAddressees->to = array($this->ticketRequest->email); + + //-- Assert + $this->emailSenderHelper->expects($this->never())->method('sendEmailForTicket'); + + //-- Act + $this->ticketCreator->createTicketByCustomer($this->ticketRequest, $this->heskSettings, $this->modsForHeskSettings, $this->userContext); + } + + function testItSendsAnEmailToTheAssignedToOwnerWhenTheTicketIsCreated() { + //-- Arrange + $this->ticketRequest->sendEmailToCustomer = true; + $this->ticketRequest->language = 'English'; + $expectedAddressees = new Addressees(); + $expectedAddressees->to = array($this->ticketRequest->email); + + //-- Assert + $this->emailSenderHelper->expects($this->once())->method('sendEmailForTicket') + ->with(EmailTemplateRetriever::NEW_TICKET, 'English', $expectedAddressees, $this->anything(), $this->heskSettings, $this->modsForHeskSettings); //-- Act $this->ticketCreator->createTicketByCustomer($this->ticketRequest, $this->heskSettings, $this->modsForHeskSettings, $this->userContext); diff --git a/api/autoload.php b/api/autoload.php index 5ffee38e..acdb59e9 100644 --- a/api/autoload.php +++ b/api/autoload.php @@ -14,9 +14,16 @@ require_once(__DIR__ . '/http_response_code.php'); hesk_load_api_database_functions(); +global $hesk_settings; + // HESK files that require database access require_once(__DIR__ . '/../inc/custom_fields.inc.php'); +// Load Spot ORM +$config = new \Spot\Config(); +$config->addConnection('mysql', "mysql://{$hesk_settings['db_user']}:{$hesk_settings['db_pass']}@{$hesk_settings['db_host']}/{$hesk_settings['db_name']}"); +$spot = new \Spot\Locator($config); + // Load the ApplicationContext $applicationContext = new \ApplicationContext(); //$modsForHeskSettings = mfh_getSettings(); \ No newline at end of file diff --git a/api/composer.json b/api/composer.json index f79dd05d..3c793199 100644 --- a/api/composer.json +++ b/api/composer.json @@ -17,6 +17,6 @@ "php-http/message": "^1.5", "php-http/curl-client": "^1.7", "guzzlehttp/psr7": "^1.3", - "doctrine/orm": "*" + "vlucas/spot2": "~2.0" } } diff --git a/api/composer.lock b/api/composer.lock index 1048b547..7ac81d56 100644 --- a/api/composer.lock +++ b/api/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "content-hash": "d7fe662ac2836f7d979fd4117ec8bca6", + "content-hash": "266b9167ab52abc3c4a2514bf29491ed", "packages": [ { "name": "clue/stream-filter", @@ -55,6 +55,422 @@ ], "time": "2015-11-08T23:41:30+00:00" }, + { + "name": "doctrine/annotations", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/doctrine/annotations.git", + "reference": "54cacc9b81758b14e3ce750f205a393d52339e97" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/annotations/zipball/54cacc9b81758b14e3ce750f205a393d52339e97", + "reference": "54cacc9b81758b14e3ce750f205a393d52339e97", + "shasum": "" + }, + "require": { + "doctrine/lexer": "1.*", + "php": "^5.6 || ^7.0" + }, + "require-dev": { + "doctrine/cache": "1.*", + "phpunit/phpunit": "^5.7" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Common\\Annotations\\": "lib/Doctrine/Common/Annotations" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "Docblock Annotations Parser", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "annotations", + "docblock", + "parser" + ], + "time": "2017-02-24 16:22:25" + }, + { + "name": "doctrine/cache", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/doctrine/cache.git", + "reference": "0da649fce4838f7a6121c501c9a86d4b8921b648" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/cache/zipball/0da649fce4838f7a6121c501c9a86d4b8921b648", + "reference": "0da649fce4838f7a6121c501c9a86d4b8921b648", + "shasum": "" + }, + "require": { + "php": "~5.6|~7.0" + }, + "conflict": { + "doctrine/common": ">2.2,<2.4" + }, + "require-dev": { + "phpunit/phpunit": "^5.7", + "predis/predis": "~1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.7.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Common\\Cache\\": "lib/Doctrine/Common/Cache" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "Caching library offering an object-oriented API for many cache backends", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "cache", + "caching" + ], + "time": "2017-03-06 14:38:51" + }, + { + "name": "doctrine/collections", + "version": "v1.4.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/collections.git", + "reference": "1a4fb7e902202c33cce8c55989b945612943c2ba" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/collections/zipball/1a4fb7e902202c33cce8c55989b945612943c2ba", + "reference": "1a4fb7e902202c33cce8c55989b945612943c2ba", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0" + }, + "require-dev": { + "doctrine/coding-standard": "~0.1@dev", + "phpunit/phpunit": "^5.7" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3.x-dev" + } + }, + "autoload": { + "psr-0": { + "Doctrine\\Common\\Collections\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "Collections Abstraction library", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "array", + "collections", + "iterator" + ], + "time": "2017-01-03T10:49:41+00:00" + }, + { + "name": "doctrine/common", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/doctrine/common.git", + "reference": "4b434dbf8d204198dac708f2e938f7c805864dd6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/common/zipball/4b434dbf8d204198dac708f2e938f7c805864dd6", + "reference": "4b434dbf8d204198dac708f2e938f7c805864dd6", + "shasum": "" + }, + "require": { + "doctrine/annotations": "1.*", + "doctrine/cache": "1.*", + "doctrine/collections": "1.*", + "doctrine/inflector": "1.*", + "doctrine/lexer": "1.*", + "php": "~5.6|~7.0" + }, + "require-dev": { + "phpunit/phpunit": "^5.7" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.8.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Common\\": "lib/Doctrine/Common" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "Common Library for Doctrine projects", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "annotations", + "collections", + "eventmanager", + "persistence", + "spl" + ], + "time": "2017-03-06 07:30:42" + }, + { + "name": "doctrine/dbal", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/doctrine/dbal.git", + "reference": "50bf623418be0feb3282bb50d07a4aea977fb33a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/dbal/zipball/50bf623418be0feb3282bb50d07a4aea977fb33a", + "reference": "50bf623418be0feb3282bb50d07a4aea977fb33a", + "shasum": "" + }, + "require": { + "doctrine/common": "^2.7.1", + "php": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^5.4.6", + "phpunit/phpunit-mock-objects": "!=3.2.4,!=3.2.5", + "symfony/console": "2.*||^3.0" + }, + "suggest": { + "symfony/console": "For helpful console commands such as SQL execution and import of files." + }, + "bin": [ + "bin/doctrine-dbal" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.6.x-dev" + } + }, + "autoload": { + "psr-0": { + "Doctrine\\DBAL\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + } + ], + "description": "Database Abstraction Layer", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "database", + "dbal", + "persistence", + "queryobject" + ], + "time": "2017-02-25 22:09:19" + }, + { + "name": "doctrine/inflector", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/doctrine/inflector.git", + "reference": "803a2ed9fea02f9ca47cd45395089fe78769a392" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/inflector/zipball/803a2ed9fea02f9ca47cd45395089fe78769a392", + "reference": "803a2ed9fea02f9ca47cd45395089fe78769a392", + "shasum": "" + }, + "require": { + "php": ">=5.3.2" + }, + "require-dev": { + "phpunit/phpunit": "4.*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1.x-dev" + } + }, + "autoload": { + "psr-0": { + "Doctrine\\Common\\Inflector\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "Common String Manipulations with regard to casing and singular/plural rules.", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "inflection", + "pluralize", + "singularize", + "string" + ], + "time": "2016-05-12 17:23:41" + }, { "name": "doctrine/instantiator", "version": "dev-master", @@ -109,6 +525,60 @@ ], "time": "2017-01-23 09:23:06" }, + { + "name": "doctrine/lexer", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/doctrine/lexer.git", + "reference": "83893c552fd2045dd78aef794c31e694c37c0b8c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/lexer/zipball/83893c552fd2045dd78aef794c31e694c37c0b8c", + "reference": "83893c552fd2045dd78aef794c31e694c37c0b8c", + "shasum": "" + }, + "require": { + "php": ">=5.3.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-0": { + "Doctrine\\Common\\Lexer\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "Base library for a lexer that can be used in Top-Down, Recursive Descent Parsers.", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "lexer", + "parser" + ], + "time": "2014-09-09 13:34:57" + }, { "name": "guzzle/guzzle", "version": "dev-master", @@ -1636,6 +2106,57 @@ ], "time": "2016-08-06 14:39:51" }, + { + "name": "sabre/event", + "version": "2.0.x-dev", + "source": { + "type": "git", + "url": "https://github.com/fruux/sabre-event.git", + "reference": "337b6f5e10ea6e0b21e22c7e5788dd3883ae73ff" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/fruux/sabre-event/zipball/337b6f5e10ea6e0b21e22c7e5788dd3883ae73ff", + "reference": "337b6f5e10ea6e0b21e22c7e5788dd3883ae73ff", + "shasum": "" + }, + "require": { + "php": ">=5.4.1" + }, + "require-dev": { + "phpunit/phpunit": "*", + "sabre/cs": "~0.0.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Sabre\\Event\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Evert Pot", + "email": "me@evertpot.com", + "homepage": "http://evertpot.com/", + "role": "Developer" + } + ], + "description": "sabre/event is a library for lightweight event-based programming", + "homepage": "http://sabre.io/event/", + "keywords": [ + "EventEmitter", + "events", + "hooks", + "plugin", + "promise", + "signal" + ], + "time": "2015-05-19 10:24:22" + }, { "name": "sebastian/code-unit-reverse-lookup", "version": "dev-master", @@ -2264,6 +2785,104 @@ "homepage": "https://symfony.com", "time": "2017-01-21 17:10:26" }, + { + "name": "vlucas/spot2", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/vlucas/spot2.git", + "reference": "f30e5439c1c8d969490d773bc3f87937e675083a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/vlucas/spot2/zipball/f30e5439c1c8d969490d773bc3f87937e675083a", + "reference": "f30e5439c1c8d969490d773bc3f87937e675083a", + "shasum": "" + }, + "require": { + "doctrine/dbal": "~2.4", + "php": ">=5.4", + "sabre/event": "~2.0", + "vlucas/valitron": "1.x" + }, + "type": "library", + "autoload": { + "psr-0": { + "Spot": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD" + ], + "authors": [ + { + "name": "Vance Lucas", + "email": "vance@vancelucas.com", + "homepage": "http://www.vancelucas.com", + "role": "Developer" + } + ], + "description": "Simple DataMapper built on top of Doctrine DBAL", + "homepage": "https://github.com/vlucas/spot2", + "keywords": [ + "database", + "datamapper", + "dbal", + "doctrine", + "entity", + "mapper", + "model", + "orm" + ], + "time": "2014-07-03T14:29:08+00:00" + }, + { + "name": "vlucas/valitron", + "version": "v1.4.0", + "source": { + "type": "git", + "url": "https://github.com/vlucas/valitron.git", + "reference": "b33c79116260637337187b7125f955ae26d306cc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/vlucas/valitron/zipball/b33c79116260637337187b7125f955ae26d306cc", + "reference": "b33c79116260637337187b7125f955ae26d306cc", + "shasum": "" + }, + "require": { + "php": ">=5.3.2" + }, + "require-dev": { + "phpunit/phpunit": "~4.0" + }, + "type": "library", + "autoload": { + "psr-0": { + "Valitron": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD" + ], + "authors": [ + { + "name": "Vance Lucas", + "email": "vance@vancelucas.com", + "homepage": "http://www.vancelucas.com" + } + ], + "description": "Simple, elegant, stand-alone validation library with NO dependencies", + "homepage": "http://github.com/vlucas/valitron", + "keywords": [ + "valid", + "validation", + "validator" + ], + "time": "2017-02-23T08:31:59+00:00" + }, { "name": "webmozart/assert", "version": "dev-master",