diff --git a/.github/workflows/run-test.yml b/.github/workflows/run-test.yml index 3b17d56..189e3a5 100644 --- a/.github/workflows/run-test.yml +++ b/.github/workflows/run-test.yml @@ -19,7 +19,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - php-version: ['8.0', '8.1'] + php-version: ['8.1', '8.2', '8.3'] steps: - uses: shivammathur/setup-php@v2 with: diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 316f0e9..0000000 --- a/.travis.yml +++ /dev/null @@ -1,14 +0,0 @@ -language: php -php: - - '8.0' - - '8.1' - - 'nightly' -jobs: - allow_failures: - - php: 'nightly' -install: - - composer install --dev --no-scripts --no-suggest - -script: - - vendor/bin/phpcs -p ./src - - vendor/bin/phpstan analyse -c phpstan.neon diff --git a/README.md b/README.md index 1be8d1b..3db82db 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ # Roadiz Font bundle +**Manage and expose web fonts with Roadiz CMS** ![Run test status](https://github.com/roadiz/font-bundle/actions/workflows/run-test.yml/badge.svg?branch=develop) diff --git a/composer.json b/composer.json index 5845cb5..9716959 100644 --- a/composer.json +++ b/composer.json @@ -1,9 +1,11 @@ { "name": "roadiz/font-bundle", + "description": "Manage and expose web fonts with Roadiz CMS", "license": "MIT", "keywords": [ "cms", "backoffice", + "roadiz", "rezo zero" ], "authors": [ @@ -15,16 +17,17 @@ } ], "type": "symfony-bundle", + "prefer-stable": true, "require": { - "php": ">=8.0", + "php": ">=8.1", "doctrine/annotations": "^1.0", "doctrine/doctrine-bundle": "^2.8.1", "doctrine/doctrine-migrations-bundle": "^3.1", - "doctrine/orm": "<2.17", + "doctrine/orm": "~2.17.0", "jms/serializer": "^3.9.0", "league/flysystem": "^3.0", - "roadiz/models": "2.1.*", - "roadiz/rozier": "2.1.*", + "roadiz/models": "2.2.*", + "roadiz/rozier": "2.2.*", "sensio/framework-extra-bundle": "^6.1", "symfony/asset": "5.4.*", "symfony/cache": "5.4.*", @@ -40,7 +43,7 @@ "symfony/twig-bundle": "5.4.*", "symfony/validator": "5.4.*", "symfony/yaml": "5.4.*", - "twig/extra-bundle": "^2.12|^3.0", + "twig/extra-bundle": "^3.0", "twig/intl-extra": "*", "twig/string-extra": "*", "twig/twig": "^3.1" @@ -54,11 +57,11 @@ "symfony/browser-kit": "5.4.*", "symfony/phpunit-bridge": "5.4.*", "symfony/stopwatch": "5.4.*", - "roadiz/core-bundle": "2.1.*", - "roadiz/compat-bundle": "2.1.*", - "roadiz/rozier-bundle": "2.1.*", - "roadiz/documents": "2.1.*", - "roadiz/entity-generator": "2.1.*" + "roadiz/core-bundle": "2.2.*", + "roadiz/compat-bundle": "2.2.*", + "roadiz/rozier-bundle": "2.2.*", + "roadiz/documents": "2.2.*", + "roadiz/entity-generator": "2.2.*" }, "config": { "optimize-autoloader": true, @@ -85,8 +88,8 @@ }, "extra": { "branch-alias": { - "dev-main": "2.1.x-dev", - "dev-develop": "2.2.x-dev" + "dev-main": "2.2.x-dev", + "dev-develop": "2.3.x-dev" } } } diff --git a/migrations/Version20230607134442.php b/migrations/Version20230607134442.php new file mode 100644 index 0000000..d184e45 --- /dev/null +++ b/migrations/Version20230607134442.php @@ -0,0 +1,36 @@ +addSql('ALTER TABLE fonts CHANGE eot_filename eot_filename VARCHAR(100) DEFAULT NULL, CHANGE woff_filename woff_filename VARCHAR(100) DEFAULT NULL, CHANGE woff2_filename woff2_filename VARCHAR(100) DEFAULT NULL, CHANGE otf_filename otf_filename VARCHAR(100) DEFAULT NULL, CHANGE svg_filename svg_filename VARCHAR(100) DEFAULT NULL, CHANGE name name VARCHAR(100) NOT NULL, CHANGE hash hash VARCHAR(128) NOT NULL, CHANGE folder folder VARCHAR(100) NOT NULL'); + } + + public function down(Schema $schema): void + { + // this down() migration is auto-generated, please modify it to your needs + $this->addSql('ALTER TABLE fonts CHANGE eot_filename eot_filename VARCHAR(255) CHARACTER SET utf8mb4 DEFAULT NULL COLLATE `utf8mb4_unicode_ci`, CHANGE woff_filename woff_filename VARCHAR(255) CHARACTER SET utf8mb4 DEFAULT NULL COLLATE `utf8mb4_unicode_ci`, CHANGE woff2_filename woff2_filename VARCHAR(255) CHARACTER SET utf8mb4 DEFAULT NULL COLLATE `utf8mb4_unicode_ci`, CHANGE otf_filename otf_filename VARCHAR(255) CHARACTER SET utf8mb4 DEFAULT NULL COLLATE `utf8mb4_unicode_ci`, CHANGE svg_filename svg_filename VARCHAR(255) CHARACTER SET utf8mb4 DEFAULT NULL COLLATE `utf8mb4_unicode_ci`, CHANGE name name VARCHAR(255) CHARACTER SET utf8mb4 NOT NULL COLLATE `utf8mb4_unicode_ci`, CHANGE hash hash VARCHAR(255) CHARACTER SET utf8mb4 NOT NULL COLLATE `utf8mb4_unicode_ci`, CHANGE folder folder VARCHAR(255) CHARACTER SET utf8mb4 NOT NULL COLLATE `utf8mb4_unicode_ci`'); + } + + public function isTransactional(): bool + { + return false; + } +} diff --git a/migrations/Version20230828092912.php b/migrations/Version20230828092912.php new file mode 100644 index 0000000..21372ca --- /dev/null +++ b/migrations/Version20230828092912.php @@ -0,0 +1,33 @@ +addSql('CREATE INDEX font_created_at ON fonts (created_at)'); + $this->addSql('CREATE INDEX font_updated_at ON fonts (updated_at)'); + } + + public function down(Schema $schema): void + { + // this down() migration is auto-generated, please modify it to your needs + $this->addSql('DROP INDEX font_created_at ON fonts'); + $this->addSql('DROP INDEX font_updated_at ON fonts'); + } +} diff --git a/phpstan.neon b/phpstan.neon index b42b403..e7b4ec4 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -26,6 +26,8 @@ parameters: - '#Doctrine\\ORM\\Mapping\\GeneratedValue constructor expects#' - '#type mapping mismatch: property can contain Doctrine\\Common\\Collections\\Collection]+> but database expects Doctrine\\Common\\Collections\\Collection&iterable<[^\>]+>#' - '#should return Doctrine\\Common\\Collections\\Collection]+Interface> but returns Doctrine\\Common\\Collections\\Collection]+>#' + - '#but returns Doctrine\\Common\\Collections\\ReadableCollection]+>#' + - '#does not accept Doctrine\\Common\\Collections\\ReadableCollection]+>#' reportUnmatchedIgnoredErrors: false checkGenericClassInNonGenericObjectType: false diff --git a/src/Controller/Admin/FontsController.php b/src/Controller/Admin/FontsController.php index 65b99ac..894ea81 100644 --- a/src/Controller/Admin/FontsController.php +++ b/src/Controller/Admin/FontsController.php @@ -154,6 +154,9 @@ public function downloadAction(Request $request, int $id): BinaryFileResponse if ($font !== null) { // Prepare File $file = tempnam(sys_get_temp_dir(), "font_" . $font->getId()); + if (false === $file) { + throw new \RuntimeException('Cannot create temporary file.'); + } $zip = new \ZipArchive(); $zip->open($file, \ZipArchive::CREATE); diff --git a/src/Controller/FontFaceController.php b/src/Controller/FontFaceController.php index 502811b..115c0d5 100644 --- a/src/Controller/FontFaceController.php +++ b/src/Controller/FontFaceController.php @@ -86,7 +86,7 @@ public function fontFileAction(Request $request, string $filename, int $variant, if (null !== $font) { [$fontData, $mime] = $this->getFontData($font, $extension); - if (null !== $fontData) { + if (\is_string($fontData)) { $response = new Response( '', Response::HTTP_NOT_MODIFIED, @@ -104,7 +104,7 @@ public function fontFileAction(Request $request, string $filename, int $variant, if (!$response->isNotModified($request)) { $response->setContent($fontData); $response->setStatusCode(Response::HTTP_OK); - $response->setEtag(md5($response->getContent())); + $response->setEtag(md5($fontData)); } return $response; @@ -164,13 +164,12 @@ public function fontFacesAction(Request $request): Response 'variantHash' => $variantHash, ]; } - $response->setContent( - $this->templating->render( - '@RoadizFont/fonts/fontfamily.css.twig', - $assignation - ) + $content = $this->templating->render( + '@RoadizFont/fonts/fontfamily.css.twig', + $assignation ); - $response->setEtag(md5($response->getContent())); + $response->setContent($content); + $response->setEtag(md5($content)); $response->setStatusCode(Response::HTTP_OK); return $response; diff --git a/src/Entity/Font.php b/src/Entity/Font.php index 7cb4809..39cc3de 100644 --- a/src/Entity/Font.php +++ b/src/Entity/Font.php @@ -20,6 +20,8 @@ ORM\Entity(repositoryClass: FontRepository::class), ORM\Table(name: "fonts"), ORM\UniqueConstraint(columns: ["name", "variant"]), + ORM\Index(columns: ["created_at"], name: "font_created_at"), + ORM\Index(columns: ["updated_at"], name: "font_updated_at"), UniqueEntity(fields: ["name", "variant"]) ] class Font extends AbstractDateTimed @@ -86,31 +88,38 @@ class Font extends AbstractDateTimed protected ?UploadedFile $otfFile = null; protected ?UploadedFile $svgFile = null; - #[ORM\Column(name: 'eot_filename', type: 'string', nullable: true)] + #[ORM\Column(name: 'eot_filename', type: 'string', length: 100, nullable: true)] + #[Assert\Length(max: 100)] private ?string $eotFilename = null; - #[ORM\Column(name: 'woff_filename', type: 'string', nullable: true)] + #[ORM\Column(name: 'woff_filename', type: 'string', length: 100, nullable: true)] + #[Assert\Length(max: 100)] private ?string $woffFilename = null; - #[ORM\Column(name: 'woff2_filename', type: 'string', nullable: true)] + #[ORM\Column(name: 'woff2_filename', type: 'string', length: 100, nullable: true)] + #[Assert\Length(max: 100)] private ?string $woff2Filename = null; - #[ORM\Column(name: 'otf_filename', type: 'string', nullable: true)] + #[ORM\Column(name: 'otf_filename', type: 'string', length: 100, nullable: true)] + #[Assert\Length(max: 100)] private ?string $otfFilename = null; - #[ORM\Column(name: 'svg_filename', type: 'string', nullable: true)] + #[ORM\Column(name: 'svg_filename', type: 'string', length: 100, nullable: true)] + #[Assert\Length(max: 100)] private ?string $svgFilename = null; - #[ORM\Column(type: 'string', unique: false, nullable: false)] + #[ORM\Column(type: 'string', length: 100, unique: false, nullable: false)] #[Assert\NotNull] #[Assert\NotBlank] #[Assert\Length(max: 100)] private string $name = ''; - #[ORM\Column(type: 'string', unique: false, nullable: false)] + #[ORM\Column(type: 'string', length: 128, unique: false, nullable: false)] + #[Assert\Length(max: 128)] private string $hash = ''; - #[ORM\Column(type: 'string', nullable: false)] + #[ORM\Column(type: 'string', length: 100, nullable: false)] + #[Assert\Length(max: 100)] private string $folder = ''; #[ORM\Column(type: 'text', nullable: true)] diff --git a/src/Repository/FontRepository.php b/src/Repository/FontRepository.php index c1a08ec..de702bf 100644 --- a/src/Repository/FontRepository.php +++ b/src/Repository/FontRepository.php @@ -31,7 +31,8 @@ public function getLatestUpdateDate(): ?\DateTimeInterface { $query = $this->_em->createQuery(' SELECT MAX(f.updatedAt) FROM RZ\Roadiz\FontBundle\Entity\Font f'); + $updatedAt = $query->getSingleScalarResult(); - return new \DateTimeImmutable($query->getSingleScalarResult()); + return \is_string($updatedAt) ? new \DateTimeImmutable($updatedAt) : null; } } diff --git a/templates/admin/add.html.twig b/templates/admin/add.html.twig index e660283..d69ae99 100644 --- a/templates/admin/add.html.twig +++ b/templates/admin/add.html.twig @@ -22,7 +22,7 @@
{% apply spaceless %}