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        echo   $this->page . "\n";
133        $this->data_buffer = "";
134        $this->xcom_get_data( 'wiki.getPage',$this->remoteClient,true, array($this->page));
135         if(is_array($this->data_buffer)) {
136              echo print_r($this->data_buffer,true);
137              exit;
138         }
139         usleep(100);
140        $this->savePage();
141    }
142    function savePage() {
143        $resp = $this->xcom_get_data( 'wiki.putPage',$this->localClient,false, array($this->page,$this->data_buffer,array('sum'=>'imported')));
144
145       if(!$resp) {
146            $this->msg('noimport',false," $this->page\n");
147            $this->logoff();
148            exit;
149        }
150        $this->msg('imported',false," $this->page\n");
151
152    }
153
154    function getMedia() {
155       $this->mediaArray=$this->xcom_get_data( 'plugin.xcom.getMedia',$this->remoteClient);
156    }
157
158    private  function xcom_get_data($task,$client,$use_buffer=false, $params="") {
159
160         if(!$params) {
161              if($params === false) {
162                  $params = array($task);
163              }
164              else $params = array($task,$this->page);
165         }
166         else {
167           array_unshift($params,$task);
168         }
169
170           $secs =  5;
171           $time_start = time();
172           while(!($resp = call_user_func_array(array($client,"query"),$params))){
173           if($resp)  echo "resp=$resp\n";
174            if((time() - $time_start ) > $secs ) {
175            break;
176            }
177           usleep(50);
178        }
179
180            if($use_buffer) {
181                $this->data_buffer = $client->getResponse();
182                return;
183             }
184
185            return $client->getResponse();
186     }
187
188    function saveMediaFile($id) {
189       $auth = $this->xcom_get_data( 'wiki.aclCheck',$this->localClient,false,array($id));
190
191        if($auth < 8) {
192            $this->msg('uploadperm',false," $id\n");
193            return;
194        }
195
196        global $conf;
197        $ftmp = $conf['tmpdir'] . '/' . md5($id.clientIP());
198        // save temporary file
199        @unlink($ftmp);
200        io_saveFile($ftmp, $this->data_buffer);
201        $this->media_save($ftmp,$id,$auth);
202  }
203
204   function media_save($file_name,$id,$auth=255) {
205       $file = array('name'=>$file_name);
206       $ow = false;
207       $move='rename';
208
209       $res = media_save($file, $id, $ow, $auth, $move) ;
210       if(is_array($res)) {
211         print_r($res);
212       }
213       else  $this->msg('msave',false," $id\n");
214 }
215
216    function xcom_connect($url,$user,$pwd, $debug=false) {
217            $url = rtrim($url,'/') . '/lib/exe/xmlrpc.php';
218            $client = new IXR_Client($url);
219            $client->debug = $debug; // enable for debugging
220
221            $resp = $client->query('dokuwiki.login',$user,$pwd);
222            $ok = $client->getResponse();
223
224            if($ok) return $client;
225            return false;
226    }
227    function logoff() {
228
229        $this->msg('logoff');
230        $resp =$this->xcom_get_data( 'dokuwiki.getVersion',$this->localClient,false,false);
231        $this->msg('localdw', false," $resp\n");
232        preg_match('/(\d+)-\d+-\d+/',$resp,$matches);
233        if($matches[1] >= 2014) {
234             $this->msg('logoff',false, " $resp\n");
235             $this->xcom_get_data( 'dokuwiki.logoff',$this->localClient,false,false);
236        }
237        else  $this->msg('nologoff');
238
239       $resp =$this->xcom_get_data( 'dokuwiki.getVersion',$this->remoteClient,false,false);
240       $this->msg('remotedw', false," $resp\n");
241        preg_match('/(\d+)-\d+-\d+/',$resp,$matches);
242        if($matches[1] >= 2014) {
243             $this->msg('logoff',false, " $resp\n");
244             $this->xcom_get_data( 'dokuwiki.logoff',$this->remoteClient,false,false);
245        }
246        else $this->msg('nologoff');
247    }
248}
249global $INPUT;
250
251$xcom=new xcom_save($INPUT->post->str('local'),$INPUT->post->str('remote'),$INPUT->post->str('id'));
252$xcom->getPage();
253$xcom->getMedia() ;
254$xcom->processMediaArray();
255$xcom->logoff();
256echo "\n";
257flush();
258