Completed
Push — master ( 3aee5c...9ea547 )
by Asif
06:14
created

ShortcodeCompiler::getRegistered()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
1
<?php namespace Webwizo\Shortcodes\Compilers;
2
3
use Illuminate\Support\Str;
4
5
class ShortcodeCompiler
6
{
7
8
    /**
9
     * Enabled state
10
     *
11
     * @var boolean
12
     */
13
    protected $enabled = false;
14
15
    /**
16
     * Enable strip state
17
     *
18
     * @var boolean
19
     */
20
    protected $strip = false;
21
22
    /**
23
     * @var
24
     */
25
    protected $matches;
26
27
    /**
28
     * Registered laravel-shortcodes
29
     *
30
     * @var array
31
     */
32
    protected $registered = [];
33
34
    /**
35
     * Attached View Data
36
     *
37
     * @var array
38
     */
39
    protected $data = [];
40
41
    /**
42
     * Enable
43
     *
44
     * @return void
45
     */
46
    public function enable()
47
    {
48
        $this->enabled = true;
49
    }
50
51
    /**
52
     * Disable
53
     *
54
     * @return void
55
     */
56
    public function disable()
57
    {
58
        $this->enabled = false;
59
    }
60
61
    /**
62
     * Add a new shortcode
63
     *
64
     * @param string          $name
65
     * @param callable|string $callback
66
     */
67
    public function add($name, $callback)
68
    {
69
        $this->registered[$name] = $callback;
70
    }
71
72
    public function attachData($data)
73
    {
74
        $this->data = $data;
75
    }
76
77
    /**
78
     * Compile the contents
79
     *
80
     * @param  string $value
81
     *
82
     * @return string
83
     */
84
    public function compile($value)
85
    {
86
        // Only continue is laravel-shortcodes have been registered
87
        if (!$this->enabled || !$this->hasShortcodes()) {
88
            return $value;
89
        }
90
        // Set empty result
91
        $result = '';
92
        // Here we will loop through all of the tokens returned by the Zend lexer and
93
        // parse each one into the corresponding valid PHP. We will then have this
94
        // template as the correctly rendered PHP that can be rendered natively.
95
        foreach (token_get_all($value) as $token) {
96
            $result .= is_array($token) ? $this->parseToken($token) : $token;
97
        }
98
99
        return $result;
100
    }
101
102
    /**
103
     * Check if laravel-shortcodes have been registered
104
     *
105
     * @return boolean
106
     */
107
    public function hasShortcodes()
108
    {
109
        return !empty($this->registered);
110
    }
111
112
    /**
113
     * Parse the tokens from the template.
114
     *
115
     * @param  array $token
116
     *
117
     * @return string
118
     */
119
    protected function parseToken($token)
120
    {
121
        list($id, $content) = $token;
122
        if ($id == T_INLINE_HTML) {
123
            $content = $this->renderShortcodes($content);
124
        }
125
126
        return $content;
127
    }
128
129
    /**
130
     * Render laravel-shortcodes
131
     *
132
     * @param  string $value
133
     *
134
     * @return string
135
     */
136
    protected function renderShortcodes($value)
137
    {
138
        $pattern = $this->getRegex();
139
140
        return preg_replace_callback("/{$pattern}/s", [$this, 'render'], $value);
141
    }
142
143
    /**
144
     * Render the current calld shortcode.
145
     *
146
     * @param  array $matches
147
     *
148
     * @return string
149
     */
150
    public function render($matches)
151
    {
152
        // Compile the shortcode
153
        $compiled = $this->compileShortcode($matches);
154
        $name = $compiled->getName();
155
156
        // Render the shortcode through the callback
157
        return call_user_func_array($this->getCallback($name), [
158
            $compiled,
159
            $compiled->getContent(),
160
            $this,
161
            $name,
162
            $this->getData()
163
        ]);
164
    }
165
166
    /**
167
     * Get Compiled Attributes.
168
     *
169
     * @param $matches
170
     *
171
     * @return \Webwizo\Shortcodes\Shortcode
172
     */
173
    protected function compileShortcode($matches)
174
    {
175
        // Set matches
176
        $this->setMatches($matches);
177
        // pars the attributes
178
        $attributes = $this->parseAttributes($this->matches[3]);
179
180
        // return shortcode instance
181
        return new Shortcode(
182
            $this->getName(),
183
            $attributes,
184
            $this->getContent()
185
        );
186
    }
187
188
    /**
189
     * Set the matches
190
     *
191
     * @param array $matches
192
     */
193
    protected function setMatches($matches = [])
194
    {
195
        $this->matches = $matches;
196
    }
197
198
    /**
199
     * Return the shortcode name
200
     *
201
     * @return string
202
     */
203
    public function getName()
204
    {
205
        return $this->matches[2];
206
    }
207
208
    /**
209
     * Return the shortcode content
210
     *
211
     * @return string
212
     */
213
    public function getContent()
214
    {
215
        // Compile the content, to support nested laravel-shortcodes
216
        return $this->compile($this->matches[5]);
217
    }
218
219
    /**
220
     * Return the view data
221
     *
222
     * @return array
223
     */
224
    public function getData()
225
    {
226
        return $this->data;
227
    }
228
229
230
    /**
231
     * Get the callback for the current shortcode (class or callback)
232
     *
233
     * @param  string $name
234
     *
235
     * @return callable|array
236
     */
237
    public function getCallback($name)
238
    {
239
        // Get the callback from the laravel-shortcodes array
240
        $callback = $this->registered[$name];
241
        // if is a string
242
        if (is_string($callback)) {
243
            // Parse the callback
244
            list($class, $method) = Str::parseCallback($callback, 'register');
245
            // If the class exist
246
            if (class_exists($class)) {
247
                // return class and method
0 ignored issues
show
Unused Code Comprehensibility introduced by
38% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
248
                return [
249
                    app($class),
250
                    $method
251
                ];
252
            }
253
        }
254
255
        return $callback;
256
    }
257
258
    /**
259
     * Parse the shortcode attributes
260
     *
261
     * @author Wordpress
262
     * @return array
263
     */
264
    protected function parseAttributes($text)
265
    {
266
        $attributes = [];
267
        // attributes pattern
268
        $pattern = '/(\w+)\s*=\s*"([^"]*)"(?:\s|$)|(\w+)\s*=\s*\'([^\']*)\'(?:\s|$)|(\w+)\s*=\s*([^\s\'"]+)(?:\s|$)|"([^"]*)"(?:\s|$)|(\S+)(?:\s|$)/';
269
        // Match
270
        if (preg_match_all($pattern, preg_replace('/[\x{00a0}\x{200b}]+/u', " ", $text), $match, PREG_SET_ORDER)) {
271
            foreach ($match as $m) {
272
                if (!empty($m[1])) {
273
                    $attributes[strtolower($m[1])] = stripcslashes($m[2]);
274
                } elseif (!empty($m[3])) {
275
                    $attributes[strtolower($m[3])] = stripcslashes($m[4]);
276
                } elseif (!empty($m[5])) {
277
                    $attributes[strtolower($m[5])] = stripcslashes($m[6]);
278
                } elseif (isset($m[7]) && strlen($m[7])) {
279
                    $attributes[] = stripcslashes($m[7]);
280
                } elseif (isset($m[8])) {
281
                    $attributes[] = stripcslashes($m[8]);
282
                }
283
            }
284
        } else {
285
            $attributes = ltrim($text);
286
        }
287
288
        // return attributes
289
        return is_array($attributes) ? $attributes : [$attributes];
290
    }
291
292
    /**
293
     * Get shortcode names
294
     *
295
     * @return string
296
     */
297
    protected function getShortcodeNames()
298
    {
299
        return join('|', array_map('preg_quote', array_keys($this->registered)));
300
    }
301
302
    /**
303
     * Get shortcode regex.
304
     *
305
     * @author Wordpress
306
     * @return string
307
     */
308
    protected function getRegex()
309
    {
310
        $shortcodeNames = $this->getShortcodeNames();
311
312
        return "\\[(\\[?)($shortcodeNames)(?![\\w-])([^\\]\\/]*(?:\\/(?!\\])[^\\]\\/]*)*?)(?:(\\/)\\]|\\](?:([^\\[]*+(?:\\[(?!\\/\\2\\])[^\\[]*+)*+)\\[\\/\\2\\])?)(\\]?)";
313
    }
314
315
    /**
316
     * Remove all shortcode tags from the given content.
317
     *
318
     * @param string $content Content to remove shortcode tags.
319
     *
320
     * @return string Content without shortcode tags.
321
     */
322
    public function strip($content)
323
    {
324
        if (empty($this->registered)) {
325
            return $content;
326
        }
327
        $pattern = $this->getRegex();
328
329
        return preg_replace_callback("/{$pattern}/s", [$this, 'stripTag'], $content);
330
    }
331
332
    /**
333
     * @return boolean
334
     */
335
    public function getStrip()
336
    {
337
        return $this->strip;
338
    }
339
340
    /**
341
     * @param boolean $strip
342
     */
343
    public function setStrip($strip)
344
    {
345
        $this->strip = $strip;
346
    }
347
348
    /**
349
     * Remove shortcode tag
350
     *
351
     * @param type $m
352
     *
353
     * @return string Content without shortcode tag.
354
     */
355
    protected function stripTag($m)
356
    {
357
        if ($m[1] == '[' && $m[6] == ']') {
358
            return substr($m[0], 1, -1);
359
        }
360
361
        return $m[1] . $m[6];
362
    }
363
    
364
    /**
365
     * Get registered shortcodes
366
     *
367
     * @return array shortcode tags.
368
     */
369
    public function getRegistered()
370
    {
371
        return $this->registered;
372
    }
373
}
374