Completed
Pull Request — master (#58)
by
unknown
02:15
created

Scanner::all()   C

Complexity

Conditions 8
Paths 20

Size

Total Lines 22
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 8

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 22
ccs 12
cts 12
cp 1
rs 6.6037
cc 8
eloc 12
nc 20
nop 0
crap 8
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
class Scanner
19
{
20
    /**
21
     * Return all sections (app & plugins) with an Template directory.
22
     *
23
     * @return array
24
     */
25 4
    public static function all(): array
26
    {
27 4
        $sections = [];
28
29 4
        foreach (App::path('Template') as $path) {
30 3
            if (is_dir($path)) {
31 3
                $sections['APP'] = isset($sections['APP']) ? $sections['APP'] : [];
32 3
                $sections['APP'] = array_merge($sections['APP'], static::iteratePath($path));
33
            }
34
        }
35
36 4
        foreach (static::pluginsWithTemplates() as $plugin) {
37 4
            foreach (App::path('Template', $plugin) as $path) {
38 4
                if (is_dir($path)) {
39 4
                    $sections[$plugin] = isset($sections[$plugin]) ? $sections[$plugin] : [];
40 4
                    $sections[$plugin] = array_merge($sections[$plugin], static::iteratePath($path));
41
                }
42
            }
43
        }
44
45 4
        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
    protected static function clearEmptySections(array $sections): array
74
    {
75 4
        array_walk($sections, function ($templates, $index) use (&$sections) {
76 4
            if (count($templates) == 0) {
77 4
                unset($sections[$index]);
78
            }
79 4
        });
80
81 4
        return $sections;
82
    }
83
84
    /**
85
     * Finds all plugins with a Template directory.
86
     *
87
     * @return array
88
     */
89 4
    protected static function pluginsWithTemplates(): array
90
    {
91 4
        $plugins = Plugin::loaded();
92
93 4
        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 4
            $paths = App::path('Template', $plugin);
95
96 4
            array_walk($paths, function ($path, $index) use (&$paths) {
97 4
                if (!is_dir($path)) {
98 4
                    unset($paths[$index]);
99
                }
100 4
            });
101 4
        });
102
103 4
        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 7
    protected static function iteratePath($path): array
114
    {
115 7
        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 7
    protected static function setupIterator($path): Iterator
126
    {
127 7
        return new RegexIterator(new RecursiveIteratorIterator(
128 7
            new RecursiveDirectoryIterator(
129 7
                $path,
130 7
                FilesystemIterator::KEY_AS_PATHNAME |
131 7
                FilesystemIterator::CURRENT_AS_FILEINFO |
132 7
                FilesystemIterator::SKIP_DOTS
133
            ),
134 7
            RecursiveIteratorIterator::CHILD_FIRST,
135 7
            RecursiveIteratorIterator::CATCH_GET_CHILD
136 7
        ), '/.*?' . 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 7
    protected static function walkIterator(Iterator $iterator): array
147
    {
148 7
        $items = [];
149
150 7
        $array = iterator_to_array($iterator);
151 7
        uasort($array, function ($a, $b) {
152 6
            if ($a == $b) {
153
                return 0;
154
            }
155
156 6
            return ($a < $b) ? -1 : 1;
157 7
        });
158
159
        foreach ($array as $paths) {
160
            foreach ($paths as $path) {
161
                $items[] = $path;
162
            }
163
        }
164
165
        return $items;
166
    }
167
}
168