Voir le code source de n'importe quel fichier d'un projet Symfony

Publié le 08/02/2019 • Mis à jour le 10/02/2019

C'est en fait le helper Twig que j'utilise sur ce site pour afficher tous les snippets. Il existe déjà un helper Twig natif source() mais il peut uniquement être utilisé pour afficher des templates. Celui-ci est plus générique et vous permet de voir le contenu de n'importe quel fichier de votre projet. (il est donc important de sécuriser les paramètres qui lui sont passés). En haut, vous pouvez voir le contenu du template _15.html.twig grâce au helper natif. En dessous, le source du nouveau helper qui est donc utilisé pour afficher son propre contenu.
PS : Vous pouvez supprimer la partie str_replace() qui est spécifique à ce projet. Jetez un coup d'oeil au code d'un des snippets exécutables pour comprendre pourquoi. 😉


{{ source('snippet/code/_15.html.twig')|escape }}
{{ source_php('src/Twig/Extension/SourceExtension.php', false)|escape }}
{# End of _15.html.twig Twig template #}

<?php

namespace App\Twig\Extension;

use Symfony\Component\HttpKernel\KernelInterface;
use Twig\Extension\AbstractExtension;
use Twig\TwigFunction;

/**
 * Source helpers for snippets.
 */
class SourceExtension extends AbstractExtension
{
    protected $kernel;

    public $traitDocblock = <<<EOD
 * I am using a PHP trait in order to isolate each snippet in a file.
 * This code should be called from a Symfony controller extending AbstractController (as of Sf 4.2)
 * or Symfony\Bundle\FrameworkBundle\Controller\Controller (Sf <= 4.1)
 * Services are injected in the controller constructor.
EOD;

    public function __construct(KernelInterface $kernel)
    {
        $this->kernel = $kernel;
    }

    public function getFunctions(): array
    {
        return [
            new TwigFunction('source_php', [$this, 'getSource']),
        ];
    }

    /**
     * @todo allow to any chunk of a file. Eg: from line 10 to line 20.
     */
    public function getSource(string $file, bool $replaceDocBlock = true, int $linesLimit = null): string
    {
        $filename = $this->kernel->getProjectDir().'/'.$file;
        if (!file_exists($filename)) {
            throw new \InvalidArgumentException(sprintf('File "%s" not found.', $file));
        }

        // Only get x first lines only
        if (is_int($linesLimit)) {
            $lines = file($filename);
            $source = implode('', array_slice(is_array($lines) ? $lines : [], 0, $linesLimit));
        } else {
            $source = file_get_contents($filename);
        }

        if ($source && $replaceDocBlock) {
            return str_replace('%docblock%', $this->traitDocblock, $source);
        }

        return (string) $source;
    }
}

 Plus sur Stackoverflow