Verzeichnisstruktur phpBB-3.2.0
- Veröffentlicht
- 06.01.2017
So funktioniert es
|
Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück |
Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis. |
|
(Beispiel Datei-Icons)
|
Auf das Icon klicken um den Quellcode anzuzeigen |
DebugCommand.php
001 <?php
002
003 /*
004 * This file is part of the Symfony package.
005 *
006 * (c) Fabien Potencier <fabien@symfony.com>
007 *
008 * For the full copyright and license information, please view the LICENSE
009 * file that was distributed with this source code.
010 */
011
012 namespace Symfony\Bridge\Twig\Command;
013
014 use Symfony\Component\Console\Command\Command;
015 use Symfony\Component\Console\Input\InputArgument;
016 use Symfony\Component\Console\Input\InputOption;
017 use Symfony\Component\Console\Input\InputInterface;
018 use Symfony\Component\Console\Output\OutputInterface;
019 use Symfony\Component\Console\Style\SymfonyStyle;
020
021 /**
022 * Lists twig functions, filters, globals and tests present in the current project.
023 *
024 * @author Jordi Boggiano <j.boggiano@seld.be>
025 */
026 class DebugCommand extends Command
027 {
028 private $twig;
029
030 /**
031 * {@inheritdoc}
032 */
033 public function __construct($name = 'debug:twig')
034 {
035 parent::__construct($name);
036 }
037
038 /**
039 * Sets the twig environment.
040 *
041 * @param \Twig_Environment $twig
042 */
043 public function setTwigEnvironment(\Twig_Environment $twig)
044 {
045 $this->twig = $twig;
046 }
047
048 /**
049 * @return \Twig_Environment $twig
050 */
051 protected function getTwigEnvironment()
052 {
053 return $this->twig;
054 }
055
056 protected function configure()
057 {
058 $this
059 ->setDefinition(array(
060 new InputArgument('filter', InputArgument::OPTIONAL, 'Show details for all entries matching this filter'),
061 new InputOption('format', null, InputOption::VALUE_REQUIRED, 'The output format (text or json)', 'text'),
062 ))
063 ->setDescription('Shows a list of twig functions, filters, globals and tests')
064 ->setHelp(<<<EOF
065 The <info>%command.name%</info> command outputs a list of twig functions,
066 filters, globals and tests. Output can be filtered with an optional argument.
067
068 <info>php %command.full_name%</info>
069
070 The command lists all functions, filters, etc.
071
072 <info>php %command.full_name% date</info>
073
074 The command lists everything that contains the word date.
075
076 <info>php %command.full_name% --format=json</info>
077
078 The command lists everything in a machine readable json format.
079 EOF
080 )
081 ;
082 }
083
084 protected function execute(InputInterface $input, OutputInterface $output)
085 {
086 $io = new SymfonyStyle($input, $output);
087 $twig = $this->getTwigEnvironment();
088
089 if (null === $twig) {
090 $io->error('The Twig environment needs to be set.');
091
092 return 1;
093 }
094
095 $types = array('functions', 'filters', 'tests', 'globals');
096
097 if ($input->getOption('format') === 'json') {
098 $data = array();
099 foreach ($types as $type) {
100 foreach ($twig->{'get'.ucfirst($type)}() as $name => $entity) {
101 $data[$type][$name] = $this->getMetadata($type, $entity);
102 }
103 }
104 $data['tests'] = array_keys($data['tests']);
105 $io->writeln(json_encode($data));
106
107 return 0;
108 }
109
110 $filter = $input->getArgument('filter');
111
112 foreach ($types as $index => $type) {
113 $items = array();
114 foreach ($twig->{'get'.ucfirst($type)}() as $name => $entity) {
115 if (!$filter || false !== strpos($name, $filter)) {
116 $items[$name] = $name.$this->getPrettyMetadata($type, $entity);
117 }
118 }
119
120 if (!$items) {
121 continue;
122 }
123
124 $io->section(ucfirst($type));
125
126 ksort($items);
127 $io->listing($items);
128 }
129
130 return 0;
131 }
132
133 private function getMetadata($type, $entity)
134 {
135 if ($type === 'globals') {
136 return $entity;
137 }
138 if ($type === 'tests') {
139 return;
140 }
141 if ($type === 'functions' || $type === 'filters') {
142 $cb = $entity->getCallable();
143 if (is_null($cb)) {
144 return;
145 }
146 if (is_array($cb)) {
147 if (!method_exists($cb[0], $cb[1])) {
148 return;
149 }
150 $refl = new \ReflectionMethod($cb[0], $cb[1]);
151 } elseif (is_object($cb) && method_exists($cb, '__invoke')) {
152 $refl = new \ReflectionMethod($cb, '__invoke');
153 } elseif (function_exists($cb)) {
154 $refl = new \ReflectionFunction($cb);
155 } elseif (is_string($cb) && preg_match('{^(.+)::(.+)$}', $cb, $m) && method_exists($m[1], $m[2])) {
156 $refl = new \ReflectionMethod($m[1], $m[2]);
157 } else {
158 throw new \UnexpectedValueException('Unsupported callback type');
159 }
160
161 // filter out context/environment args
162 $args = array_filter($refl->getParameters(), function ($param) use ($entity) {
163 if ($entity->needsContext() && $param->getName() === 'context') {
164 return false;
165 }
166
167 return !$param->getClass() || $param->getClass()->getName() !== 'Twig_Environment';
168 });
169
170 // format args
171 $args = array_map(function ($param) {
172 if ($param->isDefaultValueAvailable()) {
173 return $param->getName().' = '.json_encode($param->getDefaultValue());
174 }
175
176 return $param->getName();
177 }, $args);
178
179 if ($type === 'filters') {
180 // remove the value the filter is applied on
181 array_shift($args);
182 }
183
184 return $args;
185 }
186 }
187
188 private function getPrettyMetadata($type, $entity)
189 {
190 if ($type === 'tests') {
191 return '';
192 }
193
194 try {
195 $meta = $this->getMetadata($type, $entity);
196 if ($meta === null) {
197 return '(unknown?)';
198 }
199 } catch (\UnexpectedValueException $e) {
200 return ' <error>'.$e->getMessage().'</error>';
201 }
202
203 if ($type === 'globals') {
204 if (is_object($meta)) {
205 return ' = object('.get_class($meta).')';
206 }
207
208 return ' = '.substr(@json_encode($meta), 0, 50);
209 }
210
211 if ($type === 'functions') {
212 return '('.implode(', ', $meta).')';
213 }
214
215 if ($type === 'filters') {
216 return $meta ? '('.implode(', ', $meta).')' : '';
217 }
218 }
219 }
220