From 4c457d2abfedb5cb30dc0ba9d6b92f9eb1df2443 Mon Sep 17 00:00:00 2001 From: gvozdb Date: Tue, 14 Jul 2020 16:57:09 +0600 Subject: [PATCH] 0.2.0 --- CHANGELOG.md | 18 +- README.md | 48 +++++- composer.json | 4 +- examples/cron/config_example.yaml | 43 ++++- src/Backup.php | 128 ++++++++++---- src/Compressor/AbstractCompressor.php | 8 +- src/Compressor/Zip.php | 15 +- src/Database/AbstractDatabase.php | 6 +- src/Database/Mysql.php | 14 +- src/Logger/Handler.php | 232 ++++++++++++++++++++++++++ src/Path/AbstractPath.php | 147 ++++++++++------ src/Path/Log.php | 17 -- src/Path/System.php | 14 -- src/Path/User.php | 14 -- src/Storage/AbstractStorage.php | 24 ++- src/Storage/YandexDisk.php | 108 ++++++++---- 16 files changed, 649 insertions(+), 191 deletions(-) create mode 100644 src/Logger/Handler.php diff --git a/CHANGELOG.md b/CHANGELOG.md index ced5b25..613bf0f 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,26 +1,42 @@ # Changelog +## [0.2.0] - 2020-07-14 + +* Refactoring +* Added output of error messages +* Added information messages output +* Added recording of logs to file +* Added sending of logs to mail +* Added sending of logs to Telegram Chat +* Changed README.md + + ## [0.1.5] - 2019-05-21 * Added param **users** for **Backup::run()** + ## [0.1.4] - 2018-11-21 -* Added **class_exists** for storage in Dumper\Backup +* Added **class_exists** for storage in `Dumper\Backup` * Changed README.md + ## [0.1.3] - 2018-11-07 * Fixed composer.json, changed version of `arhitector/yandex` to ~2.0 + ## [0.1.2] - 2018-11-07 * Fixed composer.json, added property `prefer-stable` + ## [0.1.1] - 2018-11-07 * Changed README.md + ## [0.1.0] - 2018-11-06 * First release \ No newline at end of file diff --git a/README.md b/README.md index 6cbc643..c0a8bc4 100755 --- a/README.md +++ b/README.md @@ -31,10 +31,12 @@ try { ### config.yaml Конфигурационный файл приложения. ```yaml +# main: prefix: "%Y%m%d-" # expires: &main.expires 4 # clean_logs: true # + # path: tmp: '/tmp/dumper/%Y%m%d/' # @@ -42,12 +44,54 @@ path: root: '/root/' # log: '/var/log/' # etc: '/etc/' # + # storages: + # Upload to YandexDisk YandexDisk: - token: 'AQAAAAABEJ2-AAVH0ERr79Yz4E5dpd-7nhV1W18' # - path: 'disk:/Dumper/%Y%m%d/' # + token: 'AQAAAAABEJ2-AAVH0EIr79Yz4E5dpd-7nhV1W18' # + path: 'disk:/Dumper/ServerIP/%Y%m%d/' # expires: *main.expires # + +# +logs: + enabled: true # + notify: + # Print to console + Console: + path: 'php://stdout' # + #level: 'info' # + #format: "[%datetime%] [%level_name%] > %message%\n" # + #dateFormat: 'd.m.Y H:i:s' # + + # Write to file + File: + path: './log/%Y%m%d.log' # + #level: 'info' # + #format: "[%datetime%] [%level_name%] > %message%\n" # + #dateFormat: 'd.m.Y H:i:s' # + + # Send to email + Email: + host: '' # + port: 465 # + encryption: 'ssl' # + username: '' # + password: '' # + subject: '[%d.%m.%Y] Dumper Report' # + from: '' # + to: '' # + #level: 'info' # + #format: "[%datetime%] [%level_name%] > %message%\n" # + dateFormat: 'H:i:s' # + + # Send to telegram chat + Telegram: + token: '' # + chat: '' # + #level: 'info' # + #format: "[%datetime%] [%level_name%] > %message%\n" # + dateFormat: 'H:i:s' # ``` Поместить в директорию с cron.php diff --git a/composer.json b/composer.json index f24cb2d..0830583 100755 --- a/composer.json +++ b/composer.json @@ -22,7 +22,9 @@ "arhitector/yandex": "~2.0", "symfony/filesystem": "~3.4|~4.0", "symfony/yaml": "~3.4|~4.0", - "symfony/console": "~3.4|~4.0" + "symfony/console": "~3.4|~4.0", + "monolog/monolog": "^2.1", + "swiftmailer/swiftmailer": "^6.2" }, "autoload": { "psr-4": { diff --git a/examples/cron/config_example.yaml b/examples/cron/config_example.yaml index f699856..9815feb 100644 --- a/examples/cron/config_example.yaml +++ b/examples/cron/config_example.yaml @@ -14,7 +14,48 @@ path: # storages: + # Upload to YandexDisk YandexDisk: token: 'AQAAAAABEJ2-AAVH0EIr79Yz4E5dpd-7nhV1W18' # - path: 'disk:/Dumper/%Y%m%d/' # + path: 'disk:/Dumper/ServerIP/%Y%m%d/' # expires: *main.expires # + +# +logs: + enabled: true # + notify: + # Print to console + Console: + path: 'php://stdout' # + #level: 'info' # + #format: "[%datetime%] [%level_name%] > %message%\n" # + #dateFormat: 'd.m.Y H:i:s' # + + # Write to file + File: + path: './log/%Y%m%d.log' # + #level: 'info' # + #format: "[%datetime%] [%level_name%] > %message%\n" # + #dateFormat: 'd.m.Y H:i:s' # + + # Send to email + Email: + host: '' # + port: 465 # + encryption: 'ssl' # + username: '' # + password: '' # + subject: '[%d.%m.%Y] Dumper Report' # + from: '' # + to: '' # + #level: 'info' # + #format: "[%datetime%] [%level_name%] > %message%\n" # + dateFormat: 'H:i:s' # + + # Send to telegram chat + Telegram: + token: '' # + chat: '' # + #level: 'info' # + #format: "[%datetime%] [%level_name%] > %message%\n" # + dateFormat: 'H:i:s' # diff --git a/src/Backup.php b/src/Backup.php index 99acfe6..374564e 100755 --- a/src/Backup.php +++ b/src/Backup.php @@ -4,6 +4,14 @@ class Backup { + /** + * @var Logger\Handler $log + */ + public $log; + /** + * @var array $storages + */ + public $storages = []; /** * @var array $config */ @@ -11,6 +19,8 @@ class Backup /** * @param Config\Load $config + * + * @throws \Exception */ public function __construct(Config\Load $config) { @@ -24,16 +34,25 @@ public function __construct(Config\Load $config) if (!file_exists($this->config['path']['tmp'])) { @mkdir($this->config['path']['tmp'], 0755, true); } - // print_r($this->config); + + // + $this->log = new Logger\Handler($this->config['logs']); } /** * @param array $users * - * @throws \ReflectionException + * @return void|bool + * + * @throws \Exception */ public function run(array $users = []) { + if (!is_dir($this->config['path']['users'])) { + $this->log->emergency('Directory with users has been not found.'); + return false; + } + $tasks = []; $prefix = $this->config['main']['prefix']; @@ -46,73 +65,112 @@ public function run(array $users = []) $path = $this->config['path']['users'] . $k; - $config = new Config\Load($path . '/dumper.yaml', [ - 'src' => $path, - 'dest' => $this->config['path']['tmp'] . $prefix . 'www-' . $k, - ]); - $config = $config->toArray(); + try { + $config = new Config\Load($path . '/dumper.yaml', [ + 'key' => $k, + 'src' => $path, + 'dest' => $this->config['path']['tmp'] . $prefix . 'www-' . $k, + ]); + $config = $config->toArray(); + } catch (\Exception $e) { + $this->log->error("Could not read user config `{$k}`. Message: " . $e->getMessage()); + continue; + } - $tmp = new Path\User($config); - if ($tmp->isEnabled()) { - $tasks[] = $tmp; + try { + $task = new Path\User($this, $config); + if ($task->enabled()) { + $tasks[] = $task; + } + unset($task, $config, $path); + } catch (\Exception $e) { + $this->log->error($e->getMessage()); + continue; } - unset($tmp, $config, $path); } } unset($dir); // - if (!empty($this->config['path']['log'])) { - $tasks[] = new Path\Log([ - 'enabled' => true, - 'clean_logs' => $this->config['main']['clean_logs'], - 'src' => $this->config['path']['log'], - 'dest' => $this->config['path']['tmp'] . $prefix . 'log', - ]); + foreach (['root', 'etc'] as $k) { + if (!empty($this->config['path'][$k])) { + try { + $tasks[] = new Path\System($this, [ + 'key' => $k, + 'src' => $this->config['path'][$k], + 'dest' => $this->config['path']['tmp'] . $prefix . $k, + 'enabled' => true, + ]); + } catch (\Exception $e) { + $this->log->error($e->getMessage()); + } + } } // - foreach (['root', 'etc'] as $k) { - if (!empty($this->config['path'][$k])) { - $tasks[] = new Path\System([ + if (!empty($this->config['path']['log'])) { + try { + $tasks[] = new Path\Log($this, [ + 'key' => 'log', + 'src' => $this->config['path']['log'], + 'dest' => $this->config['path']['tmp'] . $prefix . 'log', + 'clean_logs' => $this->config['main']['clean_logs'], 'enabled' => true, - 'src' => $this->config['path'][$k], - 'dest' => $this->config['path']['tmp'] . $prefix . $k, ]); + } catch (\Exception $e) { + $this->log->error($e->getMessage()); } } // - $storages = []; foreach ($this->config['storages'] as $class => $config) { if (!class_exists("\Gvozdb\Dumper\Storage\\{$class}")) { + $this->log->error("Storage handler `{$class}` not found."); continue; } - $storage = new \ReflectionClass("\Gvozdb\Dumper\Storage\\{$class}"); - $storages[$class] = $storage->newInstance($config); - unset($storage); + try { + $storage = new \ReflectionClass("\Gvozdb\Dumper\Storage\\{$class}"); + $storageInstance = $storage->newInstance($config); + if ($storageInstance->enabled()) { + $this->storages[$class] = $storageInstance; + } + } catch (\Exception $e) { + $this->log->error("It was not possible to initialize the storage instance `{$class}`. Message: " . $e->getMessage()); + } } + unset($class, $config, $storage, $storageInstance); // /** @var Path\AbstractPath $task */ foreach ($tasks as $task) { - $task->run($storages); + $task->run(); } // - $this->clean($storages); + $this->clean(); + + // + $this->log->bufferReset(); + + return true; } /** - * @param array $storages + * */ - protected function clean($storages = []) + protected function clean() { // - if (!empty($storages)) { - /** @var Storage\AbstractStorage $storage */ - foreach ($storages as $storage) { - $storage->clean(); + if (!empty($this->storages)) { + /** @var Storage\AbstractStorage $storageInstance */ + foreach ($this->storages as $storageClass => $storageInstance) { + try { + if ($storageInstance->clean() === true) { + $this->log->info("Successfully cleaning old backups in the storage `{$storageClass}`."); + } + } catch (\Exception $e) { + $this->log->error("Could not remove old backups in the storage `{$storageClass}`. Message: " . $e->getMessage()); + } } } diff --git a/src/Compressor/AbstractCompressor.php b/src/Compressor/AbstractCompressor.php index 227d5d8..33fcc7c 100644 --- a/src/Compressor/AbstractCompressor.php +++ b/src/Compressor/AbstractCompressor.php @@ -9,7 +9,7 @@ abstract class AbstractCompressor */ protected $config = []; /** - * @var string $filepath + * @var null|string $filepath */ protected $filepath; @@ -28,7 +28,7 @@ public function __construct(array $config = []) // foreach (['src', 'dest'] as $k) { if (empty($this->config[$k])) { - throw new \Exception('Compressor config bad.'); + throw new \Exception("Incorrect compressor config for `{$this->config['key']}`. " . print_r($this->config, 1)); } } } @@ -50,12 +50,12 @@ protected function setFilePath($filepath) } /** - * @return mixed + * @return void|bool */ abstract public function compress(); /** - * @return mixed + * @return string */ abstract protected function excludePrepare(); } \ No newline at end of file diff --git a/src/Compressor/Zip.php b/src/Compressor/Zip.php index 8a0fb4b..3f9d8cf 100644 --- a/src/Compressor/Zip.php +++ b/src/Compressor/Zip.php @@ -20,7 +20,9 @@ public function __construct(array $config = []) } /** - * @return mixed|void + * @return void|bool + * + * @throws \Exception */ public function compress() { @@ -38,14 +40,19 @@ public function compress() $this->config['src'], $this->excludePrepare(), ]); - $output = shell_exec($command); + $result = shell_exec($command); // - $this->setFilePath(file_exists($dest) ? $dest : null); + if (!file_exists($dest)) { + throw new \Exception("It was not possible to pack the source `{$this->config['src']}`."); + } + $this->setFilePath($dest); + + return true; } /** - * @return array|mixed|string + * @return string */ protected function excludePrepare() { diff --git a/src/Database/AbstractDatabase.php b/src/Database/AbstractDatabase.php index 2881809..c4395e2 100644 --- a/src/Database/AbstractDatabase.php +++ b/src/Database/AbstractDatabase.php @@ -9,7 +9,7 @@ abstract class AbstractDatabase */ protected $config = []; /** - * @var string $filepath + * @var null|string $filepath */ protected $filepath; @@ -27,7 +27,7 @@ public function __construct(array $config = []) // foreach (['dest'] as $k) { if (empty($this->config[$k])) { - throw new \Exception('Database config bad.'); + throw new \Exception("Incorrect database config for `{$this->config['key']}`. " . print_r($this->config, 1)); } } } @@ -49,7 +49,7 @@ protected function setFilePath($filepath) } /** - * @return mixed + * @return void|bool */ abstract public function export(); } \ No newline at end of file diff --git a/src/Database/Mysql.php b/src/Database/Mysql.php index b1bd1f0..4f8d723 100644 --- a/src/Database/Mysql.php +++ b/src/Database/Mysql.php @@ -20,11 +20,12 @@ public function __construct(array $config = []) } /** - * @return mixed|void + * @return void|bool + * + * @throws \Exception */ public function export() { - // foreach (['host', 'name', 'user', 'pass'] as $k) { if (empty($this->config[$k])) { return; @@ -48,9 +49,14 @@ public function export() '>', $dest, ]); - $output = shell_exec($command); + $result = shell_exec($command); // - $this->setFilePath(file_exists($dest) ? $dest : null); + if (!file_exists($dest)) { + throw new \Exception("It was not possible to database dump `{$this->config['name']}`."); + } + $this->setFilePath($dest); + + return true; } } \ No newline at end of file diff --git a/src/Logger/Handler.php b/src/Logger/Handler.php new file mode 100644 index 0000000..136f049 --- /dev/null +++ b/src/Logger/Handler.php @@ -0,0 +1,232 @@ +config = array_merge([ + 'enabled' => false, + 'notify' => [], + ], $config); + if ($this->config['enabled'] !== true) { + return; + } + + // + $handlers = []; + foreach ($this->config['notify'] as $k => $v) { + $v = array_merge([ + 'level' => 'info', + 'format' => "[%datetime%] [%level_name%] > %message%\n", + 'dateFormat' => 'd.m.Y H:i:s', + ], $v); + $v['levelConstant'] = 'Monolog\Logger::' . strtoupper($v['level']); + + switch ($k) { + case 'Console': + if (empty($v['path'])) { + break; + } + $handlers[$k] = new StreamHandler($v['path'], constant($v['levelConstant'])); + break; + + case 'File': + if (empty($v['path'])) { + break; + } + $v['path'] = strftime($v['path']); + if (!preg_match('~^/~u', $v['path'])) { + $v['path'] = join('/', [ + dirname(realpath($_SERVER['SCRIPT_FILENAME'])), + preg_replace('~^\./?~u', '', $v['path']), + ]); + } + + $handlers[$k] = new StreamHandler($v['path'], constant($v['levelConstant'])); + break; + + case 'Email': + if (empty($v['host'])) { + break; + } + $smtpTransporter = new \Swift_SmtpTransport($v['host'], $v['port'], $v['encryption']); + $smtpTransporter->setUsername($v['username']); + $smtpTransporter->setPassword($v['password']); + $swiftMailer = new \Swift_Mailer($smtpTransporter); + $swiftMessage = new \Swift_Message(strftime($v['subject'])); + $swiftMessage->setFrom($v['from']); + $swiftMessage->setTo($v['to']); + $handlers[$k] = new BufferHandler( + new SwiftMailerHandler($swiftMailer, $swiftMessage, constant($v['levelConstant'])) + ); + break; + + case 'Telegram': + if (empty($v['token']) || empty($v['chat'])) { + break; + } + $handlers[$k] = new BufferHandler(new TelegramBotHandler( + $v['token'], + $v['chat'], + constant($v['levelConstant']), + true, + 'HTML' + ), 0); + break; + } + + if (!empty($handlers[$k])) { + $handlers[$k]->setFormatter(new LineFormatter($v['format'], $v['dateFormat'])); + } + } + + + $this->logger = new Logger('Gvozdb\Dumper'); + $this->logger->pushHandler(new GroupHandler($handlers)); + } + + /** + * @return void + */ + public function bufferReset() + { + $handlers = $this->logger->getHandlers(); + foreach ($handlers as $handler) { + $handler->reset(); + } + } + + /** + * @param string $action + * @param string $message + * @param array $context + * + * @return bool + */ + public function log(string $action, string $message, array $context = []) + { + if (empty($this->logger)) { + return false; + } + $this->logger->{$action}($message, $context); + + return true; + } + + /** + * @param string $message + * @param array $context + * + * @return bool + */ + public function debug($message, array $context = []) + { + return $this->log(__FUNCTION__, $message, $context); + } + + /** + * @param string $message + * @param array $context + * + * @return bool + */ + public function info($message, array $context = []) + { + return $this->log(__FUNCTION__, $message, $context); + } + + /** + * @param string $message + * @param array $context + * + * @return bool + */ + public function notice($message, array $context = []) + { + return $this->log(__FUNCTION__, $message, $context); + } + + /** + * @param string $message + * @param array $context + * + * @return bool + */ + public function warning($message, array $context = []) + { + return $this->log(__FUNCTION__, $message, $context); + } + + /** + * @param string $message + * @param array $context + * + * @return bool + */ + public function error($message, array $context = []) + { + return $this->log(__FUNCTION__, $message, $context); + } + + /** + * @param string $message + * @param array $context + * + * @return bool + */ + public function critical($message, array $context = []) + { + return $this->log(__FUNCTION__, $message, $context); + } + + /** + * @param string $message + * @param array $context + * + * @return bool + */ + public function alert($message, array $context = []) + { + return $this->log(__FUNCTION__, $message, $context); + } + + /** + * @param string $message + * @param array $context + * + * @return bool + */ + public function emergency($message, array $context = []) + { + return $this->log(__FUNCTION__, $message, $context); + } +} \ No newline at end of file diff --git a/src/Path/AbstractPath.php b/src/Path/AbstractPath.php index b673b5a..5f57493 100644 --- a/src/Path/AbstractPath.php +++ b/src/Path/AbstractPath.php @@ -2,12 +2,17 @@ namespace Gvozdb\Dumper\Path; +use Gvozdb\Dumper\Backup; use Gvozdb\Dumper\Storage; use Gvozdb\Dumper\Database; use Gvozdb\Dumper\Compressor; abstract class AbstractPath { + /** + * @var Backup $dumper + */ + protected $dumper; /** * @var array $config */ @@ -18,12 +23,15 @@ abstract class AbstractPath protected $files = []; /** + * @param Backup $dumper * @param array $config * * @throws \Exception */ - public function __construct(array $config = []) + public function __construct(Backup $dumper, array $config = []) { + $this->dumper = $dumper; + $this->config = array_merge([ 'enabled' => false, 'src' => null, @@ -33,7 +41,7 @@ public function __construct(array $config = []) // foreach (['src', 'dest'] as $k) { if (empty($this->config[$k])) { - throw new \Exception('Path config bad.'); + throw new \Exception("Incorrect config for `{$this->config['key']}`. " . print_r($this->config, 1)); } } @@ -46,101 +54,132 @@ public function __construct(array $config = []) } /** - * @param array|Storage\AbstractStorage $storages - * * @throws \Exception */ - public function run(array $storages) + public function run() { - $this->compress($this->config['src'], $this->config['dest'], ($this->config['exclude'] ?: [])); + $this->compress(); $this->database(); - $this->upload($storages); + $this->upload(); $this->clean(); } /** - * + * @return bool */ - public function isEnabled() + public function enabled() { - return $this->config['enabled']; + foreach (['enabled', 'src', 'dest'] as $k) { + if (empty($this->config[$k])) { + return false; + } + } + + return true; } /** - * @param string $src - * @param string $dest - * @param array $exclude + * @param null|string $src + * @param null|string $dest + * @param array $exclude + * + * @return void * * @throws \Exception */ - protected function compress($src, $dest, array $exclude = []) + protected function compress($src = null, $dest = null, array $exclude = []) { - // - $compressor = new Compressor\Zip([ - 'src' => $src, - 'dest' => $dest, - 'exclude' => $exclude, - ]); - $compressor->compress(); + if (empty($src)) { + $src = $this->config['src']; + $dest = $this->config['dest']; + $exclude = $this->config['exclude'] ?: []; + } - // - if ($filepath = $compressor->getFilePath()) { - $this->files[$filepath] = false; + try { + $compressor = new Compressor\Zip([ + 'key' => $this->config['key'], + 'src' => $src, + 'dest' => $dest, + 'exclude' => $exclude, + ]); + if ($compressor->compress() === true) { + $src_type = is_dir($src) ? 'directory' : 'file'; + $this->dumper->log->info("Successfully compressed {$src_type} `{$src}`."); + } + + // + if ($filepath = $compressor->getFilePath()) { + $this->files[$filepath] = false; + } + unset($compressor, $filepath); + } catch (\Exception $e) { + $this->dumper->log->error($e->getMessage()); } - unset($compressor, $filepath); } /** + * @return void * + * @throws \Exception */ protected function database() { - // - $config = $this->config['database'] ?: []; + $config = @$this->config['database'] ?: []; if (empty($config['type'])) { return; } - // - $class = ucfirst(strtolower($config['type'])); - if (!class_exists("\Gvozdb\Dumper\Database\\{$class}")) { - return; - } + try { + $class = ucfirst(strtolower($config['type'])); + if (!class_exists("\Gvozdb\Dumper\Database\\{$class}")) { + throw new \Exception("Database handler `{$config['type']}` not found."); + } - // - /** @var Database\AbstractDatabase $database */ - $database = new \ReflectionClass("\Gvozdb\Dumper\Database\\{$class}"); - $database = $database->newInstance(array_merge($config, [ - 'dest' => $this->config['dest'], - ])); - $database->export(); + $database = new \ReflectionClass("\Gvozdb\Dumper\Database\\{$class}"); + $database = $database->newInstance(array_merge($config, [ + 'key' => $this->config['key'], + 'dest' => $this->config['dest'], + ])); + if ($database->export() === true) { + $this->dumper->log->info("Successfully database dump for `{$this->config['key']}` user."); + } - // - if ($filepath = $database->getFilePath()) { - $this->compress($filepath, $filepath); - @unlink($filepath); - } + // + if ($filepath = $database->getFilePath()) { + $this->compress($filepath, $filepath); + @unlink($filepath); + } - unset($database, $filepath, $class, $config); + unset($database, $filepath, $class, $config); + } catch (\Exception $e) { + $this->dumper->log->error($e->getMessage()); + } } /** - * @param array|Storage\AbstractStorage $storages + * @throws \Exception */ - protected function upload($storages) + protected function upload() { - if (empty($storages) || empty($this->files)) { + if (empty($this->dumper->storages) || empty($this->files)) { return; } + + $storages = $this->dumper->storages; if (!is_array($storages)) { $storages = [$storages]; } foreach ($this->files as $filepath => &$status) { - /** @var Storage\AbstractStorage $storage */ - foreach ($storages as $storage) { - if ($storage->upload($filepath)) { - $status = true; + /** @var Storage\AbstractStorage $storageInstance */ + foreach ($storages as $storageClass => $storageInstance) { + try { + if ($storageInstance->upload($filepath)) { + $status = true; + $this->dumper->log->info("Successfully uploaded file `{$filepath}` to the storage `{$storageClass}`."); + } + } catch (\Exception $e) { + $this->dumper->log->error("Failed uploading file `{$filepath}` to the storage `{$storageClass}`. Message: " . $e->getMessage()); } } } @@ -163,10 +202,10 @@ protected function clean() } /** - * Чистит папку в файловой системе + * Clears the folder on the file system * * @param string $path - * @param bool $remove_self + * @param bool $remove_self */ static public function cleanDir($path, $remove_self = false) { diff --git a/src/Path/Log.php b/src/Path/Log.php index 328b615..061c67e 100644 --- a/src/Path/Log.php +++ b/src/Path/Log.php @@ -4,21 +4,6 @@ class Log extends System { - /** - * @var array $config - */ - protected $config = []; - - /** - * @param array $config - * - * @throws \Exception - */ - public function __construct(array $config = []) - { - parent::__construct($config); - } - /** * */ @@ -26,12 +11,10 @@ protected function clean() { parent::clean(); - // Чистим логи if (!empty($this->config['clean_logs']) && !empty($this->config['src'])) { $path = $this->config['src']; if (file_exists($path)) { $output = shell_exec("find {$path} -type f \( -name \"*.gz\" -o -name \"*.1*\" \) -exec rm '{}' \;"); - // print_r($output); } unset($path); } diff --git a/src/Path/System.php b/src/Path/System.php index f4d7405..ecab7e7 100644 --- a/src/Path/System.php +++ b/src/Path/System.php @@ -4,18 +4,4 @@ class System extends AbstractPath { - /** - * @var array $config - */ - protected $config = []; - - /** - * @param array $config - * - * @throws \Exception - */ - public function __construct(array $config = []) - { - parent::__construct($config); - } } \ No newline at end of file diff --git a/src/Path/User.php b/src/Path/User.php index 4853124..bbd11a2 100644 --- a/src/Path/User.php +++ b/src/Path/User.php @@ -4,18 +4,4 @@ class User extends AbstractPath { - /** - * @var array $config - */ - protected $config = []; - - /** - * @param array $config - * - * @throws \Exception - */ - public function __construct(array $config = []) - { - parent::__construct($config); - } } \ No newline at end of file diff --git a/src/Storage/AbstractStorage.php b/src/Storage/AbstractStorage.php index 1a05c88..9886041 100644 --- a/src/Storage/AbstractStorage.php +++ b/src/Storage/AbstractStorage.php @@ -8,6 +8,10 @@ abstract class AbstractStorage * @var array $config */ protected $config = []; + /** + * @var string $message + */ + public $message; /** * @param array $config @@ -17,27 +21,35 @@ abstract class AbstractStorage public function __construct(array $config = []) { $this->config = array_merge([ - 'path' => null, + 'path' => '', ], $config); - // + $this->config['path'] = strftime(@$this->config['path'] ?: ''); + } + + /** + * @return bool + */ + public function enabled() + { foreach (['path'] as $k) { if (empty($this->config[$k])) { - throw new \Exception('Storage config bad.'); + return false; } } - $this->config['path'] = strftime($this->config['path']); + + return true; } /** * @param $filepath * - * @return bool + * @return void|bool */ abstract public function upload($filepath); /** - * @return mixed + * @return void|bool */ abstract public function clean(); diff --git a/src/Storage/YandexDisk.php b/src/Storage/YandexDisk.php index 9d5d937..0c7080a 100644 --- a/src/Storage/YandexDisk.php +++ b/src/Storage/YandexDisk.php @@ -37,21 +37,44 @@ public function __construct(array $config = []) { parent::__construct($config); - // - if (empty($this->config['token'])) { - throw new \Exception('Token is empty.'); + try { + $this->client = new \Arhitector\Yandex\Disk($this->config['token']); + + // Checking authorization status + $this->getPath(); + } catch (\Exception $e) { + throw new \Exception($e->getMessage()); + } + } + + /** + * @return bool + */ + public function enabled() + { + if (($flag = parent::enabled()) === true) { + foreach (['token'] as $k) { + if (empty($this->config[$k])) { + $flag = false; + } + } } - $this->client = new \Arhitector\Yandex\Disk($this->config['token']); + + return $flag; } /** * @param string $filepath * - * @return bool + * @return void|bool + * * @throws \Exception */ public function upload($filepath) { + if ($this->enabled() === false) { + return; + } if (empty($filepath)) { return false; } @@ -76,56 +99,79 @@ public function upload($filepath) } /** + * @return void|bool * + * @throws \Exception */ public function clean() { - // Удаляем устаревшие бекапы - if ($expires_time = (86400 * $this->config['expires'])) { - $expires_time = time() - $expires_time; - $parent = $this->client->getResource($this->getParentPath()); - $childs = $parent->getIterator(); - - /** @var \Arhitector\Yandex\Disk\Resource\Closed $child */ - foreach ($childs['items'] as $child) { - $created_time = strtotime(date('Y-m-d', strtotime($child->get('created')))); - if ($expires_time > $created_time) { - $child->delete(true); + if ($this->enabled() === false) { + return; + } + + try { + if ($expires_time = (86400 * $this->config['expires'])) { + $expires_time = time() - $expires_time; + $parent = $this->client->getResource($this->getParentPath()); + $childs = $parent->getIterator(); + + /** @var \Arhitector\Yandex\Disk\Resource\Closed $child */ + foreach ($childs['items'] as $child) { + $created_time = strtotime(date('Y-m-d', strtotime($child->get('created')))); + if ($expires_time > $created_time) { + $child->delete(true); + } } } + } catch (\Exception $e) { + throw new \Exception($e->getMessage()); } + + return true; } /** * @return string + * + * @throws \Exception */ protected function getPath() { - $path = 'disk:/'; - $folders = explode('/', $this->config['path']); - foreach ($folders as $v) { - if (empty($v) || $v == 'disk:') { - continue; - } - $path .= $v . '/'; - $resource = $this->client->getResource($path); - if (!$resource->has()) { - $resource->create(); + try { + $path = 'disk:/'; + $folders = explode('/', $this->config['path']); + foreach ($folders as $v) { + if (empty($v) || $v == 'disk:') { + continue; + } + $path .= $v . '/'; + $resource = $this->client->getResource($path); + if (!$resource->has()) { + $resource->create(); + } + unset($resource); } - unset($resource); + unset($folders); + $this->config['path'] = $path; + } catch (\Exception $e) { + throw new \Exception($e->getMessage()); } - unset($folders); - - $this->config['path'] = $path; return $this->config['path']; } /** * @return string + * + * @throws \Exception */ protected function getParentPath() { - return dirname($this->getPath()) . '/'; + $path = $this->getPath(); + if (is_string($path)) { + $path = dirname($path) . '/'; + } + + return $path; } } \ No newline at end of file