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.
Auf den Verzeichnisnamen klicken, dies zeigt nur das Verzeichnis mit Inhalt an

      (Beispiel Datei-Icons)

Auf das Icon klicken um den Quellcode anzuzeigen

LintCommand.php

Zuletzt modifiziert: 09.10.2024, 12:56 - Dateigröße: 7.76 KiB


 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\InputInterface;
 017  use Symfony\Component\Console\Input\InputOption;
 018  use Symfony\Component\Console\Output\OutputInterface;
 019  use Symfony\Component\Console\Style\SymfonyStyle;
 020  use Symfony\Component\Finder\Finder;
 021   
 022  /**
 023   * Command that will validate your template syntax and output encountered errors.
 024   *
 025   * @author Marc Weistroff <marc.weistroff@sensiolabs.com>
 026   * @author Jérôme Tamarelle <jerome@tamarelle.net>
 027   */
 028  class LintCommand extends Command
 029  {
 030      private $twig;
 031   
 032      /**
 033       * {@inheritdoc}
 034       */
 035      public function __construct($name = 'lint:twig')
 036      {
 037          parent::__construct($name);
 038      }
 039   
 040      /**
 041       * Sets the twig environment.
 042       *
 043       * @param \Twig_Environment $twig
 044       */
 045      public function setTwigEnvironment(\Twig_Environment $twig)
 046      {
 047          $this->twig = $twig;
 048      }
 049   
 050      /**
 051       * @return \Twig_Environment $twig
 052       */
 053      protected function getTwigEnvironment()
 054      {
 055          return $this->twig;
 056      }
 057   
 058      protected function configure()
 059      {
 060          $this
 061              ->setAliases(array('twig:lint'))
 062              ->setDescription('Lints a template and outputs encountered errors')
 063              ->addOption('format', null, InputOption::VALUE_REQUIRED, 'The output format', 'txt')
 064              ->addArgument('filename', InputArgument::IS_ARRAY)
 065              ->setHelp(<<<EOF
 066  The <info>%command.name%</info> command lints a template and outputs to STDOUT
 067  the first encountered syntax error.
 068   
 069  You can validate the syntax of contents passed from STDIN:
 070   
 071    <info>cat filename | php %command.full_name%</info>
 072   
 073  Or the syntax of a file:
 074   
 075    <info>php %command.full_name% filename</info>
 076   
 077  Or of a whole directory:
 078   
 079    <info>php %command.full_name% dirname</info>
 080    <info>php %command.full_name% dirname --format=json</info>
 081   
 082  EOF
 083              )
 084          ;
 085      }
 086   
 087      protected function execute(InputInterface $input, OutputInterface $output)
 088      {
 089          $io = new SymfonyStyle($input, $output);
 090   
 091          if (false !== strpos($input->getFirstArgument(), ':l')) {
 092              $io->caution('The use of "twig:lint" command is deprecated since version 2.7 and will be removed in 3.0. Use the "lint:twig" instead.');
 093          }
 094   
 095          if (null === $twig = $this->getTwigEnvironment()) {
 096              $io->error('The Twig environment needs to be set.');
 097   
 098              return 1;
 099          }
 100   
 101          $filenames = $input->getArgument('filename');
 102   
 103          if (0 === count($filenames)) {
 104              if (0 !== ftell(STDIN)) {
 105                  throw new \RuntimeException('Please provide a filename or pipe template content to STDIN.');
 106              }
 107   
 108              $template = '';
 109              while (!feof(STDIN)) {
 110                  $template .= fread(STDIN, 1024);
 111              }
 112   
 113              return $this->display($input, $output, $io, array($this->validate($twig, $template, uniqid('sf_'))));
 114          }
 115   
 116          $filesInfo = $this->getFilesInfo($twig, $filenames);
 117   
 118          return $this->display($input, $output, $io, $filesInfo);
 119      }
 120   
 121      private function getFilesInfo(\Twig_Environment $twig, array $filenames)
 122      {
 123          $filesInfo = array();
 124          foreach ($filenames as $filename) {
 125              foreach ($this->findFiles($filename) as $file) {
 126                  $filesInfo[] = $this->validate($twig, file_get_contents($file), $file);
 127              }
 128          }
 129   
 130          return $filesInfo;
 131      }
 132   
 133      protected function findFiles($filename)
 134      {
 135          if (is_file($filename)) {
 136              return array($filename);
 137          } elseif (is_dir($filename)) {
 138              return Finder::create()->files()->in($filename)->name('*.twig');
 139          }
 140   
 141          throw new \RuntimeException(sprintf('File or directory "%s" is not readable', $filename));
 142      }
 143   
 144      private function validate(\Twig_Environment $twig, $template, $file)
 145      {
 146          $realLoader = $twig->getLoader();
 147          try {
 148              $temporaryLoader = new \Twig_Loader_Array(array((string) $file => $template));
 149              $twig->setLoader($temporaryLoader);
 150              $nodeTree = $twig->parse($twig->tokenize($template, (string) $file));
 151              $twig->compile($nodeTree);
 152              $twig->setLoader($realLoader);
 153          } catch (\Twig_Error $e) {
 154              $twig->setLoader($realLoader);
 155   
 156              return array('template' => $template, 'file' => $file, 'valid' => false, 'exception' => $e);
 157          }
 158   
 159          return array('template' => $template, 'file' => $file, 'valid' => true);
 160      }
 161   
 162      private function display(InputInterface $input, OutputInterface $output, SymfonyStyle $io, $files)
 163      {
 164          switch ($input->getOption('format')) {
 165              case 'txt':
 166                  return $this->displayTxt($output, $io, $files);
 167              case 'json':
 168                  return $this->displayJson($output, $files);
 169              default:
 170                  throw new \InvalidArgumentException(sprintf('The format "%s" is not supported.', $input->getOption('format')));
 171          }
 172      }
 173   
 174      private function displayTxt(OutputInterface $output, SymfonyStyle $io, $filesInfo)
 175      {
 176          $errors = 0;
 177   
 178          foreach ($filesInfo as $info) {
 179              if ($info['valid'] && $output->isVerbose()) {
 180                  $io->comment('<info>OK</info>'.($info['file'] ? sprintf(' in %s', $info['file']) : ''));
 181              } elseif (!$info['valid']) {
 182                  ++$errors;
 183                  $this->renderException($io, $info['template'], $info['exception'], $info['file']);
 184              }
 185          }
 186   
 187          if ($errors === 0) {
 188              $io->success(sprintf('All %d Twig files contain valid syntax.', count($filesInfo)));
 189          } else {
 190              $io->warning(sprintf('%d Twig files have valid syntax and %d contain errors.', count($filesInfo) - $errors, $errors));
 191          }
 192   
 193          return min($errors, 1);
 194      }
 195   
 196      private function displayJson(OutputInterface $output, $filesInfo)
 197      {
 198          $errors = 0;
 199   
 200          array_walk($filesInfo, function (&$v) use (&$errors) {
 201              $v['file'] = (string) $v['file'];
 202              unset($v['template']);
 203              if (!$v['valid']) {
 204                  $v['message'] = $v['exception']->getMessage();
 205                  unset($v['exception']);
 206                  ++$errors;
 207              }
 208          });
 209   
 210          $output->writeln(json_encode($filesInfo, defined('JSON_PRETTY_PRINT') ? JSON_PRETTY_PRINT : 0));
 211   
 212          return min($errors, 1);
 213      }
 214   
 215      private function renderException(OutputInterface $output, $template, \Twig_Error $exception, $file = null)
 216      {
 217          $line = $exception->getTemplateLine();
 218   
 219          if ($file) {
 220              $output->text(sprintf('<error> ERROR </error> in %s (line %s)', $file, $line));
 221          } else {
 222              $output->text(sprintf('<error> ERROR </error> (line %s)', $line));
 223          }
 224   
 225          foreach ($this->getContext($template, $line) as $lineNumber => $code) {
 226              $output->text(sprintf(
 227                  '%s %-6s %s',
 228                  $lineNumber === $line ? '<error> >> </error>' : '    ',
 229                  $lineNumber,
 230                  $code
 231              ));
 232              if ($lineNumber === $line) {
 233                  $output->text(sprintf('<error> >> %s</error> ', $exception->getRawMessage()));
 234              }
 235          }
 236      }
 237   
 238      private function getContext($template, $line, $context = 3)
 239      {
 240          $lines = explode("\n", $template);
 241   
 242          $position = max(0, $line - $context);
 243          $max = min(count($lines), $line - 1 + $context);
 244   
 245          $result = array();
 246          while ($position < $max) {
 247              $result[$position + 1] = $lines[$position];
 248              ++$position;
 249          }
 250   
 251          return $result;
 252      }
 253  }
 254