GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Passed
Push — master ( deb9bb...faaf13 )
by
unknown
02:37
created

Shortcodes::parseFile()   A

Complexity

Conditions 5
Paths 5

Size

Total Lines 17
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 8
nc 5
nop 2
dl 0
loc 17
rs 9.6111
c 0
b 0
f 0
1
<?php
2
/**
3
 * This file is part of the O2System Framework package.
4
 *
5
 * For the full copyright and license information, please view the LICENSE
6
 * file that was distributed with this source code.
7
 *
8
 * @author         Steeve Andrian Salim
9
 * @copyright      Copyright (c) Steeve Andrian Salim
10
 */
11
12
// ------------------------------------------------------------------------
13
14
namespace O2System\Parser\Engines;
15
16
// ------------------------------------------------------------------------
17
18
use O2System\Psr\Parser\ParserEngineInterface;
19
use O2System\Psr\Patterns\Structural\Provider\AbstractProvider;
20
use O2System\Psr\Patterns\Structural\Provider\ValidationInterface;
21
use O2System\Spl\Traits\Collectors\ConfigCollectorTrait;
22
use O2System\Spl\Traits\Collectors\FileExtensionCollectorTrait;
23
use O2System\Spl\Traits\Collectors\FilePathCollectorTrait;
24
25
/**
26
 * Class Shortcodes
27
 *
28
 * This parser engine is used to parse WordPress "shortcodes".
29
 * The tag and attribute parsing or regular expression code is
30
 * based on the TextPattern tag parser.
31
 *
32
 * A few examples are below:
33
 *
34
 * [shortcode /]
35
 * [shortcode foo="bar" baz="bing" /]
36
 * [shortcode foo="bar"]content[/shortcode]
37
 *
38
 * Shortcode tags support attributes and enclosed content, but does not entirely
39
 * support inline shortcodes in other shortcodes. You will have to call the
40
 * shortcode parser in your function to account for that.
41
 *
42
 * @package O2System\Parser\Engines
43
 */
44
class Shortcodes extends AbstractProvider implements
45
    ValidationInterface,
46
    ParserEngineInterface
47
{
48
    use FileExtensionCollectorTrait;
49
    use FilePathCollectorTrait;
50
    use ConfigCollectorTrait;
51
52
    /**
53
     * Shortcodes::$config
54
     *
55
     * Shortcodes engine configurations.
56
     *
57
     * @var array
58
     */
59
    protected $config;
60
61
    // ------------------------------------------------------------------------
62
63
    /**
64
     * Shortcodes::__construct
65
     *
66
     * @param array $config
67
     */
68
    public function __construct(array $config = [])
69
    {
70
        $this->config = array_merge($this->config, $config);
71
    }
72
73
    // ------------------------------------------------------------------------
74
75
    /**
76
     * Shortcodes::parseFile
77
     *
78
     * @param string $filePath
79
     * @param array  $vars
80
     *
81
     * @return string
82
     */
83
    public function parseFile($filePath, array $vars = [])
84
    {
85
        if (is_file($filePath)) {
86
            return $this->parseString(file_get_contents($filePath), $vars);
87
        }
88
89
        // Try to find from filePaths
90
        if (count($this->filePaths)) {
91
            foreach ($this->filePaths as $fileDirectory) {
92
                if (is_file($fileDirectory . $filePath)) {
93
                    return $this->parseString(file_get_contents($fileDirectory . $filePath), $vars);
94
                    break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
95
                }
96
            }
97
        }
98
99
        return null;
100
    }
101
102
    // ------------------------------------------------------------------------
103
104
    /**
105
     * Shortcodes::parseString
106
     *
107
     * @param string $source
108
     * @param array  $vars
109
     *
110
     * @return mixed
111
     */
112
    public function parseString($source, array $vars = [])
113
    {
114
        if (count($vars)) {
115
            foreach ($vars as $offset => $shortcode) {
116
                $this->register($shortcode, $offset);
117
            }
118
        }
119
120
        $pattern = $this->getRegex();
121
122
        return preg_replace_callback('/' . $pattern . '/s', [&$this, 'parseRegex'], $source);
123
    }
124
125
    // ------------------------------------------------------------------------
126
127
    /**
128
     * Shortcodes::getRegex
129
     *
130
     * Retrieve the shortcode regular expression for searching.
131
     *
132
     * The regular expression combines the shortcode tags in the regular expression
133
     * in a regex class.
134
     *
135
     * The regular expresion contains 6 different sub matches to help with parsing.
136
     *
137
     * 1/6 - An extra [ or ] to allow for escaping shortcodes with double [[]]
138
     * 2 - The shortcode name
139
     * 3 - The shortcode argument list
140
     * 4 - The self closing /
141
     * 5 - The content of a shortcode when it wraps some content.
142
     *
143
     * @return string The shortcode search regular expression
144
     */
145
    private function getRegex()
146
    {
147
        $shortcodes = $this->getIterator();
148
149
        $offsetKeys = $shortcodes->getKeys();
150
        $offsetRegex = join('|', array_map('preg_quote', $offsetKeys));
151
152
        // WARNING! Do not change this regex
153
        return '(.?)\[(' . $offsetRegex . ')\b(.*?)(?:(\/))?\](?:(.+?)\[\/\2\])?(.?)';
154
    }
155
156
    // ------------------------------------------------------------------------
157
158
    /**
159
     * Shortcodes::validate
160
     *
161
     * @param mixed $value
162
     *
163
     * @return bool
164
     */
165
    public function validate($value)
166
    {
167
        return (bool)is_callable($value);
168
    }
169
170
    // ------------------------------------------------------------------------
171
172
    /**
173
     * Shortcodes::parseRegex
174
     *
175
     * Regular Expression callable for Shortcodes::parseString for calling shortcode hook.
176
     *
177
     * @see    Shortcodes::getRegex for details of the match array contents.
178
     *
179
     * @since  1.0
180
     * @access private
181
     * @uses   $shortcode_tags
182
     *
183
     * @param array $match Regular expression match array
184
     *
185
     * @return mixed False on failure.
186
     */
187
    private function parseRegex($match)
188
    {
189
        // allow [[foo]] syntax for escaping a tag
190
        if ($match[ 1 ] == '[' && $match[ 6 ] == ']') {
191
            return substr($match[ 0 ], 1, -1);
192
        }
193
194
        $offset = $match[ 2 ];
195
        $attr = $this->parseRegexAttributes($match[ 3 ]);
196
197
        if ($this->exists($offset)) {
198
            if (isset($match[ 5 ])) {
199
                // enclosing tag - extra parameter
200
                return $match[ 1 ] . call_user_func(
201
                        $this->__get($offset),
202
                        $attr,
203
                        $match[ 5 ],
204
                        $offset
205
                    ) . $match[ 6 ];
206
            } else {
207
                // self-closing tag
208
                return $match[ 1 ] . call_user_func($this->__get($offset), $attr, null, $offset) . $match[ 6 ];
209
            }
210
        }
211
    }
212
213
    // ------------------------------------------------------------------------
214
215
    /**
216
     * Shortcodes::parseRegexAttr
217
     *
218
     * Retrieve all attributes from the shortcodes tag.
219
     *
220
     * The attributes list has the attribute name as the key and the value of the
221
     * attribute as the value in the key/value pair. This allows for easier
222
     * retrieval of the attributes, since all attributes have to be known.
223
     *
224
     * @since 1.0
225
     *
226
     * @param string $string
227
     *
228
     * @return array List of attributes and their value.
229
     */
230
    private function parseRegexAttributes($string)
231
    {
232
        $attr = [];
233
        $pattern = '/(\w+)\s*=\s*"([^"]*)"(?:\s|$)|(\w+)\s*=\s*\'([^\']*)\'(?:\s|$)|(\w+)\s*=\s*([^\s\'"]+)(?:\s|$)|"([^"]*)"(?:\s|$)|(\S+)(?:\s|$)/';
234
        $string = preg_replace("/[\x{00a0}\x{200b}]+/u", " ", $string);
235
        if (preg_match_all($pattern, $string, $match, PREG_SET_ORDER)) {
236
            foreach ($match as $m) {
237
                if ( ! empty($m[ 1 ])) {
238
                    $attr[ strtolower($m[ 1 ]) ] = stripcslashes($m[ 2 ]);
239
                } elseif ( ! empty($m[ 3 ])) {
240
                    $attr[ strtolower($m[ 3 ]) ] = stripcslashes($m[ 4 ]);
241
                } elseif ( ! empty($m[ 5 ])) {
242
                    $attr[ strtolower($m[ 5 ]) ] = stripcslashes($m[ 6 ]);
243
                } elseif (isset($m[ 7 ]) and strlen($m[ 7 ])) {
244
                    $attr[] = stripcslashes($m[ 7 ]);
245
                } elseif (isset($m[ 8 ])) {
246
                    $attr[] = stripcslashes($m[ 8 ]);
247
                }
248
            }
249
        } else {
250
            $attr = ltrim($string);
251
        }
252
253
        return $attr;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $attr also could return the type string which is incompatible with the documented return type array.
Loading history...
254
    }
255
}