Completed
Push — master ( 8167f5...1ed7b5 )
by Vitaly
07:04
created

Module::compiler()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 20
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 20
ccs 0
cts 0
cp 0
rs 9.4285
cc 3
eloc 10
nc 3
nop 3
crap 12
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
 * @author Vitaly Iegorov <[email protected]>
12
 * @author Nikita Kotenko <[email protected]>
13
 */
14
class Module extends ExternalModule
15
{
16
    /** LESS variable declaration pattern */
17
    const P_VARIABLE_DECLARATION = '/^(\s|\n)?\@(?<name>[^\s:]+)\:(?<value>[^;]+);/';
18
    /** LESS mixin declaration pattern */
19
    const P_MIXIN_DECLARATION = '/^\s*\.(?<name>[^\s(]+)\s*(?<params>\([^)]+\))?\s*(?<code>\{[^}]+\})/';
20 2
21
    /** @var \lessc LESS compiler */
22 2
    protected $less;
23
24 2
    /** @var array Collection of LESS variables */
25
    protected $variables = [];
26 2
27
    /** @var array Collection of LESS mixins */
28
    protected $mixins = [];
29
30
    /** SamsonFramework load preparation stage handler */
31
    public function prepare()
32
    {
33
        Event::subscribe(Router::E_RESOURCE_PRELOAD, [$this, 'analyzer']);
34
        Event::subscribe(Router::E_RESOURCE_COMPILE, [$this, 'compiler']);
35
36
        $this->less = new \lessc;
37
38 2
        return true;
39
    }
40
41 2
    /**
42
     * LESS resource analyzer.
43
     *
44 2
     * @param string $resource  Resource full path
45 2
     * @param string $extension Resource extension
46
     */
47
    public function analyzer($resource, $extension)
48 1
    {
49
        if ($extension === 'less') {
50 1
            $contents = file_get_contents($resource);
51 1
            // Find variable declaration
52
            if (preg_match_all(self::P_VARIABLE_DECLARATION, $contents, $matches)) {
53
                // Gather variables in collection key => value
54
                for ($i = 0, $max = count($matches['name']); $i < $max; $i++) {
55
                    if (!array_key_exists($matches['name'][$i], $this->variables)) {
56
                        $this->variables[$matches['name'][$i]] = $matches[0][$i];
57
                    }
58
                }
59
            }
60
61
            // Find variable declaration
62
            if (preg_match_all(self::P_MIXIN_DECLARATION, $contents, $matches)) {
63
                // Gather variables in collection key => value
64
                for ($i = 0, $max = count($matches[0]); $i < $max; $i++) {
65
                    $this->mixins[$matches['name'][$i]] = $matches[0][$i];
66
                }
67
            }
68
69
            return [$this->variables, $this->mixins];
70
        }
71
    }
72
73
    /**
74
     * LESS resource compiler.
75
     *
76
     * @param string $resource  Resource full path
77
     * @param string $extension Resource extension
78
     * @param string $output    Compiled output resource content
79
     *
80
     * @throws \Exception
81
     */
82
    public function compiler($resource, &$extension, &$output)
83
    {
84
        if ($extension === 'less') {
85
            try {
86
                // Read updated CSS resource file and compile it with mixins
87
                $output = $this->less->compile(
88
                    implode("\n", $this->variables)
89
                    . implode("\n", $this->mixins)
90
                    . file_get_contents($resource)
91
                );
92
93
                // Switch extension
94
                $extension = 'css';
95
            } catch (\Exception $e) {
96
                //$errorFile = 'cache/error_resourcer'.microtime(true).'.less';
97
                //file_put_contents($errorFile, $output);
98
                throw new \Exception('Failed compiling LESS[' . $resource . ']:' . "\n" . $e->getMessage());
99
            }
100
        }
101
    }
102
}
103