Completed
Push — master ( e74ae2...768df3 )
by Cees-Jan
24s
created

Scanner::pluginsWithTemplates()   A

Complexity

Conditions 2
Paths 1

Size

Total Lines 16

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 2.0078

Importance

Changes 0
Metric Value
dl 0
loc 16
ccs 7
cts 8
cp 0.875
rs 9.7333
c 0
b 0
f 0
cc 2
nc 1
nop 0
crap 2.0078
1
<?php declare(strict_types=1);
2
3
namespace WyriHaximus\TwigView\Lib;
4
5
use Cake\Core\App;
6
use Cake\Core\Plugin;
7
use FilesystemIterator;
8
use Iterator;
9
use RecursiveDirectoryIterator;
10
use RecursiveIteratorIterator;
11
use RegexIterator;
12
use WyriHaximus\TwigView\View\TwigView;
13
14
/**
15
 * Class Scanner.
16
 * @package WyriHaximus\TwigView\Lib
17
 */
18
final class Scanner
19
{
20
    /**
21
     * Return all sections (app & plugins) with an Template directory.
22
     *
23
     * @return array
24
     */
25 5
    public static function all(): array
26
    {
27 5
        $sections = [];
28
29 5
        foreach (App::path('Template') as $path) {
30 5
            if (is_dir($path)) {
31 5
                $sections['APP'] = isset($sections['APP']) ? $sections['APP'] : [];
32 5
                $sections['APP'] = array_merge($sections['APP'], static::iteratePath($path));
33
            }
34
        }
35
36 5
        foreach (static::pluginsWithTemplates() as $plugin) {
37 5
            foreach (App::path('Template', $plugin) as $path) {
38 5
                if (is_dir($path)) {
39 5
                    $sections[$plugin] = isset($sections[$plugin]) ? $sections[$plugin] : [];
40 5
                    $sections[$plugin] = array_merge($sections[$plugin], static::iteratePath($path));
41
                }
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
        $templates = [];
58
59 4
        foreach (App::path('Template', $plugin) as $path) {
60 3
            $templates = array_merge($templates, static::iteratePath($path));
61
        }
62
63 3
        return $templates;
64
    }
65
66
    /**
67
     * Check sections a remove the ones without anything in them.
68
     *
69
     * @param array $sections Sections to check.
70
     *
71
     * @return array
72
     */
73 5
    protected static function clearEmptySections(array $sections): array
74
    {
75
        array_walk($sections, function ($templates, $index) use (&$sections) {
76 5
            if (count($templates) == 0) {
77 5
                unset($sections[$index]);
78
            }
79 5
        });
80
81 5
        return $sections;
82
    }
83
84
    /**
85
     * Finds all plugins with a Template directory.
86
     *
87
     * @return array
88
     */
89 5
    protected static function pluginsWithTemplates(): array
90
    {
91 5
        $plugins = Plugin::loaded();
92
93
        array_walk($plugins, function ($plugin, $index) use (&$plugins) {
0 ignored issues
show
Unused Code introduced by
The parameter $index is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
94 5
            $paths = App::path('Template', $plugin);
95
96
            array_walk($paths, function ($path, $index) use (&$paths) {
97 5
                if (!is_dir($path)) {
98
                    unset($paths[$index]);
99
                }
100 5
            });
101 5
        });
102
103 5
        return $plugins;
104
    }
105
106
    /**
107
     * Iterage over the given path and return all matching .tpl files in it.
108
     *
109
     * @param string $path Path to iterate over.
110
     *
111
     * @return array
112
     */
113 8
    protected static function iteratePath($path): array
114
    {
115 8
        return static::walkIterator(static::setupIterator($path));
116
    }
117
118
    /**
119
     * Setup iterator for given path.
120
     *
121
     * @param string $path Path to setup iterator for.
122
     *
123
     * @return Iterator
124
     */
125 8
    protected static function setupIterator($path): Iterator
126
    {
127 8
        return new RegexIterator(new RecursiveIteratorIterator(
128 8
            new RecursiveDirectoryIterator(
129 8
                $path,
130
                FilesystemIterator::KEY_AS_PATHNAME |
131
                FilesystemIterator::CURRENT_AS_FILEINFO |
132 8
                FilesystemIterator::SKIP_DOTS
133
            ),
134 8
            RecursiveIteratorIterator::CHILD_FIRST,
135 8
            RecursiveIteratorIterator::CATCH_GET_CHILD
136 8
        ), '/.*?' . TwigView::EXT . '$/', RegexIterator::GET_MATCH);
137
    }
138
139
    /**
140
     * Walk over the iterator and compile all templates.
141
     *
142
     * @param \Iterator $iterator Iterator to walk.
143
     *
144
     * @return array
145
     */
146 8
    protected static function walkIterator(Iterator $iterator): array
147
    {
148 8
        $items = [];
149
150 8
        $array = iterator_to_array($iterator);
151
        uasort($array, function ($a, $b) {
152 8
            if ($a == $b) {
153
                return 0;
154
            }
155
156 8
            return ($a < $b) ? -1 : 1;
157 8
        });
158
159 8
        foreach ($array as $paths) {
160 8
            foreach ($paths as $path) {
161 8
                $items[] = $path;
162
            }
163
        }
164
165 8
        return $items;
166
    }
167
}
168