aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--phpBB/phpbb/di/ordered_service_collection.php117
-rw-r--r--phpBB/phpbb/di/pass/collection_pass.php11
-rw-r--r--phpBB/phpbb/di/service_collection_iterator.php2
-rw-r--r--tests/di/ordered_service_collection_test.php51
-rw-r--r--tests/di/service_collection_test.php47
5 files changed, 226 insertions, 2 deletions
diff --git a/phpBB/phpbb/di/ordered_service_collection.php b/phpBB/phpbb/di/ordered_service_collection.php
new file mode 100644
index 0000000000..046012ae5b
--- /dev/null
+++ b/phpBB/phpbb/di/ordered_service_collection.php
@@ -0,0 +1,117 @@
+<?php
+/**
+ *
+ * This file is part of the phpBB Forum Software package.
+ *
+ * @copyright (c) phpBB Limited <https://www.phpbb.com>
+ * @license GNU General Public License, version 2 (GPL-2.0)
+ *
+ * For full copyright and license information, please see
+ * the docs/CREDITS.txt file.
+ *
+ */
+
+namespace phpbb\di;
+
+use Symfony\Component\DependencyInjection\ContainerInterface;
+
+/**
+ * Collection of services in a specified order
+ */
+class ordered_service_collection extends service_collection
+{
+ /**
+ * @var bool
+ */
+ protected $is_ordered;
+
+ /**
+ * @var array
+ */
+ protected $service_ids;
+
+ /**
+ * Constructor
+ *
+ * @param ContainerInterface $container Container object
+ */
+ public function __construct(ContainerInterface $container)
+ {
+ $this->is_ordered = false;
+ $this->service_ids = array();
+
+ parent::__construct($container);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getIterator()
+ {
+ if (!$this->is_ordered)
+ {
+ $this->sort_services();
+ }
+
+ return new service_collection_iterator($this);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function offsetExists($index)
+ {
+ if (!$this->is_ordered)
+ {
+ $this->sort_services();
+ }
+
+ return parent::offsetExists($index);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function offsetGet($index)
+ {
+ if (!$this->is_ordered)
+ {
+ $this->sort_services();
+ }
+
+ return parent::offsetGet($index);
+ }
+
+ /**
+ * Adds a service ID to the collection
+ *
+ * @param string $service_id
+ * @param int $order
+ */
+ public function add($service_id, $order = 0)
+ {
+ $order = (int) $order;
+ $this->service_ids[$order][] = $service_id;
+ $this->is_ordered = false;
+ }
+
+ protected function sort_services()
+ {
+ if ($this->is_ordered)
+ {
+ return;
+ }
+
+ $this->exchangeArray(array());
+ ksort($this->service_ids);
+ foreach ($this->service_ids as $service_order_group)
+ {
+ foreach ($service_order_group as $service_id)
+ {
+ $this->offsetSet($service_id, null);
+ }
+ }
+
+ $this->is_ordered = true;
+ }
+}
diff --git a/phpBB/phpbb/di/pass/collection_pass.php b/phpBB/phpbb/di/pass/collection_pass.php
index a5c054674e..ccc1250c20 100644
--- a/phpBB/phpbb/di/pass/collection_pass.php
+++ b/phpBB/phpbb/di/pass/collection_pass.php
@@ -37,7 +37,16 @@ class collection_pass implements CompilerPassInterface
foreach ($container->findTaggedServiceIds($data[0]['tag']) as $service_id => $service_data)
{
- $definition->addMethodCall('add', array($service_id));
+ if (substr($definition->getClass(), -strlen('ordered_service_collection')) === 'ordered_service_collection')
+ {
+ $arguments = array($service_id, $service_data[0]['order']);
+ }
+ else
+ {
+ $arguments = array($service_id);
+ }
+
+ $definition->addMethodCall('add', $arguments);
}
}
}
diff --git a/phpBB/phpbb/di/service_collection_iterator.php b/phpBB/phpbb/di/service_collection_iterator.php
index 0d031ab52d..31bc156e99 100644
--- a/phpBB/phpbb/di/service_collection_iterator.php
+++ b/phpBB/phpbb/di/service_collection_iterator.php
@@ -32,7 +32,7 @@ class service_collection_iterator extends \ArrayIterator
*/
public function __construct(service_collection $collection, $flags = 0)
{
- parent::__construct($collection, $flags);
+ parent::__construct($collection->getArrayCopy(), $flags);
$this->collection = $collection;
}
diff --git a/tests/di/ordered_service_collection_test.php b/tests/di/ordered_service_collection_test.php
new file mode 100644
index 0000000000..47e6d23744
--- /dev/null
+++ b/tests/di/ordered_service_collection_test.php
@@ -0,0 +1,51 @@
+<?php
+/**
+ *
+ * This file is part of the phpBB Forum Software package.
+ *
+ * @copyright (c) phpBB Limited <https://www.phpbb.com>
+ * @license GNU General Public License, version 2 (GPL-2.0)
+ *
+ * For full copyright and license information, please see
+ * the docs/CREDITS.txt file.
+ *
+ */
+
+class phpbb_ordered_service_collection_test extends \phpbb_test_case
+{
+ /**
+ * @var \phpbb\di\ordered_service_collection
+ */
+ protected $service_collection;
+
+ public function setUp()
+ {
+ $container = new phpbb_mock_container_builder();
+ $container->set('foo', new StdClass);
+ $container->set('bar', new StdClass);
+ $container->set('foobar', new StdClass);
+ $container->set('barfoo', new StdClass);
+
+ $this->service_collection = new \phpbb\di\ordered_service_collection($container);
+ $this->service_collection->add('foo', 7);
+ $this->service_collection->add('bar', 3);
+ $this->service_collection->add('barfoo', 5);
+ $this->service_collection->add('foobar', 2);
+
+ parent::setUp();
+ }
+
+ public function test_service_collection()
+ {
+ $service_names = array();
+
+ // Test the iterator
+ foreach ($this->service_collection as $name => $service)
+ {
+ $service_names[] = $name;
+ $this->assertInstanceOf('StdClass', $service);
+ }
+
+ $this->assertSame(array('foobar', 'bar', 'barfoo', 'foo'), $service_names);
+ }
+}
diff --git a/tests/di/service_collection_test.php b/tests/di/service_collection_test.php
new file mode 100644
index 0000000000..5b51254a4a
--- /dev/null
+++ b/tests/di/service_collection_test.php
@@ -0,0 +1,47 @@
+<?php
+/**
+ *
+ * This file is part of the phpBB Forum Software package.
+ *
+ * @copyright (c) phpBB Limited <https://www.phpbb.com>
+ * @license GNU General Public License, version 2 (GPL-2.0)
+ *
+ * For full copyright and license information, please see
+ * the docs/CREDITS.txt file.
+ *
+ */
+
+class phpbb_service_collection_test extends \phpbb_test_case
+{
+ /**
+ * @var \phpbb\di\service_collection
+ */
+ protected $service_collection;
+
+ public function setUp()
+ {
+ $container = new phpbb_mock_container_builder();
+ $container->set('foo', new StdClass);
+ $container->set('bar', new StdClass);
+
+ $this->service_collection = new \phpbb\di\service_collection($container);
+ $this->service_collection->add('foo');
+ $this->service_collection->add('bar');
+
+ parent::setUp();
+ }
+
+ public function test_service_collection()
+ {
+ $service_names = array();
+
+ // Test the iterator
+ foreach ($this->service_collection as $name => $service)
+ {
+ $service_names[] = $name;
+ $this->assertInstanceOf('StdClass', $service);
+ }
+
+ $this->assertSame(array('foo', 'bar'), $service_names);
+ }
+}