Scanner::iteratePath()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
cc 1
nc 1
nop 1
crap 1
1
<?php
2
declare(strict_types=1);
3
4
namespace WyriHaximus\TwigView\Lib;
5
6
use Cake\Core\App;
7
use Cake\Core\Plugin;
8
use FilesystemIterator;
9
use Iterator;
10
use RecursiveDirectoryIterator;
11
use RecursiveIteratorIterator;
12
use RegexIterator;
13
use WyriHaximus\TwigView\View\TwigView;
14
15
/**
16
 * Class Scanner.
17
 * @package WyriHaximus\TwigView\Lib
18
 */
19
final class Scanner
20
{
21
    /**
22
     * Return all sections (app & plugins) with an Template directory.
23
     *
24
     * @return array
25
     */
26 5
    public static function all(): array
27
    {
28 5
        $sections = [];
29
30 5
        foreach (App::path('templates') as $path) {
31 5
            if (is_dir($path)) {
32 5
                $sections['APP'] = $sections['APP'] ?? [];
33 5
                $sections['APP'] = array_merge($sections['APP'], static::iteratePath($path));
34
            }
35
        }
36
37 5
        foreach (static::pluginsWithTemplates() as $plugin) {
38 5
            $path = Plugin::templatePath($plugin);
39 5
            if (is_dir($path)) {
40 5
                $sections[$plugin] = $sections[$plugin] ?? [];
41 5
                $sections[$plugin] = array_merge($sections[$plugin], static::iteratePath($path));
42
            }
43
        }
44
45 5
        return static::clearEmptySections($sections);
46
    }
47
48
    /**
49
     * Return all templates for a given plugin.
50
     *
51
     * @param string $plugin The plugin to find all templates for.
52
     *
53
     * @return mixed
54
     */
55 4
    public static function plugin($plugin)
56
    {
57 4
        $path = Plugin::templatePath($plugin);
58 3
        $templates = static::iteratePath($path);
59
60 3
        return $templates;
61
    }
62
63
    /**
64
     * Check sections a remove the ones without anything in them.
65
     *
66
     * @param array $sections Sections to check.
67
     *
68
     * @return array
69
     */
70 5
    protected static function clearEmptySections(array $sections): array
71
    {
72
        array_walk($sections, function ($templates, $index) use (&$sections) {
73 5
            if (count($templates) == 0) {
74 5
                unset($sections[$index]);
75
            }
76 5
        });
77
78 5
        return $sections;
79
    }
80
81
    /**
82
     * Finds all plugins with a Template directory.
83
     *
84
     * @return array
85
     */
86 5
    protected static function pluginsWithTemplates(): array
87
    {
88 5
        $plugins = Plugin::loaded();
89
90
        array_walk($plugins, function ($plugin, $index) use (&$plugins) {
91 5
            $path = Plugin::templatePath($plugin);
92
93 5
            if (!is_dir($path)) {
94
                unset($plugins[$index]);
95
            }
96 5
        });
97
98 5
        return $plugins;
99
    }
100
101
    /**
102
     * Iterage over the given path and return all matching .tpl files in it.
103
     *
104
     * @param string $path Path to iterate over.
105
     *
106
     * @return array
107
     */
108 8
    protected static function iteratePath($path): array
109
    {
110 8
        return static::walkIterator(static::setupIterator($path));
111
    }
112
113
    /**
114
     * Setup iterator for given path.
115
     *
116
     * @param string $path Path to setup iterator for.
117
     *
118
     * @return \Iterator
119
     */
120 8
    protected static function setupIterator($path): Iterator
121
    {
122 8
        return new RegexIterator(new RecursiveIteratorIterator(
123 8
            new RecursiveDirectoryIterator(
124 8
                $path,
125
                FilesystemIterator::KEY_AS_PATHNAME |
126
                FilesystemIterator::CURRENT_AS_FILEINFO |
127 8
                FilesystemIterator::SKIP_DOTS
128
            ),
129 8
            RecursiveIteratorIterator::CHILD_FIRST,
130 8
            RecursiveIteratorIterator::CATCH_GET_CHILD
131 8
        ), '/.*?' . TwigView::EXT . '$/', RegexIterator::GET_MATCH);
132
    }
133
134
    /**
135
     * Walk over the iterator and compile all templates.
136
     *
137
     * @param \Iterator $iterator Iterator to walk.
138
     *
139
     * @return array
140
     */
141 8
    protected static function walkIterator(Iterator $iterator): array
142
    {
143 8
        $items = [];
144
145 8
        $array = iterator_to_array($iterator);
146
        uasort($array, function ($a, $b) {
147 8
            if ($a == $b) {
148
                return 0;
149
            }
150
151 8
            return $a < $b ? -1 : 1;
152 8
        });
153
154 8
        foreach ($array as $paths) {
155 8
            foreach ($paths as $path) {
156 8
                $items[] = $path;
157
            }
158
        }
159
160 8
        return $items;
161
    }
162
}
163