/** * Syncronize with remote server if $opt[remote_server] (self::$sync[server]) is set. * Local path is $opt[cwd]|getcwd().'/'.$this->path. * Remote path is $opt[remote_server]|self::$sync[server].'/'.$opt[remote_path]|self::$sync[cwd].'/'.$opt[remote_file]|$this->path * Auto create local file directory if necessary. Retrieve remote md5 with remote_server.'/'.self::$sync[bin]?path=remote_file. * If $this->json_format is set save file information to local_file.json. Use md5_old to avoid unnecessary downloads. * * @param map $opt see constructor * */ public function synchronize($opt) { if (is_null($this->path) || mb_strlen($this->path) == 0) { throw new Exception('empty path'); } if (empty(self::$sync['server']) && empty($opt['remote_server'])) { return; } try { $cwd = empty($opt['cwd']) ? getcwd() : $opt['cwd']; $rserver = empty($opt['remote_server']) ? self::$sync['server'] : $opt['remote_server']; $rfile = empty($opt['remote_file']) ? $this->path : $opt['remote_file']; $rpath = ''; if (isset($opt['remote_path'])) { $rpath = $opt['remote_path']; } else { if (!empty(self::$sync['cwd'])) { $rpath = self::$sync['cwd']; } } $this->remote_path = empty($rpath) ? $rfile : $rpath . '/' . $rfile; $dir = $cwd . '/' . dirname($this->path); if (!Dir::exists($dir)) { Dir::create($dir, 0, true); } $this->path_absolute = empty(realpath($dir)) ? $dir . '/' . $this->path : realpath($dir) . '/' . basename($this->path); $file_exists = File::exists($this->path_absolute); if (empty(self::$sync['bin']) && ($file_exists || !empty($this->json_format))) { throw new Exception('missing sync.bin', print_r(self::$sync, true)); } else { $server_bin = $rserver . '/' . self::$sync['bin']; } if (!empty($this->json_format)) { $json_file = $this->path_absolute . '.json'; if (File::exists($json_file)) { $this->scanJSON(); } $json_query = $server_bin . '?format=' . $this->json_format . '&path=' . urlencode($this->remote_path); try { $remote_json_str = File::fromURL($json_query); $remote_json = JSON::decode($remote_json_str); } catch (Exception $e) { throw new Exception('failed to retrive file information', "query={$json_query} result={$remote_json_str}"); } if ($this->md5 != $remote_json['md5']) { File::save($json_file, $remote_json_str); $this->scanJSON($remote_json); $this->is_modified = 1; } else { $this->is_modified = 0; } } else { if (!$file_exists) { File::save($this->path_absolute, File::fromURL($rserver . '/' . $this->remote_path)); $this->is_modified = 1; $this->scanFile(); } else { $this->scanFile(); $remote_json = JSON::decode(File::fromURL($server_bin . '?path=' . urlencode($this->remote_path))); if (empty($remote_json['md5'])) { throw new Exception('remote md5 missing', print_r($remote_json, true)); } if ($remote_json['md5'] != $this->md5) { File::save($this->path_absolute, File::fromURL($rserver . '/' . $this->remote_path)); $this->is_modified = 1; $this->scanFile(); } else { $this->is_modified = 0; } } } $this->is_synchronized = 1; } catch (Exception $e) { if (!empty(self::$sync['abort'])) { throw $e; } else { $this->is_synchronized = 0; } } }