diff --git a/phpstan.neon b/phpstan.neon
index 6909da9..ce86abc 100644
--- a/phpstan.neon
+++ b/phpstan.neon
@@ -4,4 +4,3 @@ includes:
parameters:
ignoreErrors:
- identifier: missingType.iterableValue
- - identifier: missingType.generics
diff --git a/phpunit.xml.dist b/phpunit.xml.dist
index 12abbc7..80c9e4f 100644
--- a/phpunit.xml.dist
+++ b/phpunit.xml.dist
@@ -21,6 +21,7 @@
./src/Entity/AbstractEntity.php
./src/Cache/ShlinkPredisClient.php
+ ./src/Paginator/Util/PagerfantaUtilsTrait.php
diff --git a/src/Paginator/Paginator.php b/src/Paginator/Paginator.php
index 96a10d1..2325885 100644
--- a/src/Paginator/Paginator.php
+++ b/src/Paginator/Paginator.php
@@ -8,6 +8,10 @@
use function max;
+/**
+ * @template T
+ * @extends Pagerfanta
+ */
class Paginator extends Pagerfanta
{
public const ALL_ITEMS = -1;
diff --git a/src/Paginator/Util/PagerfantaUtils.php b/src/Paginator/Util/PagerfantaUtils.php
new file mode 100644
index 0000000..a7d61bf
--- /dev/null
+++ b/src/Paginator/Util/PagerfantaUtils.php
@@ -0,0 +1,58 @@
+ $paginator
+ * @param null|callable(T): mixed $serializer
+ */
+ public static function serializePaginator(
+ Pagerfanta $paginator,
+ ?callable $serializer = null,
+ string $dataProp = 'data',
+ ): array {
+ $currentPageItems = ArrayUtils::iteratorToArray($paginator->getCurrentPageResults());
+
+ return [
+ $dataProp => self::serializeItems($currentPageItems, $serializer),
+ 'pagination' => [
+ 'currentPage' => $paginator->getCurrentPage(),
+ 'pagesCount' => $paginator->getNbPages(),
+ 'itemsPerPage' => $paginator->getMaxPerPage(),
+ 'itemsInCurrentPage' => count($currentPageItems),
+ 'totalItems' => $paginator->getNbResults(),
+ ],
+ ];
+ }
+
+ /**
+ * @param T[] $items
+ * @param null|callable(T): array $serializer
+ */
+ private static function serializeItems(array $items, ?callable $serializer = null): array
+ {
+ return $serializer === null ? $items : array_map($serializer, $items);
+ }
+
+ /**
+ * @param Pagerfanta $paginator
+ */
+ public static function formatCurrentPageMessage(Pagerfanta $paginator, string $pattern): string
+ {
+ return sprintf($pattern, $paginator->getCurrentPage(), $paginator->getNbPages());
+ }
+}
diff --git a/src/Paginator/Util/PagerfantaUtilsTrait.php b/src/Paginator/Util/PagerfantaUtilsTrait.php
index bd5bad6..15ee1c4 100644
--- a/src/Paginator/Util/PagerfantaUtilsTrait.php
+++ b/src/Paginator/Util/PagerfantaUtilsTrait.php
@@ -4,42 +4,33 @@
namespace Shlinkio\Shlink\Common\Paginator\Util;
-use Laminas\Stdlib\ArrayUtils;
use Pagerfanta\Pagerfanta;
use Shlinkio\Shlink\Common\Rest\DataTransformerInterface;
-use function array_map;
-use function count;
-use function sprintf;
-
+/**
+ * @deprecated Use PagerfantaUtils instead
+ */
trait PagerfantaUtilsTrait
{
+ /**
+ * @template T
+ * @param Pagerfanta $paginator
+ */
private function serializePaginator(
Pagerfanta $paginator,
?DataTransformerInterface $transformer = null,
string $dataProp = 'data',
): array {
- $currentPageItems = ArrayUtils::iteratorToArray($paginator->getCurrentPageResults());
-
- return [
- $dataProp => $this->serializeItems($currentPageItems, $transformer),
- 'pagination' => [
- 'currentPage' => $paginator->getCurrentPage(),
- 'pagesCount' => $paginator->getNbPages(),
- 'itemsPerPage' => $paginator->getMaxPerPage(),
- 'itemsInCurrentPage' => count($currentPageItems),
- 'totalItems' => $paginator->getNbResults(),
- ],
- ];
- }
-
- private function serializeItems(array $items, ?DataTransformerInterface $transformer = null): array
- {
- return $transformer === null ? $items : array_map([$transformer, 'transform'], $items);
+ $serializer = $transformer !== null ? fn ($value) => $transformer->transform($value) : null;
+ return PagerfantaUtils::serializePaginator($paginator, $serializer, $dataProp);
}
+ /**
+ * @template T
+ * @param Pagerfanta $paginator
+ */
private function formatCurrentPageMessage(Pagerfanta $paginator, string $pattern): string
{
- return sprintf($pattern, $paginator->getCurrentPage(), $paginator->getNbPages());
+ return PagerfantaUtils::formatCurrentPageMessage($paginator, $pattern);
}
}
diff --git a/src/Rest/DataTransformerInterface.php b/src/Rest/DataTransformerInterface.php
index 3672a5c..bf06d0f 100644
--- a/src/Rest/DataTransformerInterface.php
+++ b/src/Rest/DataTransformerInterface.php
@@ -4,6 +4,7 @@
namespace Shlinkio\Shlink\Common\Rest;
+/** @deprecated */
interface DataTransformerInterface
{
/**
diff --git a/src/Validation/OrderByFilter.php b/src/Validation/OrderByFilter.php
index 0925130..c89548d 100644
--- a/src/Validation/OrderByFilter.php
+++ b/src/Validation/OrderByFilter.php
@@ -9,6 +9,9 @@
use function is_string;
use function Shlinkio\Shlink\Common\parseOrderBy;
+/**
+ * @extends AbstractFilter
+ */
class OrderByFilter extends AbstractFilter
{
/**
diff --git a/test/Doctrine/Mapping/EnhancedPHPDriverTest.php b/test/Doctrine/Mapping/EnhancedPHPDriverTest.php
index 1780723..8f3ac90 100644
--- a/test/Doctrine/Mapping/EnhancedPHPDriverTest.php
+++ b/test/Doctrine/Mapping/EnhancedPHPDriverTest.php
@@ -17,6 +17,7 @@
class EnhancedPHPDriverTest extends TestCase
{
private MockObject & FileLocator $loader;
+ /** @var MockObject & ClassMetadata */
private MockObject & ClassMetadata $meta;
public function setUp(): void
diff --git a/test/Mock/MockRepository.php b/test/Mock/MockRepository.php
index 44e4bde..84b2db7 100644
--- a/test/Mock/MockRepository.php
+++ b/test/Mock/MockRepository.php
@@ -6,6 +6,9 @@
use Doctrine\ORM\EntityRepository;
+/**
+ * @extends EntityRepository