1<?php
2
3define('DOKU_INC', realpath(dirname(__FILE__)) . '/../../../../');
4require_once(DOKU_INC.'inc/init.php');
5session_write_close();
6
7class xcom_save  {
8    private $helper;
9    private $get_media_file = 'wiki.getAttachment';
10    private $mediaArray;
11    private $get_page = 'wiki.getPage';
12    private $save_media_file = 'wiki.putAttachment';
13    private $save_page = 'wiki.putPage';
14    private $remoteClient;
15    private $localClient;
16    private $page;
17    private $data_buffer;
18    private $user;
19
20    function __construct($local_auth,$remote_auth,$page) {
21        $err = "";
22        $this->helper =  plugin_load('helper', 'xcom');
23
24        $this->page = $page;
25
26        if(!$this->page) {
27            $this->msg('nopage');
28            exit;
29        }
30        $secs =  25;
31        while(!($this->localClient = $this->ini_clients($local_auth,true))) {
32            if((time() - $time_start ) > $secs ) {
33            break;
34            }
35            usleep(50);
36        }
37        if(!$this->localClient) {
38             $err .= $this->msg('nolocal',1);
39        }
40        $time_start = time();
41        while(!($this->remoteClient = $this->ini_clients($remote_auth))) {
42            if((time() - $time_start ) > $secs ) {
43            break;
44            }
45            usleep(50);
46        }
47        if(!$this->remoteClient) {
48            $err .= $this->msg('noremote',1);
49        }
50        if($err) {
51           $err .= $this->msg('chkauth',1);
52           echo "$err\n";
53           exit;
54        }
55
56      $this->msg('success');
57
58       /*possible to query and save a single media id instead of a page id */
59       if($this->is_media_id($page)) {
60           $this->getMediaFile($page);
61           $this->logoff();
62           exit;
63       }
64
65    }
66
67    function msg($which, $ret=false, $nl="\n") {
68       if($ret) return $this->helper->getLang($which) . $nl;
69       echo $this->helper->getLang($which) . $nl;
70    }
71
72    function ini_clients($credentials,$local=false) {
73        if(is_string($credentials)) {
74            $credentials = json_decode($credentials);
75            if($credentials instanceof stdClass) {
76                if($local) $this->user = $credentials->user;
77                return $this->xcom_connect($credentials->url,$credentials->user,$credentials->pwd ,0);
78            }
79       }
80       if(is_array($credentials)) {
81           if($local) $this->user = $credentials['user'];
82           return $this->xcom_connect($credentials['url'],$credentials['user'],$credentials['pwd'] ,0);
83       }
84           return false;
85    }
86    function is_media_id($id) {
87       if(preg_match('/\.(\w{3,4})$/',$id,$matches)) {
88          echo "$id ". $this->msg('ismedia',1," " . $matches[1] . "\n");
89
90
91          return true;
92       }
93       return false;
94
95    }
96    function processMediaArray() {
97        if(!$this->mediaArray)  $this->getMedia();
98        if(!is_array($this->mediaArray)) {
99           $this->msg('nomedia',0, " $this->page.\n");
100           return;
101        }
102        $this->msg('reqmedia');
103        foreach($this->mediaArray as $mfile) {
104            $this->getMediaFile($mfile);
105        }
106    }
107
108    function getMediaFile($mfile) {
109        $this->data_buffer = "";
110        $this->xcom_get_data( 'wiki.getAttachment',$this->remoteClient,true, array($mfile));
111        if($this->data_buffer) {
112          if(is_array($this->data_buffer)) {
113              echo print_r($this->data_buffer,true);
114            }
115           else {
116                echo "$mfile " . $this->msg('fsize',true,"") . " " . strlen($this->data_buffer) ."\n";
117                $this->saveMediaFile($mfile);
118          }
119        }
120        echo "\n";
121    }
122
123
124    function getPage() {
125        $auth = $this->xcom_get_data( 'wiki.aclCheck',$this->localClient,false,array($this->page));
126
127        if($auth < 4) {
128            $this->msg('noperm',false," $this->page\n");
129            $this->logoff();
130            exit;
131        }
132        $info = $this->xcom_get_data( 'plugin.xcom.getPageInfo',$this->remoteClient,false,array($this->page));
133
134        if(!is_array($info)) {
135            $this->msg('notonremote',false," $this->page\n");
136            $this->logoff();
137             exit;
138        }
139
140        $this->data_buffer = "";
141        $this->xcom_get_data( 'wiki.getPage',$this->remoteClient,true, array($this->page));
142         if(is_array($this->data_buffer)) {
143              echo print_r($this->data_buffer,true);
144              exit;
145         }
146         usleep(100);
147        $this->savePage();
148    }
149    function savePage() {
150        $resp = $this->xcom_get_data( 'wiki.putPage',$this->localClient,false, array($this->page,$this->data_buffer,array('sum'=>'imported')));
151
152       if(!$resp) {
153            $this->msg('noimport',false," $this->page\n");
154            $this->logoff();
155            exit;
156        }
157        $this->msg('imported',false," $this->page\n");
158
159    }
160
161    function getMedia() {
162       $this->mediaArray=$this->xcom_get_data( 'plugin.xcom.getMedia',$this->remoteClient);
163    }
164
165    private  function xcom_get_data($task,$client,$use_buffer=false, $params="") {
166
167         if(!$params) {
168              if($params === false) {
169                  $params = array($task);
170              }
171              else $params = array($task,$this->page);
172         }
173         else {
174           array_unshift($params,$task);
175         }
176
177           $secs =  5;
178           $time_start = time();
179           while(!($resp = call_user_func_array(array($client,"query"),$params))){
180           if($resp)  echo "resp=$resp\n";
181            if((time() - $time_start ) > $secs ) {
182            break;
183            }
184           usleep(50);
185        }
186
187            if($use_buffer) {
188                $this->data_buffer = $client->getResponse();
189                return;
190             }
191
192            return $client->getResponse();
193     }
194
195    function saveMediaFile($id) {
196       $auth = $this->xcom_get_data( 'wiki.aclCheck',$this->localClient,false,array($id));
197
198        if($auth < 8) {
199            $this->msg('uploadperm',false," $id\n");
200            return;
201        }
202
203        global $conf;
204        $ftmp = $conf['tmpdir'] . '/' . md5($id.clientIP());
205        // save temporary file
206        @unlink($ftmp);
207        io_saveFile($ftmp, $this->data_buffer);
208        $this->media_save($ftmp,$id,$auth);
209  }
210
211   function media_save($file_name,$id,$auth=255) {
212       $file = array('name'=>$file_name);
213       $ow = false;
214       $move='rename';
215
216       $res = media_save($file, $id, $ow, $auth, $move) ;
217       if(is_array($res)) {
218         print_r($res);
219       }
220       else  $this->msg('msave',false," $id\n");
221 }
222
223    function xcom_connect($url,$user,$pwd, $debug=false) {
224            $url = rtrim($url,'/') . '/lib/exe/xmlrpc.php';
225            $client = new IXR_Client($url);
226            $client->debug = $debug; // enable for debugging
227
228            $resp = $client->query('dokuwiki.login',$user,$pwd);
229            $ok = $client->getResponse();
230
231            if($ok) return $client;
232            return false;
233    }
234    function logoff() {
235
236        $this->msg('logoff');
237        $resp =$this->xcom_get_data( 'dokuwiki.getVersion',$this->localClient,false,false);
238        $this->msg('localdw', false," $resp\n");
239        preg_match('/(\d+)-\d+-\d+/',$resp,$matches);
240        if($matches[1] >= 2014) {
241             $this->msg('logoff',false, " $resp\n");
242             $this->xcom_get_data( 'dokuwiki.logoff',$this->localClient,false,false);
243        }
244        else  $this->msg('nologoff');
245
246       $resp =$this->xcom_get_data( 'dokuwiki.getVersion',$this->remoteClient,false,false);
247       $this->msg('remotedw', false," $resp\n");
248        preg_match('/(\d+)-\d+-\d+/',$resp,$matches);
249        if($matches[1] >= 2014) {
250             $this->msg('logoff',false, " $resp\n");
251             $this->xcom_get_data( 'dokuwiki.logoff',$this->remoteClient,false,false);
252        }
253        else $this->msg('nologoff');
254    }
255}
256global $INPUT;
257
258$xcom=new xcom_save($INPUT->post->str('local'),$INPUT->post->str('remote'),$INPUT->post->str('id'));
259$xcom->getPage();
260$xcom->getMedia() ;
261$xcom->processMediaArray();
262$xcom->logoff();
263echo "\n";
264flush();
265