Completed
Push — master ( f89e3e...b1c88a )
by Asif
01:33
created

ShortcodeCompiler::viewData()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 5
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 3
nc 1
nop 1
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
    protected $_viewData;
42
43
    /**
44
     * Enable
45
     *
46
     * @return void
47
     */
48
    public function enable()
49
    {
50
        $this->enabled = true;
51
    }
52
53
    /**
54
     * Disable
55
     *
56
     * @return void
57
     */
58
    public function disable()
59
    {
60
        $this->enabled = false;
61
    }
62
63
    /**
64
     * Add a new shortcode
65
     *
66
     * @param string          $name
67
     * @param callable|string $callback
68
     */
69
    public function add($name, $callback)
70
    {
71
        $this->registered[$name] = $callback;
72
    }
73
74
    public function attachData($data)
75
    {
76
        $this->data = $data;
77
    }
78
79
    /**
80
     * Compile the contents
81
     *
82
     * @param  string $value
83
     *
84
     * @return string
85
     */
86
    public function compile($value)
87
    {
88
        // Only continue is laravel-shortcodes have been registered
89
        if (!$this->enabled || !$this->hasShortcodes()) {
90
            return $value;
91
        }
92
        // Set empty result
93
        $result = '';
94
        // Here we will loop through all of the tokens returned by the Zend lexer and
95
        // parse each one into the corresponding valid PHP. We will then have this
96
        // template as the correctly rendered PHP that can be rendered natively.
97
        foreach (token_get_all($value) as $token) {
98
            $result .= is_array($token) ? $this->parseToken($token) : $token;
99
        }
100
101
        return $result;
102
    }
103
104
    /**
105
     * Check if laravel-shortcodes have been registered
106
     *
107
     * @return boolean
108
     */
109
    public function hasShortcodes()
110
    {
111
        return !empty($this->registered);
112
    }
113
114
    /**
115
     * Parse the tokens from the template.
116
     *
117
     * @param  array $token
118
     *
119
     * @return string
120
     */
121
    protected function parseToken($token)
122
    {
123
        list($id, $content) = $token;
124
        if ($id == T_INLINE_HTML) {
125
            $content = $this->renderShortcodes($content);
126
        }
127
128
        return $content;
129
    }
130
131
    /**
132
     * Render laravel-shortcodes
133
     *
134
     * @param  string $value
135
     *
136
     * @return string
137
     */
138
    protected function renderShortcodes($value)
139
    {
140
        $pattern = $this->getRegex();
141
142
        return preg_replace_callback("/{$pattern}/s", [$this, 'render'], $value);
143
    }
144
    
145
    // get view data
146
    public function viewData( $viewData )
147
    {
148
        $this->_viewData = $viewData;
149
        return $this;
150
    }
151
152
    /**
153
     * Render the current calld shortcode.
154
     *
155
     * @param  array $matches
156
     *
157
     * @return string
158
     */
159
    public function render($matches)
160
    {
161
        // Compile the shortcode
162
        $compiled = $this->compileShortcode($matches);
163
        $name = $compiled->getName();
164
        $viewData = $this->_viewData;
165
166
        // Render the shortcode through the callback
167
        return call_user_func_array($this->getCallback($name), [
168
            $compiled,
169
            $compiled->getContent(),
170
            $this,
171
            $name,
172
            $viewData
173
        ]);
174
    }
175
176
    /**
177
     * Get Compiled Attributes.
178
     *
179
     * @param $matches
180
     *
181
     * @return \Webwizo\Shortcodes\Shortcode
182
     */
183
    protected function compileShortcode($matches)
184
    {
185
        // Set matches
186
        $this->setMatches($matches);
187
        // pars the attributes
188
        $attributes = $this->parseAttributes($this->matches[3]);
189
190
        // return shortcode instance
191
        return new Shortcode(
192
            $this->getName(),
193
            $attributes,
194
            $this->getContent()
195
        );
196
    }
197
198
    /**
199
     * Set the matches
200
     *
201
     * @param array $matches
202
     */
203
    protected function setMatches($matches = [])
204
    {
205
        $this->matches = $matches;
206
    }
207
208
    /**
209
     * Return the shortcode name
210
     *
211
     * @return string
212
     */
213
    public function getName()
214
    {
215
        return $this->matches[2];
216
    }
217
218
    /**
219
     * Return the shortcode content
220
     *
221
     * @return string
222
     */
223
    public function getContent()
224
    {
225
        // Compile the content, to support nested laravel-shortcodes
226
        return $this->compile($this->matches[5]);
227
    }
228
229
    /**
230
     * Return the view data
231
     *
232
     * @return array
233
     */
234
    public function getData()
235
    {
236
        return $this->data;
237
    }
238
239
240
    /**
241
     * Get the callback for the current shortcode (class or callback)
242
     *
243
     * @param  string $name
244
     *
245
     * @return callable|array
246
     */
247
    public function getCallback($name)
248
    {
249
        // Get the callback from the laravel-shortcodes array
250
        $callback = $this->registered[$name];
251
        // if is a string
252
        if (is_string($callback)) {
253
            // Parse the callback
254
            list($class, $method) = Str::parseCallback($callback, 'register');
255
            // If the class exist
256
            if (class_exists($class)) {
257
                // 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...
258
                return [
259
                    app($class),
260
                    $method
261
                ];
262
            }
263
        }
264
265
        return $callback;
266
    }
267
268
    /**
269
     * Parse the shortcode attributes
270
     *
271
     * @author Wordpress
272
     * @return array
273
     */
274
    protected function parseAttributes($text)
275
    {
276
        $attributes = [];
277
        // attributes pattern
278
        $pattern = '/(\w+)\s*=\s*"([^"]*)"(?:\s|$)|(\w+)\s*=\s*\'([^\']*)\'(?:\s|$)|(\w+)\s*=\s*([^\s\'"]+)(?:\s|$)|"([^"]*)"(?:\s|$)|(\S+)(?:\s|$)/';
279
        // Match
280
        if (preg_match_all($pattern, preg_replace('/[\x{00a0}\x{200b}]+/u', " ", $text), $match, PREG_SET_ORDER)) {
281
            foreach ($match as $m) {
282
                if (!empty($m[1])) {
283
                    $attributes[strtolower($m[1])] = stripcslashes($m[2]);
284
                } elseif (!empty($m[3])) {
285
                    $attributes[strtolower($m[3])] = stripcslashes($m[4]);
286
                } elseif (!empty($m[5])) {
287
                    $attributes[strtolower($m[5])] = stripcslashes($m[6]);
288
                } elseif (isset($m[7]) && strlen($m[7])) {
289
                    $attributes[] = stripcslashes($m[7]);
290
                } elseif (isset($m[8])) {
291
                    $attributes[] = stripcslashes($m[8]);
292
                }
293
            }
294
        } else {
295
            $attributes = ltrim($text);
296
        }
297
298
        // return attributes
299
        return is_array($attributes) ? $attributes : [$attributes];
300
    }
301
302
    /**
303
     * Get shortcode names
304
     *
305
     * @return string
306
     */
307
    protected function getShortcodeNames()
308
    {
309
        return join('|', array_map('preg_quote', array_keys($this->registered)));
310
    }
311
312
    /**
313
     * Get shortcode regex.
314
     *
315
     * @author Wordpress
316
     * @return string
317
     */
318
    protected function getRegex()
319
    {
320
        $shortcodeNames = $this->getShortcodeNames();
321
322
        return "\\[(\\[?)($shortcodeNames)(?![\\w-])([^\\]\\/]*(?:\\/(?!\\])[^\\]\\/]*)*?)(?:(\\/)\\]|\\](?:([^\\[]*+(?:\\[(?!\\/\\2\\])[^\\[]*+)*+)\\[\\/\\2\\])?)(\\]?)";
323
    }
324
325
    /**
326
     * Remove all shortcode tags from the given content.
327
     *
328
     * @param string $content Content to remove shortcode tags.
329
     *
330
     * @return string Content without shortcode tags.
331
     */
332
    public function strip($content)
333
    {
334
        if (empty($this->registered)) {
335
            return $content;
336
        }
337
        $pattern = $this->getRegex();
338
339
        return preg_replace_callback("/{$pattern}/s", [$this, 'stripTag'], $content);
340
    }
341
342
    /**
343
     * @return boolean
344
     */
345
    public function getStrip()
346
    {
347
        return $this->strip;
348
    }
349
350
    /**
351
     * @param boolean $strip
352
     */
353
    public function setStrip($strip)
354
    {
355
        $this->strip = $strip;
356
    }
357
358
    /**
359
     * Remove shortcode tag
360
     *
361
     * @param type $m
362
     *
363
     * @return string Content without shortcode tag.
364
     */
365
    protected function stripTag($m)
366
    {
367
        if ($m[1] == '[' && $m[6] == ']') {
368
            return substr($m[0], 1, -1);
369
        }
370
371
        return $m[1] . $m[6];
372
    }
373
    
374
    /**
375
     * Get registered shortcodes
376
     *
377
     * @return array shortcode tags.
378
     */
379
    public function getRegistered()
380
    {
381
        return $this->registered;
382
    }
383
}
384