-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add an optional Twig integration to have an extension for enum labels.
- Loading branch information
1 parent
b78bc42
commit 34dffca
Showing
9 changed files
with
347 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
<?php | ||
|
||
namespace Greg0ire\Enum\Bridge\Symfony\Bundle; | ||
|
||
use Greg0ire\Enum\Bridge\Symfony\DependencyInjection\Greg0ireEnumExtension; | ||
use Symfony\Component\HttpKernel\Bundle\Bundle; | ||
|
||
/** | ||
* @author Sullivan Senechal <[email protected]> | ||
*/ | ||
final class Greg0ireEnumBundle extends Bundle | ||
{ | ||
/** | ||
* {@inheritdoc} | ||
*/ | ||
protected function getContainerExtensionClass() | ||
{ | ||
return Greg0ireEnumExtension::class; | ||
} | ||
} |
33 changes: 33 additions & 0 deletions
33
src/Bridge/Symfony/DependencyInjection/Greg0ireEnumExtension.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
<?php | ||
|
||
namespace Greg0ire\Enum\Bridge\Symfony\DependencyInjection; | ||
|
||
use Symfony\Bundle\FrameworkBundle\Translation\Translator; | ||
use Symfony\Component\Config\FileLocator; | ||
use Symfony\Component\DependencyInjection\ContainerBuilder; | ||
use Symfony\Component\DependencyInjection\Extension\Extension; | ||
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; | ||
use Symfony\Component\DependencyInjection\Reference; | ||
|
||
/** | ||
* @author Sullivan Senechal <[email protected]> | ||
*/ | ||
final class Greg0ireEnumExtension extends Extension | ||
{ | ||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function load(array $configs, ContainerBuilder $container) | ||
{ | ||
$loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); | ||
|
||
if (class_exists(\Twig_Extension::class)) { | ||
$loader->load('twig.xml'); | ||
|
||
if (class_exists(Translator::class)) { | ||
$container->getDefinition('greg0ire_enum.twig.extension.enum') | ||
->addArgument(new Reference('translator.default')); | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
<?xml version="1.0" encoding="UTF-8" ?> | ||
|
||
<container xmlns="http://symfony.com/schema/dic/services" | ||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> | ||
<services> | ||
<service id="greg0ire_enum.twig.extension.enum" class="Greg0ire\Enum\Bridge\Twig\Extension\EnumExtension"> | ||
<tag name="twig.extension"/> | ||
</service> | ||
</services> | ||
</container> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
<?php | ||
|
||
namespace Greg0ire\Enum\Bridge\Twig\Extension; | ||
|
||
use Symfony\Component\Translation\TranslatorInterface; | ||
|
||
/** | ||
* @author Sullivan Senechal <[email protected]> | ||
*/ | ||
final class EnumExtension extends \Twig_Extension | ||
{ | ||
/** | ||
* @var TranslatorInterface | ||
*/ | ||
private $translator; | ||
|
||
/** | ||
* @param TranslatorInterface $translator | ||
*/ | ||
public function __construct(TranslatorInterface $translator = null) | ||
{ | ||
$this->translator = $translator; | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function getFilters() | ||
{ | ||
return [ | ||
new \Twig_SimpleFilter('enum_label', [$this, 'label']), | ||
]; | ||
} | ||
|
||
/** | ||
* Displays the label corresponding to a specific value of an enumeration. | ||
* | ||
* @param mixed $value Must exists in the enumeration class specified with $class | ||
* @param string $class The enum class name | ||
* @param string|bool $translationDomain The translation domain to use if the translator if available. | ||
* string: Use the specified one | ||
* null: Use the default one | ||
* false: Do not use the translator | ||
* @param bool $classPrefixed Prefix the label with the enum class. Defaults to true if the translator | ||
* is available and enabled, false otherwise. | ||
* @param string $namespaceSeparator Namespace separator to use with the class prefix. | ||
* This takes effect only if $classPrefixed is true. | ||
* | ||
* @return string | ||
*/ | ||
public function label($value, $class, $translationDomain = null, $classPrefixed = null, $namespaceSeparator = null) | ||
{ | ||
// Determine if the translator can be used or not. | ||
$useTranslation = $this->translator instanceof TranslatorInterface | ||
&& (is_null($translationDomain) || is_string($translationDomain)); | ||
|
||
// If not defined, guess the default behavior. | ||
if (is_null($classPrefixed)) { | ||
$classPrefixed = $useTranslation; | ||
} | ||
|
||
$label = array_search( | ||
$value, | ||
call_user_func([$class, 'getConstants'], 'strtolower', $classPrefixed, $namespaceSeparator) | ||
); | ||
|
||
if ($useTranslation) { | ||
$translatedLabel = $this->translator->trans($label, [], $translationDomain); | ||
|
||
return $translatedLabel ?: $label; | ||
} | ||
|
||
return $label; | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function getName() | ||
{ | ||
return 'greg0ire_enum'; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
<?php | ||
|
||
namespace Greg0ire\Enum\Tests\Bridge\Symfony\Bundle; | ||
|
||
use Greg0ire\Enum\Bridge\Symfony\Bundle\Greg0ireEnumBundle; | ||
use Greg0ire\Enum\Bridge\Symfony\DependencyInjection\Greg0ireEnumExtension; | ||
use Matthias\SymfonyDependencyInjectionTest\PhpUnit\AbstractContainerBuilderTestCase; | ||
|
||
/** | ||
* @author Sullivan Senechal <[email protected]> | ||
*/ | ||
final class Greg0ireEnumBundleTest extends AbstractContainerBuilderTestCase | ||
{ | ||
/** | ||
* @var Greg0ireEnumBundle | ||
*/ | ||
private $bundle; | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
protected function setUp() | ||
{ | ||
parent::setUp(); | ||
|
||
$this->bundle = new Greg0ireEnumBundle(); | ||
} | ||
|
||
public function testBuild() | ||
{ | ||
$this->bundle->build($this->container); | ||
} | ||
|
||
public function testGetContainerExtension() | ||
{ | ||
$this->assertInstanceOf(Greg0ireEnumExtension::class, $this->bundle->getContainerExtension()); | ||
} | ||
} |
36 changes: 36 additions & 0 deletions
36
test/Bridge/Symfony/DependencyInjection/Greg0ireEnumExtensionTest.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
<?php | ||
|
||
namespace Greg0ire\Enum\Tests\Bridge\Symfony\DependencyInjection; | ||
|
||
use Greg0ire\Enum\Bridge\Symfony\DependencyInjection\Greg0ireEnumExtension; | ||
use Greg0ire\Enum\Bridge\Twig\Extension\EnumExtension; | ||
use Matthias\SymfonyDependencyInjectionTest\PhpUnit\AbstractExtensionTestCase; | ||
use Symfony\Component\DependencyInjection\Reference; | ||
|
||
/** | ||
* @author Sullivan Senechal <[email protected]> | ||
*/ | ||
final class Greg0ireEnumExtensionTest extends AbstractExtensionTestCase | ||
{ | ||
public function testLoad() | ||
{ | ||
$this->load(); | ||
|
||
$this->assertContainerBuilderHasService('greg0ire_enum.twig.extension.enum', EnumExtension::class); | ||
$this->assertContainerBuilderHasServiceDefinitionWithArgument( | ||
'greg0ire_enum.twig.extension.enum', | ||
0, | ||
new Reference('translator.default') | ||
); | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
protected function getContainerExtensions() | ||
{ | ||
return [ | ||
new Greg0ireEnumExtension(), | ||
]; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
<?php | ||
|
||
namespace Greg0ire\Enum\Tests\Bridge\Twig\Extension; | ||
|
||
use Greg0ire\Enum\Bridge\Twig\Extension\EnumExtension; | ||
use Greg0ire\Enum\Tests\Fixtures\FooEnum; | ||
use Greg0ire\Enum\Tests\Fixtures\FooInterface; | ||
use Symfony\Component\Translation\TranslatorInterface; | ||
|
||
/** | ||
* @author Sullivan Senechal <[email protected]> | ||
*/ | ||
final class EnumExtensionTest extends \PHPUnit_Framework_TestCase | ||
{ | ||
/** | ||
* @var TranslatorInterface|\PHPUnit_Framework_MockObject_MockObject | ||
*/ | ||
private $translator; | ||
|
||
/** | ||
* @var EnumExtension | ||
*/ | ||
private $extension; | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
protected function setUp() | ||
{ | ||
$this->translator = $this->getMock(TranslatorInterface::class); | ||
$this->extension = new EnumExtension($this->translator); | ||
} | ||
|
||
public function testEnvironment() | ||
{ | ||
$twig = new \Twig_Environment(); | ||
$twig->addExtension($this->extension); | ||
|
||
$this->assertTrue($twig->hasExtension('greg0ire_enum')); | ||
$this->assertInstanceOf(\Twig_SimpleFilter::class, $twig->getFilter('enum_label')); | ||
} | ||
|
||
/** | ||
* @dataProvider getLabels | ||
*/ | ||
public function testLabel($value, $class, $classPrefix, $separator, $expectedResult) | ||
{ | ||
$this->assertSame( | ||
$expectedResult, | ||
$this->extension->label($value, $class, false, $classPrefix, $separator) | ||
); | ||
} | ||
|
||
public function getLabels() | ||
{ | ||
return [ | ||
[FooInterface::CHUCK, FooEnum::class, false, null, 'chuck'], | ||
[FooInterface::CHUCK, FooEnum::class, true, null, 'greg0ire_enum_tests_fixtures_foo_enum_chuck'], | ||
[FooInterface::CHUCK, FooEnum::class, true, '.', 'greg0ire.enum.tests.fixtures.foo_enum.chuck'], | ||
]; | ||
} | ||
|
||
public function testLabelWithTranslator() | ||
{ | ||
$this->translator->expects($this->once()) | ||
->method('trans')->with('greg0ire_enum_tests_fixtures_foo_enum_chuck', [], 'test'); | ||
|
||
$this->assertSame( | ||
'greg0ire_enum_tests_fixtures_foo_enum_chuck', | ||
$this->extension->label(FooInterface::CHUCK, FooEnum::class, 'test'), | ||
'Without any available translation, the filter should just return the key.' | ||
); | ||
} | ||
} |