Completed
Branch develop (f7dc53)
by Anton
05:49
created

DarkSyntax::createImporter()   C

Complexity

Conditions 11
Paths 9

Size

Total Lines 48
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 48
rs 5.2653
cc 11
eloc 21
nc 9
nop 2

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * Spiral Framework.
4
 *
5
 * @license   MIT
6
 * @author    Anton Titov (Wolfy-J)
7
 */
8
namespace Spiral\Stempler\Syntaxes;
9
10
use Spiral\Stempler\Exceptions\SyntaxException;
11
use Spiral\Stempler\Exporters\AttributesExporter;
12
use Spiral\Stempler\HtmlTokenizer;
13
use Spiral\Stempler\Importers\Aliaser;
14
use Spiral\Stempler\Importers\Bundler;
15
use Spiral\Stempler\Importers\Prefixer;
16
use Spiral\Stempler\Importers\Stopper;
17
use Spiral\Stempler\Supervisor;
18
use Spiral\Stempler\SyntaxInterface;
19
20
/**
21
 * Default Stempler syntax - Woo. Provides ability to define blocks, extends and includes.
22
 */
23
class DarkSyntax implements SyntaxInterface
24
{
25
    /**
26
     * Path attribute in extends and other nodes.
27
     */
28
    const PATH_ATTRIBUTE = 'path';
29
30
    /**
31
     * @var bool
32
     */
33
    private $strict = true;
34
35
    /**
36
     * Stempler syntax options, syntax and names. Every option is required.
37
     *
38
     * @todo Something with DTD? Seems compatible.
39
     * @var array
40
     */
41
    protected $constructions = [
42
        self::TYPE_BLOCK    => ['block:', 'section:', 'yield:', 'define:'],
43
        self::TYPE_EXTENDS  => [
44
            'extends:',
45
            'extends',
46
            'dark:extends',
47
            'layout:extends'
48
        ],
49
        self::TYPE_IMPORTER => ['dark:use', 'use', 'node:use', 'stempler:use']
50
    ];
51
52
    /**
53
     * @param bool $strict
54
     */
55
    public function __construct($strict = true)
56
    {
57
        $this->strict = $strict;
58
    }
59
60
    /**
61
     * {@inheritdoc}
62
     */
63
    public function tokenType(array $token, &$name = null)
64
    {
65
        $name = $token[HtmlTokenizer::TOKEN_NAME];
66
        foreach ($this->constructions as $type => $prefixes) {
67
            foreach ($prefixes as $prefix) {
68
                if (strpos($name, $prefix) === 0) {
69
                    //We found prefix pointing to needed behaviour
70
                    $name = substr($name, strlen($prefix));
71
72
                    return $type;
73
                }
74
            }
75
        }
76
77
        return self::TYPE_NONE;
78
    }
79
80
    /**
81
     * {@inheritdoc}
82
     */
83
    public function resolvePath(array $token)
84
    {
85
        $type = $this->tokenType($token, $name);
86
87
        if (isset($token[HtmlTokenizer::TOKEN_ATTRIBUTES][static::PATH_ATTRIBUTE])) {
88
            return $token[HtmlTokenizer::TOKEN_ATTRIBUTES][static::PATH_ATTRIBUTE];
89
        }
90
91
        if ($type == self::TYPE_EXTENDS && isset($token[HtmlTokenizer::TOKEN_ATTRIBUTES]['layout'])) {
92
            return $token[HtmlTokenizer::TOKEN_ATTRIBUTES]['layout'];
93
        }
94
95
        return $name;
96
    }
97
98
    /**
99
     * {@inheritdoc}
100
     */
101
    public function isStrict()
102
    {
103
        return $this->strict;
104
    }
105
106
    /**
107
     * {@inheritdoc}
108
     */
109
    public function createImporter(array $token, Supervisor $supervisor)
110
    {
111
        //Fetching path
112
        $path = $this->resolvePath($token);
113
        if (empty($attributes = $token[HtmlTokenizer::TOKEN_ATTRIBUTES])) {
114
            throw new SyntaxException("Invalid import element syntax, attributes missing.", $token);
115
        }
116
117
        /**
118
         * <dark:use bundle="path-to-bundle"/>
119
         */
120
        if (isset($attributes['bundle'])) {
121
            $path = $attributes['bundle'];
122
123
            return new Bundler($supervisor, $path, $token);
124
        }
125
126
        /**
127
         * <dark:use path="path-to-element" as="tag"/>
128
         * <dark:use path="path-to-element" element="tag"/>
129
         */
130
        if (isset($attributes['element']) || isset($attributes['as'])) {
131
            $alias = isset($attributes['element']) ? $attributes['element'] : $attributes['as'];
132
133
            return new Aliaser($alias, $path);
134
        }
135
136
        //Now we have to decide what importer to use
137
        if (isset($attributes['namespace']) || isset($attributes['prefix'])) {
138
            if (strpos($path, '*') === false) {
139
                throw new SyntaxException(
140
                    "Path in namespace/prefix import must include start symbol.", $token
141
                );
142
            }
143
144
            $prefix = isset($attributes['namespace'])
145
                ? $attributes['namespace'] . ':'
146
                : $attributes['prefix'];
147
148
            return new Prefixer($prefix, $path);
149
        }
150
151
        if (isset($attributes['stop'])) {
152
            return new Stopper($attributes['stop']);
153
        }
154
155
        throw new SyntaxException("Undefined use element.", $token);
156
    }
157
158
    /**
159
     * {@inheritdoc}
160
     */
161
    public function blockExporters()
162
    {
163
        return [
164
            new AttributesExporter()
165
        ];
166
    }
167
}