Merge pull request #3726 from CHItA/ticket/13961

[ticket/13961] Add orderable service collections
This commit is contained in:
Tristan Darricau 2015-07-06 23:31:35 +02:00
commit ca5d4fd310
5 changed files with 226 additions and 2 deletions

View file

@ -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;
}
}

View file

@ -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);
}
}
}

View file

@ -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;
}

View file

@ -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);
}
}

View file

@ -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);
}
}