Skip to content

Commit

Permalink
dimsav#5 New Feature: Can remove older backups in relative PHP dateti…
Browse files Browse the repository at this point in the history
…me format

- Local filesystem supported
- Dropbox supported
  • Loading branch information
markitosgv committed Jul 20, 2014
1 parent cf4c633 commit b225c26
Show file tree
Hide file tree
Showing 5 changed files with 141 additions and 7 deletions.
4 changes: 3 additions & 1 deletion config/config.ini.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,14 @@
"my_dropbox" => array(
"driver" => "dropbox",
"username" => "[email protected]",
"destination" => "/Backups"
"destination" => "/Backups",
"clean" => "-7 days", //All relative formats. Ex "last monday" :: http://php.net/manual/en/datetime.formats.relative.php
),

"my_system" => array(
"driver" => "local",
"destination" => "/backups",
"clean" => "-7 days", //All relative formats. Ex "last monday" :: http://php.net/manual/en/datetime.formats.relative.php
),
),

Expand Down
5 changes: 5 additions & 0 deletions src/Dimsav/Backup/Shell.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,9 @@ public function getStatusCode()
{
return $this->statusCode;
}

public function cleanOutput()
{
$this->output = null;
}
}
66 changes: 63 additions & 3 deletions src/Dimsav/Backup/Storage/Drivers/Dropbox.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ class Dropbox implements Storage
private $destination;
private $name;
private $username;
private $clean;

/**
* @var Shell
Expand All @@ -26,18 +27,48 @@ public function __construct(array $config, Shell $shell)

public function store($file, $projectName = null)
{
$file = new \SplFileInfo($file);
$prefix = ($file->getExtension() == "sql") ? "sql" : "files";

$this->validate();
$this->validateFile($file);
$this->shell->exec($this->getCommand($file, $projectName));
$this->shell->exec($this->getCommand($file, $projectName, $prefix));

$this->cleanOldBackups($projectName, $prefix);
}

public function getCommand($file, $projectName)
private function cleanOldBackups($projectName, $prefix)
{
$destination = $projectName ? $this->destination . "/$projectName" : $this->destination;
//clean shell output
$this->shell->cleanOutput();

//clean old backups
$this->shell->exec($this->getFileListCommand($projectName, $prefix));
$deleteList = $this->parseFiles($this->shell->getOutput());

foreach ($deleteList as $file) {
$this->shell->exec($this->removeCommand($projectName, $file, $prefix));
}
}

public function getCommand($file, $projectName, $prefix)
{

$destination = $projectName ? $this->destination . "/$projectName". "/". $prefix : $this->destination ."/". $prefix;
$destination .= substr($destination, -1, 1) == '/' ? basename($file) : '/' . basename($file);
return $this->getScript().' -f '.$this->getConfigFile()." upload $file " . $destination;
}

public function getFileListCommand($projectName, $prefix)
{
return $this->getScript().' -f '.$this->getConfigFile()." list ". $this->destination . "/$projectName"."/".$prefix;
}

private function removeCommand($projectName, $file, $prefix)
{
return $this->getScript().' -f '.$this->getConfigFile()." delete ". $this->destination . "/$projectName"."/".$prefix."/".$file;
}

/**
* @return void
* @throws \Dimsav\Backup\Storage\Exceptions\TokenNotSetException
Expand Down Expand Up @@ -102,5 +133,34 @@ private function setProperties(array $config)
$this->name = isset($config['name']) ? $config['name'] : null;
$this->username = isset($this->config['username']) ? $this->config['username'] : null;
$this->destination = isset($config['destination']) ? $config['destination'] : '/';
$this->clean = isset($config['clean']) ? $config['clean'] : '365 days';
}

private function parseFiles($data)
{
$deleteList = array();
$data = explode("[F]", $data);
$data = array_slice($data, 1);

foreach ($data as $file) {

preg_match('([\s-]\S{1,})', ltrim($file), $filename);
$filename = ltrim($filename[0]);

preg_match('([\s-]\S{1,16})', ltrim($file), $result);
$date = explode("_", $result[0]);
$time = str_replace("-",":",$date[1]);
$date = $date[0];
$datetime = new \DateTime($date.$time);
$today = new \DateTime();

$today->modify($this->clean);
if ($datetime < $today) {
$deleteList[] = $filename;
}
}

return $deleteList;
}

}
71 changes: 69 additions & 2 deletions src/Dimsav/Backup/Storage/Drivers/Local.php
Original file line number Diff line number Diff line change
@@ -1,22 +1,31 @@
<?php namespace Dimsav\Backup\Storage\Drivers;

use Dimsav\Backup\Shell;
use Dimsav\Backup\Storage\Exceptions\InvalidStorageException;
use Dimsav\Backup\Storage\Storage;

class Local implements Storage {

private $name;
private $destination;
private $clean;

public function __construct(array $config)
/**
* @var Shell
*/
private $shell;

public function __construct(array $config, Shell $shell)
{
$this->shell = $shell;
$this->setProperties($config);
}

private function setProperties(array $config)
{
$this->name = isset($config['name']) ? $config['name'] : null;
$this->destination = $this->getDestination($config);
$this->clean = isset($config['clean']) ? $config['clean'] : '365 days';
}

private function getDestination($config)
Expand All @@ -42,7 +51,11 @@ public function store($file, $projectName = null)
$this->validate();
$this->validateFile($file);

$exportDir = $this->destination . '/' . $projectName;
$file = new \SplFileInfo($file);

$prefix = ($file->getExtension() == "sql") ? "sql" : "files";

$exportDir = $this->destination . '/' . $projectName. "/". $prefix;
if ($projectName && ! is_dir($exportDir))
{
mkdir($exportDir, 0777, true);
Expand All @@ -51,6 +64,33 @@ public function store($file, $projectName = null)
// we don't want to move the file for the case we have more storages

copy($file, $exportDir . '/' . basename($file));

$this->cleanOldBackups($projectName, $prefix);
}

private function cleanOldBackups($projectName, $prefix)
{
//clean shell output
$this->shell->cleanOutput();

//clean old backups
$this->shell->exec($this->getFileListCommand($projectName, $prefix));

$deleteList = $this->parseFiles($this->shell->getOutput());

foreach ($deleteList as $file) {
$this->shell->exec($this->removeCommand($projectName, $file, $prefix));
}
}

public function getFileListCommand($projectName, $prefix)
{
return "ls ". $this->destination . "/$projectName"."/".$prefix." | tr '\n' '\n' | sed 's/$/|||/g'";
}

private function removeCommand($projectName, $file, $prefix)
{
return " rm ". $this->destination . "/$projectName"."/".$prefix."/".$file;
}

/**
Expand Down Expand Up @@ -79,4 +119,31 @@ private function validateFile($file)
throw new \InvalidArgumentException("Local storage '{$this->name}' could not find the file '$file'.");
}
}

private function parseFiles($data)
{
$deleteList = array();
$data = explode("|||", $data);
array_pop($data);

foreach ($data as $file) {

$filename = $file;

preg_match('(\S{1,16})', ltrim($file), $result);
$date = explode("_", $result[0]);
$time = str_replace("-",":",$date[1]);
$date = $date[0];

$datetime = new \DateTime($date.$time);
$today = new \DateTime();

$today->modify($this->clean);
if ($datetime < $today) {
$deleteList[] = $filename;
}
}

return $deleteList;
}
}
2 changes: 1 addition & 1 deletion src/Dimsav/Backup/Storage/StorageFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ private function createStorage($storageName)
case 'dropbox':
return new Dropbox($this->getDriverConfig($storageName), new Shell());
case 'local':
return new Local($this->getDriverConfig($storageName));
return new Local($this->getDriverConfig($storageName), new Shell());
}
throw new StorageDriverNotSupportedException;
}
Expand Down

0 comments on commit b225c26

Please sign in to comment.