diff --git a/Drivers/AbstractDriver.php b/Drivers/AbstractDriver.php
index 17c5d0f..8a71ced 100644
--- a/Drivers/AbstractDriver.php
+++ b/Drivers/AbstractDriver.php
@@ -2,6 +2,11 @@
namespace Lexik\Bundle\MaintenanceBundle\Drivers;
+use Lexik\Bundle\MaintenanceBundle\Event\PostLockEvent;
+use Lexik\Bundle\MaintenanceBundle\Event\PostUnlockEvent;
+use Lexik\Bundle\MaintenanceBundle\Event\PreLockEvent;
+use Lexik\Bundle\MaintenanceBundle\Event\PreUnlockEvent;
+use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\Translation\TranslatorInterface;
/**
@@ -22,6 +27,11 @@ abstract class AbstractDriver
*/
protected $translator;
+ /**
+ * @var EventDispatcherInterface
+ */
+ private $eventDispatcher;
+
/**
* Constructor
*
@@ -76,10 +86,14 @@ abstract public function getMessageUnlock($resultTest);
*
* @return boolean
*/
- public function lock()
+ final public function lock()
{
if (!$this->isExists()) {
- return $this->createLock();
+ $this->eventDispatcher->dispatch(PreLockEvent::NAME, new PreLockEvent());
+ $success = $this->createLock();
+ $this->eventDispatcher->dispatch(PostLockEvent::NAME, new PostLockEvent($success));
+
+ return $success;
} else {
return false;
}
@@ -90,10 +104,14 @@ public function lock()
*
* @return boolean
*/
- public function unlock()
+ final public function unlock()
{
if ($this->isExists()) {
- return $this->createUnlock();
+ $this->eventDispatcher->dispatch(PreUnlockEvent::NAME, new PreUnlockEvent());
+ $success = $this->createUnlock();
+ $this->eventDispatcher->dispatch(PostUnlockEvent::NAME, new PostUnlockEvent($success));
+
+ return $success;
} else {
return false;
}
@@ -128,4 +146,15 @@ public function setTranslator(TranslatorInterface $translator)
{
$this->translator = $translator;
}
+
+ /**
+ * @param EventDispatcherInterface $eventDispatcher
+ * @return AbstractDriver
+ */
+ public function setEventDispatcher(EventDispatcherInterface $eventDispatcher)
+ {
+ $this->eventDispatcher = $eventDispatcher;
+
+ return $this;
+ }
}
diff --git a/Drivers/DriverFactory.php b/Drivers/DriverFactory.php
index 3a71523..195f9c2 100644
--- a/Drivers/DriverFactory.php
+++ b/Drivers/DriverFactory.php
@@ -4,6 +4,7 @@
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Bundle\FrameworkBundle\Translation\Translator;
+use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\Translation\TranslatorInterface;
/**
@@ -29,17 +30,23 @@ class DriverFactory
*/
protected $translator;
+ /**
+ * @var EventDispatcherInterface
+ */
+ protected $eventDispatcher;
+
const DATABASE_DRIVER = 'Lexik\Bundle\MaintenanceBundle\Drivers\DatabaseDriver';
/**
* Constructor driver factory
*
- * @param DatabaseDriver $dbDriver The databaseDriver Service
- * @param TranslatorInterface $translator The translator service
- * @param array $driverOptions Options driver
+ * @param DatabaseDriver $dbDriver The databaseDriver Service
+ * @param TranslatorInterface $translator The translator service
+ * @param EventDispatcherInterface $eventDispatcher Event Dispatcher
+ * @param array $driverOptions Options driver
* @throws \ErrorException
*/
- public function __construct(DatabaseDriver $dbDriver, TranslatorInterface $translator, array $driverOptions)
+ public function __construct(DatabaseDriver $dbDriver, TranslatorInterface $translator, EventDispatcherInterface $eventDispatcher, array $driverOptions)
{
$this->driverOptions = $driverOptions;
@@ -49,6 +56,7 @@ public function __construct(DatabaseDriver $dbDriver, TranslatorInterface $trans
$this->dbDriver = $dbDriver;
$this->translator = $translator;
+ $this->eventDispatcher = $eventDispatcher;
}
/**
@@ -73,6 +81,7 @@ public function getDriver()
}
$driver->setTranslator($this->translator);
+ $driver->setEventDispatcher($this->eventDispatcher);
return $driver;
}
diff --git a/Drivers/MemcachedDriver.php b/Drivers/MemcachedDriver.php
new file mode 100644
index 0000000..d091d15
--- /dev/null
+++ b/Drivers/MemcachedDriver.php
@@ -0,0 +1,156 @@
+key = $options['key'];
+ // TODO: A configured Memcached instance should be injected into the constructor for easier testing.
+ $this->setMemcached(new \Memcached());
+ foreach ($options['servers'] as $server) {
+ if (isset($server['host']) === false) {
+ throw new \InvalidArgumentException('Option "host" must be defined for each server if driver Memcached configuration is used');
+ }
+
+ if (isset($server['port']) === false || is_int($server['port']) === false) {
+ throw new \InvalidArgumentException('Option "port" must be defined as an integer for each server if driver Memcached configuration is used');
+ }
+
+ $this->getMemcached()->addServer($server['host'], $server['port']);
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function isExists()
+ {
+ if (false !== $this->getMemcached()->get($this->key)) {
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getMessageLock($resultTest)
+ {
+ $key = $resultTest ? 'lexik_maintenance.success_lock_memc' : 'lexik_maintenance.not_success_lock';
+
+ return $this->translator->trans($key, array(), 'maintenance');
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getMessageUnlock($resultTest)
+ {
+ $key = $resultTest ? 'lexik_maintenance.success_unlock' : 'lexik_maintenance.not_success_unlock';
+
+ return $this->translator->trans($key, array(), 'maintenance');
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setTtl($value)
+ {
+ $this->options['ttl'] = $value;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getTtl()
+ {
+ return $this->options['ttl'];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function hasTtl()
+ {
+ return isset($this->options['ttl']);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function createLock()
+ {
+ return $this->getMemcached()->set($this->key, self::VALUE_TO_STORE, (isset($this->options['ttl']) ? $this->options['ttl'] : 0));
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function createUnlock()
+ {
+ return $this->getMemcached()->delete($this->key);
+ }
+
+ /**
+ * @return \Memcached
+ */
+ private function getMemcached()
+ {
+ return $this->memcached;
+ }
+
+ /**
+ * @param \Memcached $memcached
+ * @return MemcachedDriver
+ */
+ private function setMemcached($memcached)
+ {
+ $this->memcached = $memcached;
+
+ return $this;
+ }
+}
diff --git a/Event/AbstractEvent.php b/Event/AbstractEvent.php
new file mode 100644
index 0000000..882378e
--- /dev/null
+++ b/Event/AbstractEvent.php
@@ -0,0 +1,15 @@
+setSuccess($success);
+ }
+
+ /**
+ * @return bool
+ */
+ public function isSuccess()
+ {
+ return $this->success;
+ }
+
+ /**
+ * @param bool $success
+ * @return AbstractPostEvent
+ */
+ private function setSuccess($success)
+ {
+ $this->success = $success;
+
+ return $this;
+ }
+}
diff --git a/Event/PostLockEvent.php b/Event/PostLockEvent.php
new file mode 100644
index 0000000..526a9a7
--- /dev/null
+++ b/Event/PostLockEvent.php
@@ -0,0 +1,13 @@
+
+
%lexik_maintenance.driver%
diff --git a/Resources/doc/index.md b/Resources/doc/index.md
index dcf556e..2d4c262 100644
--- a/Resources/doc/index.md
+++ b/Resources/doc/index.md
@@ -99,6 +99,19 @@ Or (with the optional ttl overwriting)
---------------------
+### Events
+
+Events are thrown before and after locking and unlocking of the site, so that you can easily add other actions to the
+act of making the site available or not. For example, you might want to disable external site monitoring for the duration
+of your maintenance period.
+
+The events are:
+
+* `Lexik\Bundle\MaintenanceBundle\Event\PreLockEvent::NAME` - Throw just before the lock is engaged
+* `Lexik\Bundle\MaintenanceBundle\Event\PostLockEvent::NAME` - Throw just after the lock is engaged
+* `Lexik\Bundle\MaintenanceBundle\Event\PreUnlockEvent::NAME` - Throw just before the lock is removed
+* `Lexik\Bundle\MaintenanceBundle\Event\PostUnlockEvent::NAME` - Throw just after the lock is removed
+
Custom error page 503
---------------------
diff --git a/Tests/Event/EventDispatcherTest.php b/Tests/Event/EventDispatcherTest.php
new file mode 100644
index 0000000..6aa5b13
--- /dev/null
+++ b/Tests/Event/EventDispatcherTest.php
@@ -0,0 +1,131 @@
+getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcherInterface')->getMock();
+ if ($expectedEvents) {
+ $eventDispatcher->expects(self::at(0))
+ ->method('dispatch')
+ ->with(PreLockEvent::NAME, new PreLockEvent());
+
+ $eventDispatcher->expects(self::at(1))
+ ->method('dispatch')
+ ->with(PostLockEvent::NAME, new PostLockEvent($createLock));
+ }
+
+ $driver = $this->getMockBuilder('Lexik\Bundle\MaintenanceBundle\Drivers\FileDriver')->disableOriginalConstructor()->setMethods(array('isExists', 'createLock'))->getMock();
+ $driver->expects(self::any())
+ ->method('isExists')
+ ->willReturn($exists);
+ $driver->expects(self::any())
+ ->method('createLock')
+ ->willReturn($createLock);
+
+ $driver->setEventDispatcher($eventDispatcher);
+ $driver->lock();
+ }
+
+ public function createLockTestData()
+ {
+ return array(
+ 'Lock exists' => array(
+ 'exists' => true,
+ 'createLock' => null,
+ 'expectedEvents' => false,
+ ),
+ 'Lock does not exists / Created successfully' => array(
+ 'exists' => false,
+ 'createLock' => true,
+ 'expectedEvents' => true,
+ ),
+ 'Lock does not exists / Not created successfully' => array(
+ 'exists' => false,
+ 'createLock' => true,
+ 'expectedEvents' => true,
+ ),
+ );
+ }
+
+ /**
+ * @dataProvider createUnlockTestData
+ * @param $exists
+ * @param $createLock
+ * @param $expectedEvents
+ */
+ public function testUnlock($exists, $createUnlock, $expectedEvents)
+ {
+ $eventDispatcher = $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcherInterface')->getMock();
+ if ($expectedEvents) {
+ $eventDispatcher->expects(self::at(0))
+ ->method('dispatch')
+ ->with(PreUnlockEvent::NAME, new PreUnlockEvent());
+
+ $eventDispatcher->expects(self::at(1))
+ ->method('dispatch')
+ ->with(PostUnlockEvent::NAME, new PostUnlockEvent($createUnlock));
+ }
+
+ $driver = $this->getMockBuilder('Lexik\Bundle\MaintenanceBundle\Drivers\FileDriver')->disableOriginalConstructor()->setMethods(array('isExists', 'createUnlock'))->getMock();
+ $driver->expects(self::any())
+ ->method('isExists')
+ ->willReturn($exists);
+ $driver->expects(self::any())
+ ->method('createUnlock')
+ ->willReturn($createUnlock);
+
+ $driver->setEventDispatcher($eventDispatcher);
+ $driver->unlock();
+ }
+
+ public function createUnlockTestData()
+ {
+ return array(
+ 'Lock does not exists' => array(
+ 'exists' => false,
+ 'createUnlock' => null,
+ 'expectedEvents' => false,
+ ),
+ 'Lock exists / Created successfully' => array(
+ 'exists' => true,
+ 'createUnlock' => true,
+ 'expectedEvents' => true,
+ ),
+ 'Lock exists / Not created successfully' => array(
+ 'exists' => true,
+ 'createUnlock' => true,
+ 'expectedEvents' => true,
+ ),
+ );
+ }
+
+ /**
+ * @param array $mocks
+ * @param array $driverOptions
+ * @return DriverFactory
+ * @throws \ErrorException
+ */
+ public function createDriverFactory(array $mocks = array(), array $driverOptions = array())
+ {
+ $dbDriver = array_key_exists('dbDriver', $mocks) ? $mocks['dbDriver'] : $this->getMockBuilder('Lexik\Bundle\MaintenanceBundle\Drivers\DatabaseDriver')->disableOriginalConstructor()->getMock();
+ $translator = array_key_exists('translator', $mocks) ? $mocks['translator'] : $this->getMockBuilder('Symfony\Component\Translation\TranslatorInterface')->getMock();
+ $eventDispatcher = array_key_exists('eventDispatcher', $mocks) ? $mocks['eventDispatcher'] : $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcherInterface')->getMock();
+
+ return new DriverFactory($dbDriver, $translator, $eventDispatcher, $driverOptions);
+ }
+}
diff --git a/Tests/EventListener/MaintenanceListenerTest.php b/Tests/EventListener/MaintenanceListenerTest.php
index e4af51a..bb4c660 100644
--- a/Tests/EventListener/MaintenanceListenerTest.php
+++ b/Tests/EventListener/MaintenanceListenerTest.php
@@ -38,7 +38,7 @@ public function testBaseRequest()
$this->container = $this->initContainer();
- $this->factory = new DriverFactory($this->getDatabaseDriver(false),$this->getTranslator(), $driverOptions);
+ $this->factory = new DriverFactory($this->getDatabaseDriver(false), $this->getTranslator(), $this->getEventDispatcher(), $driverOptions);
$this->container->set('lexik_maintenance.driver.factory', $this->factory);
$listener = new MaintenanceListenerTestWrapper($this->factory);
@@ -47,7 +47,7 @@ public function testBaseRequest()
$listener = new MaintenanceListenerTestWrapper($this->factory, 'path', 'host', array('ip'), array('query'), array('cookie'), 'route');
$this->assertTrue($listener->onKernelRequest($event), 'Permissive factory should approve with args');
- $this->factory = new DriverFactory($this->getDatabaseDriver(true), $this->getTranslator(), $driverOptions);
+ $this->factory = new DriverFactory($this->getDatabaseDriver(true), $this->getTranslator(), $this->getEventDispatcher(), $driverOptions);
$this->container->set('lexik_maintenance.driver.factory', $this->factory);
$listener = new MaintenanceListenerTestWrapper($this->factory);
@@ -72,7 +72,7 @@ public function testPathFilter()
$this->container = $this->initContainer();
- $this->factory = new DriverFactory($this->getDatabaseDriver(true), $this->getTranslator(), $driverOptions);
+ $this->factory = new DriverFactory($this->getDatabaseDriver(true), $this->getTranslator(), $this->getEventDispatcher(), $driverOptions);
$this->container->set('lexik_maintenance.driver.factory', $this->factory);
$listener = new MaintenanceListenerTestWrapper($this->factory, null);
@@ -103,7 +103,7 @@ public function testHostFilter()
$this->container = $this->initContainer();
- $this->factory = new DriverFactory($this->getDatabaseDriver(true), $this->getTranslator(), $driverOptions);
+ $this->factory = new DriverFactory($this->getDatabaseDriver(true), $this->getTranslator(), $this->getEventDispatcher(), $driverOptions);
$this->container->set('lexik_maintenance.driver.factory', $this->factory);
$listener = new MaintenanceListenerTestWrapper($this->factory, null, null);
@@ -137,7 +137,7 @@ public function testIPFilter()
$this->container = $this->initContainer();
- $this->factory = new DriverFactory($this->getDatabaseDriver(true), $this->getTranslator(), $driverOptions);
+ $this->factory = new DriverFactory($this->getDatabaseDriver(true), $this->getTranslator(), $this->getEventDispatcher(), $driverOptions);
$this->container->set('lexik_maintenance.driver.factory', $this->factory);
$listener = new MaintenanceListenerTestWrapper($this->factory, null, null, null);
@@ -171,7 +171,7 @@ public function testRouteFilter($debug, $route, $expected)
$this->container = $this->initContainer();
- $this->factory = new DriverFactory($this->getDatabaseDriver(true), $this->getTranslator(), $driverOptions);
+ $this->factory = new DriverFactory($this->getDatabaseDriver(true), $this->getTranslator(), $this->getEventDispatcher(), $driverOptions);
$this->container->set('lexik_maintenance.driver.factory', $this->factory);
$listener = new MaintenanceListenerTestWrapper($this->factory, null, null, null, array(), array(), $debug);
@@ -219,7 +219,7 @@ public function testQueryFilter()
$this->container = $this->initContainer();
- $this->factory = new DriverFactory($this->getDatabaseDriver(true), $this->getTranslator(), $driverOptions);
+ $this->factory = new DriverFactory($this->getDatabaseDriver(true), $this->getTranslator(), $this->getEventDispatcher(), $driverOptions);
$this->container->set('lexik_maintenance.driver.factory', $this->factory);
$listener = new MaintenanceListenerTestWrapper($this->factory, null, null, null, null);
@@ -259,7 +259,7 @@ public function testCookieFilter()
$this->container = $this->initContainer();
- $this->factory = new DriverFactory($this->getDatabaseDriver(true), $this->getTranslator(), $driverOptions);
+ $this->factory = new DriverFactory($this->getDatabaseDriver(true), $this->getTranslator(), $this->getEventDispatcher(), $driverOptions);
$this->container->set('lexik_maintenance.driver.factory', $this->factory);
$listener = new MaintenanceListenerTestWrapper($this->factory, null, null, null, null, null);
@@ -344,4 +344,12 @@ public function getTranslator()
return TestHelper::getTranslator($this->container, $messageSelector);
}
+
+ /**
+ * @return \PHPUnit_Framework_MockObject_MockObject|\Symfony\Component\EventDispatcher\EventDispatcherInterface
+ */
+ public function getEventDispatcher()
+ {
+ return $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcherInterface')->getMock();
+ }
}
diff --git a/Tests/Maintenance/DriverFactoryTest.php b/Tests/Maintenance/DriverFactoryTest.php
index 2139aa1..6c7f254 100644
--- a/Tests/Maintenance/DriverFactoryTest.php
+++ b/Tests/Maintenance/DriverFactoryTest.php
@@ -27,7 +27,7 @@ public function setUp()
$this->container = $this->initContainer();
- $this->factory = new DriverFactory($this->getDatabaseDriver(), $this->getTranslator(), $driverOptions);
+ $this->factory = new DriverFactory($this->getDatabaseDriver(), $this->getTranslator(), $this->getEventDispatcher(), $driverOptions);
$this->container->set('lexik_maintenance.driver.factory', $this->factory);
}
@@ -47,14 +47,14 @@ public function testDriver()
*/
public function testExceptionConstructor()
{
- $factory = new DriverFactory($this->getDatabaseDriver(), $this->getTranslator(), array());
+ $factory = new DriverFactory($this->getDatabaseDriver(), $this->getTranslator(), $this->getEventDispatcher(), array());
}
public function testWithDatabaseChoice()
{
$driverOptions = array('class' => DriverFactory::DATABASE_DRIVER, 'options' => null);
- $factory = new DriverFactory($this->getDatabaseDriver(), $this->getTranslator(), $driverOptions);
+ $factory = new DriverFactory($this->getDatabaseDriver(), $this->getTranslator(), $this->getEventDispatcher(), $driverOptions);
$this->container->set('lexik_maintenance.driver.factory', $factory);
@@ -65,7 +65,7 @@ public function testExceptionGetDriver()
{
$driverOptions = array('class' => '\Unknown', 'options' => null);
- $factory = new DriverFactory($this->getDatabaseDriver(), $this->getTranslator(), $driverOptions);
+ $factory = new DriverFactory($this->getDatabaseDriver(), $this->getTranslator(), $this->getEventDispatcher(), $driverOptions);
$this->container->set('lexik_maintenance.driver.factory', $factory);
try {
@@ -109,4 +109,12 @@ public function getTranslator()
return TestHelper::getTranslator($this->container, $messageSelector);
}
+
+ /**
+ * @return \PHPUnit_Framework_MockObject_MockObject|\Symfony\Component\EventDispatcher\EventDispatcherInterface
+ */
+ public function getEventDispatcher()
+ {
+ return $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcherInterface')->getMock();
+ }
}
diff --git a/Tests/Maintenance/FileMaintenanceTest.php b/Tests/Maintenance/FileMaintenanceTest.php
index de674f2..d505366 100644
--- a/Tests/Maintenance/FileMaintenanceTest.php
+++ b/Tests/Maintenance/FileMaintenanceTest.php
@@ -78,6 +78,7 @@ public function testUnlock()
$fileM = new FileDriver($options);
$fileM->setTranslator($this->getTranslator());
+ $fileM->setEventDispatcher($this->getEventDispatcher());
$fileM->lock();
$fileM->unlock();
@@ -91,6 +92,7 @@ public function testIsExists()
$fileM = new FileDriver($options);
$fileM->setTranslator($this->getTranslator());
+ $fileM->setEventDispatcher($this->getEventDispatcher());
$fileM->lock();
$this->assertTrue($fileM->isEndTime(3600));
@@ -102,6 +104,7 @@ public function testMessages()
$fileM = new FileDriver($options);
$fileM->setTranslator($this->getTranslator());
+ $fileM->setEventDispatcher($this->getEventDispatcher());
$fileM->lock();
// lock
@@ -141,4 +144,12 @@ public function getTranslator()
return TestHelper::getTranslator($this->container, $messageSelector);
}
+
+ /**
+ * @return \PHPUnit_Framework_MockObject_MockObject|\Symfony\Component\EventDispatcher\EventDispatcherInterface
+ */
+ public function getEventDispatcher()
+ {
+ return $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcherInterface')->getMock();
+ }
}
diff --git a/Tests/Maintenance/MemcachedTest.php b/Tests/Maintenance/MemcachedTest.php
new file mode 100644
index 0000000..6937049
--- /dev/null
+++ b/Tests/Maintenance/MemcachedTest.php
@@ -0,0 +1,66 @@
+ 'mnt'));
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ */
+ public function testConstructWithNotPort()
+ {
+ $memC = new MemcachedDriver(array('key_name' => 'mnt', 'host' => '127.0.0.1'));
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ */
+ public function testConstructWithNotPortNumber()
+ {
+ $memC = new MemcachedDriver(array('key_name' => 'mnt', 'host' => '127.0.0.1', 'port' => 'roti'));
+ }
+
+ protected function initContainer()
+ {
+ $container = new ContainerBuilder(new ParameterBag(array(
+ 'kernel.debug' => false,
+ 'kernel.bundles' => array('MaintenanceBundle' => 'Lexik\Bundle\MaintenanceBundle'),
+ 'kernel.cache_dir' => sys_get_temp_dir(),
+ 'kernel.environment' => 'dev',
+ 'kernel.root_dir' => __DIR__.'/../../../../', // src dir
+ 'kernel.default_locale' => 'fr',
+ )));
+
+ return $container;
+ }
+}
diff --git a/composer.json b/composer.json
index da26c7b..ca9171e 100644
--- a/composer.json
+++ b/composer.json
@@ -22,11 +22,19 @@
"require": {
"php": ">=5.3.9",
"symfony/framework-bundle": "~2.7|~3.0|^4.0",
- "symfony/translation": "~2.7|~3.0|^4.0"
+ "symfony/translation": "~2.7|~3.0|^4.0",
+ "symfony/event-dispatcher": "~2.7|~3.0|^4.0",
+ "symfony/console": "~2.7|~3.0|^4.0"
},
"require-dev": {
"symfony/phpunit-bridge": "~2.7|~3.0|^4.0",
- "phpunit/phpunit": "~4.8|~5.7.11"
+ "phpunit/phpunit": "~4.8|~5.7.11",
+ "doctrine/doctrine-bundle": "^1.0"
+ },
+ "suggest": {
+ "doctrine/doctrine-bundle": "For database site locking",
+ "ext-memcache": "For memcache site locking - Probably don't use this as the ext-memcache has been superseded by ext-memcached",
+ "ext-memcached": "For memcached site locking"
},
"autoload": {
"psr-4": { "Lexik\\Bundle\\MaintenanceBundle\\": "" }
diff --git a/phpunit.xml.dist b/phpunit.xml.dist
index 52090e9..d3e2c15 100644
--- a/phpunit.xml.dist
+++ b/phpunit.xml.dist
@@ -11,6 +11,11 @@
syntaxCheck="false"
bootstrap="vendor/autoload.php"
>
+
+
+
+
+
./Tests/