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

Commit

Permalink
Introduce the BaseType / data_provider for subcols
Browse files Browse the repository at this point in the history
Both ColumnType and CompoundColumnType share a set of common logic, which was duplicated.

The CompoundColumnBuilder now allows to configure a `data_provider` that will be used as a default
for all sub-columns. No more duplicating a data_provider for Actions 😆
  • Loading branch information
sstok committed Sep 26, 2016
1 parent 9371dfc commit d3dbb9a
Show file tree
Hide file tree
Showing 9 changed files with 167 additions and 69 deletions.
67 changes: 67 additions & 0 deletions src/Extension/Core/Type/BaseType.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<?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\Extension\Core\Type;

use Rollerworks\Component\Datagrid\Column\AbstractType;
use Rollerworks\Component\Datagrid\Column\ColumnInterface;
use Rollerworks\Component\Datagrid\Column\HeaderView;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\PropertyAccess\PropertyPath;

/**
* Encapsulates common logic of {@link ColumnType} and {@link ComponendColumnType}.
*
* This type does not appear in the column's type inheritance chain and as such
* cannot be extended (via {@link \Rollerworks\Component\Datagrid\Column\ColumnTypeExtensionInterface}) nor themed.
*
* @author Sebastiaan Stok <s.stok@rollerscapes.net>
*/
abstract class BaseType extends AbstractType
{
public function buildHeaderView(HeaderView $view, ColumnInterface $column, array $options)
{
$view->attributes = array_replace($view->attributes, [
'label_attr' => $options['label_attr'],
'header_attr' => $options['header_attr'],
'cell_attr' => $options['header_attr'],
'label_translation_domain' => $options['label_translation_domain'],
]);
}

public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'label' => null,
'label_attr' => [],
'header_attr' => [],
'cell_attr' => [],
'label_translation_domain' => null,
]);

$resolver->setDefault('parent_column', null);
$resolver->setDefault('data_provider', null);

$resolver->setAllowedTypes('label', ['string', 'null']);
$resolver->setAllowedTypes('label_attr', 'array');
$resolver->setAllowedTypes('header_attr', 'array');
$resolver->setAllowedTypes('cell_attr', 'array');

$resolver->setAllowedTypes('data_provider', ['Closure', 'null', 'string', PropertyPath::class]);
}

public function getParent()
{
// no-op.
}
}
36 changes: 6 additions & 30 deletions src/Extension/Core/Type/ColumnType.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,7 @@

namespace Rollerworks\Component\Datagrid\Extension\Core\Type;

use Rollerworks\Component\Datagrid\Column\CellView;
use Rollerworks\Component\Datagrid\Column\ColumnInterface;
use Rollerworks\Component\Datagrid\Column\ColumnTypeInterface;
use Rollerworks\Component\Datagrid\Column\HeaderView;
use Rollerworks\Component\Datagrid\Exception\DataProviderException;
use Rollerworks\Component\Datagrid\Util\StringUtil;
use Symfony\Component\OptionsResolver\OptionsResolver;
Expand All @@ -25,7 +22,7 @@
use Symfony\Component\PropertyAccess\PropertyAccessor;
use Symfony\Component\PropertyAccess\PropertyPath;

class ColumnType implements ColumnTypeInterface
class ColumnType extends BaseType
{
/**
* @var PropertyAccessor
Expand All @@ -51,11 +48,10 @@ public function __construct(PropertyAccessor $propertyAccessor = null)
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(['data_provider' => null, 'label' => null]);
$resolver->setDefault('parent_column', null);
parent::configureOptions($resolver);

$resolver->setAllowedTypes('label', ['string', 'null']);
$resolver->setAllowedTypes('data_provider', ['Closure', 'null', 'string', PropertyPath::class]);
$resolver->setDefault('parent_data_provider', null);
$resolver->setAllowedTypes('parent_data_provider', ['Closure', 'null']);
}

/**
Expand All @@ -64,9 +60,10 @@ public function configureOptions(OptionsResolver $resolver)
public function buildColumn(ColumnInterface $column, array $options)
{
$dataProvider = $options['data_provider'];
$parentDataProvider = $options['parent_data_provider'];

if (!$dataProvider instanceof \Closure) {
$dataProvider = function ($data) use ($column, $dataProvider) {
$dataProvider = $parentDataProvider ?: function ($data) use ($column, $dataProvider) {
static $path;

if (null === $path) {
Expand All @@ -80,27 +77,6 @@ public function buildColumn(ColumnInterface $column, array $options)
$column->setDataProvider($dataProvider);
}

/**
* {@inheritdoc}
*/
public function buildCellView(CellView $view, ColumnInterface $column, array $options)
{
}

/**
* {@inheritdoc}
*/
public function buildHeaderView(HeaderView $view, ColumnInterface $column, array $options)
{
}

/**
* {@inheritdoc}
*/
public function getParent()
{
}

/**
* Returns the prefix of the template block name for this type.
*
Expand Down
24 changes: 2 additions & 22 deletions src/Extension/Core/Type/CompoundColumnType.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,34 +24,14 @@
*
* @author Sebastiaan Stok <s.stok@rollerscapes.net>
*/
class CompoundColumnType extends AbstractType
class CompoundColumnType extends BaseType
{
/**
* {@inheritdoc}
*/
public function getParent()
{
return;
}

/**
* {@inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefault('label', null);
$resolver->setDefault('parent_column', null);

// Not used but required by the ResolvedColumnType
$resolver->setAllowedTypes('label', ['string', 'null']);
}

/**
* {@inheritdoc}
*/
public function buildColumn(ColumnInterface $column, array $options)
{
// Simple pass all $data to the sub-columns;
// Simple pass all $data to the sub-columns.
$column->setDataProvider(
function ($data) {
return $data;
Expand Down
17 changes: 14 additions & 3 deletions src/Util/CompoundColumnBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,13 @@
* A CompoundColumn allows to group multiple columns together,
* eg. one more more date value or one or more row actions.
*
* The 'data_provider' of the CompoundColumn will be set as the 'data_provider'
* for each sub-column, unless a sub column sets the 'data_provider' explicitly.
*
* <code>
* createCompound('actions', ['label' => 'Actions'])
* ->add('edit', ActionType::class, ['data_provider' => '[id]', 'url_schema' => '/users/{id}/edit'])
* ->add('delete', ActionType::class, ['data_provider' => '[id]', 'url_schema' => '/users/{id}/edit'])
* createCompound('actions', ['label' => 'Actions', 'data_provider' => function ($data) {return ['id' => $data->id();}])
* ->add('edit', ActionType::class, ['url_schema' => '/users/{id}/edit'])
* ->add('delete', ActionType::class, ['url_schema' => '/users/{id}/edit'])
* ->end() // This registers the CompoundColumn at the DatagridBuilder, and return the DatagridBuilder.
* </code>
*/
Expand All @@ -47,6 +50,10 @@ public function __construct(
array $options = [],
string $type = null
) {
if (!isset($options['data_provider'])) {
$options['data_provider'] = null;
}

$this->factory = $factory;
$this->builder = $builder;
$this->name = $name;
Expand Down Expand Up @@ -102,6 +109,10 @@ public function end(): DatagridBuilderInterface
$columns = [];

foreach ($this->unresolvedColumns as $n => $column) {
if (!isset($column['options']['data_provider'])) {
$column['options']['data_provider'] = $this->options['data_provider'];
}

$columns[$n] = $this->factory->createColumn(
$n,
$column['type'],
Expand Down
7 changes: 6 additions & 1 deletion tests/DatagridBuilderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,12 @@ public function it_generates_a_compoundColumn()

$datagrid = $builder->getDatagrid('my_grid');

self::assertDatagridHasColumn($datagrid, 'actions', CompoundColumnType::class, ['abel' => 'act']);
self::assertDatagridHasColumn(
$datagrid,
'actions',
CompoundColumnType::class,
['abel' => 'act', 'data_provider' => null]
);
}

/** @test */
Expand Down
26 changes: 18 additions & 8 deletions tests/DatagridPerformanceTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -69,15 +69,20 @@ public function testGenerateViewWith100RowsAnd10Columns()
$datagrid->add('group', TextType::class);

$datagrid
->createCompound('actions', ['label' => 'Actions'])
->createCompound(
'actions',
[
'label' => 'Actions',
'data_provider' => function ($data) {
return ['id' => $data['id']];
},
]
)
->add(
'modify',
ActionType::class,
[
'label' => 'Modify',
'data_provider' => function ($data) {
return ['id' => $data['id']];
},
'uri_scheme' => 'entity/{id}/modify',
]
)
Expand Down Expand Up @@ -150,15 +155,20 @@ public function testGenerateViewWith100RowsAnd10ColumnsAutoDataProvider()
$datagrid->add('group', TextType::class);

$datagrid
->createCompound('actions', ['label' => 'Actions'])
->createCompound(
'actions',
[
'label' => 'Actions',
'data_provider' => function ($data) {
return ['id' => $data['id']];
},
]
)
->add(
'modify',
ActionType::class,
[
'label' => 'Modify',
'data_provider' => function ($data) {
return ['id' => $data['id']];
},
'uri_scheme' => 'entity/{id}/modify',
]
)
Expand Down
21 changes: 20 additions & 1 deletion tests/Extension/Core/Type/ColumnTypeTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,17 @@

class ColumnTypeTest extends BaseTypeTest
{
public function testPassLabelToView()
public function testPassLabelAndOtherToView()
{
$column = $this->factory->createColumn(
'id',
$this->getTestedType(),
[
'label' => 'My label',
'label_attr' => ['class' => 'info' ],
'header_attr' => ['class' => 'striped'],
'cell_attr' => ['class' => 'striped'],
'label_translation_domain' => 'messages',
'data_provider' => function ($data) {
return $data->key;
},
Expand All @@ -43,6 +47,21 @@ public function testPassLabelToView()
$view = $column->createHeaderView($view);

$this->assertSame('My label', $view->label);
$this->assertEquals(
[
'label_attr' => [
'class' => 'info',
],
'header_attr' => [
'class' => 'striped',
],
'cell_attr' => [
'class' => 'striped',
],
'label_translation_domain' => 'messages',
],
$view->attributes
);
}

public function testAutoConfigurationDataProvider()
Expand Down
21 changes: 20 additions & 1 deletion tests/Extension/Core/Type/DateTimeTypeTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,17 @@

class DateTimeTypeTest extends BaseTypeTest
{
public function testPassLabelToView()
public function testPassLabelAndOtherToView()
{
$column = $this->factory->createColumn(
'id',
$this->getTestedType(),
[
'label' => 'My label',
'label_attr' => ['class' => 'info' ],
'header_attr' => ['class' => 'striped'],
'cell_attr' => ['class' => 'striped'],
'label_translation_domain' => 'messages',
'data_provider' => function ($data) {
return $data->key;
},
Expand All @@ -42,6 +46,21 @@ public function testPassLabelToView()
$view = $column->createHeaderView($view);

$this->assertSame('My label', $view->label);
$this->assertEquals(
[
'label_attr' => [
'class' => 'info',
],
'header_attr' => [
'class' => 'striped',
],
'cell_attr' => [
'class' => 'striped',
],
'label_translation_domain' => 'messages',
],
$view->attributes
);
}

protected function getTestedType(): string
Expand Down
17 changes: 14 additions & 3 deletions tests/Util/CompoundColumnBuilderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -89,16 +89,27 @@ function ($column) use (&$compoundColumn) {
}

self::assertEquals('actions', $compoundColumn->getName());
self::assertEquals(['label' => 'act'], $compoundColumn->getOptions());
self::assertEquals(['label' => 'act', 'data_provider' => null], $compoundColumn->getOptions());

$columns = $compoundColumn->getColumns();

self::assertArrayHasKey('id', $columns);
self::assertArrayHasKey('name', $columns);
self::assertArrayNotHasKey('date', $columns);

self::assertColumnEquals($columns['id'], 'id', NumberType::class, ['parent_column' => $compoundColumn]);
self::assertColumnEquals($columns['name'], 'name', TextType::class, ['format' => '%s', 'parent_column' => $compoundColumn]);
self::assertColumnEquals(
$columns['id'],
'id',
NumberType::class,
['parent_column' => $compoundColumn, 'data_provider' => null]
);

self::assertColumnEquals(
$columns['name'],
'name',
TextType::class,
['format' => '%s', 'parent_column' => $compoundColumn, 'data_provider' => null]
);
}

private static function assertColumnEquals(
Expand Down

0 comments on commit d3dbb9a

Please sign in to comment.