Skip to content

Instantly share code, notes, and snippets.

@mungurs
Created December 14, 2016 11:55
Show Gist options
  • Save mungurs/1d2187332fdb5e72e64ada18a8fd9f3a to your computer and use it in GitHub Desktop.
Save mungurs/1d2187332fdb5e72e64ada18a8fd9f3a to your computer and use it in GitHub Desktop.
elFinder file sync. with db
<?php
class leafFileSync{
private $enableLog = false;
public function __construct($logSynchronization = false){
$this->enableLog = $logSynchronization;
}
public function sync($cmd, $result, $args, elFinder $elFinder, elFinderVolumeDriver $volume){
$cmd = $cmd;
switch ($cmd) {
case 'rename':
foreach($result['added'] as $key => $newFile){
$this->move($newFile, $result['removed'][$key], $result, $args, $elFinder, $volume);
}
break;
case 'paste':
$this->paste($result, $args, $elFinder, $volume);
break;
case 'upload':
case 'duplicate':
$added = $this->removeDuplicates($result['added']);
foreach ($added as $file) {
$this->added($file, $result, $args, $elFinder, $volume);
}
break;
case 'rm':
foreach ($result['removed'] as $file) {
$this->removed($file, $result, $args, $elFinder, $volume);
}
break;
default:
//nothing
}
}
private function added($file, $result, $args, elFinder $elFinder, elFinderVolumeDriver $volume){
if( $file['mime'] == 'directory' ){
//skip directory, we save only files in db
return false;
}
$absPath = $elFinder->realpath($file['hash']);
// On upload user can overwrite old files with new ones
// In this case we do not delete the old file and its relations from db, only allow to overwrite its contents
$existingFile = leafFile::getByPath( $this->getLeafFilePath( $absPath ) ) ;
if($existingFile){
return false;
}
$fileVars = [
'path' => $this->getLeafFilePath($absPath), //relative to file dir
'originalName' => $file['name'],
'type' => $file['mime']
];
$leafFile = new leafFile();
$leafFile->assignData($fileVars);
$leafFile->save();
$this->log($absPath , 'Added');
}
private function move($newFile, $oldFile, $result, $args, elFinder $elFinder, elFinderVolumeDriver $volume){
$absPath = $newFile['realpath'];
if( $newFile['mime'] == 'directory' ){
//update folder name in file paths
$oldPath = $this->getLeafFilePath($oldFile['realpath'] . DIRECTORY_SEPARATOR);
$newPath = $this->getLeafFilePath($elFinder->realpath($newFile['hash']) . DIRECTORY_SEPARATOR);
//replace old file paths to new
$q = "UPDATE " . leafFile::tableName .
" SET path = REPLACE(path, '".$oldPath."', '".$newPath."') ".
" WHERE path LIKE '" . $oldPath . "%';";
$res = dbQuery($q);
}else{
$oldPath = $this->getLeafFilePath($oldFile['realpath']); // removed files have realPath already set
$newPath = $this->getLeafFilePath($elFinder->realpath($newFile['hash']));
//check if file is overwriting other file in dest. folder
$existingFile = leafFile::getByPath($newFile);
if($existingFile){
$existingFile->delete();
}
$file = leafFile::getByPath($oldPath);
if($file){
$file->path = $newPath;
$file->save();
}
}
$this->log($absPath , 'Rename');
}
private function removed($file, $result, $args, elFinder $elFinder, elFinderVolumeDriver $volume){
$absPath = $file['realpath'];
if($file['mime'] == 'directory'){
//get all files in the directory and delete them
$dirFiles = leafFile::getByDir($this->getLeafFilePath($absPath . DIRECTORY_SEPARATOR));
foreach ($dirFiles as $dirFile){
$dirFile->delete();
}
}else{
//single file
$file = leafFile::getByPath($this->getLeafFilePath($absPath));
if($file){
$file->delete();
}
}
$this->log($absPath , 'Removed');
}
private function paste($result, $args, elFinder $elFinder, elFinderVolumeDriver $volume){
$add = $this->removeDuplicates($result['added']);
$remove = $result['removed'];
$move = [];
//check if removed items are moved
foreach ($remove as $removeKey => $revVal){
foreach ($add as $addKey => $addVal){
if($revVal['name'] === $addVal['name'] && $revVal['size'] === $addVal['size']){
//register moved files, we will need both the new and old file info.
$move[] = [
'added' => $add[$addKey],
'removed' => $remove[$removeKey]
];
unset($add[$addKey]);
unset($remove[$removeKey]);
}
}
}
foreach ($add as $item){
$this->added($item, $result, $args, $elFinder, $volume);
}
foreach ($remove as $item){
$this->removed($item, $result, $args, $elFinder, $volume);
}
foreach ($move as $item){
$this->move($item['added'], $item['removed'], $result, $args, $elFinder, $volume);
}
}
// When single file is "duplicated" elFinder will return two files new files with equal paths
// TODO: Fix it or wait for lib. update
private function removeDuplicates($added){
//removes duplicate array elements
$unique = array_map("unserialize", array_unique(array_map("serialize", $added)));
return $unique;
}
private function log($pathString, $method){
if($this->enableLog){
dumpToFile($method . ':' . $pathString);
}
}
/** Returns valid path for leafFile from absolute path
* @param $absPath
* @return mixed
*/
private function getLeafFilePath($absPath){
return fileManagerFacade::getRelativeFilePath($absPath);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment