<commit_before><?php

namespace Webfactory\Bundle\WfdMetaBundle\Util;

use Symfony\Component\Config\ConfigCache;

/**
 * Verhaelt sich wie ConfigCache, ist aber zusätzlich und auch unter !debug nicht mehr fresh,
 * wenn der im Konstruktor gegebene Timestamp sich gegenüber dem Zeitpunkt der Erstellung
 * erhöht hat (für die gleiche Cache-Datei).
 *
 * Diese Implementierung verwendet wechselnde Dateinamen für neuere Generationen,
 * weil so Cache-Datei (die letztlich ja von Klienten includiert wird) von APC gehalten
 * werden kann. In der Regel - unter Production und wenn der Cache frisch ist - müssen
 * wir dann auch nicht jedes Mal aus einer Meta-Datei laden, welche Generation im Cache
 * liegt und das für den isFresh()-Test vergleichen - der Dateiname alleine reicht
 * schon aus um zu erkennen, dass es die richtige Generation ist.
 */
class ExpirableConfigCache extends ConfigCache {
    protected $timestamp, $metaFile, $baseFile;

    public function __construct($file, $debug, $timestamp) {
        parent::__construct($this->getTimestampedFilePath($file, $timestamp), $debug);
        $this->baseFile = $file;
        $this->metaFile = "$file.expire";
        $this->timestamp = $timestamp;
    }

    public function write($content, array $metadata = null) {
        $file = $this->metaFile;
        $oldTs = @file_get_contents($file);

        if ($oldTs <= $this->timestamp) { // <=, weil es sein kann, dass wir den Cache aufgrund anderer Faktoren als dem Timestamp neu machen (think development + geänderte Resourcen)
            parent::write($content, $metadata);
            copy(
                $this->getTimestampedFilePath($this->baseFile, $this->timestamp),
                $this->baseFile
            );
        }

        if ($oldTs < $this->timestamp) { // Wenn wir keine echt neue Generation geschrieben haben, brauchen|dürfen wir das nicht neu schreiben|löschen.
            $tmpFile = tempnam(dirname($file), basename($file));
            if (false !== @file_put_contents($tmpFile, $this->timestamp) && @rename($tmpFile, $file)) {
                chmod($file, 0666);
                @unlink("{$this->baseFile}_$oldTs");
                @unlink("{$this->baseFile}_$oldTs.meta");
            }
        }
    }

    /**
     * Get the full file system path including the file name for a timestamped version of the $baseFilePath
     *
     * @param string $baseFilePath full file system path to the base file
     * @param int $timestamp
     * @return string
     */
    protected function getTimestampedFilePath($baseFilePath, $timestamp)
    {
        return $baseFilePath . '_' . $timestamp;
    }
}
<commit_msg>So wird klarer, was da vorher passierte.<commit_after><?php

namespace Webfactory\Bundle\WfdMetaBundle\Util;

use Symfony\Component\Config\ConfigCache;
use Symfony\Component\Finder\Finder;

/**
 * Verhaelt sich wie ConfigCache, ist aber zusätzlich und auch unter !debug nicht mehr fresh,
 * wenn der im Konstruktor gegebene Timestamp sich gegenüber dem Zeitpunkt der Erstellung
 * geändert hat (für die gleiche Cache-Datei).
 *
 * Diese Implementierung verwendet wechselnde Dateinamen für neuere Generationen,
 * weil so Cache-Datei (die letztlich ja von Klienten includiert wird) von APC gehalten
 * werden kann. In der Regel - unter Production und wenn der Cache frisch ist - müssen
 * wir dann auch nicht jedes Mal aus einer Meta-Datei laden, welche Generation im Cache
 * liegt und das für den isFresh()-Test vergleichen - der Dateiname alleine reicht
 * schon aus um zu erkennen, dass es die richtige Generation ist.
 */
class ExpirableConfigCache extends ConfigCache {
    protected $timestamp, $baseFilename, $timestampedFile;

    public function __construct($baseFilename, $debug, $timestamp) {
        $this->baseFilename = $baseFilename;
        $this->timestampedFile = "{$baseFilename}_{$timestamp}";
        $this->timestamp = $timestamp;

        parent::__construct($this->timestampedFile, $debug);
    }

    public function write($content, array $metadata = null) {
        parent::write($content, $metadata);

        /*
         * Für das Symfony2-Plugin in PHPStorm einen festen Dateinamen vorhalten,
         * diese Kopie ist ansonsten ohne Relevanz.
         */ 
        copy(
            $this->timestampedFile,
            $this->baseFilename
        );

        $this->cleanup();
    }

    protected function cleanup() {
        $finder = new Finder();
        $basename = basename($this->baseFilename);
        $files = $finder->files()
                        ->in(dirname($this->baseFilename))
                        ->depth('== 0')
                        ->name("#{$basename}_#")
                        ->notName("#{$basename}_{$this->timestamp}#");

        foreach ($files as $file) {
            @unlink($file->getRealpath());
        }
    }
}

{'fraction_non_alphanumeric': 0.10618919478368868, 'fraction_numerical': 0.001241978886358932, 'mean_word_length': 2.874899759422614, 'pattern_counts': {'":': 0, '<': 8, '<?xml version=': 0, '>': 33, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2948221', 'n_tokens_mistral': 1363, 'n_tokens_neox': 1369, 'n_words': 423}