Skip to content

Commit

Permalink
feat(Documents): Reduced document folder column length, use microtime…
Browse files Browse the repository at this point in the history
… to ensure folder uniqueness, refactored document utils
  • Loading branch information
roadiz-ci committed Feb 26, 2025
1 parent 85bffff commit 9347f27
Show file tree
Hide file tree
Showing 9 changed files with 63 additions and 66 deletions.
15 changes: 4 additions & 11 deletions src/AbstractDocumentFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
use League\Flysystem\FilesystemOperator;
use League\Flysystem\MountManager;
use Psr\Log\LoggerInterface;
use Psr\Log\NullLogger;
use RZ\Roadiz\Documents\Models\DocumentInterface;
use RZ\Roadiz\Documents\Models\FileHashInterface;
use RZ\Roadiz\Documents\Models\FolderInterface;
Expand All @@ -23,23 +22,17 @@
*/
abstract class AbstractDocumentFactory
{
private LoggerInterface $logger;
private ?File $file = null;
private ?FolderInterface $folder = null;
private FilesystemOperator $documentsStorage;
private DocumentFinderInterface $documentFinder;

public function __construct(
FilesystemOperator $documentsStorage,
DocumentFinderInterface $documentFinder,
?LoggerInterface $logger = null,
protected readonly FilesystemOperator $documentsStorage,
protected readonly DocumentFinderInterface $documentFinder,
protected readonly LoggerInterface $logger,
) {
if (!$documentsStorage instanceof MountManager) {
trigger_error('Document Storage must be a MountManager to address public and private files.', E_USER_WARNING);
}
$this->documentsStorage = $documentsStorage;
$this->documentFinder = $documentFinder;
$this->logger = $logger ?? new NullLogger();
}

public function getFile(): File
Expand Down Expand Up @@ -217,7 +210,7 @@ public function updateDocument(DocumentInterface $document): DocumentInterface
}
}

$document->setFolder(\mb_substr(hash('crc32b', date('YmdHi')), 0, 12));
$document->setFolder(DocumentFolderGenerator::generateFolderName());
}

$document->setFilename($this->getFileName());
Expand Down
2 changes: 1 addition & 1 deletion src/AverageColorResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

use Intervention\Image\Image;

class AverageColorResolver
final readonly class AverageColorResolver
{
public function getAverageColor(Image $image): string
{
Expand Down
4 changes: 2 additions & 2 deletions src/DocumentArchiver.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@
/**
* Easily create and serve ZIP archives from your Roadiz documents.
*/
final class DocumentArchiver
final readonly class DocumentArchiver
{
public function __construct(private readonly FilesystemOperator $documentsStorage)
public function __construct(private FilesystemOperator $documentsStorage)
{
}

Expand Down
16 changes: 16 additions & 0 deletions src/DocumentFolderGenerator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

declare(strict_types=1);

namespace RZ\Roadiz\Documents;

final readonly class DocumentFolderGenerator
{
/**
* Generate a random folder name for documents, 12 characters long.
*/
public static function generateFolderName(): string
{
return \mb_substr(hash('crc32c', microtime()), 0, 12);
}
}
14 changes: 7 additions & 7 deletions src/DownscaleImageManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,15 @@
use RZ\Roadiz\Documents\Models\DocumentInterface;
use RZ\Roadiz\Documents\Models\FileHashInterface;

final class DownscaleImageManager
final readonly class DownscaleImageManager
{
public function __construct(
private readonly EntityManagerInterface $em,
private readonly FilesystemOperator $documentsStorage,
private readonly ImageManager $imageManager,
private readonly ?LoggerInterface $logger = null,
private readonly int $maxPixelSize = 0,
private readonly string $rawImageSuffix = '.raw',
private EntityManagerInterface $em,
private FilesystemOperator $documentsStorage,
private ImageManager $imageManager,
private ?LoggerInterface $logger = null,
private int $maxPixelSize = 0,
private string $rawImageSuffix = '.raw',
) {
}

Expand Down
2 changes: 2 additions & 0 deletions src/Models/DocumentInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ public function getFolder(): string;

/**
* @return $this
*
* @internal You should use DocumentFactory to generate a document folder
*/
public function setFolder(string $folder): static;

Expand Down
47 changes: 24 additions & 23 deletions src/Models/DocumentTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
namespace RZ\Roadiz\Documents\Models;

use ApiPlatform\Metadata\ApiProperty;
use Symfony\Component\Serializer\Annotation as SymfonySerializer;
use RZ\Roadiz\Documents\DocumentFolderGenerator;
use Symfony\Component\Serializer\Annotation as Serializer;

trait DocumentTrait
{
Expand All @@ -29,7 +30,7 @@ trait DocumentTrait
*
* @internal
*/
#[SymfonySerializer\Ignore()]
#[Serializer\Ignore()]
protected static array $mimeToIcon = [
// Code
'application/javascript' => 'code',
Expand Down Expand Up @@ -141,7 +142,7 @@ trait DocumentTrait
*
* @internal
*/
#[SymfonySerializer\Ignore()]
#[Serializer\Ignore()]
protected static array $processableMimeTypes = [
'image/png',
'image/jpeg',
Expand All @@ -156,7 +157,7 @@ trait DocumentTrait
/**
* Get short type name for current document Mime type.
*/
#[SymfonySerializer\Ignore()]
#[Serializer\Ignore()]
public function getShortType(): string
{
if (null !== $this->getMimeType() && isset(static::$mimeToIcon[$this->getMimeType()])) {
Expand All @@ -169,7 +170,7 @@ public function getShortType(): string
/**
* Get short Mime type.
*/
#[SymfonySerializer\Ignore()]
#[Serializer\Ignore()]
public function getShortMimeType(): string
{
if (!empty($this->getMimeType())) {
Expand All @@ -184,7 +185,7 @@ public function getShortMimeType(): string
/**
* Is current document an image.
*/
#[SymfonySerializer\Ignore()]
#[Serializer\Ignore()]
public function isImage(): bool
{
return 'image' === static::getShortType();
Expand All @@ -193,7 +194,7 @@ public function isImage(): bool
/**
* Is current document a vector SVG file.
*/
#[SymfonySerializer\Ignore()]
#[Serializer\Ignore()]
public function isSvg(): bool
{
return 'image/svg+xml' === $this->getMimeType() || 'image/svg' === $this->getMimeType();
Expand All @@ -202,7 +203,7 @@ public function isSvg(): bool
/**
* Is current document a video.
*/
#[SymfonySerializer\Ignore()]
#[Serializer\Ignore()]
public function isVideo(): bool
{
return 'video' === static::getShortType();
Expand All @@ -211,7 +212,7 @@ public function isVideo(): bool
/**
* Is current document an audio file.
*/
#[SymfonySerializer\Ignore()]
#[Serializer\Ignore()]
public function isAudio(): bool
{
return 'audio' === static::getShortType();
Expand All @@ -220,21 +221,21 @@ public function isAudio(): bool
/**
* Is current document a PDF file.
*/
#[SymfonySerializer\Ignore()]
#[Serializer\Ignore()]
public function isPdf(): bool
{
return 'pdf' === static::getShortType();
}

#[SymfonySerializer\Ignore()]
#[Serializer\Ignore()]
public function isWebp(): bool
{
return 'image/webp' === $this->getMimeType();
}

#[
SymfonySerializer\Groups(['document', 'document_display', 'nodes_sources', 'tag', 'attribute']),
SymfonySerializer\SerializedName('relativePath'),
Serializer\Groups(['document', 'document_display', 'nodes_sources', 'tag', 'attribute']),
Serializer\SerializedName('relativePath'),
]
public function getRelativePath(): ?string
{
Expand All @@ -246,8 +247,8 @@ public function getRelativePath(): ?string
}

#[
SymfonySerializer\Groups(['document_mount']),
SymfonySerializer\SerializedName('mountPath'),
Serializer\Groups(['document_mount']),
Serializer\SerializedName('mountPath'),
]
public function getMountPath(): ?string
{
Expand All @@ -262,7 +263,7 @@ public function getMountPath(): ?string
}

#[
SymfonySerializer\Ignore
Serializer\Ignore
]
public function getMountFolderPath(): ?string
{
Expand All @@ -280,20 +281,20 @@ public function getMountFolderPath(): ?string
/**
* Tells if current document has embed media information.
*/
#[SymfonySerializer\Ignore()]
#[Serializer\Ignore()]
public function isEmbed(): bool
{
return !empty($this->getEmbedId()) && !empty($this->getEmbedPlatform());
}

protected function initDocumentTrait(): void
{
$this->setFolder(\mb_substr(hash('crc32b', date('YmdHi')), 0, 12));
$this->setFolder(DocumentFolderGenerator::generateFolderName());
}

#[
SymfonySerializer\Groups(['document', 'document_display', 'nodes_sources', 'tag', 'attribute']),
SymfonySerializer\SerializedName('processable'),
Serializer\Groups(['document', 'document_display', 'nodes_sources', 'tag', 'attribute']),
Serializer\SerializedName('processable'),
ApiProperty(
description: 'Document can be processed as an image for resampling and other image operations.',
writable: false,
Expand All @@ -305,8 +306,8 @@ public function isProcessable(): bool
}

#[
SymfonySerializer\Groups(['document', 'document_display', 'nodes_sources', 'tag', 'attribute']),
SymfonySerializer\SerializedName('alt'),
Serializer\Groups(['document', 'document_display', 'nodes_sources', 'tag', 'attribute']),
Serializer\SerializedName('alt'),
]
public function getAlternativeText(): string
{
Expand All @@ -316,7 +317,7 @@ public function getAlternativeText(): string
/**
* Return false if no local file is linked to document. i.e no filename, no folder.
*/
#[SymfonySerializer\Ignore()]
#[Serializer\Ignore()]
public function isLocal(): bool
{
return '' !== $this->getFilename() && '' !== $this->getFolder();
Expand Down
3 changes: 2 additions & 1 deletion src/Repository/DocumentRepositoryInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@
namespace RZ\Roadiz\Documents\Repository;

use Doctrine\Persistence\ObjectRepository;
use RZ\Roadiz\Documents\Models\DocumentInterface;

/**
* @template T of \RZ\Roadiz\Documents\Models\DocumentInterface
* @template T of DocumentInterface
*
* @template-extends ObjectRepository<T>
*
Expand Down
26 changes: 5 additions & 21 deletions src/Viewers/SvgDocumentViewer.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,8 @@
use RZ\Roadiz\Documents\Models\DocumentInterface;
use Symfony\Component\HttpFoundation\File\Exception\FileNotFoundException;

class SvgDocumentViewer
final class SvgDocumentViewer
{
protected array $attributes;
protected bool $asObject = false;
protected string $imageUrl;
protected FilesystemOperator $documentsStorage;
protected DocumentInterface $document;

/**
* @var string[]
*/
Expand All @@ -28,22 +22,12 @@ class SvgDocumentViewer
'class',
];

/**
* @param bool $asObject Default false
* @param string $imageUrl only needed if you set $asObject to true
*/
public function __construct(
FilesystemOperator $documentsStorage,
DocumentInterface $document,
array $attributes = [],
bool $asObject = false,
string $imageUrl = '',
private readonly FilesystemOperator $documentsStorage,
private readonly DocumentInterface $document,
private readonly array $attributes = [],
private readonly bool $asObject = false,
) {
$this->imageUrl = $imageUrl;
$this->attributes = $attributes;
$this->asObject = $asObject;
$this->documentsStorage = $documentsStorage;
$this->document = $document;
}

/**
Expand Down

0 comments on commit 9347f27

Please sign in to comment.