Skip to content

Commit 1ac3031

Browse files
Merge branch '3.4'
* 3.4: [TwigBundle] Commands as a service add (filesystem|phpfiles) cache (adapter|simple) prune method and prune command
2 parents 9fa3895 + 44d1162 commit 1ac3031

32 files changed

+734
-38
lines changed

UPGRADE-3.4.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,21 @@ TwigBridge
8383
* deprecated the `Symfony\Bridge\Twig\Form\TwigRenderer` class, use the `FormRenderer`
8484
class from the Form component instead
8585

86+
* deprecated `Symfony\Bridge\Twig\Command\DebugCommand::set/getTwigEnvironment` and the ability
87+
to pass a command name as first argument
88+
89+
* deprecated `Symfony\Bridge\Twig\Command\LintCommand::set/getTwigEnvironment` and the ability
90+
to pass a command name as first argument
91+
92+
TwigBundle
93+
----------
94+
95+
* deprecated the `Symfony\Bundle\TwigBundle\Command\DebugCommand` class, use the `DebugCommand`
96+
class from the Twig bridge instead
97+
98+
* deprecated relying on the `ContainerAwareInterface` implementation for
99+
`Symfony\Bundle\TwigBundle\Command\LintCommand`
100+
86101
Validator
87102
---------
88103

UPGRADE-4.0.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -517,6 +517,10 @@ TwigBundle
517517
* The `ContainerAwareRuntimeLoader` class has been removed. Use the
518518
Twig `Twig_ContainerRuntimeLoader` class instead.
519519

520+
* Removed `DebugCommand` in favor of `Symfony\Bridge\Twig\Command\DebugCommand`.
521+
522+
* Removed `ContainerAwareInterface` implementation in `Symfony\Bundle\TwigBundle\Command\LintCommand`.
523+
520524
TwigBridge
521525
----------
522526

@@ -556,6 +560,12 @@ TwigBridge
556560

557561
* The `TwigRendererEngine::setEnvironment()` method has been removed.
558562
Pass the Twig Environment as second argument of the constructor instead.
563+
564+
* Removed `Symfony\Bridge\Twig\Command\DebugCommand::set/getTwigEnvironment` and the ability
565+
to pass a command name as first argument.
566+
567+
* Removed `Symfony\Bridge\Twig\Command\LintCommand::set/getTwigEnvironment` and the ability
568+
to pass a command name as first argument.
559569

560570
Validator
561571
---------

src/Symfony/Bridge/Twig/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ CHANGELOG
55
-----
66

77
* deprecated `Symfony\Bridge\Twig\Form\TwigRenderer`
8+
* deprecated `Symfony\Bridge\Twig\Command\DebugCommand::set/getTwigEnvironment` and the ability to pass a command name as first argument
9+
* deprecated `Symfony\Bridge\Twig\Command\LintCommand::set/getTwigEnvironment` and the ability to pass a command name as first argument
810

911
3.3.0
1012
-----

src/Symfony/Bridge/Twig/Command/DebugCommand.php

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,15 +29,27 @@ class DebugCommand extends Command
2929
private $twig;
3030

3131
/**
32-
* {@inheritdoc}
32+
* @param Environment $twig
3333
*/
34-
public function __construct($name = 'debug:twig')
34+
public function __construct($twig = null)
3535
{
36-
parent::__construct($name);
36+
parent::__construct();
37+
38+
if (!$twig instanceof Environment) {
39+
@trigger_error(sprintf('Passing a command name as the first argument of "%s" is deprecated since version 3.4 and will be removed in 4.0. If the command was registered by convention, make it a service instead.', __METHOD__), E_USER_DEPRECATED);
40+
41+
$this->setName(null === $twig ? 'debug:twig' : $twig);
42+
43+
return;
44+
}
45+
46+
$this->twig = $twig;
3747
}
3848

3949
public function setTwigEnvironment(Environment $twig)
4050
{
51+
@trigger_error(sprintf('Method "%s" is deprecated since version 3.4 and will be removed in 4.0.', __METHOD__), E_USER_DEPRECATED);
52+
4153
$this->twig = $twig;
4254
}
4355

@@ -46,12 +58,15 @@ public function setTwigEnvironment(Environment $twig)
4658
*/
4759
protected function getTwigEnvironment()
4860
{
61+
@trigger_error(sprintf('Method "%s" is deprecated since version 3.4 and will be removed in 4.0.', __METHOD__), E_USER_DEPRECATED);
62+
4963
return $this->twig;
5064
}
5165

5266
protected function configure()
5367
{
5468
$this
69+
->setName('debug:twig')
5570
->setDefinition(array(
5671
new InputArgument('filter', InputArgument::OPTIONAL, 'Show details for all entries matching this filter'),
5772
new InputOption('format', null, InputOption::VALUE_REQUIRED, 'The output format (text or json)', 'text'),
@@ -80,9 +95,17 @@ protected function configure()
8095
protected function execute(InputInterface $input, OutputInterface $output)
8196
{
8297
$io = new SymfonyStyle($input, $output);
83-
$twig = $this->getTwigEnvironment();
8498

85-
if (null === $twig) {
99+
// BC to be removed in 4.0
100+
if (__CLASS__ !== get_class($this)) {
101+
$r = new \ReflectionMethod($this, 'getTwigEnvironment');
102+
if (__CLASS__ !== $r->getDeclaringClass()->getName()) {
103+
@trigger_error(sprintf('Usage of method "%s" is deprecated since version 3.4 and will no longer be supported in 4.0.', get_class($this).'::getTwigEnvironment'), E_USER_DEPRECATED);
104+
105+
$this->twig = $this->getTwigEnvironment();
106+
}
107+
}
108+
if (null === $this->twig) {
86109
throw new \RuntimeException('The Twig environment needs to be set.');
87110
}
88111

@@ -91,7 +114,7 @@ protected function execute(InputInterface $input, OutputInterface $output)
91114
if ($input->getOption('format') === 'json') {
92115
$data = array();
93116
foreach ($types as $type) {
94-
foreach ($twig->{'get'.ucfirst($type)}() as $name => $entity) {
117+
foreach ($this->twig->{'get'.ucfirst($type)}() as $name => $entity) {
95118
$data[$type][$name] = $this->getMetadata($type, $entity);
96119
}
97120
}
@@ -105,7 +128,7 @@ protected function execute(InputInterface $input, OutputInterface $output)
105128

106129
foreach ($types as $index => $type) {
107130
$items = array();
108-
foreach ($twig->{'get'.ucfirst($type)}() as $name => $entity) {
131+
foreach ($this->twig->{'get'.ucfirst($type)}() as $name => $entity) {
109132
if (!$filter || false !== strpos($name, $filter)) {
110133
$items[$name] = $name.$this->getPrettyMetadata($type, $entity);
111134
}

src/Symfony/Bridge/Twig/Command/LintCommand.php

Lines changed: 39 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -34,15 +34,27 @@ class LintCommand extends Command
3434
private $twig;
3535

3636
/**
37-
* {@inheritdoc}
37+
* @param Environment $twig
3838
*/
39-
public function __construct($name = 'lint:twig')
39+
public function __construct($twig = null)
4040
{
41-
parent::__construct($name);
41+
parent::__construct();
42+
43+
if (!$twig instanceof Environment) {
44+
@trigger_error(sprintf('Passing a command name as the first argument of "%s" is deprecated since version 3.4 and will be removed in 4.0. If the command was registered by convention, make it a service instead.', __METHOD__), E_USER_DEPRECATED);
45+
46+
$this->setName(null === $twig ? 'lint:twig' : $twig);
47+
48+
return;
49+
}
50+
51+
$this->twig = $twig;
4252
}
4353

4454
public function setTwigEnvironment(Environment $twig)
4555
{
56+
@trigger_error(sprintf('Method "%s" is deprecated since version 3.4 and will be removed in 4.0.', __METHOD__), E_USER_DEPRECATED);
57+
4658
$this->twig = $twig;
4759
}
4860

@@ -51,12 +63,15 @@ public function setTwigEnvironment(Environment $twig)
5163
*/
5264
protected function getTwigEnvironment()
5365
{
66+
@trigger_error(sprintf('Method "%s" is deprecated since version 3.4 and will be removed in 4.0.', __METHOD__), E_USER_DEPRECATED);
67+
5468
return $this->twig;
5569
}
5670

5771
protected function configure()
5872
{
5973
$this
74+
->setName('lint:twig')
6075
->setDescription('Lints a template and outputs encountered errors')
6176
->addOption('format', null, InputOption::VALUE_REQUIRED, 'The output format', 'txt')
6277
->addArgument('filename', InputArgument::IS_ARRAY)
@@ -86,7 +101,16 @@ protected function execute(InputInterface $input, OutputInterface $output)
86101
{
87102
$io = new SymfonyStyle($input, $output);
88103

89-
if (null === $twig = $this->getTwigEnvironment()) {
104+
// BC to be removed in 4.0
105+
if (__CLASS__ !== get_class($this)) {
106+
$r = new \ReflectionMethod($this, 'getTwigEnvironment');
107+
if (__CLASS__ !== $r->getDeclaringClass()->getName()) {
108+
@trigger_error(sprintf('Usage of method "%s" is deprecated since version 3.4 and will no longer be supported in 4.0.', get_class($this).'::getTwigEnvironment'), E_USER_DEPRECATED);
109+
110+
$this->twig = $this->getTwigEnvironment();
111+
}
112+
}
113+
if (null === $this->twig) {
90114
throw new \RuntimeException('The Twig environment needs to be set.');
91115
}
92116

@@ -102,20 +126,20 @@ protected function execute(InputInterface $input, OutputInterface $output)
102126
$template .= fread(STDIN, 1024);
103127
}
104128

105-
return $this->display($input, $output, $io, array($this->validate($twig, $template, uniqid('sf_', true))));
129+
return $this->display($input, $output, $io, array($this->validate($template, uniqid('sf_', true))));
106130
}
107131

108-
$filesInfo = $this->getFilesInfo($twig, $filenames);
132+
$filesInfo = $this->getFilesInfo($filenames);
109133

110134
return $this->display($input, $output, $io, $filesInfo);
111135
}
112136

113-
private function getFilesInfo(Environment $twig, array $filenames)
137+
private function getFilesInfo(array $filenames)
114138
{
115139
$filesInfo = array();
116140
foreach ($filenames as $filename) {
117141
foreach ($this->findFiles($filename) as $file) {
118-
$filesInfo[] = $this->validate($twig, file_get_contents($file), $file);
142+
$filesInfo[] = $this->validate(file_get_contents($file), $file);
119143
}
120144
}
121145

@@ -133,17 +157,17 @@ protected function findFiles($filename)
133157
throw new \RuntimeException(sprintf('File or directory "%s" is not readable', $filename));
134158
}
135159

136-
private function validate(Environment $twig, $template, $file)
160+
private function validate($template, $file)
137161
{
138-
$realLoader = $twig->getLoader();
162+
$realLoader = $this->twig->getLoader();
139163
try {
140164
$temporaryLoader = new ArrayLoader(array((string) $file => $template));
141-
$twig->setLoader($temporaryLoader);
142-
$nodeTree = $twig->parse($twig->tokenize(new Source($template, (string) $file)));
143-
$twig->compile($nodeTree);
144-
$twig->setLoader($realLoader);
165+
$this->twig->setLoader($temporaryLoader);
166+
$nodeTree = $this->twig->parse($this->twig->tokenize(new Source($template, (string) $file)));
167+
$this->twig->compile($nodeTree);
168+
$this->twig->setLoader($realLoader);
145169
} catch (Error $e) {
146-
$twig->setLoader($realLoader);
170+
$this->twig->setLoader($realLoader);
147171

148172
return array('template' => $template, 'file' => $file, 'line' => $e->getTemplateLine(), 'valid' => false, 'exception' => $e);
149173
}

src/Symfony/Bridge/Twig/Tests/Command/LintCommandTest.php

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,15 +68,30 @@ public function testLintFileCompileTimeException()
6868
$this->assertRegExp('/ERROR in \S+ \(line /', trim($tester->getDisplay()));
6969
}
7070

71+
/**
72+
* @group legacy
73+
* @expectedDeprecation Passing a command name as the first argument of "Symfony\Bridge\Twig\Command\LintCommand::__construct" is deprecated since version 3.4 and will be removed in 4.0. If the command was registered by convention, make it a service instead.
74+
* @expectedException \RuntimeException
75+
* @expectedExceptionMessage The Twig environment needs to be set.
76+
*/
77+
public function testLegacyLintCommand()
78+
{
79+
$command = new LintCommand();
80+
81+
$application = new Application();
82+
$application->add($command);
83+
$command = $application->find('lint:twig');
84+
85+
$tester = new CommandTester($command);
86+
$tester->execute(array());
87+
}
88+
7189
/**
7290
* @return CommandTester
7391
*/
7492
private function createCommandTester()
7593
{
76-
$twig = new Environment(new FilesystemLoader());
77-
78-
$command = new LintCommand();
79-
$command->setTwigEnvironment($twig);
94+
$command = new LintCommand(new Environment(new FilesystemLoader()));
8095

8196
$application = new Application();
8297
$application->add($command);

src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ CHANGELOG
4040
`Symfony\Component\Translation\DependencyInjection\TranslatorPass` instead
4141
* Added `command` attribute to the `console.command` tag which takes the command
4242
name as value, using it makes the command lazy
43+
* Added `cache:pool:prune` command to allow manual stale cache item pruning of supported PSR-6 and PSR-16 cache pool
44+
implementations
4345

4446
3.3.0
4547
-----
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bundle\FrameworkBundle\Command;
13+
14+
use Symfony\Component\Cache\PruneableInterface;
15+
use Symfony\Component\Console\Command\Command;
16+
use Symfony\Component\Console\Input\InputInterface;
17+
use Symfony\Component\Console\Output\OutputInterface;
18+
use Symfony\Component\Console\Style\SymfonyStyle;
19+
20+
/**
21+
* Cache pool pruner command.
22+
*
23+
* @author Rob Frawley 2nd <[email protected]>
24+
*/
25+
final class CachePoolPruneCommand extends Command
26+
{
27+
private $pools;
28+
29+
/**
30+
* @param iterable|PruneableInterface[] $pools
31+
*/
32+
public function __construct($pools)
33+
{
34+
parent::__construct();
35+
36+
$this->pools = $pools;
37+
}
38+
39+
/**
40+
* {@inheritdoc}
41+
*/
42+
protected function configure()
43+
{
44+
$this
45+
->setName('cache:pool:prune')
46+
->setDescription('Prune cache pools')
47+
->setHelp(<<<'EOF'
48+
The <info>%command.name%</info> command deletes all expired items from all pruneable pools.
49+
50+
%command.full_name%
51+
EOF
52+
)
53+
;
54+
}
55+
56+
/**
57+
* {@inheritdoc}
58+
*/
59+
protected function execute(InputInterface $input, OutputInterface $output)
60+
{
61+
$io = new SymfonyStyle($input, $output);
62+
63+
foreach ($this->pools as $name => $pool) {
64+
$io->comment(sprintf('Pruning cache pool: <info>%s</info>', $name));
65+
$pool->prune();
66+
}
67+
68+
$io->success('Successfully pruned cache pool(s).');
69+
}
70+
}

0 commit comments

Comments
 (0)