Skip to content
This repository was archived by the owner on Feb 4, 2023. It is now read-only.

Commit dfd8a4c

Browse files
authored
Merge pull request #977 from Eloar/976_issue
refs #976: fixed Datatable name validation
2 parents 3c24bec + 7bf44a1 commit dfd8a4c

4 files changed

Lines changed: 58 additions & 6 deletions

File tree

Datatable/AbstractDatatable.php

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
namespace Sg\DatatablesBundle\Datatable;
1313

1414
use Doctrine\ORM\EntityManagerInterface;
15-
use Exception;
15+
use LogicException;
1616
use Sg\DatatablesBundle\Datatable\Column\ColumnBuilder;
1717
use Symfony\Component\PropertyAccess\PropertyAccess;
1818
use Symfony\Component\PropertyAccess\PropertyAccessor;
@@ -147,7 +147,7 @@ abstract class AbstractDatatable implements DatatableInterface
147147
protected static $uniqueCounter = [];
148148

149149
/**
150-
* @throws Exception
150+
* @throws LogicException
151151
*/
152152
public function __construct(
153153
AuthorizationCheckerInterface $authorizationChecker,
@@ -313,12 +313,13 @@ public function getUniqueName()
313313
/**
314314
* Checks the name only contains letters, numbers, underscores or dashes.
315315
*
316-
* @throws Exception
316+
* @throws LogicException
317317
*/
318318
private function validateName()
319319
{
320-
if (1 !== preg_match(self::NAME_REGEX, $this->getName())) {
321-
throw new Exception('AbstractDatatable::validateName(): The result of the getName method can only contain letters, numbers, underscore and dashes.');
320+
$name = $this->getName();
321+
if (1 !== preg_match(self::NAME_REGEX, $name)) {
322+
throw new LogicException(sprintf('AbstractDatatable::validateName(): "%s" is invalid Datatable Name. Name can only contain letters, numbers, underscore and dashes.', $name));
322323
}
323324
}
324325
}

Datatable/DatatableInterface.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
*/
2020
interface DatatableInterface
2121
{
22-
const NAME_REGEX = '/[a-zA-Z0-9\-\_]+/';
22+
const NAME_REGEX = '/^[a-zA-Z0-9\-\_]+$/';
2323

2424
/**
2525
* Builds the datatable.

Resources/doc/installation.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,11 @@ class PostDatatable extends AbstractDatatable
359359
}
360360
```
361361

362+
**Important:**
363+
When declaring datatable "by hand" as extending `AbstractDatatable` class watch out for datatable name as returned from
364+
`getName()` method. Valid datatable name may contains only letters ([a-zA-Z]), digits (0-9), dashes (-) and underscores
365+
(_). Putting any other character in name will cause `\LogicException` to be thrown.
366+
362367
### Step 2: (Optional) Registering your Datatable as a Service
363368

364369
``` yaml

Tests/DatatableTest.php

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
namespace Sg\DatatablesBundle\Tests;
1313

1414
use Doctrine\ORM\EntityManager;
15+
use ReflectionClass;
16+
use Sg\DatatablesBundle\Datatable\AbstractDatatable;
1517
use Sg\DatatablesBundle\Tests\Datatables\PostDatatable;
1618
use Symfony\Component\Routing\RouterInterface;
1719
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
@@ -64,6 +66,50 @@ public function testCreate()
6466
$table->buildDatatable();
6567
}
6668

69+
public function testInvalidName()
70+
{
71+
/** @noinspection PhpUndefinedMethodInspection */
72+
$authorizationChecker = $this->createMock(AuthorizationCheckerInterface::class);
73+
/** @noinspection PhpUndefinedMethodInspection */
74+
$securityToken = $this->createMock(TokenStorageInterface::class);
75+
/** @noinspection PhpUndefinedMethodInspection */
76+
$translator = $this->createMock(TranslatorInterface::class);
77+
/** @noinspection PhpUndefinedMethodInspection */
78+
$router = $this->createMock(RouterInterface::class);
79+
/** @noinspection PhpUndefinedMethodInspection */
80+
$twig = $this->createMock(Environment::class);
81+
82+
/** @noinspection PhpUndefinedMethodInspection */
83+
$em = $this->getMockBuilder(EntityManager::class)
84+
->disableOriginalConstructor()
85+
->setMethods(
86+
['getClassMetadata']
87+
)
88+
->getMock()
89+
;
90+
91+
// @noinspection PhpUndefinedMethodInspection
92+
$em->expects(static::any())
93+
->method('getClassMetadata')
94+
->willReturn($this->getClassMetadataMock())
95+
;
96+
97+
$mock = $this->getMockBuilder(AbstractDatatable::class)
98+
->disableOriginalConstructor()
99+
->setMethods(['getName'])
100+
->getMockForAbstractClass()
101+
;
102+
$mock->expects(static::any())
103+
->method('getName')
104+
->willReturn('invalid.name')
105+
;
106+
107+
$refledtionClass = new ReflectionClass(AbstractDatatable::class);
108+
$constructor = $refledtionClass->getConstructor();
109+
$this->expectException(\LogicException::class);
110+
$constructor->invoke($mock, $authorizationChecker, $securityToken, $translator, $router, $em, $twig);
111+
}
112+
67113
public function getClassMetadataMock()
68114
{
69115
/** @noinspection PhpUndefinedMethodInspection */

0 commit comments

Comments
 (0)