feat: gate the upload replacement file behind a feature flag

This commit is contained in:
fromme committed 2026-09-26 12:13:16 +02:00
1 parent 77986776c2
commit 69b8e549ee
5 files changed
+126 -18

No files matched your search

+11 -14
View File
@@ -6,6 +6,7 @@ use App\Entity\Upload;
use App\Model\UploadDto;
use App\Model\UploadSessionDto;
use App\Service\Pdf\Sanitizer;
use Flagception\Manager\FeatureManagerInterface;
use Oneup\UploaderBundle\Uploader\Orphanage\OrphanageManager;
use Psr\Log\LoggerInterface;
use Symfony\Component\Filesystem\Exception\IOException;
@@ -21,12 +22,9 @@ class UploadHandler
private readonly OrphanageManager $orphanageManager,
private readonly Sanitizer $sanitizer,
private readonly LoggerInterface $logger,
private readonly FeatureManagerInterface $featureManager,
private readonly string $projectDir,
private readonly string $environment,
// Bound from %env(default::UPLOAD_REPLACEMENT_FILE)%, whose empty fallback parameter
// resolves to null when the variable is not set at all - so "unset", "set to empty" and
// "absent" all have to mean the same thing here.
private readonly ?string $uploadReplacementFile,
private readonly string $uploadReplacementFile,
) {
}
@@ -166,23 +164,22 @@ class UploadHandler
}
/**
* Returns the upload file path, substituting a replacement file in non-production environments
* when configured. Use this for read-only access (downloads, email attachments).
* Returns the upload file path, substituting the stand-in document while the
* upload_replacement feature is on. Use this for read-only access (downloads, email
* attachments); getUploadFilepath() stays the real location and is what writes target.
*/
public function getResolvedUploadFilepath(Upload $upload): string
{
$originalPath = $this->getUploadFilepath($upload);
if (null === $this->uploadReplacementFile
|| '' === $this->uploadReplacementFile
|| 'prod' === $this->environment) {
return $originalPath;
if (false === $this->featureManager->isActive('upload_replacement')) {
return $this->getUploadFilepath($upload);
}
$replacementPath = sprintf('%s/%s', $this->projectDir, $this->uploadReplacementFile);
if (false === file_exists($replacementPath)) {
return $originalPath;
// Falling back to the real document here is what made the old behaviour opaque: the
// feature would look active and quietly serve the genuine file instead.
throw new \RuntimeException('Upload replacement file not found at '.$replacementPath);
}
return $replacementPath;