Scrutinizer GitHub App not installed

We could not synchronize checks via GitHub's checks API since Scrutinizer's GitHub App is not installed for this repository.

Install GitHub App

Passed
Push — match-route-file-end ( 6141ed...e46dff )
by Pedro
14:37 queued 03:08
created

AddCustomRouteContent::handle()   B

Complexity

Conditions 6
Paths 12

Size

Total Lines 49
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
eloc 24
nc 12
nop 0
dl 0
loc 49
rs 8.9137
c 0
b 0
f 0
1
<?php
2
3
namespace Backpack\CRUD\app\Console\Commands;
4
5
use Illuminate\Console\Command;
6
7
class AddCustomRouteContent extends Command
8
{
9
    use \Backpack\CRUD\app\Console\Commands\Traits\PrettyCommandOutput;
0 ignored issues
show
introduced by
The trait Backpack\CRUD\app\Consol...its\PrettyCommandOutput requires some properties which are not provided by Backpack\CRUD\app\Consol...s\AddCustomRouteContent: $progressBar, $statusColor, $status
Loading history...
10
11
    /**
12
     * The name and signature of the console command.
13
     *
14
     * @var string
15
     */
16
    protected $signature = 'backpack:add-custom-route
17
                                {code : HTML/PHP code that registers a route. Use either single quotes or double quotes. Never both. }
18
                                {--route-file=routes/backpack/custom.php : The file where the code should be added relative to the root of the project. }';
19
20
    /**
21
     * The console command description.
22
     *
23
     * @var string
24
     */
25
    protected $description = 'Add HTML/PHP code to the routes/backpack/custom.php file';
26
27
28
    /**
29
     * Create a new command instance.
30
     *
31
     * @return void
32
     */
33
    public function __construct()
34
    {
35
        parent::__construct();
36
    }
37
38
    /**
39
     * Execute the console command.
40
     *
41
     * @return mixed
42
     */
43
    public function handle()
44
    {
45
        $routeFilePath = base_path($this->option('route-file'));
46
        // check if the file exists
47
        if (!file_exists($routeFilePath)) {
48
            $this->line("The route file  <fg=blue>$routeFilePath</> does not exist.");
49
            $createRouteFile = $this->confirm('Should we create the file in  <fg=blue>'.  $routeFilePath . '</> ?', 'yes');
0 ignored issues
show
Bug introduced by
'yes' of type string is incompatible with the type boolean expected by parameter $default of Illuminate\Console\Command::confirm(). ( Ignorable by Annotation )

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

49
            $createRouteFile = $this->confirm('Should we create the file in  <fg=blue>'.  $routeFilePath . '</> ?', /** @scrutinizer ignore-type */ 'yes');
Loading history...
50
            if($createRouteFile) {
51
                $this->call('vendor:publish', ['--provider' => \Backpack\CRUD\BackpackServiceProvider::class, '--tag' => 'custom_routes']);
52
            }else{
53
                $this->error('The route file does not exist. Please create it first.');
54
            }
55
56
        }
57
58
        $code = $this->argument('code');
59
60
        $this->progressBlock("Adding route to <fg=blue>$routeFilePath</>");
61
62
        $originalContent = file($routeFilePath);
63
64
        // clean the content from comments etc
65
        $cleanContent = $this->cleanContentArray($originalContent);
66
67
        // if the content contains code, don't add it again.
68
        if (array_search($code, $cleanContent, true) !== false) {
69
            $this->closeProgressBlock('Already existed', 'yellow');
70
71
            return;
72
        }
73
74
        // get the last element of the array contains '}'
75
        $lastLine = $this->getLastLineNumberThatContains('}', $cleanContent);
76
77
        if($lastLine === false) {
0 ignored issues
show
introduced by
The condition $lastLine === false is always false.
Loading history...
78
            $this->closeProgressBlock('Could not find the last line, file ' . $routeFilePath . ' may be corrupted.', 'red');
79
            return;
80
        }
81
82
        // add the code to the line before the last line
83
        array_splice($originalContent, $lastLine, 0, '    ' . $code.PHP_EOL);
84
85
        // write the new content to the file
86
        if(file_put_contents($routeFilePath, implode('', $originalContent)) === false) {
87
            $this->closeProgressBlock('Failed to add route. Failed writing the modified route file. Maybe check file permissions?', 'red');
88
            return;
89
        }
90
91
        $this->closeProgressBlock('done', 'green');
92
    }
93
94
    private function cleanContentArray(array $content)
95
    {
96
        return array_filter(array_map(function ($line) {
97
            $lineText = trim($line);
98
            if  ($lineText === '' ||
99
                $lineText === '\n' ||
100
                $lineText === '\r' ||
101
                $lineText === '\r\n' ||
102
                $lineText === PHP_EOL ||
103
                str_starts_with($lineText, '<?php') ||
104
                str_starts_with($lineText, '?>') ||
105
                str_starts_with($lineText, '//') ||
106
                str_starts_with($lineText, '/*') ||
107
                str_starts_with($lineText, '*/') ||
108
                str_ends_with($lineText, '*/') ||
109
                str_starts_with($lineText, '*') ||
110
                str_starts_with($lineText, 'use ') ||
111
                str_starts_with($lineText, 'return ') ||
112
                str_starts_with($lineText, 'namespace ')) {
113
                    return null;
114
            }
115
            return $lineText;
116
        }, $content));
117
    }
118
119
    /**
120
     * Parse the given file stream and return the line number where a string is found.
121
     *
122
     * @param  string  $needle  The string that's being searched for.
123
     * @param  array  $haystack  The file where the search is being performed.
124
     * @return bool|int The last line number where the string was found. Or false.
125
     */
126
    private function getLastLineNumberThatContains($needle, $haystack)
127
    {
128
        $matchingLines = array_filter($haystack, function ($k) use ($needle) {
129
            return strpos($k, $needle) !== false;
130
        });
131
132
        if ($matchingLines) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $matchingLines of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
133
            return array_key_last($matchingLines);
0 ignored issues
show
Bug Best Practice introduced by
The expression return array_key_last($matchingLines) also could return the type string which is incompatible with the documented return type boolean|integer.
Loading history...
134
        }
135
136
        return false;
137
    }
138
}
139