Storage::decompressBackupFile()   A
last analyzed

Complexity

Conditions 4
Paths 2

Size

Total Lines 26
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 14
nc 2
nop 2
dl 0
loc 26
rs 9.7998
c 0
b 0
f 0
1
<?php
2
3
namespace EDouna\LaravelDBBackup\Databases;
4
5
use EDouna\LaravelDBBackup\ProcessHandler;
6
use Exception;
7
use Illuminate\Support\Facades\Config;
8
use Illuminate\Support\Facades\File;
9
use Illuminate\Support\Facades\Log;
10
use Symfony\Component\Process\Process;
11
12
class Storage
13
{
14
    protected $storagePath;
15
    protected $backupFilename;
16
17
    /**
18
     * @return void
19
     */
20
    public function sanitizeStoragePath(): void
21
    {
22
        $configStoragePath = Config::get('db-backup.backup_folder');
23
        if (substr($configStoragePath, -1, 1) !== DIRECTORY_SEPARATOR) {
24
            Log::debug('Stored back-up folder is not probably set. Fixing.');
25
            $configStoragePath = $configStoragePath.DIRECTORY_SEPARATOR;
26
        }
27
28
        $this->storagePath = $configStoragePath;
29
    }
30
31
    /**
32
     * @return bool
33
     */
34
    public function initializeStorageFolder(): bool
35
    {
36
        $this->sanitizeStoragePath();
37
        Log::debug(sprintf('Checking if storage path exists at %s', $this->storagePath));
38
        if (false === File::isDirectory($this->storagePath)) {
39
            Log::debug('Storage path does not exist. Attempting to create.');
40
            if (false === File::makeDirectory($this->storagePath)) {
41
                Log::error('Unable to create create storage path.');
42
43
                return false;
44
            }
45
            Log::debug('Storage path successfully created.');
46
        }
47
48
        Log::debug('Finished checking storage path.');
49
50
        return true;
51
    }
52
53
    /**
54
     * @param string $backupFilePath
55
     *
56
     * @return bool
57
     */
58
    public function createArchiveFile(string $backupFilePath): bool
59
    {
60
        Log::debug('Trying to start creating an archive file');
61
        if (false === ProcessHandler::runArray(['gzip', '-9', $backupFilePath])) {
62
            return false;
63
        }
64
65
        Log::debug('Finished creating an archive file.');
66
67
        return true;
68
    }
69
70
    /**
71
     * @param string $databaseIdentifier
72
     * @param string $databaseFileExtension
73
     *
74
     * @return string
75
     */
76
    public function generateBackupFilename(string $databaseIdentifier, string $databaseFileExtension): string
77
    {
78
        return $this->backupFilename = $this->storagePath.$databaseIdentifier.'-'.time().'.'.$databaseFileExtension;
79
    }
80
81
    /**
82
     * @param string   $backupFile
83
     * @param Database $database
84
     *
85
     * @return string|string[]|null
86
     */
87
    public function decompressBackupFile(string $backupFile, Database $database)
88
    {
89
        Log::debug('Decompressing archive file.');
90
        $workableFile = $this->createTmpFile($backupFile, $database);
91
92
        if (null === $workableFile) {
93
            return null;
94
        }
95
96
        $process = new Process(['gzip', '-d', $workableFile]);
97
        $process->run(function ($type, $buffer): bool {
98
            if (Process::OUT === $type) {
99
                Log::debug('gzip buffer: '.$buffer);
100
            }
101
            if (Process::ERR === $type) {
102
                Log::error('Error whilst performing zip action. Output of buffer: '.$buffer);
103
104
                return false;
105
            }
106
107
            return true;
108
        });
109
110
        Log::debug('Finished decompressing archive file.');
111
112
        return str_replace('.gz', '', $workableFile);
113
    }
114
115
    /**
116
     * @param string $databaseIdentifier
117
     *
118
     * @return array|null
119
     */
120
    public function getMostRecentBackups(string $databaseIdentifier): ?array
121
    {
122
        Log::debug('Searching for archived back-up files.');
123
124
        try {
125
            $files = File::files($this->storagePath);
126
        } catch (Exception $e) {
127
            Log::error(sprintf('Unable to reach storage path. Exception thrown: %s', $e->getMessage()));
128
129
            return null;
130
        }
131
132
        // Get the files matching the database identifier
133
        $filesFilter = array_filter($files, function ($item) use ($databaseIdentifier) {
134
            return strpos($item, $databaseIdentifier);
135
        });
136
137
        if (null === $filesFilter || empty($filesFilter)) {
138
            Log::error(sprintf('No back-up files found for driver %s. No need to continue the restore procedure.', $databaseIdentifier));
139
140
            return null;
141
        }
142
143
        return $filesFilter;
144
    }
145
146
    /**
147
     * @param string   $backupFile
148
     * @param Database $database
149
     *
150
     * @return string|null
151
     */
152
    protected function createTmpFile(string $backupFile, Database $database): ?string
153
    {
154
        Log::debug('Creating temp back-up file to not corrupt the archives.');
155
        $tmpFilename = 'tmp.'.microtime(true).'.'.$database->getRealDatabase()->getFileExtension().'.gz';
156
        $filePath = $this->storagePath.$tmpFilename;
157
158
        try {
159
            File::copy($backupFile, $filePath);
160
        } catch (Exception $e) {
161
            Log::error('Could not create temporary archive file. Exception throw: '.$e->getMessage());
162
163
            return null;
164
        }
165
166
        Log::debug('Finished creating temp back-up file.');
167
168
        return $filePath;
169
    }
170
171
    /**
172
     * @param string $backupFile
173
     *
174
     * @return bool
175
     */
176
    public function clearTmPFile(string $backupFile): bool
177
    {
178
        Log::debug('Cleaning up temp back-up file.');
179
180
        try {
181
            File::delete($backupFile);
182
        } catch (Exception $e) {
183
            Log::error(sprintf('Could not clean up temp back-up file. Exception thrown: %s', $e->getMessage()));
184
185
            return false;
186
        }
187
188
        Log::debug('Finished cleaning up temp back-up file.');
189
190
        return true;
191
    }
192
}
193