├── src ├── Namers │ ├── NamerInterface.php │ ├── SimpleNamer.php │ └── TimestampNamer.php ├── Sources │ ├── SourceInterface.php │ ├── UploadsSource.php │ └── MysqlDumpSource.php ├── Processors │ ├── ProcessorInterface.php │ ├── ZipProcessor.php │ └── GzipProcessor.php ├── Destinations │ ├── DestinationInterface.php │ └── LocalDestination.php ├── Backup.php ├── ProfileBuilderFactory.php ├── ProfileRegistryFactory.php └── BackupServiceProvider.php ├── LICENSE ├── composer.json └── config └── backup.php /src/Namers/NamerInterface.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | declare(strict_types=1); 13 | 14 | namespace Vinkla\Backup\Namers; 15 | 16 | /** 17 | * This is the namer interface. 18 | * 19 | * @author Vincent Klaiber 20 | */ 21 | interface NamerInterface 22 | { 23 | /** 24 | * Bootstrap the namer. 25 | * 26 | * @return \Zenstruck\Backup\Namer 27 | */ 28 | public function bootstrap(); 29 | 30 | /** 31 | * Get the namer name. 32 | * 33 | * @return string 34 | */ 35 | public function getName(); 36 | } 37 | -------------------------------------------------------------------------------- /src/Sources/SourceInterface.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | declare(strict_types=1); 13 | 14 | namespace Vinkla\Backup\Sources; 15 | 16 | /** 17 | * This is the source interface. 18 | * 19 | * @author Vincent Klaiber 20 | */ 21 | interface SourceInterface 22 | { 23 | /** 24 | * Bootstrap the source. 25 | * 26 | * @return \Zenstruck\Backup\Source 27 | */ 28 | public function bootstrap(); 29 | 30 | /** 31 | * Get the source name. 32 | * 33 | * @return string 34 | */ 35 | public function getName(); 36 | } 37 | -------------------------------------------------------------------------------- /src/Processors/ProcessorInterface.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | declare(strict_types=1); 13 | 14 | namespace Vinkla\Backup\Processors; 15 | 16 | /** 17 | * This is the processor interface. 18 | * 19 | * @author Vincent Klaiber 20 | */ 21 | interface ProcessorInterface 22 | { 23 | /** 24 | * Bootstrap the processor. 25 | * 26 | * @return \Zenstruck\Backup\Processor 27 | */ 28 | public function bootstrap(); 29 | 30 | /** 31 | * Get the processor name. 32 | * 33 | * @return string 34 | */ 35 | public function getName(); 36 | } 37 | -------------------------------------------------------------------------------- /src/Destinations/DestinationInterface.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | declare(strict_types=1); 13 | 14 | namespace Vinkla\Backup\Destinations; 15 | 16 | /** 17 | * This is the destination interface. 18 | * 19 | * @author Vincent Klaiber 20 | */ 21 | interface DestinationInterface 22 | { 23 | /** 24 | * Bootstrap the destination. 25 | * 26 | * @return \Zenstruck\Backup\Destination 27 | */ 28 | public function bootstrap(); 29 | 30 | /** 31 | * Get the destination name. 32 | * 33 | * @return string 34 | */ 35 | public function getName(); 36 | } 37 | -------------------------------------------------------------------------------- /src/Namers/SimpleNamer.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | declare(strict_types=1); 13 | 14 | namespace Vinkla\Backup\Namers; 15 | 16 | use Zenstruck\Backup\Namer\SimpleNamer as Namer; 17 | 18 | /** 19 | * This is the simple namer class. 20 | * 21 | * @author Vincent Klaiber 22 | */ 23 | class SimpleNamer implements NamerInterface 24 | { 25 | /** 26 | * Bootstrap the namer. 27 | * 28 | * @return \Zenstruck\Backup\Namer\SimpleNamer 29 | */ 30 | public function bootstrap(): Namer 31 | { 32 | return new Namer($this->getName()); 33 | } 34 | 35 | /** 36 | * Get the namer name. 37 | * 38 | * @return string 39 | */ 40 | public function getName(): string 41 | { 42 | return 'simple'; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/Namers/TimestampNamer.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | declare(strict_types=1); 13 | 14 | namespace Vinkla\Backup\Namers; 15 | 16 | use Zenstruck\Backup\Namer\TimestampNamer as Namer; 17 | 18 | /** 19 | * This is timestamp namer class. 20 | * 21 | * @author Vincent Klaiber 22 | */ 23 | class TimestampNamer implements NamerInterface 24 | { 25 | /** 26 | * Bootstrap the namer. 27 | * 28 | * @return \Zenstruck\Backup\Namer\TimestampNamer 29 | */ 30 | public function bootstrap(): Namer 31 | { 32 | return new Namer($this->getName()); 33 | } 34 | 35 | /** 36 | * Get the namer name. 37 | * 38 | * @return string 39 | */ 40 | public function getName(): string 41 | { 42 | return 'timestamp'; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/Sources/UploadsSource.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | declare(strict_types=1); 13 | 14 | namespace Vinkla\Backup\Sources; 15 | 16 | use Zenstruck\Backup\Source\RsyncSource; 17 | 18 | /** 19 | * This is the uploads source class. 20 | * 21 | * @author Vincent Klaiber 22 | */ 23 | class UploadsSource implements SourceInterface 24 | { 25 | /** 26 | * Bootstrap the source. 27 | * 28 | * @return \Zenstruck\Backup\Source\RsyncSource 29 | */ 30 | public function bootstrap(): RsyncSource 31 | { 32 | return new RsyncSource($this->getName(), public_path('uploads')); 33 | } 34 | 35 | /** 36 | * Get the source name. 37 | * 38 | * @return string 39 | */ 40 | public function getName(): string 41 | { 42 | return 'uploads'; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/Processors/ZipProcessor.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | declare(strict_types=1); 13 | 14 | namespace Vinkla\Backup\Processors; 15 | 16 | use Zenstruck\Backup\Processor\ZipArchiveProcessor; 17 | 18 | /** 19 | * This is the zip processor class. 20 | * 21 | * @author Vincent Klaiber 22 | */ 23 | class ZipProcessor implements ProcessorInterface 24 | { 25 | /** 26 | * Bootstrap the processor. 27 | * 28 | * @return \Zenstruck\Backup\Processor\ZipArchiveProcessor 29 | */ 30 | public function bootstrap(): ZipArchiveProcessor 31 | { 32 | return new ZipArchiveProcessor($this->getName()); 33 | } 34 | 35 | /** 36 | * Get the processor name. 37 | * 38 | * @return string 39 | */ 40 | public function getName(): string 41 | { 42 | return 'zip'; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/Processors/GzipProcessor.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | declare(strict_types=1); 13 | 14 | namespace Vinkla\Backup\Processors; 15 | 16 | use Zenstruck\Backup\Processor\GzipArchiveProcessor; 17 | 18 | /** 19 | * This is the gzip processor class. 20 | * 21 | * @author Vincent Klaiber 22 | */ 23 | class GzipProcessor implements ProcessorInterface 24 | { 25 | /** 26 | * Bootstrap the processor. 27 | * 28 | * @return \Zenstruck\Backup\Processor\GzipArchiveProcessor 29 | */ 30 | public function bootstrap(): GzipArchiveProcessor 31 | { 32 | return new GzipArchiveProcessor($this->getName()); 33 | } 34 | 35 | /** 36 | * Get the processor name. 37 | * 38 | * @return string 39 | */ 40 | public function getName(): string 41 | { 42 | return 'gzip'; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/Destinations/LocalDestination.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | declare(strict_types=1); 13 | 14 | namespace Vinkla\Backup\Destinations; 15 | 16 | use Zenstruck\Backup\Destination\StreamDestination; 17 | 18 | /** 19 | * This is the local destination class. 20 | * 21 | * @author Vincent Klaiber 22 | */ 23 | class LocalDestination implements DestinationInterface 24 | { 25 | /** 26 | * Bootstrap the destination. 27 | * 28 | * @return \Zenstruck\Backup\Destination\StreamDestination 29 | */ 30 | public function bootstrap(): StreamDestination 31 | { 32 | return new StreamDestination($this->getName(), storage_path('backups')); 33 | } 34 | 35 | /** 36 | * Get the destination name. 37 | * 38 | * @return string 39 | */ 40 | public function getName(): string 41 | { 42 | return 'local'; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) Vincent Klaiber 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vinkla/backup", 3 | "description": "An easy-to-use backup manager for Laravel", 4 | "license": "MIT", 5 | "keywords": ["laravel", "backup", "database", "flysystem"], 6 | "authors": [ 7 | { 8 | "name": "Vincent Klaiber", 9 | "email": "hello@vinkla.com", 10 | "homepage": "https://vinkla.com" 11 | } 12 | ], 13 | "require": { 14 | "php": "^7.0", 15 | "illuminate/console": "5.3.* || 5.4.* || 5.5.*", 16 | "illuminate/contracts": "5.3.* || 5.4.* || 5.5.*", 17 | "illuminate/support": "5.3.* || 5.4.* || 5.5.*", 18 | "zenstruck/backup": "^1.2" 19 | }, 20 | "require-dev": { 21 | "graham-campbell/analyzer": "^1.1", 22 | "graham-campbell/testbench": "^4.0", 23 | "phpunit/phpunit": "^6.3" 24 | }, 25 | "autoload": { 26 | "psr-4": { 27 | "Vinkla\\Backup\\": "src/" 28 | } 29 | }, 30 | "autoload-dev": { 31 | "psr-4": { 32 | "Vinkla\\Tests\\Backup\\": "tests/" 33 | } 34 | }, 35 | "config": { 36 | "preferred-install": "dist" 37 | }, 38 | "extra": { 39 | "branch-alias": { 40 | "dev-master": "2.2-dev" 41 | }, 42 | "laravel": { 43 | "providers": [ 44 | "Vinkla\\Backup\\BackupServiceProvider" 45 | ] 46 | } 47 | }, 48 | "minimum-stability": "dev", 49 | "prefer-stable": true 50 | } 51 | -------------------------------------------------------------------------------- /src/Sources/MysqlDumpSource.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | declare(strict_types=1); 13 | 14 | namespace Vinkla\Backup\Sources; 15 | 16 | use Illuminate\Contracts\Config\Repository; 17 | use InvalidArgumentException; 18 | use Zenstruck\Backup\Source\MySqlDumpSource as Source; 19 | 20 | /** 21 | * This is the mysql dump source class. 22 | * 23 | * @author Vincent Klaiber 24 | */ 25 | class MysqlDumpSource implements SourceInterface 26 | { 27 | /** 28 | * The config repository instance. 29 | * 30 | * @var \Illuminate\Contracts\Config\Repository 31 | */ 32 | protected $config; 33 | 34 | /** 35 | * Create a new database source instance. 36 | * 37 | * @param \Illuminate\Contracts\Config\Repository $config 38 | * 39 | * @return void 40 | */ 41 | public function __construct(Repository $config) 42 | { 43 | $this->config = $config; 44 | } 45 | 46 | /** 47 | * Bootstrap the source. 48 | * 49 | * @throws \InvalidArgumentException 50 | * 51 | * @return \Zenstruck\Backup\Source\MySqlDumpSource 52 | */ 53 | public function bootstrap(): Source 54 | { 55 | $connection = $this->getDatabaseConnection(); 56 | 57 | $config = $this->config->get("database.connections.$connection"); 58 | 59 | if (array_get($config, 'driver') !== 'mysql') { 60 | throw new InvalidArgumentException("Unsupported database driver [{$config['driver']}]."); 61 | } 62 | 63 | return new Source( 64 | $this->getName(), 65 | array_get($config, 'database'), 66 | array_get($config, 'host'), 67 | array_get($config, 'username'), 68 | array_get($config, 'password') 69 | ); 70 | } 71 | 72 | /** 73 | * Get the database driver. 74 | * 75 | * @return string 76 | */ 77 | protected function getDatabaseConnection(): string 78 | { 79 | return $this->config->get('database.default'); 80 | } 81 | 82 | /** 83 | * Get the source name. 84 | * 85 | * @return string 86 | */ 87 | public function getName(): string 88 | { 89 | return 'mysql'; 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /src/Backup.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | declare(strict_types=1); 13 | 14 | namespace Vinkla\Backup; 15 | 16 | use Illuminate\Contracts\Config\Repository; 17 | use Zenstruck\Backup\Executor; 18 | use Zenstruck\Backup\ProfileRegistry; 19 | 20 | /** 21 | * This is the backup class. 22 | * 23 | * @author Vincent Klaiber 24 | */ 25 | class Backup 26 | { 27 | /** 28 | * The config repository. 29 | * 30 | * @var \Illuminate\Contracts\Config\Repository 31 | */ 32 | protected $config; 33 | 34 | /** 35 | * The profile registry. 36 | * 37 | * @var \Zenstruck\Backup\ProfileRegistry 38 | */ 39 | protected $registry; 40 | 41 | /** 42 | * The executor instance. 43 | * 44 | * @var \Zenstruck\Backup\Executor 45 | */ 46 | protected $executor; 47 | 48 | /** 49 | * The backup profile. 50 | * 51 | * @var string 52 | */ 53 | protected $profile; 54 | 55 | /** 56 | * Create a new backup instance. 57 | * 58 | * @param \Illuminate\Contracts\Config\Repository $config 59 | * @param \Zenstruck\Backup\ProfileRegistry $registry 60 | * @param \Zenstruck\Backup\Executor $executor 61 | * 62 | * @return void 63 | */ 64 | public function __construct(Repository $config, ProfileRegistry $registry, Executor $executor) 65 | { 66 | $this->config = $config; 67 | $this->registry = $registry; 68 | $this->executor = $executor; 69 | } 70 | 71 | /** 72 | * Get the backup profile. 73 | * 74 | * @return string 75 | */ 76 | public function getProfile(): string 77 | { 78 | if ($this->profile) { 79 | return $this->profile; 80 | } 81 | 82 | return $this->config->get('backup.default'); 83 | } 84 | 85 | /** 86 | * Set the backup profile. 87 | * 88 | * @param string $profile 89 | * 90 | * @return void 91 | */ 92 | public function setProfile(string $profile) 93 | { 94 | $this->profile = $profile; 95 | } 96 | 97 | /** 98 | * Set the backup profile. 99 | * 100 | * @param string $profile 101 | * 102 | * @return $this 103 | */ 104 | public function profile(string $profile): self 105 | { 106 | $this->setProfile($profile); 107 | 108 | return $this; 109 | } 110 | 111 | /** 112 | * Execute the backup. 113 | * 114 | * @param bool $clear 115 | * 116 | * @return void 117 | */ 118 | public function run(bool $clear = false) 119 | { 120 | $profile = $this->registry->get($this->getProfile()); 121 | 122 | $this->executor->backup($profile, $clear); 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /src/ProfileBuilderFactory.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | declare(strict_types=1); 13 | 14 | namespace Vinkla\Backup; 15 | 16 | use Illuminate\Contracts\Foundation\Application; 17 | use InvalidArgumentException; 18 | use Zenstruck\Backup\ProfileBuilder; 19 | 20 | /** 21 | * This is the profile builder factory class. 22 | * 23 | * @author Vincent Klaiber 24 | */ 25 | class ProfileBuilderFactory 26 | { 27 | /** 28 | * The application instance. 29 | * 30 | * @var \Illuminate\Contracts\Foundation\Application 31 | */ 32 | protected $app; 33 | 34 | /** 35 | * Create a new profile builder factory. 36 | * 37 | * @param \Illuminate\Contracts\Foundation\Application $app 38 | * 39 | * @return void 40 | */ 41 | public function __construct(Application $app) 42 | { 43 | $this->app = $app; 44 | } 45 | 46 | /** 47 | * Make the profile builder. 48 | * 49 | * @param array $config 50 | * 51 | * @return \Zenstruck\Backup\ProfileBuilder 52 | */ 53 | public function make(array $config): ProfileBuilder 54 | { 55 | $config = $this->getConfig($config); 56 | 57 | return $this->getProfileBuilder($config); 58 | } 59 | 60 | /** 61 | * Get the configuration data. 62 | * 63 | * @param array $config 64 | * 65 | * @throws \InvalidArgumentException 66 | * 67 | * @return array 68 | */ 69 | protected function getConfig(array $config): array 70 | { 71 | $keys = ['sources', 'destinations', 'processors', 'namers']; 72 | 73 | foreach ($keys as $key) { 74 | if (!array_key_exists($key, $config)) { 75 | throw new InvalidArgumentException("Missing configuration key [$key]."); 76 | } 77 | } 78 | 79 | return $config; 80 | } 81 | 82 | /** 83 | * Get the profile builder. 84 | * 85 | * @param array $config 86 | * 87 | * @return \Zenstruck\Backup\ProfileBuilder 88 | */ 89 | protected function getProfileBuilder(array $config): ProfileBuilder 90 | { 91 | return new ProfileBuilder( 92 | $this->bootstrap(array_get($config, 'processors')), 93 | $this->bootstrap(array_get($config, 'namers')), 94 | $this->bootstrap(array_get($config, 'sources')), 95 | $this->bootstrap(array_get($config, 'destinations')) 96 | ); 97 | } 98 | 99 | /** 100 | * Make multiple objects using the container. 101 | * 102 | * @param array $classes 103 | * 104 | * @return object[] 105 | */ 106 | protected function bootstrap(array $classes): array 107 | { 108 | foreach ($classes as $index => $class) { 109 | $classes[$index] = $this->app->make($class)->bootstrap(); 110 | } 111 | 112 | return $classes; 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /src/ProfileRegistryFactory.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | declare(strict_types=1); 13 | 14 | namespace Vinkla\Backup; 15 | 16 | use InvalidArgumentException; 17 | use Zenstruck\Backup\ProfileBuilder; 18 | use Zenstruck\Backup\ProfileRegistry; 19 | 20 | /** 21 | * This is the profile registry factory class. 22 | * 23 | * @author Vincent Klaiber 24 | */ 25 | class ProfileRegistryFactory 26 | { 27 | /** 28 | * The profile builder. 29 | * 30 | * @var \Zenstruck\Backup\ProfileBuilder 31 | */ 32 | protected $builder; 33 | 34 | /** 35 | * Create a new profile registry factory instance. 36 | * 37 | * @param \Zenstruck\Backup\ProfileBuilder $builder 38 | * 39 | * @return void 40 | */ 41 | public function __construct(ProfileBuilder $builder) 42 | { 43 | $this->builder = $builder; 44 | } 45 | 46 | /** 47 | * Make the profile registry. 48 | * 49 | * @param array $config 50 | * 51 | * @return \Zenstruck\Backup\ProfileRegistry 52 | */ 53 | public function make(array $config): ProfileRegistry 54 | { 55 | $config = $this->getConfig($config); 56 | 57 | return $this->getProfileRegistry($config); 58 | } 59 | 60 | /** 61 | * Get the configuration data. 62 | * 63 | * @param array $config 64 | * 65 | * @throws \InvalidArgumentException 66 | * 67 | * @return array 68 | */ 69 | protected function getConfig(array $config): array 70 | { 71 | if (!array_key_exists('profiles', $config)) { 72 | throw new InvalidArgumentException('Missing configuration key [profiles].'); 73 | } 74 | 75 | foreach (array_get($config, 'profiles') as $profile) { 76 | $keys = ['sources', 'destinations', 'processor', 'namer']; 77 | 78 | foreach ($keys as $key) { 79 | if (!array_key_exists($key, $profile)) { 80 | throw new InvalidArgumentException("Missing profile configuration key [$key]."); 81 | } 82 | } 83 | } 84 | 85 | return $config; 86 | } 87 | 88 | /** 89 | * Get the profile registry. 90 | * 91 | * @param array $config 92 | * 93 | * @return \Zenstruck\Backup\ProfileRegistry 94 | */ 95 | protected function getProfileRegistry(array $config): ProfileRegistry 96 | { 97 | $registry = new ProfileRegistry(); 98 | 99 | foreach (array_get($config, 'profiles') as $name => $profile) { 100 | $profile = $this->builder->create( 101 | $name, 102 | array_get($profile, 'scratch_dir', storage_path('backups')), 103 | array_get($profile, 'processor'), 104 | array_get($profile, 'namer'), 105 | array_get($profile, 'sources'), 106 | array_get($profile, 'destinations') 107 | ); 108 | 109 | $registry->add($profile); 110 | } 111 | 112 | return $registry; 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /config/backup.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | declare(strict_types=1); 13 | 14 | return [ 15 | 16 | /* 17 | |-------------------------------------------------------------------------- 18 | | Default Backup Profile 19 | |-------------------------------------------------------------------------- 20 | | 21 | | Here you may specify which of the profiles below you wish to use as 22 | | your default profile for backups. 23 | | 24 | */ 25 | 26 | 'default' => 'main', 27 | 28 | /* 29 | |-------------------------------------------------------------------------- 30 | | Backup Profiles 31 | |-------------------------------------------------------------------------- 32 | | 33 | | The profiles array allows you to setup multiple backup profiles. Example 34 | | configuration has been included, but you may add as many profiles as you 35 | | would like. 36 | | 37 | */ 38 | 39 | 'profiles' => [ 40 | 41 | 'main' => [ 42 | 'sources' => ['mysql', 'uploads'], 43 | 'destinations' => ['local'], 44 | 'processor' => 'gzip', 45 | 'namer' => 'timestamp', 46 | ], 47 | 48 | ], 49 | 50 | /* 51 | |-------------------------------------------------------------------------- 52 | | Backup Sources 53 | |-------------------------------------------------------------------------- 54 | | 55 | | What to backup (i.e. database/files). The source fetches files and copies 56 | | them to a "scratch" directory. These files are typically persisted 57 | | between backups (improves rsync performance) but can be cleared by the 58 | | executor. 59 | | 60 | */ 61 | 62 | 'sources' => [ 63 | Vinkla\Backup\Sources\MysqlDumpSource::class, 64 | Vinkla\Backup\Sources\UploadsSource::class, 65 | ], 66 | 67 | /* 68 | |-------------------------------------------------------------------------- 69 | | Backup Destinations 70 | |-------------------------------------------------------------------------- 71 | | 72 | | Where to send the backup i.e. filesystem, S3, Dropbox, etc. We have 73 | | provided a default local destination that will save the backup file 74 | | the Laravel's storage directory (storage/backups). 75 | | 76 | */ 77 | 78 | 'destinations' => [ 79 | Vinkla\Backup\Destinations\LocalDestination::class, 80 | ], 81 | 82 | /* 83 | |-------------------------------------------------------------------------- 84 | | Backup Processors 85 | |-------------------------------------------------------------------------- 86 | | 87 | | The processors converts the backup to a single file (i.e. zip/tar.gz). 88 | | The processors use a namer to name the file (read more below). 89 | | 90 | */ 91 | 92 | 'processors' => [ 93 | Vinkla\Backup\Processors\GzipProcessor::class, 94 | Vinkla\Backup\Processors\ZipProcessor::class, 95 | ], 96 | 97 | /* 98 | |-------------------------------------------------------------------------- 99 | | Backup Namers 100 | |-------------------------------------------------------------------------- 101 | | 102 | | Generates the backup filename to be used by the processors. Below we've 103 | | provided default namers. Of course, you may setup custom namers. 104 | | 105 | */ 106 | 107 | 'namers' => [ 108 | Vinkla\Backup\Namers\SimpleNamer::class, 109 | Vinkla\Backup\Namers\TimestampNamer::class, 110 | ], 111 | 112 | ]; 113 | -------------------------------------------------------------------------------- /src/BackupServiceProvider.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | declare(strict_types=1); 13 | 14 | namespace Vinkla\Backup; 15 | 16 | use Illuminate\Contracts\Container\Container; 17 | use Illuminate\Foundation\Application as LaravelApplication; 18 | use Illuminate\Support\ServiceProvider; 19 | use Laravel\Lumen\Application as LumenApplication; 20 | use Vinkla\Backup\Sources\MysqlDumpSource; 21 | use Zenstruck\Backup\Executor; 22 | use Zenstruck\Backup\ProfileBuilder; 23 | use Zenstruck\Backup\ProfileRegistry; 24 | 25 | /** 26 | * This is the backup service provider class. 27 | * 28 | * @author Vincent Klaiber 29 | */ 30 | class BackupServiceProvider extends ServiceProvider 31 | { 32 | /** 33 | * Boot the service provider. 34 | * 35 | * @return void 36 | */ 37 | public function boot() 38 | { 39 | $this->setupConfig(); 40 | } 41 | 42 | /** 43 | * Setup the config. 44 | * 45 | * @return void 46 | */ 47 | protected function setupConfig() 48 | { 49 | $source = realpath(__DIR__.'/../config/backup.php'); 50 | 51 | if ($this->app instanceof LaravelApplication && $this->app->runningInConsole()) { 52 | $this->publishes([$source => config_path('backup.php')]); 53 | } elseif ($this->app instanceof LumenApplication) { 54 | $this->app->configure('backup'); 55 | } 56 | 57 | $this->mergeConfigFrom($source, 'backup'); 58 | } 59 | 60 | /** 61 | * Register the service provider. 62 | * 63 | * @return void 64 | */ 65 | public function register() 66 | { 67 | $this->registerExecutor(); 68 | $this->registerProfileBuilder(); 69 | $this->registerProfileRegistry(); 70 | $this->registerMysqlDumpSource(); 71 | $this->registerBackup(); 72 | } 73 | 74 | /** 75 | * Register the executor class. 76 | * 77 | * @return void 78 | */ 79 | protected function registerExecutor() 80 | { 81 | $this->app->singleton('backup.executor', function (Container $app) { 82 | $logger = $app['log']; 83 | 84 | return new Executor($logger); 85 | }); 86 | 87 | $this->app->alias('backup.executor', Executor::class); 88 | } 89 | 90 | /** 91 | * Register the profile builder class. 92 | * 93 | * @return void 94 | */ 95 | protected function registerProfileBuilder() 96 | { 97 | $this->app->singleton('backup.builder', function (Container $app) { 98 | $config = $app['config']['backup']; 99 | 100 | $factory = new ProfileBuilderFactory($app); 101 | 102 | return $factory->make($config); 103 | }); 104 | 105 | $this->app->alias('backup.builder', ProfileBuilder::class); 106 | } 107 | 108 | /** 109 | * Register the profile registry class. 110 | * 111 | * @return void 112 | */ 113 | protected function registerProfileRegistry() 114 | { 115 | $this->app->singleton('backup.registry', function (Container $app) { 116 | $config = $app['config']['backup']; 117 | $builder = $app['backup.builder']; 118 | 119 | $factory = new ProfileRegistryFactory($builder); 120 | 121 | return $factory->make($config); 122 | }); 123 | 124 | $this->app->alias('backup.registry', ProfileRegistry::class); 125 | } 126 | 127 | /** 128 | * Register the database source class. 129 | * 130 | * @return void 131 | */ 132 | protected function registerMysqlDumpSource() 133 | { 134 | $this->app->bind(MysqlDumpSource::class, function (Container $app) { 135 | $config = $app['config']; 136 | 137 | return new MysqlDumpSource($config); 138 | }); 139 | } 140 | 141 | /** 142 | * Register the backup class. 143 | * 144 | * @return void 145 | */ 146 | protected function registerBackup() 147 | { 148 | $this->app->singleton('backup', function (Container $app) { 149 | $config = $app['config']; 150 | $registry = $app['backup.registry']; 151 | $executor = $app['backup.executor']; 152 | 153 | return new Backup($config, $registry, $executor); 154 | }); 155 | 156 | $this->app->alias('backup', Backup::class); 157 | } 158 | 159 | /** 160 | * Get the services provided by the provider. 161 | * 162 | * @return string[] 163 | */ 164 | public function provides(): array 165 | { 166 | return [ 167 | 'backup', 168 | 'backup.builder', 169 | 'backup.executor', 170 | 'backup.registry', 171 | ]; 172 | } 173 | } 174 | --------------------------------------------------------------------------------