Skip to content

Commit

Permalink
Drop Twig 1.x support / Add Twig 3.x support (#1270)
Browse files Browse the repository at this point in the history
* Drop Twig 1.x support

* Avoid using internal method/class usage

* Support Twig 3.x

* Update tests
  • Loading branch information
deguif authored Oct 7, 2020
1 parent ec9cdaf commit b7af516
Show file tree
Hide file tree
Showing 11 changed files with 89 additions and 138 deletions.
8 changes: 5 additions & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ matrix:
fast_finish: true
include:
- php: 7.2
env: SYMFONY_REQUIRE="^4.4"
env:
- SYMFONY_REQUIRE="^4.4"
- TWIG_VERSION="^2.9"
- php: 7.3
- php: 7.4
- php: nightly
Expand All @@ -20,8 +22,8 @@ before_install:
- composer global require --no-progress --no-scripts --no-plugins symfony/flex dev-master

install:
- if [ "$SYMFONY_VERSION" != "" ]; then composer require "symfony/symfony:${SYMFONY_VERSION}" --no-update; fi;
- composer update --prefer-source --no-interaction --no-scripts $COMPOSER_FLAGS
- if [ "$TWIG_VERSION" != "" ]; then composer require "twig/twig:${TWIG_VERSION}" --no-update; fi;
- composer update --prefer-dist --no-interaction --no-scripts $COMPOSER_FLAGS

script:
- vendor/bin/phpunit
Expand Down
1 change: 1 addition & 0 deletions Form/Extension/TabbedFormTypeExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ public function finishView(FormView $view, FormInterface $form, array $options)

$tabs[$tabIndex] = [
'id' => $child->vars['id'],
'name' => $child->vars['name'],
'label' => $child->vars['label'],
'icon' => $child->vars['icon'],
'active' => false,
Expand Down
6 changes: 5 additions & 1 deletion Resources/views/Form/fields.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,11 @@
<li{% if class|trim is not empty %} class="{{ class }}"{% endif %}>
<a data-toggle="tab" href="#{{ tab.id }}">
{% if tab.icon %}{{ mopa_bootstrap_icon(tab.icon) }}{% endif %}
{{ tab.translation_domain is same as(false) ? tab.label : tab.label|trans({}, tab.translation_domain) }}
{%- if tab.label is not empty -%}
{{ tab.translation_domain is same as(false) ? tab.label : tab.label|trans({}, tab.translation_domain) }}
{%- elseif tab.label is not same as(false) -%}
{{ tab.translation_domain is same as(false) ? tab.name|humanize : tab.name|humanize|trans({}, tab.translation_domain) }}
{%- endif -%}
</a>
</li>
{% endfor %}
Expand Down
44 changes: 13 additions & 31 deletions Tests/Form/AbstractDivLayoutTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,20 +21,22 @@
use Mopa\Bundle\BootstrapBundle\Form\Extension\WidgetCollectionFormTypeExtension;
use Mopa\Bundle\BootstrapBundle\Form\Extension\WidgetFormTypeExtension;
use Mopa\Bundle\BootstrapBundle\Form\Type\TabType;
use Mopa\Bundle\BootstrapBundle\Tests\Stub\StubTranslator;
use Mopa\Bundle\BootstrapBundle\Twig\FormExtension as TwigFormExtension;
use Mopa\Bundle\BootstrapBundle\Twig\IconExtension;
use Symfony\Bridge\Twig\Extension\FormExtension;
use Symfony\Bridge\Twig\Extension\TranslationExtension;
use Symfony\Bridge\Twig\Form\TwigRenderer;
use Symfony\Bridge\Twig\Form\TwigRendererEngine;
use Symfony\Bridge\Twig\Tests\Extension\Fixtures\StubTranslator;
use Symfony\Component\Form\Extension\Core\Type\FormType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormRenderer;
use Symfony\Component\Form\Forms;
use Symfony\Component\Form\FormView;
use Symfony\Component\Form\PreloadedExtension;
use Symfony\Component\Form\Test\FormIntegrationTestCase;
use Twig\Environment;
use Twig\Loader\FilesystemLoader;
use Twig\RuntimeLoader\FactoryRuntimeLoader;

abstract class AbstractDivLayoutTest extends FormIntegrationTestCase
{
Expand All @@ -43,28 +45,24 @@ abstract class AbstractDivLayoutTest extends FormIntegrationTestCase
protected $environment;
protected $tabFactory;

/**
* @throws \Twig_Error_Loader
*/
protected function setUp(): void
{
// Setup factory for tabs
$this->tabFactory = Forms::createFormFactory();

parent::setUp();

$reflectionClass = \class_exists('Symfony\Bridge\Twig\Form\TwigRenderer') ? 'Symfony\Bridge\Twig\Form\TwigRenderer' : 'Symfony\Bridge\Twig\Form\TwigRendererEngine';
$reflection = new \ReflectionClass($reflectionClass);
$reflection = new \ReflectionClass(TwigRendererEngine::class);
$bridgeDirectory = \dirname($reflection->getFileName()).'/../Resources/views/Form';

$loader = new \Twig_Loader_Filesystem([
$loader = new FilesystemLoader([
$bridgeDirectory,
__DIR__.'/../../Resources/views/Form',
]);

$loader->addPath(__DIR__.'/../../Resources/views', 'MopaBootstrap');

$this->environment = new \Twig_Environment($loader, ['strict_variables' => true]);
$this->environment = new Environment($loader, ['strict_variables' => true]);
$this->environment->addExtension(new TranslationExtension(new StubTranslator()));
$this->environment->addExtension(new IconExtension('fontawesome'));
$this->environment->addExtension(new TwigFormExtension());
Expand All @@ -75,31 +73,15 @@ protected function setUp(): void
'fields.html.twig',
], $this->environment);

$this->setUpVersion4Plus();
}

private function setUpVersion4Plus()
{
$csrfProvider = $this->getMockBuilder('Symfony\Component\Security\Csrf\CsrfTokenManagerInterface')->getMock();
$loaders = [
'Symfony\Component\Form\FormRenderer' => function () use ($csrfProvider) {
return new FormRenderer($this->rendererEngine, $csrfProvider);
},
];

$runtime = 'Symfony\Component\Form\FormRenderer';

if (\class_exists('Symfony\Bridge\Twig\Form\TwigRenderer')) {
$loaders['Symfony\Bridge\Twig\Form\TwigRenderer'] = function () use ($csrfProvider) {
return new TwigRenderer($this->rendererEngine, $csrfProvider);
};

$runtime = 'Symfony\Bridge\Twig\Form\TwigRenderer';
}

// Add runtime loader
$this->environment->addRuntimeLoader(new \Twig_FactoryRuntimeLoader($loaders));
$this->renderer = $this->environment->getRuntime($runtime);
$this->environment->addRuntimeLoader(new FactoryRuntimeLoader([
FormRenderer::class => function () use ($csrfProvider) {
return new FormRenderer($this->rendererEngine, $csrfProvider);
},
]));
$this->renderer = $this->environment->getRuntime(FormRenderer::class);

$this->environment->addExtension(new FormExtension());
}
Expand Down
22 changes: 22 additions & 0 deletions Tests/Stub/StubTranslator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

/*
* This file is part of the MopaBootstrapBundle.
*
* (c) Philipp A. Mohrenweiser <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Mopa\Bundle\BootstrapBundle\Tests\Stub;

use Symfony\Contracts\Translation\TranslatorInterface;

class StubTranslator implements TranslatorInterface
{
public function trans(string $id, array $parameters = [], string $domain = null, string $locale = null): string
{
return '[trans]'.\strtr($id, $parameters).'[/trans]';
}
}
23 changes: 6 additions & 17 deletions Twig/FlashExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,33 +11,30 @@

namespace Mopa\Bundle\BootstrapBundle\Twig;

use Twig\Extension\AbstractExtension;
use Twig\TwigFunction;

/**
* MopaBootstrap Flash Extension.
*
* @author Nikolai Zujev (jaymecd) <[email protected]>
*/
class FlashExtension extends \Twig_Extension
class FlashExtension extends AbstractExtension
{
/**
* @var array
*/
protected $mapping = [];

/**
* Constructor.
*/
public function __construct(array $mapping)
{
$this->mapping = $mapping;
}

/**
* {@inheritdoc}
*/
public function getFunctions()
public function getFunctions(): array
{
return [
new \Twig_SimpleFunction('mopa_bootstrap_flash_mapping', [$this, 'getMapping'], ['is_safe' => ['html']]),
new TwigFunction('mopa_bootstrap_flash_mapping', [$this, 'getMapping'], ['is_safe' => ['html']]),
];
}

Expand All @@ -50,12 +47,4 @@ public function getMapping()
{
return $this->mapping;
}

/**
* {@inheritdoc}
*/
public function getName()
{
return 'mopa_bootstrap_flash';
}
}
26 changes: 7 additions & 19 deletions Twig/FormExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@

namespace Mopa\Bundle\BootstrapBundle\Twig;

use Twig\Extension\AbstractExtension;
use Twig\TwigFunction;

/**
* Twig extension for form.
*
Expand All @@ -19,34 +22,19 @@
* @author Paweł Madej (nysander) <[email protected]>
* @author Charles Sanquer <[email protected]>
*/
class FormExtension extends \Twig_Extension
class FormExtension extends AbstractExtension
{
/**
* Returns a list of functions to add to the existing list.
*
* @return array An array of functions
*/
public function getFunctions()
public function getFunctions(): array
{
return [
new \Twig_SimpleFunction('form_help', null, [
new TwigFunction('form_help', null, [
'node_class' => 'Symfony\Bridge\Twig\Node\SearchAndRenderBlockNode',
'is_safe' => ['html'],
]),
new \Twig_SimpleFunction('form_tabs', null, [
new TwigFunction('form_tabs', null, [
'node_class' => 'Symfony\Bridge\Twig\Node\SearchAndRenderBlockNode',
'is_safe' => ['html'],
]),
];
}

/**
* Returns the name of the extension.
*
* @return string The extension name
*/
public function getName()
{
return 'bootstrap_form';
}
}
45 changes: 15 additions & 30 deletions Twig/IconExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,58 +11,56 @@

namespace Mopa\Bundle\BootstrapBundle\Twig;

use Symfony\Component\HttpFoundation\Response;
use Twig\Environment;
use Twig\Extension\AbstractExtension;
use Twig\TemplateWrapper;
use Twig\TwigFunction;

/**
* MopaBootstrap Icon Extension.
*
* @author Craig Blanchette (isometriks) <[email protected]>
*/
class IconExtension extends \Twig_Extension
class IconExtension extends AbstractExtension
{
/**
* @var string
*/
protected $iconSet;

/**
* @var string
* @var string|null
*/
protected $shortcut;

/**
* @var \Twig_Template
* @var TemplateWrapper|null
*/
protected $iconTemplate;

/**
* Constructor.
*
* @param string $iconSet
* @param string $shortcut
* @param string $iconSet
* @param string|null $shortcut
*/
public function __construct($iconSet, $shortcut = null)
{
$this->iconSet = $iconSet;
$this->shortcut = $shortcut;
}

/**
* {@inheritdoc}
*/
public function getFunctions()
public function getFunctions(): array
{
$options = [
'is_safe' => ['html'],
'needs_environment' => true,
];

$functions = [
new \Twig_SimpleFunction('mopa_bootstrap_icon', [$this, 'renderIcon'], $options),
new TwigFunction('mopa_bootstrap_icon', [$this, 'renderIcon'], $options),
];

if ($this->shortcut) {
$functions[] = new \Twig_SimpleFunction($this->shortcut, [$this, 'renderIcon'], $options);
$functions[] = new TwigFunction($this->shortcut, [$this, 'renderIcon'], $options);
}

return $functions;
Expand All @@ -73,10 +71,8 @@ public function getFunctions()
*
* @param string $icon
* @param bool $inverted
*
* @return Response
*/
public function renderIcon(\Twig_Environment $env, $icon, $inverted = false)
public function renderIcon(Environment $env, $icon, $inverted = false): string
{
$template = $this->getIconTemplate($env);
$context = [
Expand All @@ -87,21 +83,10 @@ public function renderIcon(\Twig_Environment $env, $icon, $inverted = false)
return $template->renderBlock($this->iconSet, $context);
}

/**
* {@inheritdoc}
*/
public function getName()
{
return 'mopa_bootstrap_icon';
}

/**
* @return \Twig_Template
*/
protected function getIconTemplate(\Twig_Environment $env)
protected function getIconTemplate(Environment $env): TemplateWrapper
{
if ($this->iconTemplate === null) {
$this->iconTemplate = $env->loadTemplate('@MopaBootstrap/icons.html.twig');
$this->iconTemplate = $env->load('@MopaBootstrap/icons.html.twig');
}

return $this->iconTemplate;
Expand Down
Loading

0 comments on commit b7af516

Please sign in to comment.