Passed
Push — dev5 ( da16e0...6692a0 )
by Ron
08:20
created

backupRestore::handle()   A

Complexity

Conditions 5
Paths 5

Size

Total Lines 38
Code Lines 26

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 30

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 5
eloc 26
nc 5
nop 0
dl 0
loc 38
ccs 0
cts 27
cp 0
crap 30
rs 9.1928
c 1
b 0
f 0
1
<?php
2
3
namespace App\Console\Commands;
4
5
use Zip;
6
use Illuminate\Support\Arr;
7
use Illuminate\Console\Command;
8
use Illuminate\Support\Facades\Storage;
9
use Illuminate\Support\Facades\File;
10
use Symfony\Component\Process\Process;
11
use Symfony\Component\Process\Exception\ProcessFailedException;
12
13
use Illuminate\Support\Facades\DB;
14
15
class backupRestore extends Command
16
{
17
    /**
18
     * The name and signature of the console command.
19
     *
20
     * @var string
21
     */
22
    protected $signature = 'tb-backup:restore {filename} {--confirmed}';
23
24
    /**
25
     * The console command description.
26
     *
27
     * @var string
28
     */
29
    protected $description = 'Restore application from a previous backup';
30
    protected $archive, $bar, $baseName;
31
32
    /**
33
     * Create a new command instance.
34
     *
35
     * @return void
36
     */
37 2
    public function __construct()
38
    {
39 2
        parent::__construct();
40 2
    }
41
42
    /**
43
     * Execute the console command.
44
     *
45
     * @return mixed
46
     */
47
    public function handle()
48
    {
49
        if(!Storage::disk('backup')->exists(
50
        /** @scrutinizer ignore-type */
51
        $this->argument('filename')))
52
        {
53
            $this->error('The backup filename you entered does not exist.');
54
            $this->error('Exiting                                        ');
55
            return 1;
56
        }
57
58
        if(!$this->option('confirmed'))
59
        {
60
            $this->question('____________________________________________________________');
61
            $this->question('|                  IMPORTANT NOTE:                         |');
62
            $this->question('|   ALL DATA WILL BE ERASED AND REPLACED WITH THE BACKUP   |');
63
            $this->question('|__________________________________________________________|');
64
        }
65
66
        if($this->option('confirmed') || $this->confirm('Are You Sure?'))
67
        {
68
            $this->line('Restoring Backup.  Please Wait');
69
            $this->line('This could take some time');
70
            $this->bar = $this->output->createProgressBar(10);
71
            $this->call('down');
72
            $this->prepareBackup();
73
            $this->checkVersion();
74
            $this->replaceFiles();
75
            $this->wipeDatabase();
76
            $this->loadDatabase();
77
            $this->cleanup();
78
            $this->bar->finish();
79
            $this->line('');
80
            $this->call('up');
81
            $this->line('Restore Completed');
82
        }
83
84
        return 1;
85
    }
86
87
    //  Open the zip and prepare it for restore
88
    protected function prepareBackup()
89
    {
90
        $this->bar->advance();
91
        $fileParts = pathinfo(
92
        /** @scrutinizer ignore-type */
93
        $this->argument('filename'));
94
        $this->baseName = $fileParts['filename'];
95
        $this->archive = Zip::open(config('filesystems.disks.backup.root').DIRECTORY_SEPARATOR.
96
        /** @scrutinizer ignore-type */
97
        $this->argument('filename'));
98
        // if (!$this->archive->has('version.txt')) {
99
        //     $this->error('THIS IS NOT A VALID TECH BENCH BACKUP');
100
        //     $this->error('Exiting');
101
        //     return 1;
102
        // }
103
104
        $this->archive->extract(config('filesystems.disks.backup.root').DIRECTORY_SEPARATOR.$this->baseName);
105
        $this->bar->advance();
106
    }
107
108
    protected function cleanup()
109
    {
110
        Storage::disk('backup')->deleteDirectory($this->baseName);
111
    }
112
113
    //  Check to verify that the version matches
114
    protected function checkVersion()
115
    {
116
        $backupVer = Storage::disk('backup')->get($this->baseName.DIRECTORY_SEPARATOR.'version.txt');
117
        $appVer = new \PragmaRX\Version\Package\Version();
118
        $this->bar->advance();
119
120
        if($backupVer !== $appVer->version_only())
121
        {
122
            $this->error('Unable to Restore, you are running '.$appVer->version());
123
            $this->error('This backup is for version '.$backupVer);
124
            $this->error('Please load the proper version before loading this backup');
125
126
            $this->cleanup();
127
            return 1;
128
        }
129
    }
130
131
    protected function clearAllFiles($disk)
132
    {
133
        $files = Storage::disk($disk)->files();
134
        foreach($files as $file)
135
        {
136
            if($file != '.gitignore')
137
            {
138
                Storage::disk($disk)->delete($file);
139
            }
140
        }
141
        $folders = Storage::disk($disk)->directories();
142
        foreach($folders as $folder)
143
        {
144
            Storage::disk($disk)->deleteDirectory($folder);
145
        }
146
    }
147
148
    protected function copyAllFiles($backupFolder, $disk)
149
    {
150
        $files = Storage::disk('backup')->allFiles($this->baseName.DIRECTORY_SEPARATOR.$backupFolder);
151
152
        foreach($files as $file)
153
        {
154
            $newFile = str_replace($this->baseName.'/'.$backupFolder.'/', '', $file);
155
            Storage::disk($disk)->put($newFile, Storage::disk('backup')->get($file));
156
        }
157
    }
158
159
    //  Replace the system files
160
    protected function replaceFiles()
161
    {
162
        $this->bar->advance();
163
        //  Start with the .env file
164
        $env = Storage::disk('backup')->get($this->baseName.DIRECTORY_SEPARATOR.'.env');
165
        File::put(base_path().DIRECTORY_SEPARATOR.'.env', $env);
166
        $this->bar->advance();
167
        //  Replace the log files
168
        $this->clearAllFiles('logs');
169
        $this->copyAllFiles('logs', 'logs');
170
        $this->bar->advance();
171
        //  Replace the public files
172
        $this->clearAllFiles('public');
173
        $this->copyAllFiles('public', 'public');
174
        $this->bar->advance();
175
        //  Replace all upladed files
176
        $this->clearAllFiles('local');
177
        $this->copyAllFiles('files', 'local');
178
        $this->bar->advance();
179
    }
180
181
    //  Clear out current database
182
    protected function wipeDatabase()
183
    {
184
        DB::connection(DB::getDefaultConnection())
185
            ->getSchemaBuilder()
186
            ->dropAllTables();
187
        DB::reconnect();
188
        $this->bar->advance();
189
    }
190
191
    //  Load the backed up database
192
    protected function loadDatabase()
193
    {
194
        $dbContents = Storage::disk('backup')->get($this->baseName.DIRECTORY_SEPARATOR.'database.sql');
195
        DB::unprepared($dbContents);
196
        $this->bar->advance();
197
    }
198
}
199