CheckViews   A
last analyzed

Complexity

Total Complexity 17

Size/Duplication

Total Lines 90
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 10

Importance

Changes 0
Metric Value
dl 0
loc 90
rs 10
c 0
b 0
f 0
wmc 17
lcom 1
cbo 10

6 Methods

Rating   Name   Duplication   Size   Complexity  
A handle() 0 14 2
A checkForViewMake() 0 18 5
A checkViewParams() 0 17 4
A checkRoutePaths() 0 9 2
A checkPsr4Classes() 0 12 3
A checkBladeFiles() 0 4 1
1
<?php
2
3
namespace Imanghafoori\LaravelMicroscope\Commands;
4
5
use Illuminate\Console\Command;
6
use Illuminate\Support\Facades\View;
7
use Imanghafoori\LaravelMicroscope\Analyzers\ComposerJson;
8
use Imanghafoori\LaravelMicroscope\Analyzers\FunctionCall;
9
use Imanghafoori\LaravelMicroscope\BladeFiles;
10
use Imanghafoori\LaravelMicroscope\Checks\CheckViewFilesExistence;
11
use Imanghafoori\LaravelMicroscope\ErrorReporters\ErrorPrinter;
12
use Imanghafoori\LaravelMicroscope\ErrorTypes\BladeFile;
13
use Imanghafoori\LaravelMicroscope\LaravelPaths\FilePath;
14
use Imanghafoori\LaravelMicroscope\SpyClasses\RoutePaths;
15
16
class CheckViews extends Command
17
{
18
    public static $checkedCallsNum = 0;
19
20
    public static $skippedCallsNum = 0;
21
22
    protected $signature = 'check:views {--d|detailed : Show files being checked}';
23
24
    protected $description = 'Checks the validity of blade files';
25
26
    public function handle(ErrorPrinter $errorPrinter)
27
    {
28
        event('microscope.start.command');
29
        $this->info('Checking views...');
30
        $errorPrinter->printer = $this->output;
31
        $this->checkRoutePaths();
32
        $this->checkPsr4Classes();
33
        $this->checkBladeFiles();
34
35
        $this->getOutput()->writeln(' - '.self::$checkedCallsNum.' view references were checked to exist. ('.self::$skippedCallsNum.' skipped)');
36
        event('microscope.finished.checks', [$this]);
37
38
        return $errorPrinter->hasErrors() ? 1 : 0;
39
    }
40
41
    private function checkForViewMake($absPath, $staticCalls)
42
    {
43
        $tokens = \token_get_all(\file_get_contents($absPath));
44
45
        foreach ($tokens as $i => $token) {
46
            if (FunctionCall::isGlobalCall('view', $tokens, $i)) {
47
                $this->checkViewParams($absPath, $tokens, $i, 0);
48
                continue;
49
            }
50
51
            foreach ($staticCalls as $class => $method) {
52
                if (FunctionCall::isStaticCall($method[0], $tokens, $i, $class)) {
53
                    $this->checkViewParams($absPath, $tokens, $i, $method[1]);
54
                    continue;
55
                }
56
            }
57
        }
58
    }
59
60
    private function checkViewParams($absPath, &$tokens, $i, $index)
61
    {
62
        $params = FunctionCall::readParameters($tokens, $i);
63
64
        $param1 = null;
0 ignored issues
show
Unused Code introduced by
$param1 is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
65
        // it should be a hard-coded string which is not concatinated like this: 'hi'. $there
66
        $paramTokens = $params[$index] ?? ['_', '_', '_'];
67
68
        if (FunctionCall::isSolidString($paramTokens)) {
69
            self::$checkedCallsNum++;
70
            $viewName = \trim($paramTokens[0][1], '\'\"');
71
72
            $viewName && ! View::exists($viewName) && BladeFile::isMissing($absPath, $paramTokens[0][2], $viewName);
73
        } else {
74
            self::$skippedCallsNum++;
75
        }
76
    }
77
78
    private function checkRoutePaths()
79
    {
80
        foreach (RoutePaths::get() as $filePath) {
81
            $this->checkForViewMake($filePath, [
82
                'View' => ['make', 0],
83
                'Route' => ['view', 1],
84
            ]);
85
        }
86
    }
87
88
    private function checkPsr4Classes()
89
    {
90
        $psr4Mapping = ComposerJson::readAutoload();
91
92
        foreach ($psr4Mapping as $_namespace => $dirPath) {
93
            foreach (FilePath::getAllPhpFiles($dirPath) as $filePath) {
94
                $this->checkForViewMake($filePath->getRealPath(), [
95
                    'View' => ['make', 0],
96
                ]);
97
            }
98
        }
99
    }
100
101
    private function checkBladeFiles()
102
    {
103
        BladeFiles::check([CheckViewFilesExistence::class]);
104
    }
105
}
106