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 ( cf9260...b52382 )
by
unknown
03:19
created

AbstractPosition   F

Complexity

Total Complexity 60

Size/Duplication

Total Lines 422
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 193
dl 0
loc 422
rs 3.6
c 0
b 0
f 0
wmc 60

8 Methods

Rating   Name   Duplication   Size   Complexity  
C publishFile() 0 86 13
B loadUrl() 0 29 9
A getUrl() 0 18 2
B loadCollections() 0 18 7
A getVersion() 0 12 2
D bundleFile() 0 98 16
A __get() 0 3 2
B getFilePath() 0 45 9

How to fix   Complexity   

Complex Class

Complex classes like AbstractPosition often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use AbstractPosition, and based on these observations, apply Extract Interface, too.

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\Framework\Http\Presenter\Assets\Positions\Abstracts;
15
16
// ------------------------------------------------------------------------
17
18
use MatthiasMullie\Minify\CSS;
19
use MatthiasMullie\Minify\JS;
20
use O2System\Kernel\Http\Message\Uri;
21
22
/**
23
 * Class AbstractPosition
24
 *
25
 * @package O2System\Framework\Http\Presenter\Assets\Positions\Abstracts
26
 */
27
abstract class AbstractPosition
28
{
29
    /**
30
     * AbstractPosition::__get
31
     *
32
     * @param string $property
33
     *
34
     * @return \O2System\Framework\Http\Presenter\Assets\Collections\Css|\O2System\Framework\Http\Presenter\Assets\Collections\Font|\O2System\Framework\Http\Presenter\Assets\Collections\Javascript|null
0 ignored issues
show
Bug introduced by
The type O2System\Framework\Http\...\Assets\Collections\Css was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
35
     */
36
    public function __get($property)
37
    {
38
        return isset($this->{$property}) ? $this->{$property} : null;
39
    }
40
41
    // ------------------------------------------------------------------------
42
43
    /**
44
     * AbstractPosition::getUrl
45
     *
46
     * @param string $realPath
47
     *
48
     * @return string
49
     */
50
    public function getUrl($realPath)
51
    {
52
        if (strpos($realPath, 'http') !== false) {
53
            return $realPath;
54
        }
55
56
        return (new Uri())
57
            ->withQuery(null)
58
            ->withSegments(
59
                new Uri\Segments(
60
                    str_replace(
61
                        [PATH_PUBLIC, DIRECTORY_SEPARATOR],
62
                        ['', '/'],
63
                        $realPath
64
                    )
65
                )
66
            )
67
            ->__toString();
68
    }
69
70
    // ------------------------------------------------------------------------
71
72
    /**
73
     * AbstractPosition::loadCollections
74
     *
75
     * @param array $collections
76
     */
77
    public function loadCollections(array $collections)
78
    {
79
        foreach ($collections as $subDir => $files) {
80
            if (is_array($files) and count($files)) {
81
82
                // normalize the subDirectory with a trailing separator
83
                $subDir = str_replace(['/', '\\'], DIRECTORY_SEPARATOR, $subDir);
84
                $subDir = rtrim($subDir, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
85
86
                foreach ($files as $file) {
87
                    if (strpos($file, 'http') !== false) {
88
                        $this->loadUrl($file, $subDir);
89
                    } else {
90
                        $this->loadFile($file, $subDir);
91
                    }
92
                }
93
            } elseif (is_string($files)) {
94
                $this->loadFile($files);
95
            }
96
        }
97
    }
98
99
    // ------------------------------------------------------------------------
100
101
    /**
102
     * AbstractPosition::loadUrl
103
     *
104
     * @param string      $url
105
     * @param string|null $subDir
106
     *
107
     * @return bool
108
     */
109
    public function loadUrl($url, $subDir = null)
110
    {
111
        $property = is_null($subDir) ? 'css' : null;
112
113
        if (is_null($property)) {
114
            switch ($subDir) {
115
                default:
116
                case 'css/':
117
                    $property = 'css';
118
                    break;
119
                case 'font/':
120
                case 'fonts/':
121
                    $property = 'font';
122
                    break;
123
                case 'js/':
124
                    $property = 'javascript';
125
                    break;
126
            }
127
        }
128
129
        if (property_exists($this, $property)) {
130
            if ( ! call_user_func_array([$this->{$property}, 'has'], [$url])) {
131
                $this->{$property}->append($url);
132
133
                return true;
134
            }
135
        }
136
137
        return false;
138
    }
139
140
    // ------------------------------------------------------------------------
141
142
    /**
143
     * AbstractPosition::loadFile
144
     *
145
     * @param string      $filename
146
     * @param string|null $subDir
147
     *
148
     * @return void
149
     */
150
    abstract public function loadFile($filename, $subDir = null);
151
152
    // ------------------------------------------------------------------------
153
154
    /**
155
     * AbstractPosition::publishFile
156
     *
157
     * @param $filePath
158
     *
159
     * @return array
160
     */
161
    protected function publishFile($filePath)
162
    {
163
        $publicFilePath = str_replace(PATH_RESOURCES, PATH_PUBLIC, $filePath);
164
        $publicFileDir = dirname($publicFilePath) . DIRECTORY_SEPARATOR;
165
166
        $extension = pathinfo($filePath, PATHINFO_EXTENSION);
167
168
        $publicMinifyFilePath = str_replace('.' . $extension, '.min.' . $extension, $publicFilePath);
169
170
        $fileContent = file_get_contents($filePath);
171
        $fileVersion = $this->getVersion($fileContent);
172
        
173
        if (is_file($mapFilePath = $publicFilePath . '.map')) {
174
            $mapMetadata = json_decode(file_get_contents($mapFilePath), true);
175
            // if the file version is changed delete it first
176
            if ( ! hash_equals($fileVersion, $mapMetadata[ 'version' ])) {
177
                unlink($publicFilePath);
178
                unlink($publicMinifyFilePath);
179
                unlink($mapFilePath);
180
            }
181
        }
182
183
        if ( ! is_file($mapFilePath)) {
184
            if ( ! empty($fileContent)) {
185
                $mapMetadata = [
186
                    'version'        => $fileVersion,
187
                    'sources'        => [
188
                        $filePath,
189
                    ],
190
                    'names'          => [],
191
                    'mappings'       => [],
192
                    'file'           => pathinfo($publicMinifyFilePath, PATHINFO_BASENAME),
193
                    'sourcesContent' => [
194
                        $fileContent,
195
                    ],
196
                    'sourceRoot'     => '',
197
                ];
198
                
199
                if ( ! is_dir($publicFileDir)) {
200
                    @mkdir($publicFileDir, 0777, true);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for mkdir(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unhandled  annotation

200
                    /** @scrutinizer ignore-unhandled */ @mkdir($publicFileDir, 0777, true);

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
201
                }
202
203
                if (is_writable($publicFileDir)) {
204
                    if ($fileStream = @fopen($publicFilePath, 'ab')) {
205
                        flock($fileStream, LOCK_EX);
206
                        fwrite($fileStream, $fileContent);
207
                        flock($fileStream, LOCK_UN);
208
                        fclose($fileStream);
209
210
                        // File Map
211
                        if ($fileStream = @fopen($mapFilePath, 'ab')) {
212
                            flock($fileStream, LOCK_EX);
213
214
                            fwrite($fileStream, json_encode($mapMetadata));
215
216
                            flock($fileStream, LOCK_UN);
217
                            fclose($fileStream);
218
                        }
219
220
                        switch ($extension) {
221
                            case 'min.css':
222
                            case 'css':
223
                                $minifyStyleHandler = new CSS($publicFilePath);
224
                                $minifyStyleHandler->minify($publicMinifyFilePath);
225
                                break;
226
227
                            case 'min.js':
228
                            case 'js':
229
                                $minifyJavascriptHandler = new JS($publicFilePath);
230
                                $minifyJavascriptHandler->minify($publicMinifyFilePath);
231
                                break;
232
                        }
233
234
                    }
235
                }
236
            }
237
        }
238
239
        return [
240
            'filePath' => $publicFilePath,
241
            'url'      => $this->getUrl($publicFilePath),
242
            'minify'   => [
243
                'filePath' => $publicMinifyFilePath,
244
                'url'      => $this->getUrl($publicMinifyFilePath),
245
            ],
246
            'version'  => $fileVersion,
247
        ];
248
    }
249
250
    // ------------------------------------------------------------------------
251
252
    /**
253
     * AbstractPosition::bundleFile
254
     *
255
     * @param string $filename
256
     * @param array  $sources
257
     *
258
     * @return array
259
     */
260
    protected function bundleFile($filename, array $sources)
261
    {
262
        $sourcesContent = [];
263
        foreach ($sources as $key => $source) {
264
            $content = file_get_contents($source);
265
266
            if ( ! empty($content)) {
267
                $sourcesContent[] = $content;
268
            } else {
269
                unset($sources[ $key ]);
270
            }
271
        }
272
273
        $fileContent = implode(PHP_EOL, $sourcesContent);
274
        $fileVersion = $this->getVersion($fileContent);
275
276
        $publicFilePath = PATH_PUBLIC . $filename;
277
        $filename = pathinfo($publicFilePath, PATHINFO_BASENAME);
278
279
        $publicFileDir = dirname($publicFilePath) . DIRECTORY_SEPARATOR . 'bundled' . DIRECTORY_SEPARATOR;
280
        $publicFilePath = $publicFileDir . $filename;
281
282
        $extension = pathinfo($publicFilePath, PATHINFO_EXTENSION);
283
284
        $publicMinifyFilePath = str_replace('.' . $extension, '.min.' . $extension, $publicFilePath);
285
286
        if ( ! empty($sourcesContent)) {
287
            if (is_file($mapFilePath = $publicFilePath . '.map')) {
288
                $mapMetadata = json_decode(file_get_contents($mapFilePath), true);
289
                // if the file version is changed delete it first
290
                if ( ! hash_equals($fileVersion, $mapMetadata[ 'version' ])) {
291
                    unlink($publicFilePath);
292
                    unlink($publicMinifyFilePath);
293
                    unlink($mapFilePath);
294
                }
295
            }
296
297
            if ( ! is_file($mapFilePath)) {
298
                if ( ! empty($fileContent)) {
299
                    $mapMetadata = [
300
                        'version'        => $fileVersion,
301
                        'sources'        => $sources,
302
                        'names'          => [],
303
                        'mappings'       => [],
304
                        'file'           => pathinfo($publicMinifyFilePath, PATHINFO_BASENAME),
305
                        'sourcesContent' => $sourcesContent,
306
                        'sourceRoot'     => '',
307
                    ];
308
309
                    if ( ! is_writable($publicFileDir)) {
310
                        @mkdir($publicFileDir, 0777, true);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for mkdir(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unhandled  annotation

310
                        /** @scrutinizer ignore-unhandled */ @mkdir($publicFileDir, 0777, true);

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
311
                    }
312
313
                    if (is_writable($publicFileDir)) {
314
                        if ($fileStream = @fopen($publicFilePath, 'ab')) {
315
                            flock($fileStream, LOCK_EX);
316
                            fwrite($fileStream, $fileContent);
317
                            flock($fileStream, LOCK_UN);
318
                            fclose($fileStream);
319
320
                            // File Map
321
                            if ($fileStream = @fopen($mapFilePath, 'ab')) {
322
                                flock($fileStream, LOCK_EX);
323
324
                                fwrite($fileStream, json_encode($mapMetadata));
325
326
                                flock($fileStream, LOCK_UN);
327
                                fclose($fileStream);
328
                            }
329
330
                            switch ($extension) {
331
                                case 'min.css':
332
                                case 'css':
333
                                    $minifyStyleHandler = new CSS($publicFilePath);
334
                                    $minifyStyleHandler->minify($publicMinifyFilePath);
335
                                    break;
336
337
                                case 'min.js':
338
                                case 'js':
339
                                    $minifyJavascriptHandler = new JS($publicFilePath);
340
                                    $minifyJavascriptHandler->minify($publicMinifyFilePath);
341
                                    break;
342
                            }
343
344
                        }
345
                    }
346
                }
347
            }
348
        }
349
350
        return [
351
            'filePath' => $publicFilePath,
352
            'url'      => $this->getUrl($publicFilePath),
353
            'minify'   => [
354
                'filePath' => $publicMinifyFilePath,
355
                'url'      => $this->getUrl($publicMinifyFilePath),
356
            ],
357
            'version'  => $fileVersion,
358
        ];
359
    }
360
361
    // ------------------------------------------------------------------------
362
363
    /**
364
     * AbstractPosition::getFilePath
365
     *
366
     * @param string      $filename
367
     * @param string|null $subDir
368
     *
369
     * @return string
370
     */
371
    protected function getFilePath($filename, $subDir = null)
372
    {
373
        $directories = presenter()->assets->getFilePaths();
374
        
375
        foreach ($directories as $directory) {
376
377
            /**
378
             * Try with sub directory
379
             * find from public directory first then resource directory
380
             */
381
            if (isset($subDir)) {
382
                $subDir = str_replace(['\\', '/'], DIRECTORY_SEPARATOR, $subDir);
383
384
                if (is_file($filePath = str_replace(PATH_RESOURCES, PATH_PUBLIC,
385
                        $directory) . $subDir . $filename)) {
386
                    return $filePath;
387
                    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...
388
                } elseif (is_file($filePath = str_replace(PATH_RESOURCES, PATH_PUBLIC . 'assets' . DIRECTORY_SEPARATOR,
389
                        $directory) . $subDir . $filename)) {
390
                    return $filePath;
391
                    break;
392
                } elseif (is_file($filePath = $directory . $subDir . $filename)) {
393
                    return $filePath;
394
                    break;
395
                }
396
            }
397
398
            /**
399
             * Try without sub directory
400
             * find from public directory first then resource directory
401
             */
402
            if (is_file($filePath = str_replace(PATH_RESOURCES, PATH_PUBLIC, $directory) . $filename)) {
403
                return $filePath;
404
                break;
405
            } elseif (is_file($filePath = str_replace(PATH_RESOURCES, PATH_PUBLIC . 'assets' . DIRECTORY_SEPARATOR,
406
                    $directory) . $filename)) {
407
                return $filePath;
408
                break;
409
            } elseif (is_file($filePath = $directory . $filename)) {
410
                return $filePath;
411
                break;
412
            }
413
        }
414
415
        return false;
0 ignored issues
show
Bug Best Practice introduced by
The expression return false returns the type false which is incompatible with the documented return type string.
Loading history...
416
    }
417
418
    // ------------------------------------------------------------------------
419
420
    /**
421
     * AbstractPosition::getVersion
422
     *
423
     * @param string $code
424
     *
425
     * @return string
426
     */
427
    public function getVersion($codeSerialize)
428
    {
429
        $codeMd5 = md5($codeSerialize);
430
431
        $strSplit = str_split($codeMd5, 4);
432
        foreach ($strSplit as $strPart) {
433
            $strInt[] = str_pad(hexdec($strPart), 5, '0', STR_PAD_LEFT);
434
        }
435
436
        $codeVersion = round(implode('', $strInt), 10);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $strInt seems to be defined by a foreach iteration on line 432. Are you sure the iterator is never empty, otherwise this variable is not defined?
Loading history...
Bug introduced by
implode('', $strInt) of type string is incompatible with the type double expected by parameter $val of round(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

436
        $codeVersion = round(/** @scrutinizer ignore-type */ implode('', $strInt), 10);
Loading history...
437
438
        return substr_replace($codeVersion, '.', 3, strlen($codeVersion) - 5);
439
    }
440
441
    // ------------------------------------------------------------------------
442
443
    /**
444
     * AbstractPosition::__toString
445
     *
446
     * @return string
447
     */
448
    abstract public function __toString();
449
}