Skip to content
This repository has been archived by the owner on Jan 16, 2018. It is now read-only.

Commit

Permalink
feature #66 Introduce a better way of reusing datagrids (sstok)
Browse files Browse the repository at this point in the history
This PR was merged into the master branch.

Discussion
----------

|Q            |A  |
|---          |---|
|Bug Fix?     |no |
|New Feature? |yes|
|BC Breaks?   |yes|
|Deprecations?|no |
|Fixed Tickets|   |

Commits
-------

bc40bb5 Introduce a better way of reusing datagrids
  • Loading branch information
sstok committed Sep 27, 2016
2 parents 99fbbaf + bc40bb5 commit 52b5bdc
Show file tree
Hide file tree
Showing 19 changed files with 499 additions and 44 deletions.
6 changes: 6 additions & 0 deletions UPGRADE.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,12 @@ UPGRADE

* The `type` property of the `CellView` is removed, this was already no longer populated.

* The purpose of the `DatagridFactoryInterface::createDatagrid` method changed to create
a new Datagrid using a DatagridConfigurator which is loaded using a registry.

The default registry's implementation registers Configurators lazily using closures
and allows to load configurators using there FQCN (similar to ColumnType's).

### View transformers

* Adding multiple view transformers to a column is removed, a column can now only have one
Expand Down
28 changes: 28 additions & 0 deletions src/DatagridConfiguratorInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

declare(strict_types=1);

/*
* This file is part of the RollerworksDatagrid package.
*
* (c) Sebastiaan Stok <s.stok@rollerscapes.net>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/

namespace Rollerworks\Component\Datagrid;

/**
* A DatagridConfigurator configures a DatagridBuilder instance.
*
* The purpose of a configurator is to allow re-usage of a Datagrid.
* When you want to combine configurators, simply use PHP inheritance and
* traits.
*
* @author Sebastiaan Stok <s.stok@rollerscapes.net>
*/
interface DatagridConfiguratorInterface
{
public function buildDatagrid(DatagridBuilderInterface $builder, array $options);
}
28 changes: 18 additions & 10 deletions src/DatagridFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,31 +15,39 @@

use Rollerworks\Component\Datagrid\Column\ColumnInterface;
use Rollerworks\Component\Datagrid\Column\ColumnTypeRegistryInterface;
use Rollerworks\Component\Datagrid\Util\StringUtil;

/**
* @author Sebastiaan Stok <s.stok@rollerscapes.net>
*/
class DatagridFactory implements DatagridFactoryInterface
{
/**
* @var ColumnTypeRegistryInterface
*/
private $typeRegistry;
private $datagridRegistry;

/**
* @param ColumnTypeRegistryInterface $registry
*/
public function __construct(ColumnTypeRegistryInterface $registry)
public function __construct(ColumnTypeRegistryInterface $typeRegistry, DatagridRegistryInterface $datagridRegistry)
{
$this->typeRegistry = $registry;
$this->typeRegistry = $typeRegistry;
$this->datagridRegistry = $datagridRegistry;
}

/**
* {@inheritdoc}
*/
public function createDatagrid(string $name, array $columns): DatagridInterface
public function createDatagrid($configurator, string $name = null, array $options = []): DatagridInterface
{
return new Datagrid($name, $columns);
if (!$configurator instanceof DatagridConfiguratorInterface) {
$configurator = $this->datagridRegistry->getConfigurator($configurator);
}

if (null === $name) {
$name = StringUtil::fqcnToBlockPrefix(get_class($configurator));
}

$builder = $this->createDatagridBuilder();
$configurator->buildDatagrid($builder, $options);

return $builder->getDatagrid($name);
}

/**
Expand Down
9 changes: 6 additions & 3 deletions src/DatagridFactoryInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,15 @@ public function createColumn(string $name, string $type, array $options = []): C
/**
* Create a new DatagridInterface instance with a unique name.
*
* @param string $name Name of the datagrid
* @param ColumnInterface[] $columns Columns of the datagrid
* @param string|DatagridConfiguratorInterface $configurator Configurator for building the datagrid,
* a string will be resolved to a configurator
* @param string $name Name of the datagrid,
* defaults to the simple name of the configurator
* @param array $options Additional options for the configurator
*
* @return DatagridInterface
*/
public function createDatagrid(string $name, array $columns): DatagridInterface;
public function createDatagrid($configurator, string $name = null, array $options = []): DatagridInterface;

/**
* Create a new DatagridBuilderInterface instance.
Expand Down
106 changes: 106 additions & 0 deletions src/DatagridRegistry.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
<?php

declare(strict_types=1);

/*
* This file is part of the RollerworksDatagrid package.
*
* (c) Sebastiaan Stok <s.stok@rollerscapes.net>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/

namespace Rollerworks\Component\Datagrid;

use Rollerworks\Component\Datagrid\Exception\InvalidArgumentException;
use Rollerworks\Component\Datagrid\Exception\UnexpectedTypeException;

/**
* @author Sebastiaan Stok <s.stok@rollerscapes.net>
*/
class DatagridRegistry implements DatagridRegistryInterface
{
private $configurators;

/** @var \Closure[] */
private $lazyConfigurators = [];

/**
* Constructor.
*
* Note you don't have to register the Configurator when it has no constructor
* or setter dependencies. You can simple use the FQCN of the configurator class,
* and will be initialized upon first usage.
*
* @param \Closure[] $configurators An array of lazy loading configurators.
* The Closure when called it expected to return
* the DatagridConfiguratorInterface object
*
* @throws UnexpectedTypeException
*/
public function __construct(array $configurators = [])
{
/** @var string $name */
foreach ($configurators as $name => $configurator) {
if (!$configurator instanceof \Closure) {
throw new UnexpectedTypeException($configurator, \Closure::class);
}

$this->lazyConfigurators[$name] = $configurator;
}
}

/**
* Returns a DatagridConfigurator by name.
*
* @param string $name The name of the datagrid configurator
*
* @throws InvalidArgumentException if the configurator can not be retrieved
*
* @return DatagridConfiguratorInterface
*/
public function getConfigurator(string $name): DatagridConfiguratorInterface
{
if (!isset($this->configurators[$name])) {
$configurator = null;

if (isset($this->lazyConfigurators[$name])) {
$configurator = $this->lazyConfigurators[$name]();
}

if (!$configurator) {
// Support fully-qualified class names.
if (!class_exists($name) || !in_array(DatagridConfiguratorInterface::class, class_implements($name), true)) {
throw new InvalidArgumentException(sprintf('Could not load datagrid configurator "%s"', $name));
}

$configurator = new $name();
}

$this->configurators[$name] = $configurator;
}

return $this->configurators[$name];
}

/**
* Returns whether the given DatagridConfigurator is supported.
*
* @param string $name The name of the datagrid configurator
*
* @return bool
*/
public function hasConfigurator(string $name): bool
{
if (isset($this->configurators[$name])) {
return true;
}

if (isset($this->lazyConfigurators[$name])) {
return true;
}

return class_exists($name) && in_array(DatagridConfiguratorInterface::class, class_implements($name), true);
}
}
42 changes: 42 additions & 0 deletions src/DatagridRegistryInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?php

declare(strict_types=1);

/*
* This file is part of the RollerworksDatagrid package.
*
* (c) Sebastiaan Stok <s.stok@rollerscapes.net>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/

namespace Rollerworks\Component\Datagrid;

use Rollerworks\Component\Datagrid\Exception\InvalidArgumentException;

/**
* @author Sebastiaan Stok <s.stok@rollerscapes.net>
*/
interface DatagridRegistryInterface
{
/**
* Returns a DatagridConfigurator by name.
*
* @param string $name The name of the datagrid configurator
*
* @throws InvalidArgumentException if the configurator can not be retrieved
*
* @return DatagridConfiguratorInterface
*/
public function getConfigurator(string $name): DatagridConfiguratorInterface;

/**
* Returns whether the given DatagridConfigurator is supported.
*
* @param string $name The name of the datagrid configurator
*
* @return bool
*/
public function hasConfigurator(string $name): bool;
}
6 changes: 4 additions & 2 deletions src/Test/ColumnTypeTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@

namespace Rollerworks\Component\Datagrid\Test;

use Rollerworks\Component\Datagrid\Datagrid;

abstract class ColumnTypeTestCase extends DatagridIntegrationTestCase
{
public static function assertDateTimeEquals(\DateTime $expected, \DateTime $actual)
Expand All @@ -36,7 +38,7 @@ protected function assertCellValueEquals($expectedValue, $data, array $options =
)
);

$datagrid = $this->factory->createDatagrid('grid', [$column]);
$datagrid = new Datagrid('grid', [$column]);

if (!is_array($data)) {
$object = new \stdClass();
Expand Down Expand Up @@ -74,7 +76,7 @@ protected function assertCellValueNotEquals($expectedValue, $data, array $option
)
);

$datagrid = $this->factory->createDatagrid('grid', [$column]);
$datagrid = new Datagrid('grid', [$column]);

if (!is_array($data)) {
$object = new \stdClass();
Expand Down
4 changes: 3 additions & 1 deletion src/Test/DatagridIntegrationTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
use Rollerworks\Component\Datagrid\Column\ColumnTypeRegistry;
use Rollerworks\Component\Datagrid\Column\ResolvedColumnTypeFactory;
use Rollerworks\Component\Datagrid\DatagridFactory;
use Rollerworks\Component\Datagrid\DatagridRegistry;
use Rollerworks\Component\Datagrid\Extension\Core\CoreExtension;

abstract class DatagridIntegrationTestCase extends \PHPUnit_Framework_TestCase
Expand All @@ -33,7 +34,8 @@ protected function setUp()
$extensions = array_merge($extensions, $this->getExtensions());

$typesRegistry = new ColumnTypeRegistry($extensions, $resolvedTypeFactory);
$this->factory = new DatagridFactory($typesRegistry);
$datagridRegistry = new DatagridRegistry();
$this->factory = new DatagridFactory($typesRegistry, $datagridRegistry);
}

protected function getExtensions(): array
Expand Down
19 changes: 17 additions & 2 deletions src/Util/DatagridFactoryBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
use Rollerworks\Component\Datagrid\Column\ResolvedColumnTypeFactoryInterface;
use Rollerworks\Component\Datagrid\DatagridExtensionInterface;
use Rollerworks\Component\Datagrid\DatagridFactory;
use Rollerworks\Component\Datagrid\DatagridRegistry;
use Rollerworks\Component\Datagrid\DatagridRegistryInterface;
use Rollerworks\Component\Datagrid\PreloadedExtension;

/**
Expand All @@ -28,6 +30,7 @@
final class DatagridFactoryBuilder
{
private $resolvedTypeFactory;
private $datagridRegistry;
private $extensions = [];
private $types = [];
private $typeExtensions = [];
Expand All @@ -44,6 +47,18 @@ public function setResolvedTypeFactory(ResolvedColumnTypeFactoryInterface $resol
return $this;
}

/**
* @param DatagridRegistryInterface $datagridRegistry
*
* @return DatagridFactoryBuilder
*/
public function setDatagridRegistry(DatagridRegistryInterface $datagridRegistry): self
{
$this->datagridRegistry = $datagridRegistry;

return $this;
}

/**
* @param DatagridExtensionInterface $extension
*
Expand Down Expand Up @@ -131,11 +146,11 @@ public function getDatagridFactory(): DatagridFactory
$extensions[] = new PreloadedExtension($this->types, $this->typeExtensions);
}

$registry = new ColumnTypeRegistry(
$typesRegistry = new ColumnTypeRegistry(
$extensions,
$this->resolvedTypeFactory ?: new ResolvedColumnTypeFactory()
);

return new DatagridFactory($registry);
return new DatagridFactory($typesRegistry, $this->datagridRegistry ?: new DatagridRegistry());
}
}
Loading

0 comments on commit 52b5bdc

Please sign in to comment.