View source
<?php
namespace BackupMigrate\Core\Destination;
use BackupMigrate\Core\Config\ConfigurableInterface;
use BackupMigrate\Core\Exception\DestinationNotWritableException;
use BackupMigrate\Core\Plugin\FileProcessorInterface;
use BackupMigrate\Core\File\BackupFile;
use BackupMigrate\Core\File\BackupFileInterface;
use BackupMigrate\Core\File\BackupFileReadableInterface;
use BackupMigrate\Core\File\ReadableStreamBackupFile;
class DirectoryDestination extends DestinationBase implements ListableDestinationInterface, ReadableDestinationInterface, ConfigurableInterface, FileProcessorInterface {
use SidecarMetadataDestinationTrait;
function saveFile(BackupFileReadableInterface $file) {
$this
->_saveFile($file);
$this
->_saveFileMetadata($file);
}
public function checkWritable() {
$this
->checkDirectory();
}
public function configSchema($params = []) {
$schema = [];
if ($params['operation'] == 'initialize') {
$schema['fields']['directory'] = [
'type' => 'text',
'title' => $this
->t('Directory Path'),
];
}
return $schema;
}
function _saveFile(BackupFileReadableInterface $file) {
$this
->checkDirectory();
copy($file
->realpath(), $this
->_idToPath($file
->getFullName()));
}
protected function checkDirectory() {
$dir = $this
->confGet('directory');
if (!file_exists($dir)) {
throw new DestinationNotWritableException("The backup file could not be saved to '%dir' because it does not exist.", [
'%dir' => $dir,
]);
}
if (!is_writable($this
->confGet('directory'))) {
throw new DestinationNotWritableException("The backup file could not be saved to '%dir' because Backup and Migrate does not have write access to that directory.", [
'%dir' => $dir,
]);
}
}
public function getFile($id) {
if ($this
->fileExists($id)) {
$out = new BackupFile();
$out
->setMeta('id', $id);
$out
->setFullName($id);
return $out;
}
return NULL;
}
public function loadFileForReading(BackupFileInterface $file) {
if ($file instanceof BackupFileReadableInterface) {
return $file;
}
$id = $file
->getMeta('id');
if ($this
->fileExists($id)) {
return new ReadableStreamBackupFile($this
->_idToPath($id));
}
return NULL;
}
public function listFiles() {
$dir = $this
->confGet('directory');
$out = [];
$files = $this
->_getAllFileNames();
foreach ($files as $file) {
$filepath = $dir . '/' . $file;
$out[$file] = new ReadableStreamBackupFile($filepath);
}
return $out;
}
public function queryFiles($filters = [], $sort = 'datestamp', $sort_direction = SORT_DESC, $count = 100, $start = 0) {
$out = $this
->listFiles($count + $start);
foreach ($out as $key => $file) {
$out[$key] = $this
->loadFileMetadata($file);
}
if ($filters) {
$out = array_filter($out, function ($file) use ($filters) {
foreach ($filters as $key => $value) {
if ($file
->getMeta($key) !== $value) {
return FALSE;
}
}
return TRUE;
});
}
if ($sort && $sort_direction) {
uasort($out, function ($a, $b) use ($sort, $sort_direction) {
if ($sort_direction == SORT_DESC) {
return $b
->getMeta($sort) < $b
->getMeta($sort);
}
else {
return $b
->getMeta($sort) > $b
->getMeta($sort);
}
});
}
if ($count || $start) {
$out = array_slice($out, $start, $count);
}
return $out;
}
public function countFiles() {
$files = $this
->_getAllFileNames();
return count($files);
}
public function fileExists($id) {
return file_exists($this
->_idToPath($id));
}
public function _deleteFile($id) {
if ($file = $this
->getFile($id)) {
if ($file = $this
->loadFileForReading($file)) {
return unlink($file
->realpath());
}
}
return FALSE;
}
protected function _idToPath($id) {
return rtrim($this
->confGet('directory'), '/') . '/' . $id;
}
protected function _getAllFileNames() {
$files = [];
$dir = $this
->confGet('directory');
$fileSystem = \Drupal::service('file_system');
$scheme = $fileSystem
->uriScheme($dir);
if (!$fileSystem
->validScheme($scheme)) {
drupal_set_message(t('Your @scheme stream is not configured.', [
'@scheme' => $scheme . '://',
]), 'warning');
return $files;
}
if ($handle = opendir($dir)) {
while (FALSE !== ($file = readdir($handle))) {
$filepath = $dir . '/' . $file;
if (substr($file, 0, 1) !== '.' && is_readable($filepath) && substr($file, strlen($file) - 5) !== '.info') {
$files[] = $file;
}
}
}
return $files;
}
}