Passed
Push — master ( 284e72...816a06 )
by Iman
04:12
created

CrudboosterInstallationCommand   A

Complexity

Total Complexity 23

Size/Duplication

Total Lines 184
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
dl 0
loc 184
rs 10
c 0
b 0
f 0
wmc 23

8 Methods

Rating   Name   Duplication   Size   Complexity  
A findComposer() 0 7 2
B handle() 0 35 3
A symlinkForUpload() 0 15 3
A symlinkForAsset() 0 19 3
B rrmdir() 0 19 5
B installCrudbooster() 0 26 3
A removeDefaultMigrations() 0 5 1
A createVendorAtPublic() 0 11 3
1
<?php namespace crocodicstudio\crudbooster\commands;
2
3
use App;
4
use Cache;
5
use DB;
6
use Illuminate\Console\Command;
7
use Request;
8
use Symfony\Component\Process\Process;
9
10
class CrudboosterInstallationCommand extends Command
11
{
12
    /**
13
     * The console command name.
14
     *
15
     * @var string
16
     */
17
    protected $name = 'crudbooster:install';
18
19
    /**
20
     * The console command description.
21
     *
22
     * @var string
23
     */
24
    protected $description = 'CRUDBooster Installation Command';
25
26
    /**
27
     * Execute the console command.
28
     *
29
     * @return mixed
30
     */
31
    public function handle()
32
    {
33
        $printer = new ConsolePrinter($this);
34
35
        $printer->printHeader();
36
37
        if (! ((new RequirementChecker($this))->check())) {
38
            $this->info('Sorry unfortunately your system is not meet with our requirements !');
39
            $printer->printFooter(false);
40
            $this->info('--');
41
42
            return;
43
        }
44
45
        $this->info('Installing: ');
46
        /* Removing the default user and password reset, it makes you ambigous when using CRUDBooster */
47
        $this->removeDefaultMigrations();
48
49
        //Create vendor folder at public
50
        $this->createVendorAtPublic();
51
52
        //Create symlink for uploads path
53
        $this->symlinkForUpload();
54
55
        //Crate symlink for assets
56
        $this->symlinkForAsset();
57
58
        if ($this->confirm('Do you have setting the database configuration at .env ?')) {
59
            $this->installCrudbooster();
60
        } else {
61
            $this->info('Setup Aborted !');
62
            $this->info('Please setting the database configuration for first !');
63
        }
64
65
        $printer->printFooter();
66
    }
67
68
    private function removeDefaultMigrations()
69
    {
70
        $this->info('I remove some default migration files from laravel...');
71
        @unlink(base_path('database/migrations/2014_10_12_000000_create_users_table.php'));
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for unlink(). 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

71
        /** @scrutinizer ignore-unhandled */ @unlink(base_path('database/migrations/2014_10_12_000000_create_users_table.php'));

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...
72
        @unlink(base_path('database/migrations/2014_10_12_100000_create_password_resets_table.php'));
73
    }
74
75
    private function createVendorAtPublic()
76
    {
77
        $this->info('Checking public/vendor directory...');
78
        if (! file_exists(public_path('vendor'))) {
79
            mkdir(public_path('vendor'), 0777);
80
        }
81
82
        if (! is_writable(public_path('vendor'))) {
83
            $this->info('Setup aborted !');
84
            $this->info('Please set public/vendor directory to writable 0777');
85
            exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
86
        }
87
    }
88
89
    private function symlinkForUpload()
90
    {
91
        $this->info('Checking public/uploads symlink...');
92
        if (! file_exists(public_path('uploads'))) {
93
            $this->info('Creating public/uploads symlink...');
94
            app('files')->link(storage_path('app'), public_path('uploads'));
95
96
            return;
97
        }
98
        $uploadPath = public_path('uploads');
99
        $this->info('Upload Path: '.$uploadPath);
100
        if (realpath($uploadPath) == $uploadPath) {
101
            $this->info('Remove the existing uploads dir, and create a symlink for it...');
102
            $this->rrmdir(public_path('uploads'));
103
            app('files')->link(storage_path('app'), public_path('uploads'));
104
        }
105
    }
106
107
    private function rrmdir($dir)
108
    {
109
        if (! is_dir($dir)) {
110
            return;
111
        }
112
        foreach (scandir($dir) as $object) {
113
            if (in_array($object, ['.', '..'])) {
114
                continue;
115
            }
116
117
            $objPath = $dir."/".$object;
118
119
            if (is_dir($objPath)) {
120
                $this->rrmdir($objPath);
121
            } else {
122
                unlink($objPath);
123
            }
124
        }
125
        rmdir($dir);
126
    }
127
128
    private function symlinkForAsset()
129
    {
130
        $this->info('Checking public/vendor/crudbooster symlink...');
131
132
        $vendorPath = public_path('vendor'.DIRECTORY_SEPARATOR.'crudbooster');
133
134
        if (! file_exists($vendorPath)) {
135
            $this->info('Creating public/vendor/crudbooster symlink...');
136
            app('files')->link(__DIR__.'/../assets', public_path('vendor/crudbooster'));
137
138
            return;
139
        }
140
141
        $this->info('Vendor Path: '.$vendorPath);
142
143
        if (realpath($vendorPath) == $vendorPath) {
144
            $this->info('Removing public/vendor/crudbooster dir, instead of creating a symlink...');
145
            $this->rrmdir($vendorPath);
146
            app('files')->link(__DIR__.'/../assets', $vendorPath);
147
        }
148
    }
149
150
    private function installCrudbooster()
151
    {
152
        $this->info('Publishing CRUDBooster needs file...');
153
        $this->callSilent('vendor:publish', ['--provider' => 'crocodicstudio\\crudbooster\\CRUDBoosterServiceProvider', '--force' => true]);
154
        $this->callSilent('vendor:publish', ['--tag' => 'cb_migration', '--force' => true]);
155
        $this->callSilent('vendor:publish', ['--tag' => 'cb_lfm', '--force' => true]);
156
        $this->callSilent('vendor:publish', ['--tag' => 'cb_localization', '--force' => true]);
157
158
        $this->info('Dumping the autoloaded files and reloading all new files...');
159
        $composer = $this->findComposer();
160
        $process = new Process($composer.' dumpautoload');
161
        $process->setWorkingDirectory(base_path())->run();
162
163
        $this->info('Migrating database...');
164
        $this->call('migrate', ['--path' => '\database\migrations\crudbooster']);
165
166
        if (! class_exists('CBSeeder')) {
167
            require_once __DIR__.'/../database/seeds/CBSeeder.php';
168
        }
169
        $this->callSilent('db:seed', ['--class' => 'CBSeeder']);
170
        $this->call('config:clear');
171
        if (app()->version() < 5.6) {
0 ignored issues
show
introduced by
The method version() does not exist on Illuminate\Container\Container. Are you sure you never get this type here, but always one of the subclasses? ( Ignorable by Annotation )

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

171
        if (app()->/** @scrutinizer ignore-call */ version() < 5.6) {
Loading history...
172
            $this->call('optimize');
173
        }
174
175
        $this->info('Installing CRUDBooster Is Completed ! Thank You :)');
176
    }
177
178
    /*
179
    * http://stackoverflow.com/questions/3338123/how-do-i-recursively-delete-a-directory-and-its-entire-contents-files-sub-dir
180
    */
181
182
    /**
183
     * Get the composer command for the environment.
184
     *
185
     * @return string
186
     */
187
    protected function findComposer()
188
    {
189
        if (file_exists(getcwd().'/composer.phar')) {
190
            return '"'.PHP_BINARY.'" '.getcwd().'/composer.phar';
191
        }
192
193
        return 'composer';
194
    }
195
}
196