diff --git a/.github/workflows/php.yml b/.github/workflows/php.yml
index 80fd101..b87217b 100644
--- a/.github/workflows/php.yml
+++ b/.github/workflows/php.yml
@@ -5,6 +5,9 @@ on:
branches: [ "*" ]
pull_request:
branches: [ "main" ]
+ schedule:
+ - cron: '13 5 * * *'
+ workflow_dispatch:
permissions:
contents: read
@@ -59,6 +62,7 @@ jobs:
- name: Run phpstan
run: vendor/bin/phpstan analyse
+ if: matrix.dep == 'highest'
- name: Run phpunit
run: |
diff --git a/.phive/phars.xml b/.phive/phars.xml
index 2b1f5c8..ad6ca89 100644
--- a/.phive/phars.xml
+++ b/.phive/phars.xml
@@ -1,4 +1,4 @@
-
+
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0aa0be6..79f438a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,14 @@
# CHANGELOG
+## 1.12.0
+
+* fix: fix phpstan errors
+* build: schedule weekly CI
+* build: update to phpstan 2
+* build: update to psalm 6
+* fix: handle attempts to resize corrupt images
+* feat: `FileLocationResolverCommand` to debug file location
+
## 1.11.0
* test: modernization
diff --git a/composer.json b/composer.json
index 62f782b..a95b838 100644
--- a/composer.json
+++ b/composer.json
@@ -50,17 +50,17 @@
"require-dev": {
"bnf/phpstan-psr-container": "^1.0",
"doctrine/doctrine-bundle": "^2.10",
- "ekino/phpstan-banned-code": "^2.1",
+ "ekino/phpstan-banned-code": "^3.0",
"league/flysystem-memory": "^3.16",
"mockery/mockery": "^1.6",
- "phpstan/phpstan": "^1.12.5 || ^1.13",
- "phpstan/phpstan-deprecation-rules": "^1.1",
- "phpstan/phpstan-mockery": "^1.1",
- "phpstan/phpstan-phpunit": "^1.3",
+ "phpstan/phpstan": "^2.0",
+ "phpstan/phpstan-deprecation-rules": "^2.0",
+ "phpstan/phpstan-mockery": "^2.0",
+ "phpstan/phpstan-phpunit": "^2.0",
"phpunit/phpunit": "^10.5",
"psalm/plugin-mockery": "^1.1",
"psalm/plugin-phpunit": "^0.19.0",
- "rector/rector": "^1.2",
+ "rector/rector": "^2.0",
"symfony/asset": "^6.2 || ^7.0",
"symfony/asset-mapper": "^6.2 || ^7.0",
"symfony/console": "^6.2 || ^7.0",
@@ -80,7 +80,8 @@
"symfony/yaml": "^6.2 || ^7.0",
"symplify/monorepo-builder": "^11.2.20 || ^11.3",
"twig/extra-bundle": "^2.12|^3.0",
- "vimeo/psalm": "^5.26"
+ "vimeo/psalm": "^6.0",
+ "league/flysystem-bundle": "^3.4"
},
"autoload": {
"psr-4": {
@@ -116,22 +117,22 @@
}
},
"replace": {
- "rekalogika/file": "1.11.0",
- "rekalogika/file-association": "1.11.0",
- "rekalogika/file-association-contracts": "1.11.0",
- "rekalogika/file-association-entity": "1.11.0",
- "rekalogika/file-bundle": "1.11.0",
- "rekalogika/file-contracts": "1.11.0",
- "rekalogika/file-derivation": "1.11.0",
- "rekalogika/file-filepond": "1.11.0",
- "rekalogika/file-image": "1.11.0",
- "rekalogika/file-metadata": "1.11.0",
- "rekalogika/file-metadata-contracts": "1.11.0",
- "rekalogika/file-null": "1.11.0",
- "rekalogika/file-oneup-uploader-bridge": "1.11.0",
- "rekalogika/file-server": "1.11.0",
- "rekalogika/file-symfony-bridge": "1.11.0",
- "rekalogika/file-tree-contracts": "1.11.0",
- "rekalogika/file-zip": "1.11.0"
+ "rekalogika/file": "1.12.0",
+ "rekalogika/file-association": "1.12.0",
+ "rekalogika/file-association-contracts": "1.12.0",
+ "rekalogika/file-association-entity": "1.12.0",
+ "rekalogika/file-bundle": "1.12.0",
+ "rekalogika/file-contracts": "1.12.0",
+ "rekalogika/file-derivation": "1.12.0",
+ "rekalogika/file-filepond": "1.12.0",
+ "rekalogika/file-image": "1.12.0",
+ "rekalogika/file-metadata": "1.12.0",
+ "rekalogika/file-metadata-contracts": "1.12.0",
+ "rekalogika/file-null": "1.12.0",
+ "rekalogika/file-oneup-uploader-bridge": "1.12.0",
+ "rekalogika/file-server": "1.12.0",
+ "rekalogika/file-symfony-bridge": "1.12.0",
+ "rekalogika/file-tree-contracts": "1.12.0",
+ "rekalogika/file-zip": "1.12.0"
}
}
diff --git a/packages/file-association-contracts/composer.json b/packages/file-association-contracts/composer.json
index 8197597..b6084f2 100644
--- a/packages/file-association-contracts/composer.json
+++ b/packages/file-association-contracts/composer.json
@@ -23,7 +23,7 @@
},
"extra": {
"branch-alias": {
- "dev-main": "1.12-dev"
+ "dev-main": "1.13-dev"
}
}
}
diff --git a/packages/file-association-entity/composer.json b/packages/file-association-entity/composer.json
index a554604..127af87 100644
--- a/packages/file-association-entity/composer.json
+++ b/packages/file-association-entity/composer.json
@@ -27,14 +27,14 @@
},
"require": {
"doctrine/collections": "^2.0",
- "rekalogika/file-contracts": "^1.11",
- "rekalogika/file-metadata": "^1.11",
- "rekalogika/file-null": "^1.11",
+ "rekalogika/file-contracts": "^1.12",
+ "rekalogika/file-metadata": "^1.12",
+ "rekalogika/file-null": "^1.12",
"rekalogika/doctrine-collections-decorator": "^2.0"
},
"extra": {
"branch-alias": {
- "dev-main": "1.12-dev"
+ "dev-main": "1.13-dev"
}
}
}
diff --git a/packages/file-association-entity/src/EmbeddedMetadata.php b/packages/file-association-entity/src/EmbeddedMetadata.php
index a56ce1a..127350d 100644
--- a/packages/file-association-entity/src/EmbeddedMetadata.php
+++ b/packages/file-association-entity/src/EmbeddedMetadata.php
@@ -22,7 +22,7 @@
*
* @implements \IteratorAggregate
*/
-class EmbeddedMetadata implements RawMetadataInterface, \IteratorAggregate
+final class EmbeddedMetadata implements RawMetadataInterface, \IteratorAggregate
{
private ?string $name = null;
@@ -38,6 +38,7 @@ class EmbeddedMetadata implements RawMetadataInterface, \IteratorAggregate
/**
* @var array
+ * @phpstan-ignore property.unusedType
*/
private ?array $other = [];
diff --git a/packages/file-association-entity/src/FileDecorator.php b/packages/file-association-entity/src/FileDecorator.php
index ead454c..6207db4 100644
--- a/packages/file-association-entity/src/FileDecorator.php
+++ b/packages/file-association-entity/src/FileDecorator.php
@@ -21,7 +21,7 @@
use Rekalogika\Domain\File\Null\NullFile;
use Rekalogika\File\RawMetadata;
-class FileDecorator implements FileInterface
+final class FileDecorator implements FileInterface
{
use FileDecoratorTrait;
@@ -125,6 +125,7 @@ public static function syncMetadata(FileInterface $file): void
}
+ #[\Override]
protected function getWrapped(): FileInterface
{
return $this->file;
diff --git a/packages/file-association-entity/src/FileMetadataDecorator.php b/packages/file-association-entity/src/FileMetadataDecorator.php
index f364f1f..bda9c28 100644
--- a/packages/file-association-entity/src/FileMetadataDecorator.php
+++ b/packages/file-association-entity/src/FileMetadataDecorator.php
@@ -18,7 +18,7 @@
/**
* @implements \IteratorAggregate
*/
-class FileMetadataDecorator implements RawMetadataInterface, \IteratorAggregate
+final class FileMetadataDecorator implements RawMetadataInterface, \IteratorAggregate
{
/**
* @param RawMetadataInterface $embeddedMetadata Metadata embedded in entities
diff --git a/packages/file-association-entity/src/UnsetFile.php b/packages/file-association-entity/src/UnsetFile.php
index c6bc1e8..31a7c56 100644
--- a/packages/file-association-entity/src/UnsetFile.php
+++ b/packages/file-association-entity/src/UnsetFile.php
@@ -24,7 +24,7 @@
* A null file that indicates the file is unset. Used by `FileTrait` when the
* file property is unset.
*/
-class UnsetFile extends \Exception implements NullFileInterface
+final class UnsetFile extends \Exception implements NullFileInterface
{
use NullFileTrait;
diff --git a/packages/file-association/composer.json b/packages/file-association/composer.json
index 06854b5..c67987f 100644
--- a/packages/file-association/composer.json
+++ b/packages/file-association/composer.json
@@ -27,14 +27,17 @@
},
"require": {
"rekalogika/direct-property-access": "^1.1.2 || ^1.2",
- "rekalogika/file-association-contracts": "^1.11",
- "rekalogika/file-contracts": "^1.11",
+ "rekalogika/file-association-contracts": "^1.12",
+ "rekalogika/file-contracts": "^1.12",
"rekalogika/reconstitutor": "^1.3.2 || ^1.4",
"symfony/property-access": "^6.2 || ^7.0"
},
+ "suggest": {
+ "symfony/console": "Enables console commands"
+ },
"extra": {
"branch-alias": {
- "dev-main": "1.12-dev"
+ "dev-main": "1.13-dev"
}
}
}
diff --git a/packages/file-association/src/Attribute/AsFileAssociation.php b/packages/file-association/src/Attribute/AsFileAssociation.php
index 554065f..dc7f168 100644
--- a/packages/file-association/src/Attribute/AsFileAssociation.php
+++ b/packages/file-association/src/Attribute/AsFileAssociation.php
@@ -14,7 +14,7 @@
namespace Rekalogika\File\Association\Attribute;
#[\Attribute(\Attribute::TARGET_PROPERTY)]
-class AsFileAssociation
+final class AsFileAssociation
{
/**
* @var 'EAGER'|'LAZY'
diff --git a/packages/file-association/src/Attribute/WithFileAssociation.php b/packages/file-association/src/Attribute/WithFileAssociation.php
index e5c4174..acf1dab 100644
--- a/packages/file-association/src/Attribute/WithFileAssociation.php
+++ b/packages/file-association/src/Attribute/WithFileAssociation.php
@@ -14,4 +14,4 @@
namespace Rekalogika\File\Association\Attribute;
#[\Attribute(\Attribute::TARGET_CLASS)]
-class WithFileAssociation {}
+final class WithFileAssociation {}
diff --git a/packages/file-association/src/Command/FileLocationResolverCommand.php b/packages/file-association/src/Command/FileLocationResolverCommand.php
new file mode 100644
index 0000000..a431956
--- /dev/null
+++ b/packages/file-association/src/Command/FileLocationResolverCommand.php
@@ -0,0 +1,78 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE file
+ * that was distributed with this source code.
+ */
+
+namespace Rekalogika\File\Association\Command;
+
+use Doctrine\Persistence\ManagerRegistry;
+use Rekalogika\File\Association\Contracts\FileLocationResolverInterface;
+use Symfony\Component\Console\Attribute\AsCommand;
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+
+#[AsCommand(
+ name: 'rekalogika:file:resolve',
+ description: 'Resolves the location of the file based on the object and property name.',
+)]
+final class FileLocationResolverCommand extends Command
+{
+ public function __construct(
+ private readonly ManagerRegistry $managerRegistry,
+ private readonly FileLocationResolverInterface $fileLocationResolver,
+ ) {
+ parent::__construct();
+ }
+
+ #[\Override]
+ protected function configure(): void
+ {
+ $this->addArgument('class', InputArgument::REQUIRED, 'Class name');
+ $this->addArgument('id', InputArgument::REQUIRED, 'Identifier');
+ $this->addArgument('property', InputArgument::REQUIRED, 'Property name');
+ }
+
+ #[\Override]
+ protected function execute(InputInterface $input, OutputInterface $output): int
+ {
+ $class = $input->getArgument('class');
+
+ if (!\is_string($class) || !class_exists($class)) {
+ throw new \InvalidArgumentException(\sprintf('Class %s not found', get_debug_type($class)));
+ }
+
+ $id = $input->getArgument('id');
+
+ if (!\is_string($id)) {
+ throw new \InvalidArgumentException(\sprintf('Id %s not found', get_debug_type($id)));
+ }
+
+ $propertyName = $input->getArgument('property');
+
+ if (!\is_string($propertyName)) {
+ throw new \InvalidArgumentException(\sprintf('Property name %s not found', get_debug_type($propertyName)));
+ }
+
+ $object = $this->managerRegistry->getRepository($class)->find($id);
+
+ if (!$object) {
+ throw new \InvalidArgumentException('Object not found');
+ }
+
+ $filePointer = $this->fileLocationResolver->getFileLocation($object, $propertyName);
+
+ $output->writeln($filePointer->getKey());
+
+ return Command::SUCCESS;
+ }
+}
diff --git a/packages/file-association/src/Exception/FileLocationResolver/ChainedObjectNotSupportedException.php b/packages/file-association/src/Exception/FileLocationResolver/ChainedObjectNotSupportedException.php
index 417a9e1..86a055d 100644
--- a/packages/file-association/src/Exception/FileLocationResolver/ChainedObjectNotSupportedException.php
+++ b/packages/file-association/src/Exception/FileLocationResolver/ChainedObjectNotSupportedException.php
@@ -13,7 +13,7 @@
namespace Rekalogika\File\Association\Exception\FileLocationResolver;
-class ChainedObjectNotSupportedException extends FileLocationResolverException
+final class ChainedObjectNotSupportedException extends FileLocationResolverException
{
/**
* @param iterable $exceptions
diff --git a/packages/file-association/src/Exception/FileLocationResolver/ObjectNotSupportedException.php b/packages/file-association/src/Exception/FileLocationResolver/ObjectNotSupportedException.php
index 48b24ed..23ae34c 100644
--- a/packages/file-association/src/Exception/FileLocationResolver/ObjectNotSupportedException.php
+++ b/packages/file-association/src/Exception/FileLocationResolver/ObjectNotSupportedException.php
@@ -15,7 +15,7 @@
use Rekalogika\File\Association\Contracts\FileLocationResolverInterface;
-class ObjectNotSupportedException extends FileLocationResolverException
+final class ObjectNotSupportedException extends FileLocationResolverException
{
/**
* @param class-string $class
diff --git a/packages/file-association/src/Exception/ObjectIdResolver/ChainedObjectIdResolverException.php b/packages/file-association/src/Exception/ObjectIdResolver/ChainedObjectIdResolverException.php
index 1c034d6..0af94f2 100644
--- a/packages/file-association/src/Exception/ObjectIdResolver/ChainedObjectIdResolverException.php
+++ b/packages/file-association/src/Exception/ObjectIdResolver/ChainedObjectIdResolverException.php
@@ -13,7 +13,7 @@
namespace Rekalogika\File\Association\Exception\ObjectIdResolver;
-class ChainedObjectIdResolverException extends ObjectIdResolverException
+final class ChainedObjectIdResolverException extends ObjectIdResolverException
{
/**
* @param iterable $exceptions
diff --git a/packages/file-association/src/Exception/ObjectIdResolver/EmptyIdException.php b/packages/file-association/src/Exception/ObjectIdResolver/EmptyIdException.php
index ce2ee58..9786222 100644
--- a/packages/file-association/src/Exception/ObjectIdResolver/EmptyIdException.php
+++ b/packages/file-association/src/Exception/ObjectIdResolver/EmptyIdException.php
@@ -13,7 +13,7 @@
namespace Rekalogika\File\Association\Exception\ObjectIdResolver;
-class EmptyIdException extends ObjectIdResolverException
+final class EmptyIdException extends ObjectIdResolverException
{
public function __construct(
object $object,
diff --git a/packages/file-association/src/Exception/ObjectIdResolver/IdNotSupportedException.php b/packages/file-association/src/Exception/ObjectIdResolver/IdNotSupportedException.php
index 13d3eab..e3d3c61 100644
--- a/packages/file-association/src/Exception/ObjectIdResolver/IdNotSupportedException.php
+++ b/packages/file-association/src/Exception/ObjectIdResolver/IdNotSupportedException.php
@@ -13,7 +13,7 @@
namespace Rekalogika\File\Association\Exception\ObjectIdResolver;
-class IdNotSupportedException extends ObjectIdResolverException
+final class IdNotSupportedException extends ObjectIdResolverException
{
public function __construct(
object $object,
diff --git a/packages/file-association/src/Exception/ObjectIdResolver/MethodNotFoundException.php b/packages/file-association/src/Exception/ObjectIdResolver/MethodNotFoundException.php
index eac97eb..0c454b7 100644
--- a/packages/file-association/src/Exception/ObjectIdResolver/MethodNotFoundException.php
+++ b/packages/file-association/src/Exception/ObjectIdResolver/MethodNotFoundException.php
@@ -13,7 +13,7 @@
namespace Rekalogika\File\Association\Exception\ObjectIdResolver;
-class MethodNotFoundException extends ObjectIdResolverException
+final class MethodNotFoundException extends ObjectIdResolverException
{
public function __construct(
object $object,
diff --git a/packages/file-association/src/Exception/ObjectIdResolver/ObjectNotSupportedException.php b/packages/file-association/src/Exception/ObjectIdResolver/ObjectNotSupportedException.php
index 7c8550a..973500b 100644
--- a/packages/file-association/src/Exception/ObjectIdResolver/ObjectNotSupportedException.php
+++ b/packages/file-association/src/Exception/ObjectIdResolver/ObjectNotSupportedException.php
@@ -13,7 +13,7 @@
namespace Rekalogika\File\Association\Exception\ObjectIdResolver;
-class ObjectNotSupportedException extends ObjectIdResolverException
+final class ObjectNotSupportedException extends ObjectIdResolverException
{
public function __construct(
object $object,
diff --git a/packages/file-association/src/Exception/PropertyInspector/MissingPropertyException.php b/packages/file-association/src/Exception/PropertyInspector/MissingPropertyException.php
index d7e07d2..a3b4378 100644
--- a/packages/file-association/src/Exception/PropertyInspector/MissingPropertyException.php
+++ b/packages/file-association/src/Exception/PropertyInspector/MissingPropertyException.php
@@ -13,7 +13,7 @@
namespace Rekalogika\File\Association\Exception\PropertyInspector;
-class MissingPropertyException extends PropertyInspectorException
+final class MissingPropertyException extends PropertyInspectorException
{
public function __construct(
string $propertyName,
diff --git a/packages/file-association/src/Exception/PropertyReader/PropertyReaderException.php b/packages/file-association/src/Exception/PropertyReader/PropertyReaderException.php
index 179966f..6bffdf3 100644
--- a/packages/file-association/src/Exception/PropertyReader/PropertyReaderException.php
+++ b/packages/file-association/src/Exception/PropertyReader/PropertyReaderException.php
@@ -15,7 +15,7 @@
use Rekalogika\File\Association\Exception\FileAssociationException;
-class PropertyReaderException extends FileAssociationException
+final class PropertyReaderException extends FileAssociationException
{
public function __construct(
object $object,
diff --git a/packages/file-association/src/Exception/PropertyWriter/PropertyWriterException.php b/packages/file-association/src/Exception/PropertyWriter/PropertyWriterException.php
index 06e646f..6fd28b2 100644
--- a/packages/file-association/src/Exception/PropertyWriter/PropertyWriterException.php
+++ b/packages/file-association/src/Exception/PropertyWriter/PropertyWriterException.php
@@ -15,7 +15,7 @@
use Rekalogika\File\Association\Exception\FileAssociationException;
-class PropertyWriterException extends FileAssociationException
+final class PropertyWriterException extends FileAssociationException
{
/**
* @param object|array $object
diff --git a/packages/file-association/src/FileLocationResolver/ChainedFileLocationResolver.php b/packages/file-association/src/FileLocationResolver/ChainedFileLocationResolver.php
index afec9c2..a27f352 100644
--- a/packages/file-association/src/FileLocationResolver/ChainedFileLocationResolver.php
+++ b/packages/file-association/src/FileLocationResolver/ChainedFileLocationResolver.php
@@ -18,7 +18,7 @@
use Rekalogika\File\Association\Exception\FileLocationResolver\ChainedObjectNotSupportedException;
use Rekalogika\File\Association\Exception\FileLocationResolver\ObjectNotSupportedException;
-class ChainedFileLocationResolver implements FileLocationResolverInterface
+final class ChainedFileLocationResolver implements FileLocationResolverInterface
{
/**
* @param iterable $fileLocationResolvers
diff --git a/packages/file-association/src/FileLocationResolver/DefaultFileLocationResolver.php b/packages/file-association/src/FileLocationResolver/DefaultFileLocationResolver.php
index ba83650..f74e96d 100644
--- a/packages/file-association/src/FileLocationResolver/DefaultFileLocationResolver.php
+++ b/packages/file-association/src/FileLocationResolver/DefaultFileLocationResolver.php
@@ -18,7 +18,7 @@
use Rekalogika\File\Association\Contracts\ObjectIdResolverInterface;
use Rekalogika\File\Association\Model\FilePointer;
-class DefaultFileLocationResolver implements FileLocationResolverInterface
+final class DefaultFileLocationResolver implements FileLocationResolverInterface
{
public function __construct(
private readonly ObjectIdResolverInterface $objectIdResolver,
diff --git a/packages/file-association/src/Model/FilePointer.php b/packages/file-association/src/Model/FilePointer.php
index d431e78..0e1da0c 100644
--- a/packages/file-association/src/Model/FilePointer.php
+++ b/packages/file-association/src/Model/FilePointer.php
@@ -20,7 +20,7 @@
* An implementation of FilePointerInterface. We don't use the one in the
* rekalogika/file package so that this package does not have to depend on that.
*/
-class FilePointer implements FilePointerInterface
+final class FilePointer implements FilePointerInterface
{
use EqualityTrait;
diff --git a/packages/file-association/src/Model/MissingFile.php b/packages/file-association/src/Model/MissingFile.php
index b13c487..23aa8fa 100644
--- a/packages/file-association/src/Model/MissingFile.php
+++ b/packages/file-association/src/Model/MissingFile.php
@@ -24,7 +24,7 @@
* A null file that indicates the file is expected to exist, but missing in the
* storage backend.
*/
-class MissingFile extends \Exception implements NullFileInterface
+final class MissingFile extends \Exception implements NullFileInterface
{
use NullFileTrait;
diff --git a/packages/file-association/src/ObjectIdResolver/ChainedObjectIdResolver.php b/packages/file-association/src/ObjectIdResolver/ChainedObjectIdResolver.php
index c80e685..2c6aeb8 100644
--- a/packages/file-association/src/ObjectIdResolver/ChainedObjectIdResolver.php
+++ b/packages/file-association/src/ObjectIdResolver/ChainedObjectIdResolver.php
@@ -17,7 +17,7 @@
use Rekalogika\File\Association\Exception\ObjectIdResolver\ChainedObjectIdResolverException;
use Rekalogika\File\Association\Exception\ObjectIdResolver\ObjectIdResolverException;
-class ChainedObjectIdResolver implements ObjectIdResolverInterface
+final class ChainedObjectIdResolver implements ObjectIdResolverInterface
{
/**
* @var \WeakMap