Passed
Push — master ( ad6b2a...b41ca0 )
by Caen
07:45 queued 14s
created

getCoreIdentifierPart()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Hyde\Framework\Features\Navigation;
6
7
use Illuminate\Support\Str;
8
9
use function ltrim;
10
use function substr;
11
use function explode;
12
use function implode;
13
use function sprintf;
14
use function array_map;
15
use function preg_match;
16
17
/**
18
 * @internal This class contains shared helper code for the framework to provide numerical page ordering for documentation sidebars.
19
 *           It is not intended to be used outside the framework code internals.
20
 */
21
class NumericalPageOrderingHelper
22
{
23
    /** @var array<string> The delimiters that are used to separate the numerical prefix from the rest of the identifier. */
24
    protected const DELIMITERS = ['-', '_'];
25
26
    /** Determines if a given identifier has a numerical prefix. */
27
    public static function hasNumericalPrefix(string $identifier): bool
28
    {
29
        if (static::isIdentifierNested($identifier)) {
30
            $identifier = static::getCoreIdentifierPart($identifier);
31
        }
32
33
        return preg_match(sprintf('/^\d+[%s]/', implode(static::DELIMITERS)), $identifier) === 1;
34
    }
35
36
    /**
37
     * Splits a numbered identifier into its numerical prefix and the rest of the identifier.
38
     *
39
     * @return array{int, string}
0 ignored issues
show
Documentation Bug introduced by
The doc comment array{int, string} at position 2 could not be parsed: Expected ':' at position 2, but found 'int'.
Loading history...
40
     */
41
    public static function splitNumericPrefix(string $identifier): array
42
    {
43
        if (static::isIdentifierNested($identifier)) {
44
            $parentPath = static::getNestedIdentifierPrefix($identifier);
45
            $identifier = static::getCoreIdentifierPart($identifier);
46
        }
47
48
        $separator = static::getFirstCharacterFromIdentifier($identifier);
49
        $parts = explode($separator, $identifier, 2);
50
51
        $parts[0] = (int) $parts[0];
52
53
        if (isset($parentPath)) {
54
            $parentPaths = explode('/', $parentPath);
55
            $parentPaths = array_map(function (string $part): string {
56
                return static::hasNumericalPrefix($part) ? static::splitNumericPrefix($part)[1] : $part;
57
            }, $parentPaths);
58
            $parentPath = implode('/', $parentPaths);
59
60
            $parts[1] = "$parentPath/$parts[1]";
61
        }
62
63
        return $parts;
64
    }
65
66
    protected static function isIdentifierNested(string $identifier): bool
67
    {
68
        return str_contains($identifier, '/');
69
    }
70
71
    protected static function getNestedIdentifierPrefix(string $identifier): string
72
    {
73
        return Str::beforeLast($identifier, '/');
74
    }
75
76
    protected static function getCoreIdentifierPart(string $identifier): string
77
    {
78
        return Str::afterLast($identifier, '/');
79
    }
80
81
    protected static function getFirstCharacterFromIdentifier(string $identifier): string
82
    {
83
        return substr(ltrim($identifier, '0123456789'), 0, 1);
84
    }
85
}
86