[core] fix #1176 sync check with HTTP long polling

Set client configuration option `sync` to enable auto sync.

Example
```javascript
var options = {
    url  : 'php/connector.php',
    sync : 10000  // Checks every 10sec
}
$('#elfinder').elfinder(options);
```

And added new volume driver root options this time.

```php
// Is support parent directory time stamp update on add|remove|rename item
// Default `null` is auto detection that is LocalFileSystem, FTP or
// Dropbox are `true`
'syncChkAsTs'  => null,

// Long pooling sync checker function for syncChkAsTs is true
// Calls with args (TARGET DIRCTORY PATH, STAND-BY(sec), OLD TIMESTAMP, VOLUME DRIVER INSTANCE, ELFINDER INSTANCE)
// This function must return the following values. Changed: New Timestamp or Same: Old Timestamp or Error: false
// Default `null` is try use
// elFinderVolumeLocalFileSystem::localFileSystemInotify() on LocalFileSystem driver
// another driver use elFinder stat() checker
'syncCheckFunc'=> null,

// Long polling sync stand-by time (sec)
'plStandby'    => 30,

// Sleep time (sec) for elFinder stat() checker (syncChkAsTs is true)
'tsPlSleep'    => 10,

// Sleep time (sec) for elFinder ls() checker (syncChkAsTs is false)
'lsPlSleep'    => 30,

// Client side sync interval minimum (ms)
// Default `null` is auto set to ('tsPlSleep' or 'lsPlSleep') * 1000
'syncMinMs'    => null,
```
This commit is contained in:
nao-pon
2016-01-08 16:15:25 +09:00
parent 5243ac33a3
commit e23f80ab38
6 changed files with 362 additions and 37 deletions
@@ -76,6 +76,14 @@ class elFinderVolumeLocalFileSystem extends elFinderVolumeDriver {
if (!empty($this->options['startPath'])) {
$this->options['startPath'] = $this->getFullPath($this->options['startPath'], $cwd);
}
if (is_null($this->options['syncChkAsTs'])) {
$this->options['syncChkAsTs'] = true;
}
if (is_null($this->options['syncCheckFunc'])) {
$this->options['syncCheckFunc'] = array($this, 'localFileSystemInotify');
}
return true;
}
@@ -148,6 +156,56 @@ class elFinderVolumeLocalFileSystem extends elFinderVolumeDriver {
}
}
/**
* Long pooling sync checker
* This function require server command `inotifywait`
* If `inotifywait` need full path, Please add `define('ELFINER_INOTIFYWAIT_PATH', '/PATH_TO/inotifywait');` into connector.php
*
* @param string $path
* @param int $standby
* @param number $compare
* @return number|bool
*/
public function localFileSystemInotify($path, $standby, $compare) {
if (isset($this->sessionCache['localFileSystemInotify_disable'])) {
return false;
}
$path = realpath($path);
$mtime = filemtime($path);
if ($mtime != $compare) {
return $mtime;
}
$inotifywait = defined('ELFINER_INOTIFYWAIT_PATH')? ELFINER_INOTIFYWAIT_PATH : 'inotifywait';
$path = escapeshellarg($path);
$standby = max(1, intval($standby));
$cmd = $inotifywait.' '.$path.' -t '.$standby.' -e moved_to,moved_from,move,create,delete,delete_self';
$o = $r = '';
$this->procExec($cmd , $o, $r);
if ($r === 0) {
// changed
clearstatcache();
return filemtime($path);
} else if ($r === 2) {
// not changed (timeout)
return $compare;
}
// error
// cache to $_SESSION
$sessionClose = true;;
try {
$sessionStart = session_start();
} catch (Exception $e) {
$sessionClose = false;
}
if ($sessionStart) {
$this->sessionCache = &$_SESSION[elFinder::$sessionCacheKey][$this->id];
$this->sessionCache['localFileSystemInotify_disable'] = true;
$sessionClose && session_write_close();
}
return false;
}
/*********************************************************************/
/* FS API */
/*********************************************************************/