Completed
Pull Request — master (#4)
by James Ekow Abaka
03:06 queued 36s
created

TemplateFileResolver::searchTemplateDirectory()   A

Complexity

Conditions 5
Paths 10

Size

Total Lines 35
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 17
CRAP Score 5

Importance

Changes 0
Metric Value
cc 5
eloc 18
nc 10
nop 2
dl 0
loc 35
ccs 17
cts 17
cp 1
crap 5
rs 9.3554
c 0
b 0
f 0
1
<?php
2
3
namespace ntentan\honam;
4
5
use ntentan\honam\exceptions\TemplateResolutionException;
6
use ntentan\utils\Filesystem;
7
8
class TemplateFileResolver
9
{
10
    /**
11
     * The array which holds the template path heirachy.
12
     *
13
     * @var array<string>
14
     */
15
    private $pathHierarchy = array();
16
17
    /**
18
     * Append a directory to the end of the template path heirachy.
19
     *
20
     * @param string $path
21
     */
22 37
    public function appendToPathHierarchy($path)
23
    {
24 37
        $this->pathHierarchy[] = $path;
25 37
    }
26
27
    /**
28
     * Prepend a directory to the beginning of the template path heirachy.
29
     *
30
     * @param string $path
31
     */
32 2
    public function prependToPathHierarchy($path)
33
    {
34 2
        array_unshift($this->pathHierarchy, $path);
35 2
    }
36
37 30
    private function testTemplateFile($testTemplate, $paths, $extension)
38
    {
39 30
        $templateFile = '';
40 30
        foreach ($paths as $path) {
41 30
            $newTemplateFile = "$path/$testTemplate.$extension";
42 30
            if (file_exists($newTemplateFile)) {
43 29
                $templateFile = $newTemplateFile;
44 29
                break;
45
            }
46
        }
47 30
        return $templateFile;
48
    }
49
50 15
    private function testNoEngineTemplateFile($testTemplate, $paths)
51
    {
52 15
        $templateFile = '';
53 15
        foreach ($paths as $path) {
54 15
            $newTemplateFile = "$testTemplate.*";
55 15
            $files = array_filter(
56 15
                iterator_to_array(Filesystem::directory($path)->getFiles(false)),
57
                function($file) use($newTemplateFile) {
58 15
                    return fnmatch($newTemplateFile, basename($file));
59 15
                });
60
            $files = array_map(function($file) { return basename($file);}, $files);
61 15
            if (count($files) == 1) {
62 15
                $templateFile = $path . "/" . reset($files);
63 15
                break;
64 5
            } else if (count($files) > 1) {
65
                $templates = implode(", ", $files);
66
                throw new TemplateResolutionException("Multiple templates were resolved for the request '$testTemplate'. Please ensure that only one supported template type of the name '$testTemplate' exists in the path '$path'. Files found: $templates");
67
            }
68
        }
69 15
        return $templateFile;
70
    }
71
72 31
    private function searchTemplateDirectory($template, $ignoreEngine = false)
73
    {
74 31
        $templateFile = '';
75 31
        $extension = '';
76
77
        // Split the filename on the dots. The first part before the first dot
78
        // would be used to implement the file breakdown. The other parts are
79
        // fused together again and appended during the evaluation of the
80
        // breakdown.
81
82 31
        if ($ignoreEngine) {
83 15
            $breakDown = explode('_', $template);
84
        } else {
85 30
            $splitOnDots = explode('.', $template);
86 30
            $breakDown = explode('_', array_shift($splitOnDots));
87 30
            $extension = implode(".", $splitOnDots);
88
        }
89
90 31
        $parts = count($breakDown);
91
92 31
        for ($i = 0; $i < $parts; $i++) {
93 31
            $testTemplate = implode("_", array_slice($breakDown, $i, count($breakDown) - $i));
94
95 31
            if ($ignoreEngine) {
96 15
                $templateFile = $this->testNoEngineTemplateFile($testTemplate, $this->pathHierarchy);
97
            } else {
98 30
                $templateFile = $this->testTemplateFile($testTemplate, $this->pathHierarchy, $extension);
99
            }
100
101 31
            if ($templateFile != '') {
102 30
                break;
103
            }
104
        }
105
106 31
        return $templateFile;
107
    }
108
109
    /**
110
     * Resolve a template file by running through all the directories in the
111
     * template heirachy till a file that matches the template is found.
112
     *
113
     * @param string $template
114
     * @return string
115
     * @throws TemplateResolutionException
116
     */
117 31
    public function resolveTemplateFile($template)
118
    {
119 31
        if ($template == '') {
120
            throw new TemplateResolutionException("Empty template file requested");
121
        }
122
123 31
        $templateFile = $this->searchTemplateDirectory($template, pathinfo($template, PATHINFO_EXTENSION) === '');
124
125 31
        if ($templateFile == null) {
126 1
            $pathString = "[" . implode('; ', $this->pathHierarchy) . "]";
127 1
            throw new TemplateResolutionException(
128 1
                "Could not find a suitable template file for the current request '{$template}'. Current template path $pathString"
129
            );
130
        }
131
132 30
        return $templateFile;
133
    }
134
}
135