Completed
Push — master ( e65eb6...df5dfe )
by Nikita
10:08
created

Module   A

Complexity

Total Complexity 8

Size/Duplication

Total Lines 85
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Test Coverage

Coverage 100%

Importance

Changes 17
Bugs 2 Features 5
Metric Value
wmc 8
c 17
b 2
f 5
lcom 1
cbo 3
dl 0
loc 85
ccs 25
cts 25
cp 1
rs 10

3 Methods

Rating   Name   Duplication   Size   Complexity  
A prepare() 0 8 1
A readImport() 0 19 4
A compiler() 0 20 3
1
<?php
2
namespace samsonphp\less;
3
4
use samson\core\ExternalModule;
5
use samsonphp\event\Event;
6
use samsonphp\resource\Router;
7
8
/**
9
 * SamsonPHP LESS compiler module.
10
 *
11
 * TODO: Nested mixin parsing to remove file name mixin hack
12
 * TODO: Switch to independent generic file system manager
13
 *
14
 * @author Vitaly Iegorov <[email protected]>
15
 */
16
class Module extends ExternalModule
17
{
18
    /** LESS mixin declaration pattern */
19
    const P_IMPORT_DECLARATION = '/@import\s+(\'|\")(?<path>[^\'\"]+)(\'|\");/';
20
21
22
    /** @var \lessc LESS compiler */
23
    protected $less;
24
25
    /** @var array Collection of LESS variables */
26
    protected $variables = [];
27
28
    /** @var array Collection of LESS mixins */
29
    protected $mixins = [];
30
31
    /** @var string Cached LESS code */
32
    protected $lessCode;
33
34
    /** SamsonFramework load preparation stage handler */
35 3
    public function prepare()
36
    {
37 3
        Event::subscribe(Router::E_RESOURCE_COMPILE, [$this, 'compiler']);
38
39 3
        $this->less = new \lessc;
40
41 3
        return true;
42
    }
43
44
    /**
45
     * Replace @import in content of the file
46
     *
47
     * @param string $resource Resource full path
48
     * @param string $content less file content
49
     * @return string
50
     */
51 2
    protected function readImport($resource, $content)
52
    {
53
        // Rewrite imports
54 2
        $matches = [];
55 2
        if (preg_match_all(self::P_IMPORT_DECLARATION, $content, $matches)) {
56 1
            for ($i=0, $size = count($matches[0]); $i < $size; $i++) {
57 1
                $path = dirname($resource).DIRECTORY_SEPARATOR.$matches['path'][$i];
58 1
                $path = (is_file($path))?$path:$path.'.less';
59 1
                $path = realpath($path);
60
61 1
                $newContent = file_get_contents($path);
62
63
                // Replace path in LESS @import command
64 1
                $content = str_replace($matches[0][$i], $this->readImport($path, $newContent), $content);
65 1
            }
66 1
        }
67
68 2
        return $content;
69
    }
70
71
    /**
72
     * LESS resource compiler.
73
     *
74
     * @param string $resource  Resource full path
75
     * @param string $extension Resource extension
76
     * @param string $content   Compiled output resource content
77
     *
78
     * @throws \Exception
79
     */
80 2
    public function compiler($resource, &$extension, &$content)
81
    {
82 2
        if ($extension === 'less') {
83
            try {
0 ignored issues
show
Coding Style introduced by
Blank line found at start of control structure
Loading history...
84
85
                // Rewrite imports
86 2
                $content = $this->readImport($resource, $content);
87
88
                // Compile LESS content to CSS
89 2
                $content = $this->less->compile($content);
90
91
                // Switch extension
92 1
                $extension = 'css';
93 2
            } catch (\Exception $e) {
94
                //$errorFile = 'cache/error_resourcer'.microtime(true).'.less';
95
                //file_put_contents($errorFile, $output);
96 1
                throw new \Exception('Failed compiling LESS in "' . $resource . '":' . "\n" . $e->getMessage());
97
            }
98 1
        }
99 1
    }
100
}
101