Completed
Pull Request — develop (#716)
by Agel_Nash
09:00
created

Cache::buildCache()   F

Complexity

Conditions 30
Paths > 20000

Size

Total Lines 173
Code Lines 119

Duplication

Lines 6
Ratio 3.47 %

Importance

Changes 0
Metric Value
cc 30
eloc 119
nc 4838400
nop 1
dl 6
loc 173
rs 2
c 0
b 0
f 0

How to fix   Long Method    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 namespace EvolutionCMS;
2
3
/**
4
 * @class: synccache
5
 */
6
class Cache
0 ignored issues
show
Coding Style introduced by
The property $request_time is not named in camelCase.

This check marks property names that have not been written in camelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. Thus the name database connection string becomes databaseConnectionString.

Loading history...
7
{
8
    public $cachePath;
9
    public $showReport;
10
    public $deletedfiles = array();
11
    /**
12
     * @var array
13
     */
14
    public $aliases = array();
15
    /**
16
     * @var array
17
     */
18
    public $parents = array();
19
    /**
20
     * @var array
21
     */
22
    public $aliasVisible = array();
23
    public $request_time;
24
    public $cacheRefreshTime;
25
26
    /**
27
     * synccache constructor.
28
     */
29
    public function __construct()
0 ignored issues
show
Coding Style introduced by
__construct uses the super-global variable $_SERVER which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
30
    {
31
        $modx = evolutionCMS();
32
33
        $this->request_time = $_SERVER['REQUEST_TIME'] + $modx->config['server_offset_time'];
34
    }
35
36
    /**
37
     * @param string $path
38
     */
39
    public function setCachepath($path)
40
    {
41
        $this->cachePath = $path;
42
    }
43
44
    /**
45
     * @param bool $bool
46
     */
47
    public function setReport($bool)
48
    {
49
        $this->showReport = $bool;
50
    }
51
52
    /**
53
     * @param string $s
54
     * @return string
55
     */
56
    public function escapeSingleQuotes($s)
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $s. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
57
    {
58
        if ($s === '') {
59
            return $s;
60
        }
61
        $q1 = array("\\", "'");
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $q1. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
62
        $q2 = array("\\\\", "\\'");
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $q2. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
63
64
        return str_replace($q1, $q2, $s);
65
    }
66
67
    /**
68
     * @param string $s
69
     * @return string
70
     */
71
    public function escapeDoubleQuotes($s)
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $s. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
72
    {
73
        $q1 = array("\\", "\"", "\r", "\n", "\$");
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $q1. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
74
        $q2 = array("\\\\", "\\\"", "\\r", "\\n", "\\$");
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $q2. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
75
76
        return str_replace($q1, $q2, $s);
77
    }
78
79
    /**
80
     * @param int|string $id
81
     * @param string $path
82
     * @return string
83
     */
84
    public function getParents($id, $path = '')
85
    { // modx:returns child's parent
86
        $modx = evolutionCMS();
87
        if (empty($this->aliases)) {
88
            $f = "id, IF(alias='', id, alias) AS alias, parent, alias_visible";
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $f. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
89
            $rs = $modx->db->select($f, '[+prefix+]site_content', 'deleted=0');
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $rs. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
90
            while ($row = $modx->db->getRow($rs)) {
91
                $docid = $row['id'];
92
                $this->aliases[$docid] = $row['alias'];
93
                $this->parents[$docid] = $row['parent'];
94
                $this->aliasVisible[$docid] = $row['alias_visible'];
95
            }
96
        }
97
        if (isset($this->aliases[$id])) {
98
            if ($this->aliasVisible[$id] == 1) {
99
                if ($path != '') {
100
                    $path = $this->aliases[$id] . '/' . $path;
101
                } else {
102
                    $path = $this->aliases[$id];
103
                }
104
            }
105
106
            return $this->getParents($this->parents[$id], $path);
107
        }
108
109
        return $path;
110
    }
111
112
    /**
113
     * @param null|DocumentParser $modx
114
     */
115
    public function emptyCache($modx = null)
0 ignored issues
show
Coding Style introduced by
emptyCache uses the super-global variable $GLOBALS which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
116
    {
117
        if (!($modx instanceof Interfaces\CoreInterface)) {
118
            $modx = $GLOBALS['modx'];
119
        }
120
        if (!isset($this->cachePath)) {
121
            $modx->messageQuit("Cache path not set.");
122
        }
123
124
        $files = glob(realpath($this->cachePath) . '/*.pageCache.php');
125
        $filesincache = count($files);
126
        $deletedfiles = array();
127
        while ($file = array_shift($files)) {
128
            $name = basename($file);
129
            clearstatcache();
130
            if (is_file($file)) {
131
                if (unlink($file)) {
132
                    $deletedfiles[] = $name;
133
                }
134
            }
135
        }
136
        $opcache_restrict_api = trim(ini_get('opcache.restrict_api'));
137
        $opcache_restrict_api = $opcache_restrict_api && mb_stripos(__FILE__, $opcache_restrict_api) !== 0;
138
139
        if (!$opcache_restrict_api && function_exists('opcache_get_status')) {
140
            $opcache = opcache_get_status();
141
            if (!empty($opcache['opcache_enabled'])) {
142
                opcache_reset();
143
            }
144
        }
145
146
        $this->buildCache($modx);
147
148
        $this->publishTimeConfig();
149
150
        // finished cache stuff.
151
        if ($this->showReport == true) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
152
            global $_lang;
153
            $total = count($deletedfiles);
154
            echo sprintf($_lang['refresh_cache'], $filesincache, $total);
155
            if ($total > 0) {
156
                if (isset($opcache)) {
157
                    echo '<p>Opcache empty.</p>';
158
                }
159
                echo '<p>' . $_lang['cache_files_deleted'] . '</p><ul>';
160
                foreach ($deletedfiles as $deletedfile) {
161
                    echo '<li>' . $deletedfile . '</li>';
162
                }
163
                echo '</ul>';
164
            }
165
        }
166
    }
167
168
    /**
169
     * @param string|int $cacheRefreshTime
170
     */
171
    public function publishTimeConfig($cacheRefreshTime = '')
172
    {
173
        $cacheRefreshTimeFromDB = $this->getCacheRefreshTime();
174
        if (!preg_match('@^[0-9]+$]@', $cacheRefreshTime) || $cacheRefreshTimeFromDB < $cacheRefreshTime) {
175
            $cacheRefreshTime = $cacheRefreshTimeFromDB;
176
        }
177
178
179
        // write the file
180
        $content = '<?php' . "\n";
181
        $content .= '$recent_update=\'' . $this->request_time . '\';' . "\n";
182
        $content .= '$cacheRefreshTime=\'' . $cacheRefreshTime . '\';' . "\n";
183
184
        $filename = $this->cachePath . '/sitePublishing.idx.php';
185
        if (!$handle = fopen($filename, 'w')) {
186
            exit("Cannot open file ({$filename}");
0 ignored issues
show
Coding Style Compatibility introduced by
The method publishTimeConfig() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
187
        }
188
189
        $content .= "\n";
190
191
        // Write $somecontent to our opened file.
192
        if (fwrite($handle, $content) === false) {
193
            exit("Cannot write publishing info file! Make sure the assets/cache directory is writable!");
0 ignored issues
show
Coding Style Compatibility introduced by
The method publishTimeConfig() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
194
        }
195
    }
196
197
    /**
198
     * @return int
199
     */
200
    public function getCacheRefreshTime()
201
    {
202
        $modx = evolutionCMS();
203
204
        // update publish time file
205
        $timesArr = array();
206
207
        $result = $modx->db->select('MIN(pub_date) AS minpub', '[+prefix+]site_content',
208
            'pub_date>' . $this->request_time);
209
        if (!$result) {
210
            echo "Couldn't determine next publish event!";
211
        }
212
213
        $minpub = $modx->db->getValue($result);
214
        if ($minpub != null) {
215
            $timesArr[] = $minpub;
216
        }
217
218
        $result = $modx->db->select('MIN(unpub_date) AS minunpub', '[+prefix+]site_content',
219
            'unpub_date>' . $this->request_time);
220
        if (!$result) {
221
            echo "Couldn't determine next unpublish event!";
222
        }
223
224
        $minunpub = $modx->db->getValue($result);
225
        if ($minunpub != null) {
226
            $timesArr[] = $minunpub;
227
        }
228
229
        if (isset($this->cacheRefreshTime) && !empty($this->cacheRefreshTime)) {
230
            $timesArr[] = $this->cacheRefreshTime;
231
        }
232
233
        if (count($timesArr) > 0) {
234
            $cacheRefreshTime = min($timesArr);
235
        } else {
236
            $cacheRefreshTime = 0;
237
        }
238
239
        return $cacheRefreshTime;
240
    }
241
242
    /**
243
     * build siteCache file
244
     * @param DocumentParser $modx
245
     * @return boolean success
0 ignored issues
show
Documentation introduced by
Should the return type not be null|boolean?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
246
     */
247
    public function buildCache($modx)
248
    {
249
        $content = "<?php\n";
250
251
        // SETTINGS & DOCUMENT LISTINGS CACHE
252
253
        // get settings
254
        $rs = $modx->db->select('*', '[+prefix+]system_settings');
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $rs. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
255
        $config = array();
256
        $content .= '$c=&$this->config;';
257
        while (list($key, $value) = $modx->db->getRow($rs, 'num')) {
258
            $content .= '$c[\'' . $key . '\']="' . $this->escapeDoubleQuotes($value) . '";';
259
            $config[$key] = $value;
260
        }
261
262
        if ($config['enable_filter']) {
263
            $where = "plugincode LIKE '%phx.parser.class.inc.php%OnParseDocument();%' AND disabled != 1";
264
            $count = $modx->db->getRecordCount($modx->db->select('id', '[+prefix+]site_plugins', $where));
265
            if ($count) {
266
                $content .= '$this->config[\'enable_filter\']=\'0\';';
267
            }
268
        }
269
270
        if ($config['aliaslistingfolder'] == 1) {
271
            $f['id'] = 'c.id';
0 ignored issues
show
Coding Style Comprehensibility introduced by
$f was never initialized. Although not strictly required by PHP, it is generally a good practice to add $f = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
Comprehensibility introduced by
Avoid variables with short names like $f. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
272
            $f['alias'] = "IF( c.alias='', c.id, c.alias)";
273
            $f['parent'] = 'c.parent';
274
            $f['isfolder'] = 'c.isfolder';
275
            $f['alias_visible'] = 'c.alias_visible';
276
            $from = array();
277
            $from[] = '[+prefix+]site_content c';
278
            $from[] = 'LEFT JOIN [+prefix+]site_content p ON p.id=c.parent';
279
            $where = 'c.deleted=0 AND (c.isfolder=1 OR p.alias_visible=0)';
280
            $rs = $modx->db->select($f, $from, $where, 'c.parent, c.menuindex');
281
        } else {
282
            $f = "id, IF(alias='', id, alias) AS alias, parent, isfolder, alias_visible";
283
            $rs = $modx->db->select($f, '[+prefix+]site_content', 'deleted=0', 'parent, menuindex');
284
        }
285
286
        $use_alias_path = ($config['friendly_urls'] && $config['use_alias_path']) ? 1 : 0;
287
        $tmpPath = '';
288
        $content .= '$this->aliasListing=array();';
289
        $content .= '$a=&$this->aliasListing;';
290
        $content .= '$d=&$this->documentListing;';
291
        $content .= '$m=&$this->documentMap;';
292
        while ($doc = $modx->db->getRow($rs)) {
293
            $docid = $doc['id'];
294
            if ($use_alias_path) {
295
                $tmpPath = $this->getParents($doc['parent']);
296
                $alias = (strlen($tmpPath) > 0 ? "$tmpPath/" : '') . $doc['alias'];
297
                $key = $alias;
298
            } else {
299
                $key = $doc['alias'];
300
            }
301
302
            $doc['path'] = $tmpPath;
303
            $content .= '$a[' . $docid . ']=array(\'id\'=>' . $docid . ',\'alias\'=>\'' . $doc['alias'] . '\',\'path\'=>\'' . $doc['path'] . '\',\'parent\'=>' . $doc['parent'] . ',\'isfolder\'=>' . $doc['isfolder'] . ',\'alias_visible\'=>' . $doc['alias_visible'] . ');';
304
            $content .= '$d[\'' . $key . '\']=' . $docid . ';';
305
            $content .= '$m[]=array(' . $doc['parent'] . '=>' . $docid . ');';
306
        }
307
308
        // get content types
309
        $rs = $modx->db->select('id, contentType', '[+prefix+]site_content', "contentType!='text/html'");
310
        $content .= '$c=&$this->contentTypes;';
311
        while ($doc = $modx->db->getRow($rs)) {
312
            $content .= '$c[\'' . $doc['id'] . '\']=\'' . $doc['contentType'] . '\';';
313
        }
314
315
        // WRITE Chunks to cache file
316
        $rs = $modx->db->select('*', '[+prefix+]site_htmlsnippets');
317
        $content .= '$c=&$this->chunkCache;';
318
        while ($doc = $modx->db->getRow($rs)) {
319
            if ($modx->config['minifyphp_incache']) {
320
                $doc['snippet'] = $this->php_strip_whitespace($doc['snippet']);
321
            }
322
            $content .= '$c[\'' . $doc['name'] . '\']=\'' . ($doc['disabled'] ? '' : $this->escapeSingleQuotes($doc['snippet'])) . '\';';
323
        }
324
325
        // WRITE snippets to cache file
326
        $f = 'ss.*, sm.properties as sharedproperties';
327
        $from = '[+prefix+]site_snippets ss LEFT JOIN [+prefix+]site_modules sm on sm.guid=ss.moduleguid';
328
        $rs = $modx->db->select($f, $from);
329
        $content .= '$s=&$this->snippetCache;';
330
        while ($row = $modx->db->getRow($rs)) {
331
            $key = $row['name'];
332
            if ($row['disabled']) {
333
                $content .= '$s[\'' . $key . '\']=\'return false;\';';
334
            } else {
335
                $value = trim($row['snippet']);
336
                if ($modx->config['minifyphp_incache']) {
337
                    $value = $this->php_strip_whitespace($value);
338
                }
339
                $content .= '$s[\'' . $key . '\']=\'' . $this->escapeSingleQuotes($value) . '\';';
340
                $properties = $modx->parseProperties($row['properties']);
341
                $sharedproperties = $modx->parseProperties($row['sharedproperties']);
342
                $properties = array_merge($sharedproperties, $properties);
343 View Code Duplication
                if (0 < count($properties)) {
344
                    $content .= '$s[\'' . $key . 'Props\']=\'' . $this->escapeSingleQuotes(json_encode($properties)) . '\';';
345
                }
346
            }
347
        }
348
349
        // WRITE plugins to cache file
350
        $f = 'sp.*, sm.properties as sharedproperties';
351
        $from = array();
352
        $from[] = '[+prefix+]site_plugins sp';
353
        $from[] = 'LEFT JOIN [+prefix+]site_modules sm on sm.guid=sp.moduleguid';
354
        $rs = $modx->db->select($f, $from, 'sp.disabled=0');
355
        $content .= '$p=&$this->pluginCache;';
356
        while ($row = $modx->db->getRow($rs)) {
357
            $key = $row['name'];
358
            $value = trim($row['plugincode']);
359
            if ($modx->config['minifyphp_incache']) {
360
                $value = $this->php_strip_whitespace($value);
361
            }
362
            $content .= '$p[\'' . $key . '\']=\'' . $this->escapeSingleQuotes($value) . '\';';
363
            if ($row['properties'] != '' || $row['sharedproperties'] != '') {
364
                $properties = $modx->parseProperties($row['properties']);
365
                $sharedproperties = $modx->parseProperties($row['sharedproperties']);
366
                $properties = array_merge($sharedproperties, $properties);
367 View Code Duplication
                if (0 < count($properties)) {
368
                    $content .= '$p[\'' . $key . 'Props\']=\'' . $this->escapeSingleQuotes(json_encode($properties)) . '\';';
369
                }
370
            }
371
        }
372
373
        // WRITE system event triggers
374
        $f = 'sysevt.name as evtname, event.pluginid, plugin.name as pname';
375
        $from = array();
376
        $from[] = '[+prefix+]system_eventnames sysevt';
377
        $from[] = 'INNER JOIN [+prefix+]site_plugin_events event ON event.evtid=sysevt.id';
378
        $from[] = 'INNER JOIN [+prefix+]site_plugins plugin ON plugin.id=event.pluginid';
379
        $rs = $modx->db->select($f, $from, 'plugin.disabled=0', 'sysevt.name, event.priority');
380
        $content .= '$e=&$this->pluginEvent;';
381
        $events = array();
382
        while ($row = $modx->db->getRow($rs)) {
383
            $evtname = $row['evtname'];
384
            if (!isset($events[$evtname])) {
385
                $events[$evtname] = array();
386
            }
387
            $events[$evtname][] = $row['pname'];
388
        }
389
        foreach ($events as $evtname => $pluginnames) {
390
            $events[$evtname] = $pluginnames;
391
            $content .= '$e[\'' . $evtname . '\']=array(\'' . implode('\',\'',
392
                    $this->escapeSingleQuotes($pluginnames)) . '\');';
393
        }
394
395
        $content .= "\n";
396
397
        // close and write the file
398
        $filename = $this->cachePath . 'siteCache.idx.php';
399
400
        // invoke OnBeforeCacheUpdate event
401
        if ($modx) {
402
            $modx->invokeEvent('OnBeforeCacheUpdate');
403
        }
404
405
        if (@file_put_contents($filename, $content) === false) {
406
            exit("Cannot write main MODX cache file! Make sure the assets/cache directory is writable!");
0 ignored issues
show
Coding Style Compatibility introduced by
The method buildCache() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
407
        }
408
409
        if (!is_file($this->cachePath . '/.htaccess')) {
410
            file_put_contents($this->cachePath . '/.htaccess', "order deny,allow\ndeny from all\n");
411
        }
412
413
        // invoke OnCacheUpdate event
414
        if ($modx) {
415
            $modx->invokeEvent('OnCacheUpdate');
416
        }
417
418
        return true;
419
    }
420
421
    /**
422
     * @param string $source
423
     * @return string
424
     *
425
     * @see http://php.net/manual/en/tokenizer.examples.php
426
     */
427
    public function php_strip_whitespace($source)
0 ignored issues
show
Coding Style introduced by
This method is not in camel caps format.

This check looks for method names that are not written in camelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. Thus the name database connection seeker becomes databaseConnectionSeeker.

Loading history...
428
    {
429
430
        $source = trim($source);
431
        if (substr($source, 0, 5) !== '<?php') {
432
            $source = '<?php ' . $source;
433
        }
434
435
        $tokens = token_get_all($source);
436
        $_ = '';
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $_. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
437
        $prev_token = 0;
438
        $chars = explode(' ', '( ) ; , = { } ? :');
439
        foreach ($tokens as $i => $token) {
440
            if (is_string($token)) {
441
                if (in_array($token, array('=', ':'))) {
442
                    $_ = trim($_);
443
                } elseif (in_array($token, array('(', '{')) && in_array($prev_token, array(T_IF, T_ELSE, T_ELSEIF))) {
444
                    $_ = trim($_);
445
                }
446
                $_ .= $token;
447
                if ($prev_token == T_END_HEREDOC) {
448
                    $_ .= "\n";
449
                }
450
                continue;
451
            }
452
453
            list($type, $text) = $token;
454
455
            switch ($type) {
456
                case T_COMMENT    :
0 ignored issues
show
Coding Style introduced by
There must be no space before the colon in a CASE statement

As per the PSR-2 coding standard, there must not be a space in front of the colon in case statements.

switch ($selector) {
    case "A": //right
        doSomething();
        break;
    case "B" : //wrong
        doSomethingElse();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
457
                case T_DOC_COMMENT:
458
                    break;
459
                case T_WHITESPACE :
0 ignored issues
show
Coding Style introduced by
There must be no space before the colon in a CASE statement

As per the PSR-2 coding standard, there must not be a space in front of the colon in case statements.

switch ($selector) {
    case "A": //right
        doSomething();
        break;
    case "B" : //wrong
        doSomethingElse();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
460
                    if ($prev_token != T_END_HEREDOC) {
461
                        $_ = trim($_);
462
                    }
463
                    $lastChar = substr($_, -1);
464
                    if (!in_array($lastChar, $chars)) {// ,320,327,288,284,289
0 ignored issues
show
Unused Code Comprehensibility introduced by
91% 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...
465
                        if (!in_array($prev_token,
466
                            array(T_FOREACH, T_WHILE, T_FOR, T_BOOLEAN_AND, T_BOOLEAN_OR, T_DOUBLE_ARROW))) {
467
                            $_ .= ' ';
468
                        }
469
                    }
470
                    break;
471
                case T_IS_EQUAL :
0 ignored issues
show
Coding Style introduced by
There must be no space before the colon in a CASE statement

As per the PSR-2 coding standard, there must not be a space in front of the colon in case statements.

switch ($selector) {
    case "A": //right
        doSomething();
        break;
    case "B" : //wrong
        doSomethingElse();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
472
                case T_IS_IDENTICAL :
0 ignored issues
show
Coding Style introduced by
There must be no space before the colon in a CASE statement

As per the PSR-2 coding standard, there must not be a space in front of the colon in case statements.

switch ($selector) {
    case "A": //right
        doSomething();
        break;
    case "B" : //wrong
        doSomethingElse();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
473
                case T_IS_NOT_EQUAL :
0 ignored issues
show
Coding Style introduced by
There must be no space before the colon in a CASE statement

As per the PSR-2 coding standard, there must not be a space in front of the colon in case statements.

switch ($selector) {
    case "A": //right
        doSomething();
        break;
    case "B" : //wrong
        doSomethingElse();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
474
                case T_DOUBLE_ARROW :
0 ignored issues
show
Coding Style introduced by
There must be no space before the colon in a CASE statement

As per the PSR-2 coding standard, there must not be a space in front of the colon in case statements.

switch ($selector) {
    case "A": //right
        doSomething();
        break;
    case "B" : //wrong
        doSomethingElse();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
475
                case T_BOOLEAN_AND :
0 ignored issues
show
Coding Style introduced by
There must be no space before the colon in a CASE statement

As per the PSR-2 coding standard, there must not be a space in front of the colon in case statements.

switch ($selector) {
    case "A": //right
        doSomething();
        break;
    case "B" : //wrong
        doSomethingElse();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
476
                case T_BOOLEAN_OR :
0 ignored issues
show
Coding Style introduced by
There must be no space before the colon in a CASE statement

As per the PSR-2 coding standard, there must not be a space in front of the colon in case statements.

switch ($selector) {
    case "A": //right
        doSomething();
        break;
    case "B" : //wrong
        doSomethingElse();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
477
                case T_START_HEREDOC :
0 ignored issues
show
Coding Style introduced by
There must be no space before the colon in a CASE statement

As per the PSR-2 coding standard, there must not be a space in front of the colon in case statements.

switch ($selector) {
    case "A": //right
        doSomething();
        break;
    case "B" : //wrong
        doSomethingElse();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
478
                    if ($prev_token != T_START_HEREDOC) {
479
                        $_ = trim($_);
480
                    }
481
                    $prev_token = $type;
482
                    $_ .= $text;
483
                    break;
484
                default:
485
                    $prev_token = $type;
486
                    $_ .= $text;
487
            }
488
        }
489
        $source = preg_replace(array('@^<\?php@i', '|\s+|', '|<!--|', '|-->|', '|-->\s+<!--|'),
490
            array('', ' ', "\n" . '<!--', '-->' . "\n", '-->' . "\n" . '<!--'), $_);
491
        $source = trim($source);
492
493
        return $source;
494
    }
495
}
496