Skip to content

Commit 87e1ee3

Browse files
committed
Simplify instantiator logic
1 parent 9a7aeaa commit 87e1ee3

File tree

6 files changed

+33
-93
lines changed

6 files changed

+33
-93
lines changed

src/DataTable.php

Lines changed: 3 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ class DataTable
108108
*/
109109
public function __construct(array $options = [], Instantiator $instantiator = null)
110110
{
111-
$this->instantiator = $instantiator;
111+
$this->instantiator = $instantiator ?? new Instantiator();
112112

113113
$resolver = new OptionsResolver();
114114
$this->configureOptions($resolver);
@@ -128,7 +128,7 @@ public function add(string $name, string $type, array $options = [])
128128
throw new InvalidArgumentException(sprintf("There already is a column with name '%s'", $name));
129129
}
130130

131-
$column = $this->createColumn($type);
131+
$column = $this->instantiator->getColumn($type);
132132
$column->initialize($name, count($this->columns), $options, $this);
133133

134134
$this->columns[] = $column;
@@ -158,28 +158,7 @@ public function addOrderBy($column, string $direction = self::SORT_ASCENDING)
158158
*/
159159
public function createAdapter(string $adapter, array $options = []): self
160160
{
161-
if (null !== $this->instantiator && $instance = $this->instantiator->getAdapter($adapter)) {
162-
return $this->setAdapter($instance, $options);
163-
} elseif (class_exists($adapter) && in_array(AdapterInterface::class, class_implements($adapter), true)) {
164-
return $this->setAdapter(new $adapter(), $options);
165-
} else {
166-
throw new InvalidArgumentException(sprintf('Could not resolve adapter type "%s" to a service or class implementing AdapterInterface', $adapter));
167-
}
168-
}
169-
170-
/**
171-
* @param string $column
172-
* @return AbstractColumn
173-
*/
174-
protected function createColumn(string $column): AbstractColumn
175-
{
176-
if (null !== $this->instantiator && $instance = $this->instantiator->getColumn($column)) {
177-
return $instance;
178-
} elseif (class_exists($column) && is_subclass_of($column, AbstractColumn::class)) {
179-
return new $column();
180-
} else {
181-
throw new InvalidArgumentException(sprintf('Could not resolve column type "%s" to a service or class extending AbstractColumn', $column));
182-
}
161+
return $this->setAdapter($this->instantiator->getAdapter($adapter), $options);
183162
}
184163

185164
/**

src/DataTableFactory.php

Lines changed: 2 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
namespace Omines\DataTablesBundle;
1414

1515
use Omines\DataTablesBundle\DependencyInjection\Instantiator;
16-
use Omines\DataTablesBundle\Exception\InvalidArgumentException;
1716
use Symfony\Component\HttpFoundation\Request;
1817

1918
class DataTableFactory
@@ -36,17 +35,10 @@ class DataTableFactory
3635
* @param array $config
3736
* @param DataTableRendererInterface $renderer
3837
*/
39-
public function __construct(array $config, DataTableRendererInterface $renderer)
38+
public function __construct(array $config, DataTableRendererInterface $renderer, Instantiator $instantiator)
4039
{
4140
$this->config = $config;
4241
$this->renderer = $renderer;
43-
}
44-
45-
/**
46-
* @param Instantiator $instantiator
47-
*/
48-
public function setInstantiator(Instantiator $instantiator)
49-
{
5042
$this->instantiator = $instantiator;
5143
}
5244

@@ -83,29 +75,12 @@ public function createFromType($type, array $typeOptions = [], array $options =
8375
if (isset($this->resolvedTypes[$name])) {
8476
$type = $this->resolvedTypes[$name];
8577
} else {
86-
$this->resolvedTypes[$name] = $type = $this->resolveType($name);
78+
$this->resolvedTypes[$name] = $type = $this->instantiator->getType($name);
8779
}
8880
}
8981

9082
$type->configure($dataTable, $typeOptions);
9183

9284
return $dataTable;
9385
}
94-
95-
/**
96-
* Resolves a dynamic type to an instance via services or instantiation.
97-
*
98-
* @param string $type
99-
* @return DataTableTypeInterface
100-
*/
101-
private function resolveType(string $type): DataTableTypeInterface
102-
{
103-
if (null !== $this->instantiator && $type = $this->instantiator->getType($type)) {
104-
return $type;
105-
} elseif (class_exists($type) && in_array(DataTableTypeInterface::class, class_implements($type), true)) {
106-
return new $type();
107-
}
108-
109-
throw new InvalidArgumentException(sprintf('Could not resolve type "%s" to a service or class', $type));
110-
}
11186
}

src/DependencyInjection/Compiler/LocatorRegistrationPass.php

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@
1212

1313
namespace Omines\DataTablesBundle\DependencyInjection\Compiler;
1414

15-
use Omines\DataTablesBundle\DataTableFactory;
15+
use Omines\DataTablesBundle\Adapter\AdapterInterface;
16+
use Omines\DataTablesBundle\Column\AbstractColumn;
17+
use Omines\DataTablesBundle\DataTableTypeInterface;
1618
use Omines\DataTablesBundle\DependencyInjection\Instantiator;
1719
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
1820
use Symfony\Component\DependencyInjection\ContainerBuilder;
@@ -32,17 +34,12 @@ class LocatorRegistrationPass implements CompilerPassInterface
3234
*/
3335
public function process(ContainerBuilder $container)
3436
{
35-
$instantiator = $container->getDefinition(Instantiator::class);
36-
37-
$instantiator->setArguments([
38-
$this->registerLocator($container, 'adapter'),
39-
$this->registerLocator($container, 'column'),
40-
$this->registerLocator($container, 'type'),
41-
]);
42-
43-
$container->getDefinition(DataTableFactory::class)
44-
->addMethodCall('setInstantiator', [$instantiator])
45-
;
37+
$container->getDefinition(Instantiator::class)
38+
->setArguments([[
39+
AdapterInterface::class => $this->registerLocator($container, 'adapter'),
40+
AbstractColumn::class => $this->registerLocator($container, 'column'),
41+
DataTableTypeInterface::class => $this->registerLocator($container, 'type'),
42+
]]);
4643
}
4744

4845
/**
@@ -60,6 +57,7 @@ private function registerLocator(ContainerBuilder $container, string $baseTag):
6057
return $container
6158
->register("datatables.{$baseTag}_locator", ServiceLocator::class)
6259
->addTag('container.service_locator')
60+
->setPrivate(true)
6361
->setArguments([$types])
6462
;
6563
}

src/DependencyInjection/Instantiator.php

Lines changed: 11 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -25,27 +25,17 @@
2525
*/
2626
class Instantiator
2727
{
28-
/** @var ServiceLocator */
29-
private $adapterLocator;
30-
31-
/** @var ServiceLocator */
32-
private $columnLocator;
33-
34-
/** @var ServiceLocator */
35-
private $typeLocator;
28+
/** @var ServiceLocator[] */
29+
private $locators;
3630

3731
/**
3832
* Instantiator constructor.
3933
*
40-
* @param ServiceLocator $adapterLocator
41-
* @param ServiceLocator $columnLocator
42-
* @param ServiceLocator $typeLocator
34+
* @param ServiceLocator[] $locators
4335
*/
44-
public function __construct(ServiceLocator $adapterLocator, ServiceLocator $columnLocator, ServiceLocator $typeLocator)
36+
public function __construct(array $locators = [])
4537
{
46-
$this->adapterLocator = $adapterLocator;
47-
$this->columnLocator = $columnLocator;
48-
$this->typeLocator = $typeLocator;
38+
$this->locators = $locators;
4939
}
5040

5141
/**
@@ -54,7 +44,7 @@ public function __construct(ServiceLocator $adapterLocator, ServiceLocator $colu
5444
*/
5545
public function getAdapter(string $type): AdapterInterface
5646
{
57-
return $this->getInstance($this->adapterLocator, $type, AdapterInterface::class);
47+
return $this->getInstance($type, AdapterInterface::class);
5848
}
5949

6050
/**
@@ -63,7 +53,7 @@ public function getAdapter(string $type): AdapterInterface
6353
*/
6454
public function getColumn(string $type): AbstractColumn
6555
{
66-
return $this->getInstance($this->columnLocator, $type, AbstractColumn::class);
56+
return $this->getInstance($type, AbstractColumn::class);
6757
}
6858

6959
/**
@@ -72,19 +62,18 @@ public function getColumn(string $type): AbstractColumn
7262
*/
7363
public function getType(string $type): DataTableTypeInterface
7464
{
75-
return $this->getInstance($this->typeLocator, $type, DataTableTypeInterface::class);
65+
return $this->getInstance($type, DataTableTypeInterface::class);
7666
}
7767

7868
/**
79-
* @param ServiceLocator $locator
8069
* @param string $type
8170
* @param string $baseType
8271
* @return mixed
8372
*/
84-
private function getInstance(ServiceLocator $locator, string $type, string $baseType)
73+
private function getInstance(string $type, string $baseType)
8574
{
86-
if ($locator->has($type)) {
87-
return $locator->get($type);
75+
if (isset($this->locators[$baseType]) && $this->locators[$baseType]->has($type)) {
76+
return $this->locators[$baseType]->get($type);
8877
} elseif (class_exists($type) && is_subclass_of($type, $baseType)) {
8978
return new $type();
9079
}

src/Resources/config/services.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ services:
1313
arguments: ['@?twig']
1414

1515
Omines\DataTablesBundle\DataTableFactory:
16-
arguments: ['%datatables.config%', '@datatables.renderer']
16+
arguments: ['%datatables.config%', '@datatables.renderer', '@Omines\DataTablesBundle\DependencyInjection\Instantiator']
1717
public: true
1818

1919
Omines\DataTablesBundle\DependencyInjection\Instantiator: ~

tests/Unit/DataTableTest.php

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ public function testBundle()
4949

5050
public function testFactory()
5151
{
52-
$factory = new DataTableFactory(['language_from_cdn' => false], $this->createMock(TwigRenderer::class));
52+
$factory = new DataTableFactory(['language_from_cdn' => false], $this->createMock(TwigRenderer::class), new Instantiator());
5353

5454
$table = $factory->create(['pageLength' => 684, 'dom' => 'bar']);
5555
$this->assertSame(684, $table->getOption('pageLength'));
@@ -63,7 +63,7 @@ public function testFactory()
6363

6464
public function testFactoryRemembersInstances()
6565
{
66-
$factory = new DataTableFactory([], $this->createMock(TwigRenderer::class));
66+
$factory = new DataTableFactory([], $this->createMock(TwigRenderer::class), new Instantiator());
6767

6868
$reflection = new \ReflectionClass(DataTableFactory::class);
6969
$property = $reflection->getProperty('resolvedTypes');
@@ -119,8 +119,7 @@ public function testFactoryFailsOnInvalidType()
119119
$container = new ContainerBuilder();
120120
(new DataTablesExtension())->load([], $container);
121121

122-
$factory = new DataTableFactory($container->getParameter('datatables.config'), $this->createMock(TwigRenderer::class));
123-
$factory->setInstantiator(new Instantiator($dummy, $dummy, $dummy));
122+
$factory = new DataTableFactory($container->getParameter('datatables.config'), $this->createMock(TwigRenderer::class), new Instantiator());
124123
$factory->createFromType('foobar');
125124
}
126125

@@ -162,7 +161,7 @@ public function testDuplicateColumnNameThrows()
162161

163162
/**
164163
* @expectedException \InvalidArgumentException
165-
* @expectedExceptionMessage Could not resolve adapter type
164+
* @expectedExceptionMessage Could not resolve type "foo\bar" to a service or class, are you missing a use statement? Or is it implemented but does it not correctly derive from "Omines\DataTablesBundle\Adapter\AdapterInterface"?
166165
*/
167166
public function testInvalidAdapterThrows()
168167
{
@@ -173,7 +172,7 @@ public function testInvalidAdapterThrows()
173172

174173
/**
175174
* @expectedException \InvalidArgumentException
176-
* @expectedExceptionMessage Could not resolve column type "bar"
175+
* @expectedExceptionMessage Could not resolve type "bar" to a service or class, are you missing a use statement? Or is it implemented but does it not correctly derive from "Omines\DataTablesBundle\Column\AbstractColumn"?
177176
*/
178177
public function testInvalidColumnThrows()
179178
{
@@ -231,7 +230,7 @@ public function testMissingStateThrows()
231230
*/
232231
public function testInvalidDataTableTypeThrows()
233232
{
234-
(new DataTableFactory([], $this->createMock(DataTableRendererInterface::class)))
233+
(new DataTableFactory([], $this->createMock(DataTableRendererInterface::class), new Instantiator()))
235234
->createFromType('foo');
236235
}
237236
}

0 commit comments

Comments
 (0)