2016-07-22 20:00:27 +00:00
|
|
|
<?php
|
|
|
|
|
2018-05-23 10:14:20 +00:00
|
|
|
require_once(__DIR__.'/util.php');
|
2016-07-22 20:00:27 +00:00
|
|
|
|
|
|
|
/**
|
2020-08-29 11:06:54 +00:00
|
|
|
* Syncronizes the data directory with the database, this may take some time.
|
2017-05-08 15:54:35 +00:00
|
|
|
*/
|
2018-05-23 10:14:20 +00:00
|
|
|
class Sync extends Vn\Lib\Method {
|
2016-07-22 20:00:27 +00:00
|
|
|
private $trashSubdir;
|
2016-08-25 10:47:09 +00:00
|
|
|
private $util;
|
|
|
|
|
2018-05-23 10:14:20 +00:00
|
|
|
function __construct($app) {
|
|
|
|
parent::__construct($app);
|
|
|
|
$this->util = new Util($app);
|
2016-08-25 10:47:09 +00:00
|
|
|
$this->dataDir = $this->util->dataDir;
|
|
|
|
}
|
2016-07-22 20:00:27 +00:00
|
|
|
|
2018-05-23 10:14:20 +00:00
|
|
|
function run($db) {
|
|
|
|
$db = $this->getSysConn();
|
2016-07-22 20:00:27 +00:00
|
|
|
|
2018-05-23 10:14:20 +00:00
|
|
|
set_time_limit(0);
|
|
|
|
$this->trashSubdir = date('YmdHis');
|
2016-07-22 20:00:27 +00:00
|
|
|
|
2020-08-29 11:06:54 +00:00
|
|
|
$deleteCount = 0;
|
2018-05-23 10:14:20 +00:00
|
|
|
$dir = opendir($this->dataDir);
|
2020-08-29 11:06:54 +00:00
|
|
|
|
2016-07-22 20:00:27 +00:00
|
|
|
if ($dir)
|
2020-08-29 11:06:54 +00:00
|
|
|
while ($collection = readdir($dir))
|
|
|
|
if (!in_array($collection, ['.', '..'])) {
|
|
|
|
$info = $this->util->loadInfo($collection);
|
|
|
|
$collectionPath = "{$this->dataDir}/$collection";
|
|
|
|
|
|
|
|
// Deletes unreferenced collections.
|
|
|
|
|
2018-05-23 10:14:20 +00:00
|
|
|
if (!isset($info)) {
|
2020-08-29 11:06:54 +00:00
|
|
|
$this->recycle($collection);
|
2016-07-22 20:00:27 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Deletes unreferenced sizes.
|
|
|
|
|
2020-08-29 11:06:54 +00:00
|
|
|
$collectionDir = opendir($collectionPath);
|
2016-07-22 20:00:27 +00:00
|
|
|
|
2020-08-29 11:06:54 +00:00
|
|
|
if ($collectionDir)
|
|
|
|
while ($size = readdir($collectionDir))
|
2018-05-23 10:14:20 +00:00
|
|
|
if (!in_array($size, ['.', '..', 'full'])
|
|
|
|
&& !isset($info['sizes'][$size]))
|
2020-08-29 11:06:54 +00:00
|
|
|
$this->recycle("$collection/$size");
|
2016-07-22 20:00:27 +00:00
|
|
|
|
2020-08-29 11:06:54 +00:00
|
|
|
// Deletes unreferenced images.
|
2016-07-22 20:00:27 +00:00
|
|
|
|
2020-08-29 11:48:32 +00:00
|
|
|
try {
|
|
|
|
$db->query('START TRANSACTION');
|
|
|
|
$res = $db->query(
|
|
|
|
'SELECT id, `name`, collectionFk
|
|
|
|
FROM `image`
|
|
|
|
WHERE nRefs = 0 AND collectionFk = #collection
|
|
|
|
FOR UPDATE',
|
|
|
|
['collection' => $collection]
|
|
|
|
);
|
|
|
|
|
2020-08-29 11:54:38 +00:00
|
|
|
if ($res->num_rows == 0) continue;
|
|
|
|
echo "Deleting {$res->num_rows} from collection '$collection'.\n";
|
|
|
|
|
2020-08-29 11:48:32 +00:00
|
|
|
while ($image = $res->fetch_object())
|
2020-08-29 11:54:38 +00:00
|
|
|
if (!empty($image->name) && !in_array($image->name, ['.', '..'])) {
|
2020-08-29 11:48:32 +00:00
|
|
|
$deleteCount++;
|
|
|
|
$this->recycle("$collection/full/{$image->name}.png");
|
|
|
|
|
|
|
|
foreach ($info['sizes'] as $size => $i)
|
|
|
|
$this->recycle("$collection/$size/{$image->name}.png");
|
|
|
|
|
|
|
|
$db->query(
|
|
|
|
'DELETE FROM `image`
|
|
|
|
WHERE nRefs = 0 AND id = #id',
|
|
|
|
['id' => $image->id]
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
$res->free();
|
|
|
|
$db->query('COMMIT');
|
|
|
|
} catch(Exception $e) {
|
|
|
|
$db->query('ROLLBACK');
|
2020-08-29 11:54:38 +00:00
|
|
|
throw $e;
|
2016-07-22 20:00:27 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-29 11:06:54 +00:00
|
|
|
echo "Syncronization finished. $deleteCount images moved to trash.\n";
|
2016-07-22 20:00:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2020-08-29 11:06:54 +00:00
|
|
|
* Moves data file to trash.
|
2016-07-22 20:00:27 +00:00
|
|
|
*
|
2020-08-29 11:06:54 +00:00
|
|
|
* @param string $file File or directory to move
|
2017-05-08 15:54:35 +00:00
|
|
|
*/
|
2020-08-29 11:06:54 +00:00
|
|
|
function recycle($file) {
|
|
|
|
$filePath = "{$this->dataDir}/$file";
|
|
|
|
if (!file_exists($filePath)) return;
|
|
|
|
|
2018-07-20 14:30:29 +00:00
|
|
|
$trashBasedir = "{$this->dataDir}/.trash/". $this->trashSubdir;
|
2018-05-23 10:14:20 +00:00
|
|
|
$trashdir = "$trashBasedir/". dirname($file);
|
2016-07-22 20:00:27 +00:00
|
|
|
|
2018-05-23 10:14:20 +00:00
|
|
|
if (!is_dir($trashdir))
|
|
|
|
mkdir($trashdir, 0775, TRUE);
|
2016-07-22 20:00:27 +00:00
|
|
|
|
2018-05-23 10:14:20 +00:00
|
|
|
rename(
|
2020-08-29 11:06:54 +00:00
|
|
|
"$filePath",
|
2016-07-22 20:00:27 +00:00
|
|
|
"$trashBasedir/$file"
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|