';
}
}
/**
* Load profiles from serialized storage
*/
function _profileLoad(){
global $conf;
$profiles = $conf['metadir'].'/sync.profiles';
if(file_exists($profiles)){
$this->profiles = unserialize(io_readFile($profiles,false));
}
}
/**
* Save profiles to serialized storage
*/
function _profileSave(){
global $conf;
$profiles = $conf['metadir'].'/sync.profiles';
io_saveFile($profiles,serialize($this->profiles));
}
/**
* Check connection for choosen profile and display last sync date.
*/
function _profileView(){
if(!$this->_connect()) return false;
global $conf;
$no = $this->profno;
$ok = $this->client->query('dokuwiki.getVersion');
$version = '';
if($ok) $version = $this->client->getResponse();
echo '';
}
/**
* Dropdown list of available sync profiles
*/
function _profilelist($no=''){
echo '';
}
/**
* Form to edit or create a sync profile
*/
function _profileform($no=''){
echo '';
}
/**
* Lock files that will be modified on either side.
*
* Lock fails are printed and removed from synclist
*
* @returns list of locked files
*/
function _lockFiles(&$synclist){
if(!$this->_connect()) return array();
// lock the files
$lock = array();
foreach((array) $synclist as $id => $dir){
if($dir == 0) continue;
if(checklock($id)){
$this->_listOut($this->getLang('lockfail').' '.hsc($id),'error');
unset($synclist[$id]);
}else{
lock($id); // lock local
$lock[] = $id;
}
}
// lock remote files
$ok = $this->client->query('dokuwiki.setLocks',array('lock'=>$lock,'unlock'=>array()));
if(!$ok){
$this->_listOut('failed RPC communication');
$synclist = array();
return array();
}
$data = $this->client->getResponse();
foreach((array) $data['lockfail'] as $id){
$this->_listOut($this->getLang('lockfail').' '.hsc($id),'error');
unset($synclist[$id]);
}
return $lock;
}
/**
* Print a message as list item using the given class
*/
function _listOut($msg,$class='ok'){
echo '
';
echo hsc($msg);
echo "
\n";
flush();
ob_flush();
}
/**
* Execute the sync action and print the results
*/
function _sync(&$synclist,$type){
if(!$this->_connect()) return false;
$no = $this->profno;
$sum = $_REQUEST['sum'];
if($type == 'pages')
$lock = $this->_lockfiles($synclist);
// do the sync
foreach((array) $synclist as $id => $dir){
@set_time_limit(30);
if($dir == 0){
$this->_listOut($this->getLang('skipped').' '.$id,'skipped');
continue;
}
if($dir == -2){
//delete local
if($type == 'pages'){
saveWikiText($id,'',$sum,false);
$this->_listOut($this->getLang('localdelok').' '.$id,'del_okay');
}else{
if(unlink(mediaFN($id))){
$this->_listOut($this->getLang('localdelok').' '.$id,'del_okay');
}else{
$this->_listOut($this->getLang('localdelfail').' '.$id,'del_fail');
}
}
continue;
}
if($dir == -1){
//pull
if($type == 'pages'){
$ok = $this->client->query('wiki.getPage',$id);
}else{
$ok = $this->client->query('wiki.getAttachment',$id);
}
if(!$ok){
$this->_listOut($this->getLang('pullfail').' '.$id.' '.
$this->client->getErrorMessage(),'pull_fail');
continue;
}
$data = $this->client->getResponse();
if($type == 'pages'){
saveWikiText($id,$data,$sum,false);
idx_addPage($id);
}else{
if($this->apiversion < 7){
$data = base64_decode($data);
}
io_saveFile(mediaFN($id),$data);
}
$this->_listOut($this->getLang('pullok').' '.$id,'pull_okay');
continue;
}
if($dir == 1){
// push
if($type == 'pages'){
$data = rawWiki($id);
$ok = $this->client->query('wiki.putPage',$id,$data,array('sum'=>$sum));
}else{
$data = io_readFile(mediaFN($id),false);
if($this->apiversion < 6){
$data = base64_encode($data);
}else{
$data = new IXR_Base64($data);
}
$ok = $this->client->query('wiki.putAttachment',$id,$data,array('ow'=>true));
}
if(!$ok){
$this->_listOut($this->getLang('pushfail').' '.$id.' '.
$this->client->getErrorMessage(),'push_fail');
continue;
}
$this->_listOut($this->getLang('pushok').' '.$id,'push_okay');
continue;
}
if($dir == 2){
// remote delete
if($type == 'pages'){
$ok = $this->client->query('wiki.putPage',$id,'',array('sum'=>$sum));
}else{
$ok = $this->client->query('wiki.deleteAttachment',$id);
}
if(!$ok){
$this->_listOut($this->getLang('remotedelfail').' '.$id.' '.
$this->client->getErrorMessage(),'del_fail');
continue;
}
$this->_listOut($this->getLang('remotedelok').' '.$id,'del_okay');
continue;
}
}
// unlock
if($type == 'pages'){
foreach((array) $synclist as $id => $dir){
unlock($id);
}
$this->client->query('dokuwiki.setLocks',array('lock'=>array(),'unlock'=>$lock));
}
}
/**
* Save synctimes
*/
function _saveSyncTimes($ltime,$rtime){
$no = $this->profno;
list($letime,$retime) = $this->_getTimes();
$this->profiles[$no]['ltime'] = $ltime;
$this->profiles[$no]['rtime'] = $rtime;
$this->profiles[$no]['letime'] = $letime;
$this->profiles[$no]['retime'] = $retime;
$this->_profileSave();
}
/**
* Open the sync direction form and initialize the table
*/
function _directionFormStart($lnow,$rnow){
$no = $this->profno;
echo $this->locale_xhtml('list');
echo '';
}
/**
* Print a list of changed files and ask for the sync direction
*
* Tries to be clever about suggesting the direction
*/
function _directionForm($type,&$synclist){
global $conf;
global $lang;
$no = $this->profno;
$ltime = (int) $this->profiles[$no]['ltime'];
$rtime = (int) $this->profiles[$no]['rtime'];
$letime = (int) $this->profiles[$no]['letime'];
$retime = (int) $this->profiles[$no]['retime'];
foreach($synclist as $id => $item){
// check direction
$dir = 0;
if($ltime && $rtime){ // synced before
if($item['remote']['mtime'] > $rtime &&
$item['local']['mtime'] <= $letime){
$dir = -1;
}
if($item['remote']['mtime'] <= $retime &&
$item['local']['mtime'] > $ltime){
$dir = 1;
}
}else{ // never synced
if(!$item['local']['mtime'] && $item['remote']['mtime']){
$dir = -1;
}
if($item['local']['mtime'] && !$item['remote']['mtime']){
$dir = 1;
}
}
echo '