mimmi20/navigation-helper-converttopages

View on GitHub
src/ConvertToPages.php

Summary

Maintainability
A
0 mins
Test Coverage
A
95%
<?php
 
/**
* This file is part of the mimmi20/navigation-helper-converttopages package.
*
* Copyright (c) 2021-2025, Thomas Mueller <mimmi20@live.de>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
 
declare(strict_types = 1);
 
namespace Mimmi20\NavigationHelper\ConvertToPages;
 
use Laminas\Navigation\AbstractContainer;
use Laminas\Navigation\Page\AbstractPage;
use Laminas\Stdlib\ArrayUtils;
use Mimmi20\Mezzio\Navigation\ContainerInterface;
use Mimmi20\Mezzio\Navigation\Exception\InvalidArgumentException;
use Mimmi20\Mezzio\Navigation\Page\PageFactoryInterface;
use Mimmi20\Mezzio\Navigation\Page\PageInterface;
use Override;
use Traversable;
 
use function array_map;
use function assert;
use function is_array;
use function is_numeric;
use function is_string;
use function key;
 
final readonly class ConvertToPages implements ConvertToPagesInterface
{
/** @throws void */
public function __construct(private PageFactoryInterface | null $pageFactory)
{
// nothing to do
}
 
/**
* Converts a $mixed value to an array of pages
*
* @param AbstractContainer<AbstractPage>|AbstractPage|ContainerInterface<PageInterface>|int|iterable<iterable<string>|string>|PageInterface|string $mixed mixed value to get page(s) from
* @param bool $recursive whether $value should be looped if it is an array or a config
*
* @return array<int|string, AbstractPage|PageInterface>
*
* @throws InvalidArgumentException
*/
#[Override]
public function convert(
AbstractContainer | AbstractPage | iterable | ContainerInterface | int | PageInterface | string $mixed,
bool $recursive = true,
): array {
if ($mixed instanceof PageInterface || $mixed instanceof AbstractPage) {
// value is a page instance; return directly
return [$mixed];
}
 
if ($mixed instanceof ContainerInterface || $mixed instanceof AbstractContainer) {
// value is a container; return pages in it
$pages = [];
 
foreach ($mixed as $page) {
assert($page instanceof PageInterface || $page instanceof AbstractPage);
$pages[] = $page;
}
 
return $pages;
}
 
if (is_string($mixed)) {
// value is a string; make a URI page
try {
$page = $this->pageFactory?->factory(
[
'type' => 'uri',
'uri' => $mixed,
],
) ?? AbstractPage::factory(
[
'type' => 'uri',
'uri' => $mixed,
],
);
 
return [$page];
} catch (\Laminas\Navigation\Exception\InvalidArgumentException $e) {
throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e);
}
}
 
if ($mixed instanceof Traversable) {
try {
$mixed = ArrayUtils::iteratorToArray($mixed);
} catch (\Laminas\Stdlib\Exception\InvalidArgumentException $e) {
throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e);
}
}
 
if (is_array($mixed) && $mixed !== []) {
if ($recursive && is_numeric(key($mixed))) {
// first key is numeric; assume several pages
return array_map(
/** @return AbstractPage|PageInterface */
function (AbstractContainer | AbstractPage | iterable | ContainerInterface | int | PageInterface | string $value) {
[$page] = $this->convert($value, false);
 
return $page;
},
$mixed,
);
}
 
// pass array to factory directly
try {
$page = $this->pageFactory?->factory($mixed) ?? AbstractPage::factory($mixed);
 
return [$page];
} catch (\Laminas\Navigation\Exception\InvalidArgumentException $e) {
throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e);
}
}
 
// nothing found
return [];
}
}