Skip to content

Commit

Permalink
Merge pull request #231 from FriendsOfCake/field-formatter
Browse files Browse the repository at this point in the history
Add ability to set field formatters based on column type.
  • Loading branch information
josegonzalez authored Feb 5, 2018
2 parents ac6d8a0 + 10651c9 commit acf81af
Show file tree
Hide file tree
Showing 10 changed files with 286 additions and 19 deletions.
24 changes: 22 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,22 +1,42 @@
language: php

php:
- 5.6
- 7.0
- 7.1
- 7.2

env:
global:
- DEFAULT=1

matrix:
fast_finish: true

include:
- php: 7.0
env: PHPCS=1
env: PHPCS=1 DEFAULT=0

- php: 7.0
env: PHPSTAN=1
env: PHPSTAN=1 DEFAULT=0

before_script:
- if [[ $TRAVIS_PHP_VERSION != 7.0 ]]; then phpenv config-rm xdebug.ini; fi

- composer install --prefer-dist --no-interaction

- if [[ $PHPCS = 1 ]]; then composer require cakephp/cakephp-codesniffer:dev-master; fi
- if [[ $PHPSTAN = 1 ]]; then composer require phpstan/phpstan:^0.8; fi

script:
- if [[ $DEFAULT = 1 && $TRAVIS_PHP_VERSION != 7.0 ]]; then vendor/bin/phpunit; fi
- if [[ $DEFAULT = 1 && $TRAVIS_PHP_VERSION = 7.0 ]]; then vendor/bin/phpunit --coverage-clover=clover.xml; fi

- if [[ $PHPCS = 1 ]]; then vendor/bin/phpcs -p --extensions=php --standard=vendor/cakephp/cakephp-codesniffer/CakePHP src/ config/; fi
- if [[ $PHPSTAN = 1 ]]; then vendor/bin/phpstan analyse -l 5 src; fi

after_success:
- if [[ $DEFAULT = 1 && $TRAVIS_PHP_VERSION = 7.0 ]]; then bash <(curl -s https://codecov.io/bash); fi

notifications:
email: false
8 changes: 7 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,19 @@
},
"require-dev": {
"friendsofcake/cakephp-test-utilities": "dev-master",
"markstory/asset_compress": "^3.2"
"markstory/asset_compress": "^3.2",
"phpunit/phpunit": "^5.7|^6.0"
},
"autoload": {
"psr-4": {
"CrudView\\": "src"
}
},
"autoload-dev": {
"psr-4": {
"CrudView\\Test\\": "tests"
}
},
"support": {
"source": "https://github.com/FriendsOfCake/crud-view",
"issues": "https://github.com/FriendsOfCake/crud-view/issues",
Expand Down
2 changes: 1 addition & 1 deletion docs/.editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ root = false

[*]
indent_style = space
indent_size = 2
indent_size = 4
charset = "utf-8"
end_of_line = lf
insert_final_newline = true
Expand Down
21 changes: 21 additions & 0 deletions docs/_partials/fields/formatter-callable.rst
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,24 @@ In some cases, it may be useful to access a helper within the callable. For inst
}
],
]);
You can also keep your code DRY by configuring the ``CrudViewHelper`` to use
a callable formatter based on column type. For .e.g.

.. code-block:: php
// In controller action or preferably in beforeRender()
$this->viewBuilder()->setHelpers([
'CrudView' => [
'className' => 'CrudView.CrudView',
'fieldFormatters' => [
// Key can be any valid column type of table schema.
'datetime' => function ($name, $value, $entity, $options, $View) {
return $View->Time->nice($value);
},
'boolean' => function ($name, $value, $entity, $options, $View) {
return $value ? 'Yes' : 'No';
},
],
],
]);
37 changes: 37 additions & 0 deletions phpunit.xml.dist
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit
colors="true"
processIsolation="false"
stopOnFailure="false"
syntaxCheck="false"
bootstrap="./tests/bootstrap.php"
>
<php>
<ini name="memory_limit" value="-1"/>
</php>

<!-- Add any additional test suites you want to run here -->
<testsuites>
<testsuite name="CrudView Tests">
<directory>./tests/TestCase</directory>
</testsuite>
<!-- Add plugin test suites here. -->
</testsuites>

<!-- Setup a listener for fixtures -->
<listeners>
<listener
class="\Cake\TestSuite\Fixture\FixtureInjector"
file="./vendor/cakephp/cakephp/src/TestSuite/Fixture/FixtureInjector.php">
<arguments>
<object class="\Cake\TestSuite\Fixture\FixtureManager" />
</arguments>
</listener>
</listeners>

<filter>
<whitelist>
<directory suffix=".php">./src/</directory>
</whitelist>
</filter>
</phpunit>
59 changes: 44 additions & 15 deletions src/View/CrudView.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,16 @@

use Cake\Core\Configure;
use Cake\Core\Plugin;
use Cake\Event\Event;
use Cake\Event\EventListenerInterface;
use Cake\View\Exception\MissingTemplateException;
use Cake\View\View;
use CrudView\Traits\CrudViewConfigTrait;

/**
* @property \AssetCompress\View\Helper\AssetCompressHelper $AssetCompress
*/
class CrudView extends View
class CrudView extends View implements EventListenerInterface
{
use CrudViewConfigTrait;

Expand All @@ -37,9 +39,33 @@ public function initialize()
{
parent::initialize();

$this->getEventManager()->on($this, ['priority' => 9]);
$this->ensureConfig();
$this->_setupPaths();
$this->_setupHelpers();
}

/**
* Events this class is interested in.
*
* @return array
*/
public function implementedEvents()
{
return [
'View.beforeLayout' => 'beforeLayout',
];
}

/**
* Handler for View.beforeLayout event.
*
* @param \Cake\Event\Event $event The View.beforeLayout event
* @param string $layoutFileName Layout filename.
* @return void
*/
public function beforeLayout(Event $event, $layoutFileName)
{
$this->_loadAssets();
}

Expand Down Expand Up @@ -83,25 +109,28 @@ protected function _loadAssets()
*/
protected function _setupHelpers()
{
$this->loadHelper('Html', ['className' => 'BootstrapUI.Html']);
$this->loadHelper('Form', [
'className' => 'BootstrapUI.Form',
'widgets' => [
'datetime' => ['CrudView\View\Widget\DateTimeWidget', 'select']
]
]);
$this->loadHelper('Flash', ['className' => 'BootstrapUI.Flash']);
$this->loadHelper('Paginator', ['className' => 'BootstrapUI.Paginator']);
$helpers = [
'Html' => ['className' => 'BootstrapUI.Html'],
'Form' => [
'className' => 'BootstrapUI.Form',
'widgets' => [
'datetime' => ['CrudView\View\Widget\DateTimeWidget', 'select']
],
],
'Flash' => ['className' => 'BootstrapUI.Flash'],
'Paginator' => ['className' => 'BootstrapUI.Paginator'],
'CrudView' => ['className' => 'CrudView.CrudView'],
];

if (class_exists('\Cake\View\Helper\BreadcrumbsHelper')) {
$this->loadHelper('Breadcrumbs', ['className' => 'BootstrapUI.Breadcrumbs']);
$helpers['Breadcrumbs'] = ['className' => 'BootstrapUI.Breadcrumbs'];
}

$this->loadHelper('CrudView.CrudView');
$this->loadHelper('BootstrapUI.Flash');

if (Configure::read('CrudView.useAssetCompress')) {
$this->loadHelper('AssetCompress.AssetCompress');
$helpers['AssetCompress'] = ['className' => 'AssetCompress.AssetCompress'];
}

$this->helpers = array_merge($helpers, $this->helpers);
}

/**
Expand Down
18 changes: 18 additions & 0 deletions src/View/Helper/CrudViewHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,15 @@ class CrudViewHelper extends Helper
*/
protected $_context;

/**
* Default config.
*
* @var array
*/
protected $_defaultConfig = [
'fieldFormatters' => null
];

/**
* Set context
*
Expand Down Expand Up @@ -123,6 +132,15 @@ public function introspect($field, $value, array $options = [])

$type = $this->columnType($field);

$fieldFormatters = $this->getConfig('fieldFormatters');
if (isset($fieldFormatters[$type])) {
if (is_callable($fieldFormatters[$type])) {
return $fieldFormatters[$type]($field, $value, $this->getContext(), $options, $this->getView());
}

return $this->{$fieldFormatters[$type]}($field, $value, $options);
}

if ($type === 'boolean') {
return $this->formatBoolean($field, $value, $options);
}
Expand Down
35 changes: 35 additions & 0 deletions tests/TestCase/View/CrudViewTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php
namespace CrudView\Test\TestCase\View;

use Cake\TestSuite\TestCase;
use CrudView\View\CrudView;

/**
* ViewTest class
*/
class ViewTest extends TestCase
{
public function testCreation()
{
$CrudView = new CrudView(
null,
null,
null,
[
'helpers' => [
'CrudView' => [
'className' => 'CrudView.CrudView',
'fieldFormatters' => ['datetime' => 'formatTime']
]
]
]
);

$expected = [
'className' => 'CrudView.CrudView',
'fieldFormatters' => ['datetime' => 'formatTime'],
];
$result = $CrudView->CrudView->getConfig();
$this->assertEquals($expected, $result);
}
}
75 changes: 75 additions & 0 deletions tests/TestCase/View/Helper/CrudViewHelperTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<?php
namespace CrudView\Test\TestCase\View\Helper;

use Cake\I18n\FrozenTime;
use Cake\TestSuite\TestCase;
use Cake\View\View;
use CrudView\View\Helper\CrudViewHelper;

/**
* CrudViewHelperTest class
*/
class CrudViewHelperTest extends TestCase
{
/**
* Helper to be tested
*
* @var \Cake\View\Helper\CrudViewHelper
*/
public $CrudView;

/**
* Mocked view
*
* @var \Cake\View\View|\PHPUnit_Framework_MockObject_MockObject
*/
public $View;

/**
* setUp method
*
* @return void
*/
public function setUp()
{
parent::setUp();

$this->View = $this->getMockBuilder(View::class)
->setMethods()
->getMock();

static::setAppNamespace();
}

public function testIntrospect()
{
$this->CrudView = $this->getMockBuilder(CrudViewHelper::class)
->setConstructorArgs([$this->View])
->setMethods(['columnType'])
->getMock();

$this->CrudView
->expects($this->any())
->method('columnType')
->with('created')
->will($this->returnValue('datetime'));

$value = new FrozenTime();
$result = $this->CrudView->introspect('created', $value);
$this->assertEquals('just now', $result);

$this->CrudView->setConfig('fieldFormatters', [
'datetime' => 'formatTime',
]);
$result = $this->CrudView->introspect('created', $value);
$this->assertEquals($this->CrudView->Time->nice($value), $result);

$this->CrudView->setConfig('fieldFormatters', [
'datetime' => function () {
return 'formatted time';
},
]);
$result = $this->CrudView->introspect('created', $value);
$this->assertEquals('formatted time', $result);
}
}
Loading

0 comments on commit acf81af

Please sign in to comment.