Completed
Pull Request — v3 (#279)
by Gabriel
11:00
created

Theme::assertAllThemesInHierarchyAreLeafThemes()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 7
rs 10
c 0
b 0
f 0
cc 3
nc 3
nop 1
1
<?php
2
3
namespace League\Plates\Template;
4
5
final class Theme
6
{
7
    private $dir;
8
    private $name;
9
    /** @var ?Theme */
10
    private $next;
11
12
    private function __construct(string $dir, string $name) {
13
        $this->dir = $dir;
14
        $this->name = $name;
15
    }
16
17
    /** @param Theme[] $themes */
18
    public static function hierarchy(array $themes): Theme {
19
        self::assertThemesForHierarchyAreNotEmpty($themes);
20
        self::assertAllThemesInHierarchyAreLeafThemes($themes);
21
22
        /** @var Theme $theme */
23
        $theme = array_reduce(array_slice($themes, 1), function(Theme $parent, Theme $child) {
24
            $child->next = $parent;
25
            return $child;
26
        }, $themes[0]);
27
        self::assertHierarchyContainsUniqueThemeNames($theme);
28
        return $theme;
29
    }
30
31
    public static function new(string $dir, string $name = 'Default'): self {
32
        return new self($dir, $name);
33
    }
34
35
    public function dir(): string {
36
        return $this->dir;
37
    }
38
39
    public function name(): string {
40
        return $this->name;
41
    }
42
43
    /**
44
     * list all directories in the hierarchy from first to last
45
     * @return Theme[]
46
     */
47
    public function listThemeHierarchy(): \Generator {
48
        yield $this;
49
        if ($this->next) {
50
            yield from $this->next->listThemeHierarchy();
51
        }
52
    }
53
54
    /** @param Theme[] $themes */
55
    private static function assertThemesForHierarchyAreNotEmpty(array $themes) {
56
        if (count($themes) === 0) {
57
            throw new \RuntimeException('Empty theme hierarchies are not allowed.');
58
        }
59
    }
60
61
    /** @param Theme[] $themes */
62
    private static function assertAllThemesInHierarchyAreLeafThemes(array $themes) {
63
        foreach ($themes as $theme) {
64
            if ($theme->next) {
65
                throw new \RuntimeException('Nested theme hierarchies are not allowed, make sure to use Theme::new when creating themes in your hierarchy. Theme ' . $theme->name . ' is already in a hierarchy.');
66
            }
67
        }
68
    }
69
70
    private static function assertHierarchyContainsUniqueThemeNames(Theme $theme) {
71
        $names = [];
72
        foreach ($theme->listThemeHierarchy() as $theme) {
73
            $names[] = $theme->name;
74
        }
75
76
        if (count(array_unique($names)) !== count($names)) {
77
            throw new \RuntimeException('Duplicate theme names in hierarchies are not allowed. Received theme names: [' . implode(', ', $names) . '].');
78
        }
79
    }
80
}
81