xref: /plugin/siteexport/inc/functions.php (revision 7d101cc131696cb3a0de345d8044a69fb2ef70e9)
1*7d101cc1SGerry Weißbach<?php
2*7d101cc1SGerry Weißbach
3*7d101cc1SGerry Weißbachif(!defined('DOKU_PLUGIN')) die('meh');
4*7d101cc1SGerry Weißbachrequire_once(DOKU_PLUGIN.'siteexport/inc/settings.php');
5*7d101cc1SGerry Weißbachrequire_once(DOKU_PLUGIN.'siteexport/inc/debug.php');
6*7d101cc1SGerry Weißbach
7*7d101cc1SGerry Weißbachclass siteexport_functions extends DokuWiki_Plugin
8*7d101cc1SGerry Weißbach{
9*7d101cc1SGerry Weißbach    public $debug = null;
10*7d101cc1SGerry Weißbach    public $settings = null;
11*7d101cc1SGerry Weißbach
12*7d101cc1SGerry Weißbach    public function siteexport_functions($init=true)
13*7d101cc1SGerry Weißbach    {
14*7d101cc1SGerry Weißbach        if ( $init )
15*7d101cc1SGerry Weißbach        {
16*7d101cc1SGerry Weißbach            $this->debug = new siteexport_debug();
17*7d101cc1SGerry Weißbach            $this->settings = new settings_plugin_siteexport_settings($this);
18*7d101cc1SGerry Weißbach
19*7d101cc1SGerry Weißbach            $this->debug->setDebugLevel($this->settings->getConf('debugLevel'));
20*7d101cc1SGerry Weißbach            $this->debug->setDebugFile ($this->settings->getConf('debugFile'));
21*7d101cc1SGerry Weißbach
22*7d101cc1SGerry Weißbach            $this->debug->message("Settings completed: zipFile", $this->settings->zipFile, 1);
23*7d101cc1SGerry Weißbach        }
24*7d101cc1SGerry Weißbach    }
25*7d101cc1SGerry Weißbach
26*7d101cc1SGerry Weißbach    public function getPluginName()
27*7d101cc1SGerry Weißbach    {
28*7d101cc1SGerry Weißbach        return 'siteexport';
29*7d101cc1SGerry Weißbach    }
30*7d101cc1SGerry Weißbach
31*7d101cc1SGerry Weißbach    public function downloadURL()
32*7d101cc1SGerry Weißbach    {
33*7d101cc1SGerry Weißbach        return ml($this->settings->origZipFile, array('cache' => 'nocache', 'siteexport' => $this->settings->pattern), true, '&');
34*7d101cc1SGerry Weißbach    }
35*7d101cc1SGerry Weißbach
36*7d101cc1SGerry Weißbach    public function checkIfCacheFileExistsForFileWithPattern($file, $pattern)
37*7d101cc1SGerry Weißbach    {
38*7d101cc1SGerry Weißbach        if ( !@file_exists($file) )
39*7d101cc1SGerry Weißbach        {
40*7d101cc1SGerry Weißbach            // If the cache File does not exist, move the newly created one over ...
41*7d101cc1SGerry Weißbach            $newCacheFile = mediaFN($this->getSpecialExportFileName($this->settings->origZipFile, $pattern));
42*7d101cc1SGerry Weißbach
43*7d101cc1SGerry Weißbach            if ( !@file_exists($newCacheFile) )
44*7d101cc1SGerry Weißbach            {
45*7d101cc1SGerry Weißbach                $this->debug->message("The export must have gone wrong. The cached file does not exist.", array("pattern" => $pattern, "original File" => $this->settings->origZipFile, "expected cached file" => $newCacheFile), 3);
46*7d101cc1SGerry Weißbach            }
47*7d101cc1SGerry Weißbach
48*7d101cc1SGerry Weißbach            $status = io_rename($newCacheFile, $file);
49*7d101cc1SGerry Weißbach            $this->debug->message("had to move another original file over. Did it work? " . ($status ? 'Yes, it did.' : 'No, it did not.'), null, 2 );
50*7d101cc1SGerry Weißbach        }
51*7d101cc1SGerry Weißbach    }
52*7d101cc1SGerry Weißbach
53*7d101cc1SGerry Weißbach
54*7d101cc1SGerry Weißbach    /**
55*7d101cc1SGerry Weißbach     * Returns an utf8 encoded Namespace for a Page and input Namespace
56*7d101cc1SGerry Weißbach     * @param $NS
57*7d101cc1SGerry Weißbach     * @param $PAGE
58*7d101cc1SGerry Weißbach     */
59*7d101cc1SGerry Weißbach    function getNamespaceFromID($NS, &$PAGE) {
60*7d101cc1SGerry Weißbach        global $conf;
61*7d101cc1SGerry Weißbach        // Check current page - if its an NS add the startpage
62*7d101cc1SGerry Weißbach        $clean = true;
63*7d101cc1SGerry Weißbach        resolve_pageid(getNS($NS), $NS, $clean);
64*7d101cc1SGerry Weißbach        if ( ! page_exists($NS) && array_pop(explode(':', $NS)) != strtolower($conf['start'] )) { // Compare to lowercase since clean lowers it.
65*7d101cc1SGerry Weißbach            $NS .= ':' . $conf['start'];
66*7d101cc1SGerry Weißbach            resolve_pageid(getNS($NS), $NS, $clean);
67*7d101cc1SGerry Weißbach        }
68*7d101cc1SGerry Weißbach
69*7d101cc1SGerry Weißbach        $PAGE = noNS($NS);
70*7d101cc1SGerry Weißbach        $NS = getNS($NS);
71*7d101cc1SGerry Weißbach
72*7d101cc1SGerry Weißbach        return utf8_encodeFN(str_replace(':', '/', $NS));
73*7d101cc1SGerry Weißbach    }
74*7d101cc1SGerry Weißbach
75*7d101cc1SGerry Weißbach    /**
76*7d101cc1SGerry Weißbach     * create a file name for the page
77*7d101cc1SGerry Weißbach     **/
78*7d101cc1SGerry Weißbach    public function getSiteName($ID, $overrideRewrite=false) {
79*7d101cc1SGerry Weißbach        global $conf;
80*7d101cc1SGerry Weißbach
81*7d101cc1SGerry Weißbach        if ( empty($ID) ) return false;
82*7d101cc1SGerry Weißbach
83*7d101cc1SGerry Weißbach        $url = $this->wl($this->cleanID($ID), null, true, null, null, $overrideRewrite); // this must be done with rewriting set to override
84*7d101cc1SGerry Weißbach        //$url = $this->wl($this->cleanID($ID), null, true); // this must be done with rewriting set to override
85*7d101cc1SGerry Weißbach        $uri = @parse_url($url);
86*7d101cc1SGerry Weißbach        if ( $uri['path'][0] == '/' ) {
87*7d101cc1SGerry Weißbach            $uri['path'] = substr($uri['path'], 1);
88*7d101cc1SGerry Weißbach        }
89*7d101cc1SGerry Weißbach
90*7d101cc1SGerry Weißbach        return $this->shortenName($uri['path'] . '.' . $this->settings->fileType);
91*7d101cc1SGerry Weißbach    }
92*7d101cc1SGerry Weißbach
93*7d101cc1SGerry Weißbach    /**
94*7d101cc1SGerry Weißbach     * get the Title for the page
95*7d101cc1SGerry Weißbach     **/
96*7d101cc1SGerry Weißbach    public function getSiteTitle($ID) {
97*7d101cc1SGerry Weißbach        if (useHeading('content') && $ID) {
98*7d101cc1SGerry Weißbach            $heading = p_get_first_heading($ID,true);
99*7d101cc1SGerry Weißbach            if ($heading) {
100*7d101cc1SGerry Weißbach                return $this->xmlEntities($heading);
101*7d101cc1SGerry Weißbach            }
102*7d101cc1SGerry Weißbach        }
103*7d101cc1SGerry Weißbach        return ucwords($this->xmlEntities(array_pop(explode(':', $ID))));
104*7d101cc1SGerry Weißbach    }
105*7d101cc1SGerry Weißbach
106*7d101cc1SGerry Weißbach    /**
107*7d101cc1SGerry Weißbach     * Encoding ()taken from DW - but without needing the renderer
108*7d101cc1SGerry Weißbach     **/
109*7d101cc1SGerry Weißbach    public function xmlEntities($string) {
110*7d101cc1SGerry Weißbach        return htmlspecialchars($string,ENT_QUOTES,'UTF-8');
111*7d101cc1SGerry Weißbach    }
112*7d101cc1SGerry Weißbach
113*7d101cc1SGerry Weißbach    /**
114*7d101cc1SGerry Weißbach     * Create name for the file inside the zip and the replacements
115*7d101cc1SGerry Weißbach     **/
116*7d101cc1SGerry Weißbach    function shortenName($NAME)
117*7d101cc1SGerry Weißbach    {
118*7d101cc1SGerry Weißbach        $NS = $this->settings->exportNamespace;
119*7d101cc1SGerry Weißbach        $NAME = preg_replace("%^" . DOKU_BASE . "%", "", $NAME);
120*7d101cc1SGerry Weißbach        $NAME = preg_replace("%^(_media/)?(" . $NS . "/)?%", "", $NAME);
121*7d101cc1SGerry Weißbach
122*7d101cc1SGerry Weißbach        $this->debug->message("Shortening file to '$NAME'", null, 1);
123*7d101cc1SGerry Weißbach        return $NAME;
124*7d101cc1SGerry Weißbach    }
125*7d101cc1SGerry Weißbach
126*7d101cc1SGerry Weißbach    /**
127*7d101cc1SGerry Weißbach     * Remove unwanted chars from ID
128*7d101cc1SGerry Weißbach     *
129*7d101cc1SGerry Weißbach     * Cleans a given ID to only use allowed characters. Accented characters are
130*7d101cc1SGerry Weißbach     * converted to unaccented ones
131*7d101cc1SGerry Weißbach     *
132*7d101cc1SGerry Weißbach     * @author Andreas Gohr <andi@splitbrain.org>
133*7d101cc1SGerry Weißbach     * @param  string  $raw_id    The pageid to clean
134*7d101cc1SGerry Weißbach     * @param  boolean $ascii     Force ASCII
135*7d101cc1SGerry Weißbach     * @param  boolean $media     Allow leading or trailing _ for media files
136*7d101cc1SGerry Weißbach     */
137*7d101cc1SGerry Weißbach    function cleanID($raw_id,$ascii=false,$media=false){
138*7d101cc1SGerry Weißbach        global $conf;
139*7d101cc1SGerry Weißbach        global $lang;
140*7d101cc1SGerry Weißbach        static $sepcharpat = null;
141*7d101cc1SGerry Weißbach
142*7d101cc1SGerry Weißbach        global $cache_cleanid;
143*7d101cc1SGerry Weißbach        $cache = & $cache_cleanid;
144*7d101cc1SGerry Weißbach
145*7d101cc1SGerry Weißbach        // check if it's already in the memory cache
146*7d101cc1SGerry Weißbach        if (isset($cache[(string)$raw_id])) {
147*7d101cc1SGerry Weißbach            return $cache[(string)$raw_id];
148*7d101cc1SGerry Weißbach        }
149*7d101cc1SGerry Weißbach
150*7d101cc1SGerry Weißbach        $sepchar = $conf['sepchar'];
151*7d101cc1SGerry Weißbach        if($sepcharpat == null) // build string only once to save clock cycles
152*7d101cc1SGerry Weißbach        $sepcharpat = '#\\'.$sepchar.'+#';
153*7d101cc1SGerry Weißbach
154*7d101cc1SGerry Weißbach        $id = trim((string)$raw_id);
155*7d101cc1SGerry Weißbach        //        $id = utf8_strtolower($id); // NO LowerCase for us!
156*7d101cc1SGerry Weißbach
157*7d101cc1SGerry Weißbach        //alternative namespace seperator
158*7d101cc1SGerry Weißbach        $id = strtr($id,';',':');
159*7d101cc1SGerry Weißbach        if($conf['useslash']){
160*7d101cc1SGerry Weißbach            $id = strtr($id,'/',':');
161*7d101cc1SGerry Weißbach        }else{
162*7d101cc1SGerry Weißbach            $id = strtr($id,'/',$sepchar);
163*7d101cc1SGerry Weißbach        }
164*7d101cc1SGerry Weißbach
165*7d101cc1SGerry Weißbach        if($conf['deaccent'] == 2 || $ascii) $id = utf8_romanize($id);
166*7d101cc1SGerry Weißbach        if($conf['deaccent'] || $ascii) $id = utf8_deaccent($id,-1);
167*7d101cc1SGerry Weißbach
168*7d101cc1SGerry Weißbach        //remove specials
169*7d101cc1SGerry Weißbach        $id = utf8_stripspecials($id,$sepchar,'\*');
170*7d101cc1SGerry Weißbach
171*7d101cc1SGerry Weißbach        if($ascii) $id = utf8_strip($id);
172*7d101cc1SGerry Weißbach
173*7d101cc1SGerry Weißbach        //clean up
174*7d101cc1SGerry Weißbach        $id = preg_replace($sepcharpat,$sepchar,$id);
175*7d101cc1SGerry Weißbach        $id = preg_replace('#:+#',':',$id);
176*7d101cc1SGerry Weißbach        $id = ($media ? trim($id,':.-') : trim($id,':._-'));
177*7d101cc1SGerry Weißbach        $id = preg_replace('#:[:\._\-]+#',':',$id);
178*7d101cc1SGerry Weißbach
179*7d101cc1SGerry Weißbach        $cache[(string)$raw_id] = $id;
180*7d101cc1SGerry Weißbach        return($id);
181*7d101cc1SGerry Weißbach    }
182*7d101cc1SGerry Weißbach
183*7d101cc1SGerry Weißbach
184*7d101cc1SGerry Weißbach    /**
185*7d101cc1SGerry Weißbach     * This builds a link to a wikipage - changed for internal use here
186*7d101cc1SGerry Weißbach     *
187*7d101cc1SGerry Weißbach     * It handles URL rewriting and adds additional parameter if
188*7d101cc1SGerry Weißbach     * given in $more
189*7d101cc1SGerry Weißbach     *
190*7d101cc1SGerry Weißbach     * @author Andreas Gohr <andi@splitbrain.org>
191*7d101cc1SGerry Weißbach     */
192*7d101cc1SGerry Weißbach
193*7d101cc1SGerry Weißbach    function wl($id='',$more='',$abs=false,$sep='&amp;', $IDexists=true, $overrideRewrite=false, $hadBase=false){
194*7d101cc1SGerry Weißbach        global $conf;
195*7d101cc1SGerry Weißbach
196*7d101cc1SGerry Weißbach        $this->debug->message("Starting to build WL-URL for '$id'", null, 1);
197*7d101cc1SGerry Weißbach
198*7d101cc1SGerry Weißbach        if(is_array($more)){
199*7d101cc1SGerry Weißbach            $more = buildURLparams($more,$sep);
200*7d101cc1SGerry Weißbach        }else{
201*7d101cc1SGerry Weißbach            $more = str_replace(',',$sep,$more);
202*7d101cc1SGerry Weißbach        }
203*7d101cc1SGerry Weißbach
204*7d101cc1SGerry Weißbach        $id = idfilter($id);
205*7d101cc1SGerry Weißbach
206*7d101cc1SGerry Weißbach        if($abs){
207*7d101cc1SGerry Weißbach            $xlink = DOKU_URL;
208*7d101cc1SGerry Weißbach            if ( !$IDexists && !$hadBase ) { // If the file does not exist, we have to remove the base. This link my be one to an parallel BASE.
209*7d101cc1SGerry Weißbach                $xlink = preg_replace('#' . DOKU_BASE . '$#', '', $xlink);
210*7d101cc1SGerry Weißbach            }
211*7d101cc1SGerry Weißbach        }else if ($IDexists || $hadBase) { // if the ID does exist, we may add the base.
212*7d101cc1SGerry Weißbach            $xlink = DOKU_BASE;
213*7d101cc1SGerry Weißbach        } else{
214*7d101cc1SGerry Weißbach            $xlink = "";
215*7d101cc1SGerry Weißbach        }
216*7d101cc1SGerry Weißbach
217*7d101cc1SGerry Weißbach        // $this->debug->message("internal WL function Before Replacing: '$xlink'", array(DOKU_REL, DOKU_URL, DOKU_BASE, $xlink), 2);
218*7d101cc1SGerry Weißbach        $xlink = preg_replace('#(?<!http:|https:)//+#','/', ($abs ? '' : '/') . "$xlink/"); // ensure slashes at beginning and ending, but strip doubles
219*7d101cc1SGerry Weißbach        $this->debug->message("'$xlink'", array(DOKU_REL, DOKU_URL, DOKU_BASE, $xlink), 2);
220*7d101cc1SGerry Weißbach
221*7d101cc1SGerry Weißbach        if ( $overrideRewrite ) {
222*7d101cc1SGerry Weißbach            $this->debug->message("Override enabled.", null, 1);
223*7d101cc1SGerry Weißbach            $id = strtr($id,':','/');
224*7d101cc1SGerry Weißbach
225*7d101cc1SGerry Weißbach            $xlink .= $id;
226*7d101cc1SGerry Weißbach            if($more) $xlink .= '?'.$more;
227*7d101cc1SGerry Weißbach        } else {
228*7d101cc1SGerry Weißbach            if($conf['userewrite'] == 2 ){
229*7d101cc1SGerry Weißbach                $xlink .= DOKU_SCRIPT.'/'.$id;
230*7d101cc1SGerry Weißbach                if($more) $xlink .= '?'.$more;
231*7d101cc1SGerry Weißbach            }elseif($conf['userewrite'] ){
232*7d101cc1SGerry Weißbach                $xlink .= $id;
233*7d101cc1SGerry Weißbach                if($more) $xlink .= '?'.$more;
234*7d101cc1SGerry Weißbach            }elseif($id){
235*7d101cc1SGerry Weißbach                $xlink .= DOKU_SCRIPT.'?id='.$id;
236*7d101cc1SGerry Weißbach                if($more) $xlink .= $sep.$more;
237*7d101cc1SGerry Weißbach            }else{
238*7d101cc1SGerry Weißbach                $xlink .= DOKU_SCRIPT;
239*7d101cc1SGerry Weißbach                if($more) $xlink .= '?'.$more;
240*7d101cc1SGerry Weißbach            }
241*7d101cc1SGerry Weißbach        }
242*7d101cc1SGerry Weißbach
243*7d101cc1SGerry Weißbach        $this->debug->message("internal WL function result: '$xlink'", null, 2);
244*7d101cc1SGerry Weißbach
245*7d101cc1SGerry Weißbach        return $xlink;
246*7d101cc1SGerry Weißbach    }
247*7d101cc1SGerry Weißbach
248*7d101cc1SGerry Weißbach    /**
249*7d101cc1SGerry Weißbach     * Create the export file name - this is the file where everything is being stored
250*7d101cc1SGerry Weißbach     * @param $FILE
251*7d101cc1SGerry Weißbach     * @param $PATTERN - additional pattern for re-using old files
252*7d101cc1SGerry Weißbach     */
253*7d101cc1SGerry Weißbach    public function getSpecialExportFileName($FILE, $PATTERN=null) {
254*7d101cc1SGerry Weißbach
255*7d101cc1SGerry Weißbach        if ( empty($FILE) )
256*7d101cc1SGerry Weißbach        {
257*7d101cc1SGerry Weißbach            $FILE = $this->settings->origZipFile;
258*7d101cc1SGerry Weißbach        }
259*7d101cc1SGerry Weißbach
260*7d101cc1SGerry Weißbach        if ( empty($PATTERN) && empty($this->settings->pattern) ){
261*7d101cc1SGerry Weißbach            $this->debug("Generating an internal md5 pattern. This will go wrong - and won't cache properly.");
262*7d101cc1SGerry Weißbach            $PATTERN = md5(microtime(false));
263*7d101cc1SGerry Weißbach        }
264*7d101cc1SGerry Weißbach
265*7d101cc1SGerry Weißbach        // Set Pattern Global for other stuff
266*7d101cc1SGerry Weißbach        if ( empty($this->settings->pattern) ) {
267*7d101cc1SGerry Weißbach            $this->settings['pattern'] = $PATTERN;
268*7d101cc1SGerry Weißbach        } else {
269*7d101cc1SGerry Weißbach            $PATTERN = $this->settings->pattern;
270*7d101cc1SGerry Weißbach        }
271*7d101cc1SGerry Weißbach
272*7d101cc1SGerry Weißbach        $FA = explode('.', $FILE);
273*7d101cc1SGerry Weißbach        $EXT = array_pop($FA);
274*7d101cc1SGerry Weißbach        array_push($FA, 'auto');
275*7d101cc1SGerry Weißbach        array_push($FA, $PATTERN);
276*7d101cc1SGerry Weißbach        array_push($FA, $EXT);
277*7d101cc1SGerry Weißbach
278*7d101cc1SGerry Weißbach        $fileName = implode('.', $FA);
279*7d101cc1SGerry Weißbach        $this->debug->message("Export Filename for '$FILE' will be: '$fileName'", null, 2);
280*7d101cc1SGerry Weißbach        return $fileName;
281*7d101cc1SGerry Weißbach    }
282*7d101cc1SGerry Weißbach
283*7d101cc1SGerry Weißbach    public function getCacheFileNameForPattern($PATTERN = null)
284*7d101cc1SGerry Weißbach    {
285*7d101cc1SGerry Weißbach        if ( $PATTERN == null ) {
286*7d101cc1SGerry Weißbach            $PATTERN = $this->settings->pattern;
287*7d101cc1SGerry Weißbach        }
288*7d101cc1SGerry Weißbach
289*7d101cc1SGerry Weißbach        return getCacheName($this->getSpecialExportFileName($this->settings->origZipFile, $PATTERN), '.' . basename(mediaFN($this->settings->origZipFile)) );
290*7d101cc1SGerry Weißbach    }
291*7d101cc1SGerry Weißbach
292*7d101cc1SGerry Weißbach    function startRedirctProcess($counter) {
293*7d101cc1SGerry Weißbach        global $ID;
294*7d101cc1SGerry Weißbach
295*7d101cc1SGerry Weißbach        $URL = wl($ID);
296*7d101cc1SGerry Weißbach
297*7d101cc1SGerry Weißbach        $additionalParameters = $_REQUEST;
298*7d101cc1SGerry Weißbach        $additionalParameters['startcounter'] = $counter;
299*7d101cc1SGerry Weißbach        $additionalParameters['pattern'] = $this->settings->pattern;
300*7d101cc1SGerry Weißbach
301*7d101cc1SGerry Weißbach        unset($additionalParameters['id']);
302*7d101cc1SGerry Weißbach        unset($additionalParameters['u']);
303*7d101cc1SGerry Weißbach        unset($additionalParameters['p']);
304*7d101cc1SGerry Weißbach        unset($additionalParameters['r']);
305*7d101cc1SGerry Weißbach        unset($additionalParameters['http_credentials']);
306*7d101cc1SGerry Weißbach
307*7d101cc1SGerry Weißbach        $this->addAdditionalParametersToURL($URL, $additionalParameters);
308*7d101cc1SGerry Weißbach        $this->debug->message("Redirecting to '$URL'", null, 2);
309*7d101cc1SGerry Weißbach
310*7d101cc1SGerry Weißbach        send_redirect($URL);
311*7d101cc1SGerry Weißbach        exit(0); // Should not be reached, but anyways
312*7d101cc1SGerry Weißbach    }
313*7d101cc1SGerry Weißbach
314*7d101cc1SGerry Weißbach    /**
315*7d101cc1SGerry Weißbach     * Builds additional Parameters into the URL given
316*7d101cc1SGerry Weißbach     * @param $URL
317*7d101cc1SGerry Weißbach     * @param $newAdditionalParameters
318*7d101cc1SGerry Weißbach     */
319*7d101cc1SGerry Weißbach    function addAdditionalParametersToURL(&$URL, $newAdditionalParameters) {
320*7d101cc1SGerry Weißbach
321*7d101cc1SGerry Weißbach        // Add additionalParameters
322*7d101cc1SGerry Weißbach        if ( !empty($newAdditionalParameters) ) {
323*7d101cc1SGerry Weißbach            foreach($newAdditionalParameters as $key => $value ) {
324*7d101cc1SGerry Weißbach                if ( empty($key) || empty($value) ) { continue; }
325*7d101cc1SGerry Weißbach
326*7d101cc1SGerry Weißbach                $append = '';
327*7d101cc1SGerry Weißbach
328*7d101cc1SGerry Weißbach                if ( is_array($value) ) {
329*7d101cc1SGerry Weißbach                    foreach( array_values($value) as $aValue ) { // Array Handling
330*7d101cc1SGerry Weißbach                        $URL .= (strstr($URL, '?') ? '&' : '?') . $key . "[]=$aValue";
331*7d101cc1SGerry Weißbach                    }
332*7d101cc1SGerry Weißbach                } else {
333*7d101cc1SGerry Weißbach                    $append = "$key=$value";
334*7d101cc1SGerry Weißbach                    $URL .= empty($append) || strstr($URL, $append)  ? '' : (strstr($URL, '?') ? '&' : '?') . $append;
335*7d101cc1SGerry Weißbach                }
336*7d101cc1SGerry Weißbach
337*7d101cc1SGerry Weißbach            }
338*7d101cc1SGerry Weißbach        }
339*7d101cc1SGerry Weißbach    }
340*7d101cc1SGerry Weißbach
341*7d101cc1SGerry Weißbach    /**
342*7d101cc1SGerry Weißbach     * Cleans the wiki variables and returns a rebuild URL that has the new variables at hand
343*7d101cc1SGerry Weißbach     * @param $data
344*7d101cc1SGerry Weißbach     */
345*7d101cc1SGerry Weißbach    function prepare_POSTData($data)
346*7d101cc1SGerry Weißbach    {
347*7d101cc1SGerry Weißbach        $NS = !empty($data['ns']) ? $data['ns'] : $data['id'];
348*7d101cc1SGerry Weißbach
349*7d101cc1SGerry Weißbach        $this->removeWikiVariables($data);
350*7d101cc1SGerry Weißbach        $data['do'] = 'siteexport';
351*7d101cc1SGerry Weißbach        $additionalKeys = '';
352*7d101cc1SGerry Weißbach
353*7d101cc1SGerry Weißbach        ksort($data);
354*7d101cc1SGerry Weißbach
355*7d101cc1SGerry Weißbach        $this->debug->message("Prepared POST data:", $data, 1);
356*7d101cc1SGerry Weißbach
357*7d101cc1SGerry Weißbach        foreach( $data as $key => $value ) {
358*7d101cc1SGerry Weißbach
359*7d101cc1SGerry Weißbach            if ( !is_array($value) ) { continue; }
360*7d101cc1SGerry Weißbach            $this->debug->message("Found inner Array:", $value, 1);
361*7d101cc1SGerry Weißbach
362*7d101cc1SGerry Weißbach            asort($value);
363*7d101cc1SGerry Weißbach            foreach ( $value as $innerKey => $aValue )
364*7d101cc1SGerry Weißbach            {
365*7d101cc1SGerry Weißbach                if ( is_numeric($innerKey))
366*7d101cc1SGerry Weißbach                {
367*7d101cc1SGerry Weißbach                    $innerKey = '';
368*7d101cc1SGerry Weißbach                }
369*7d101cc1SGerry Weißbach
370*7d101cc1SGerry Weißbach                $additionalKeys .= "&$key" . "[$innerKey]=$aValue";
371*7d101cc1SGerry Weißbach            }
372*7d101cc1SGerry Weißbach
373*7d101cc1SGerry Weißbach            unset($data[$key]);
374*7d101cc1SGerry Weißbach        }
375*7d101cc1SGerry Weißbach
376*7d101cc1SGerry Weißbach        return wl($NS, $data, true, '&') . $additionalKeys;
377*7d101cc1SGerry Weißbach    }
378*7d101cc1SGerry Weißbach
379*7d101cc1SGerry Weißbach    /**
380*7d101cc1SGerry Weißbach     * Parses a String into a $_REQUEST Like variant. You have to tell if a decode of the values is needed
381*7d101cc1SGerry Weißbach     * @param $inputArray
382*7d101cc1SGerry Weißbach     * @param $decode
383*7d101cc1SGerry Weißbach     */
384*7d101cc1SGerry Weißbach    public function parseStringToRequestArray($inputArray, $decode=false)
385*7d101cc1SGerry Weißbach    {
386*7d101cc1SGerry Weißbach        global $plugin_controller;
387*7d101cc1SGerry Weißbach
388*7d101cc1SGerry Weißbach        $outputArray = $inputArray;
389*7d101cc1SGerry Weißbach        if ( !is_array($inputArray) )
390*7d101cc1SGerry Weißbach        {
391*7d101cc1SGerry Weißbach            $intermediate = str_replace("&amp;", "&", $inputArray);
392*7d101cc1SGerry Weißbach
393*7d101cc1SGerry Weißbach            $outputArray = array();
394*7d101cc1SGerry Weißbach            foreach( explode("&", $intermediate) as $param ) {
395*7d101cc1SGerry Weißbach                list($key, $value) = explode("=", $param, 2);
396*7d101cc1SGerry Weißbach
397*7d101cc1SGerry Weißbach                // This is needed if we do want to calculate $_REQUEST for a non HTTP-Request
398*7d101cc1SGerry Weißbach                if ( $decode)
399*7d101cc1SGerry Weißbach                {
400*7d101cc1SGerry Weißbach                    $value = urldecode($value);
401*7d101cc1SGerry Weißbach                }
402*7d101cc1SGerry Weißbach
403*7d101cc1SGerry Weißbach                if ( empty($key) ) { continue; } // Don't check on Value, because there may be only the key that should be preserved
404*7d101cc1SGerry Weißbach
405*7d101cc1SGerry Weißbach                if ( substr($key, -2) == '[]' ) {
406*7d101cc1SGerry Weißbach	                $key = substr($key, 0, -2);
407*7d101cc1SGerry Weißbach	                if ( !is_array($outputArray[$key]) ) {
408*7d101cc1SGerry Weißbach		                $outputArray[$key] = array();
409*7d101cc1SGerry Weißbach	                }
410*7d101cc1SGerry Weißbach
411*7d101cc1SGerry Weißbach                    array_push($outputArray[$key], $value); // Array Handling
412*7d101cc1SGerry Weißbach                } else {
413*7d101cc1SGerry Weißbach                    $outputArray[$key] = $value;
414*7d101cc1SGerry Weißbach                }
415*7d101cc1SGerry Weißbach            }
416*7d101cc1SGerry Weißbach        }
417*7d101cc1SGerry Weißbach
418*7d101cc1SGerry Weißbach        if ( !empty($outputArray['diPlu']) ) {
419*7d101cc1SGerry Weißbach
420*7d101cc1SGerry Weißbach            $allPlugins = array();
421*7d101cc1SGerry Weißbach            foreach($plugin_controller->getList(null,true) as $plugin ) {
422*7d101cc1SGerry Weißbach                // check for CSS or JS
423*7d101cc1SGerry Weißbach                if ( !file_exists(DOKU_PLUGIN."$plugin/script.js") && !file_exists(DOKU_PLUGIN."$p/style.css") ) { continue; }
424*7d101cc1SGerry Weißbach                $allPlugins[] = $plugin;
425*7d101cc1SGerry Weißbach            }
426*7d101cc1SGerry Weißbach
427*7d101cc1SGerry Weißbach            if ( count($outputArray['diPlu']) > (count($allPlugins) / 2) ) {
428*7d101cc1SGerry Weißbach                $outputArray['diInv'] = 1;
429*7d101cc1SGerry Weißbach                $outputArray['diPlu'] = array_diff($allPlugins, $outputArray['diPlu']);
430*7d101cc1SGerry Weißbach            }
431*7d101cc1SGerry Weißbach        }
432*7d101cc1SGerry Weißbach
433*7d101cc1SGerry Weißbach        return $outputArray;
434*7d101cc1SGerry Weißbach    }
435*7d101cc1SGerry Weißbach
436*7d101cc1SGerry Weißbach    /**
437*7d101cc1SGerry Weißbach     * Remove certain fields from the list.
438*7d101cc1SGerry Weißbach     * @param $removeArray
439*7d101cc1SGerry Weißbach     * @param $advanced
440*7d101cc1SGerry Weißbach     * @param $isString
441*7d101cc1SGerry Weißbach     */
442*7d101cc1SGerry Weißbach    function removeWikiVariables(&$removeArray, $advanced=false, $isString=false) {
443*7d101cc1SGerry Weißbach
444*7d101cc1SGerry Weißbach        $removeArray = $this->parseStringToRequestArray($removeArray);
445*7d101cc1SGerry Weißbach
446*7d101cc1SGerry Weißbach        // 2010-08-23 - If there is still the media set, retain the id for e.g. detail.php
447*7d101cc1SGerry Weißbach        if ( !isset($removeArray['media']) ) {
448*7d101cc1SGerry Weißbach            unset($removeArray['id']);
449*7d101cc1SGerry Weißbach        }
450*7d101cc1SGerry Weißbach
451*7d101cc1SGerry Weißbach        unset($removeArray['do']);
452*7d101cc1SGerry Weißbach        unset($removeArray['ns']);
453*7d101cc1SGerry Weißbach        unset($removeArray['call']);
454*7d101cc1SGerry Weißbach        unset($removeArray['sectok']);
455*7d101cc1SGerry Weißbach        unset($removeArray['rndval']);
456*7d101cc1SGerry Weißbach        unset($removeArray['tseed']);
457*7d101cc1SGerry Weißbach        unset($removeArray['http_credentials']);
458*7d101cc1SGerry Weißbach        unset($removeArray['u']);
459*7d101cc1SGerry Weißbach        unset($removeArray['p']);
460*7d101cc1SGerry Weißbach        unset($removeArray['r']);
461*7d101cc1SGerry Weißbach        unset($removeArray['base']);
462*7d101cc1SGerry Weißbach        unset($removeArray['siteexport']);
463*7d101cc1SGerry Weißbach        unset($removeArray['DokuWiki']);
464*7d101cc1SGerry Weißbach        unset($removeArray['cronOverwriteExisting']);
465*7d101cc1SGerry Weißbach
466*7d101cc1SGerry Weißbach        if ( $removeArray['renderer'] == 'xhtml' ) {
467*7d101cc1SGerry Weißbach            $removeArray['do'] = 'export_' . $removeArray['renderer'];
468*7d101cc1SGerry Weißbach            unset($removeArray['renderer']);
469*7d101cc1SGerry Weißbach        }
470*7d101cc1SGerry Weißbach
471*7d101cc1SGerry Weißbach        if ( $advanced ) {
472*7d101cc1SGerry Weißbach            if ( $removeArray['renderer'] != 'xhtml' && !empty($removeArray['renderer']) ) {
473*7d101cc1SGerry Weißbach                $removeArray['do'] = 'export_' . $removeArray['renderer'];
474*7d101cc1SGerry Weißbach            }
475*7d101cc1SGerry Weißbach
476*7d101cc1SGerry Weißbach            // 2010-08-25 - Need fakeMedia for some _detail cases with rewrite = 2
477*7d101cc1SGerry Weißbach            if ( isset($removeArray['fakeMedia'])  ) {
478*7d101cc1SGerry Weißbach                unset($removeArray['media']);
479*7d101cc1SGerry Weißbach                unset($removeArray['fakeMedia']);
480*7d101cc1SGerry Weißbach            }
481*7d101cc1SGerry Weißbach
482*7d101cc1SGerry Weißbach            /* remove internal params */
483*7d101cc1SGerry Weißbach            unset($removeArray['ens']);
484*7d101cc1SGerry Weißbach            unset($removeArray['renderer']);
485*7d101cc1SGerry Weißbach            unset($removeArray['site']);
486*7d101cc1SGerry Weißbach            unset($removeArray['namespace']);
487*7d101cc1SGerry Weißbach            unset($removeArray['exportbody']);
488*7d101cc1SGerry Weißbach            unset($removeArray['addParams']);
489*7d101cc1SGerry Weißbach            unset($removeArray['template']);
490*7d101cc1SGerry Weißbach            unset($removeArray['eclipseDocZip']);
491*7d101cc1SGerry Weißbach            unset($removeArray['useTocFile']);
492*7d101cc1SGerry Weißbach            unset($removeArray['JavaHelpDocZip']);
493*7d101cc1SGerry Weißbach            unset($removeArray['depth']);
494*7d101cc1SGerry Weißbach            unset($removeArray['depthType']);
495*7d101cc1SGerry Weißbach            unset($removeArray['startcounter']);
496*7d101cc1SGerry Weißbach            unset($removeArray['pattern']);
497*7d101cc1SGerry Weißbach            unset($removeArray['TOCMapWithoutTranslation']);
498*7d101cc1SGerry Weißbach
499*7d101cc1SGerry Weißbach            // Keep custom options
500*7d101cc1SGerry Weißbach            if ( is_array($removeArray['customOptions']) )
501*7d101cc1SGerry Weißbach            {
502*7d101cc1SGerry Weißbach                foreach( $removeArray['customOptions'] as $key => $value )
503*7d101cc1SGerry Weißbach                {
504*7d101cc1SGerry Weißbach                    $removeArray[$key] = $value;
505*7d101cc1SGerry Weißbach                }
506*7d101cc1SGerry Weißbach            }
507*7d101cc1SGerry Weißbach            unset($removeArray['customOptions']);
508*7d101cc1SGerry Weißbach        }
509*7d101cc1SGerry Weißbach
510*7d101cc1SGerry Weißbach        if ( $isString && is_array($removeArray) ) {
511*7d101cc1SGerry Weißbach            $intermediate = $removeArray;
512*7d101cc1SGerry Weißbach            $removeArray = array();
513*7d101cc1SGerry Weißbach
514*7d101cc1SGerry Weißbach            foreach ( $intermediate as $key => $value ) {
515*7d101cc1SGerry Weißbach                if ( is_array($value) ) {
516*7d101cc1SGerry Weißbach                    foreach( array_values($value) as $aValue ) { // Array Handling
517*7d101cc1SGerry Weißbach                        $removeArray[] = $key . "[]=$aValue";
518*7d101cc1SGerry Weißbach                    }
519*7d101cc1SGerry Weißbach                } else {
520*7d101cc1SGerry Weißbach                    $value = trim($value);
521*7d101cc1SGerry Weißbach
522*7d101cc1SGerry Weißbach                    $removeArray[] = "$key" . ( ((empty($value) && intval($value) !== 0)) || $value == '' ? '' : "=$value" ); // If the Value is empty, the Key must be preserved
523*7d101cc1SGerry Weißbach                }
524*7d101cc1SGerry Weißbach            }
525*7d101cc1SGerry Weißbach
526*7d101cc1SGerry Weißbach            $removeArray = implode( ($this->settings->fileType == 'pdf' ? "&" : "&amp;"), $removeArray);
527*7d101cc1SGerry Weißbach        }
528*7d101cc1SGerry Weißbach    }
529*7d101cc1SGerry Weißbach
530*7d101cc1SGerry Weißbach    /**
531*7d101cc1SGerry Weißbach     * authenticate for direct downloads
532*7d101cc1SGerry Weißbach     **/
533*7d101cc1SGerry Weißbach    function basic_authentication() {
534*7d101cc1SGerry Weißbach        if (!isset($_SERVER['PHP_AUTH_USER'])) {
535*7d101cc1SGerry Weißbach            header('WWW-Authenticate: Basic realm="Siteexport Authentication"');
536*7d101cc1SGerry Weißbach            header('HTTP/1.0 401 Unauthorized');
537*7d101cc1SGerry Weißbach            print 'Unauthorized'; // print has to stay here
538*7d101cc1SGerry Weißbach            exit;
539*7d101cc1SGerry Weißbach        }
540*7d101cc1SGerry Weißbach
541*7d101cc1SGerry Weißbach        return array($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']);
542*7d101cc1SGerry Weißbach    }
543*7d101cc1SGerry Weißbach
544*7d101cc1SGerry Weißbach    /**
545*7d101cc1SGerry Weißbach     * returns a hashed name for the parameters
546*7d101cc1SGerry Weißbach     * @param $parameters
547*7d101cc1SGerry Weißbach     */
548*7d101cc1SGerry Weißbach    public function cronJobNameForParameters($parameters)
549*7d101cc1SGerry Weißbach    {
550*7d101cc1SGerry Weißbach        return md5($parameters);
551*7d101cc1SGerry Weißbach    }
552*7d101cc1SGerry Weißbach
553*7d101cc1SGerry Weißbach    /**
554*7d101cc1SGerry Weißbach     * Takes an URL and transforms it into the path+query part
555*7d101cc1SGerry Weißbach     * Used several times, e.g. for genering the hash for the cache file
556*7d101cc1SGerry Weißbach     * @param $url
557*7d101cc1SGerry Weißbach     */
558*7d101cc1SGerry Weißbach    public function urlToPathAndParams($url)
559*7d101cc1SGerry Weißbach    {
560*7d101cc1SGerry Weißbach        $query = parse_url($url, PHP_URL_QUERY);
561*7d101cc1SGerry Weißbach        $path = preg_replace(":^".DOKU_REL.":", "", parse_url($url, PHP_URL_PATH));
562*7d101cc1SGerry Weißbach        return "{$path}?{$query}";
563*7d101cc1SGerry Weißbach    }
564*7d101cc1SGerry Weißbach
565*7d101cc1SGerry Weißbach    /**
566*7d101cc1SGerry Weißbach     * Transforms an $_REQUEST into a Hash that can be used for cron and cache file
567*7d101cc1SGerry Weißbach     * @param $request
568*7d101cc1SGerry Weißbach     */
569*7d101cc1SGerry Weißbach    public function requestParametersToCacheHash($request)
570*7d101cc1SGerry Weißbach    {
571*7d101cc1SGerry Weißbach        $params = $this->urlToPathAndParams($this->prepare_POSTData($request));
572*7d101cc1SGerry Weißbach        $this->debug->message("Calculated the following Cache Hash URL: ", $params, 2);
573*7d101cc1SGerry Weißbach        return $this->cronJobNameForParameters($params);
574*7d101cc1SGerry Weißbach    }
575*7d101cc1SGerry Weißbach
576*7d101cc1SGerry Weißbach    /**
577*7d101cc1SGerry Weißbach     * Check a replaceID against a baseID - and make the replaceID relative against it
578*7d101cc1SGerry Weißbach     * @param $replaceID - ID which will be made relative if needed
579*7d101cc1SGerry Weißbach     * @param $baseID - ID which is the reference to be made relative against
580*7d101cc1SGerry Weißbach     */
581*7d101cc1SGerry Weißbach    public function getRelativeURL($replaceID, $baseID)
582*7d101cc1SGerry Weißbach    {
583*7d101cc1SGerry Weißbach        $origReplaceID = $replaceID;
584*7d101cc1SGerry Weißbach
585*7d101cc1SGerry Weißbach        $replaceTmp = cleanID($replaceID);
586*7d101cc1SGerry Weißbach        $file = noNS($replaceTmp);
587*7d101cc1SGerry Weißbach
588*7d101cc1SGerry Weißbach        $replaceID = getNS($replaceTmp);
589*7d101cc1SGerry Weißbach        $baseID = getNS($baseID);
590*7d101cc1SGerry Weißbach
591*7d101cc1SGerry Weißbach        $replaceParts = explode(':', $replaceID);
592*7d101cc1SGerry Weißbach        $baseParts = explode(':', $baseID);
593*7d101cc1SGerry Weißbach        $exportNSParts = explode(':', cleanID($this->settings->exportNamespace));
594*7d101cc1SGerry Weißbach
595*7d101cc1SGerry Weißbach        $newBase = array();
596*7d101cc1SGerry Weißbach
597*7d101cc1SGerry Weißbach        foreach($exportNSParts as $exportNS)
598*7d101cc1SGerry Weißbach        {
599*7d101cc1SGerry Weißbach            if ( $replaceParts[0] == $exportNS && $baseParts[0] == $exportNS )
600*7d101cc1SGerry Weißbach            {
601*7d101cc1SGerry Weißbach                array_shift($replaceParts);
602*7d101cc1SGerry Weißbach                array_shift($baseParts);
603*7d101cc1SGerry Weißbach                array_shift($exportNSParts);
604*7d101cc1SGerry Weißbach            }
605*7d101cc1SGerry Weißbach            else {
606*7d101cc1SGerry Weißbach                // Nothing is matching anymore
607*7d101cc1SGerry Weißbach                break;
608*7d101cc1SGerry Weißbach            }
609*7d101cc1SGerry Weißbach        }
610*7d101cc1SGerry Weißbach
611*7d101cc1SGerry Weißbach        $i = count($exportNSParts);
612*7d101cc1SGerry Weißbach        $this->debug->message("Checking", array('current extra removing amount'=>$i,'replace'=>$replaceParts,'base'=>$baseParts,'exportNSParts'=>$exportNSParts),1);
613*7d101cc1SGerry Weißbach
614*7d101cc1SGerry Weißbach        // Now if there is just one item in the ens left and it matches the base, but not the replace, this miiiiiight be the case we want.
615*7d101cc1SGerry Weißbach        if ( count($exportNSParts) == 1 && $exportNSParts[0] == $baseParts[0] )
616*7d101cc1SGerry Weißbach        {
617*7d101cc1SGerry Weißbach            array_shift($replaceParts);
618*7d101cc1SGerry Weißbach            $newBase = implode('/', $replaceParts);
619*7d101cc1SGerry Weißbach
620*7d101cc1SGerry Weißbach            if ( substr($newBase, -1) != '/' )
621*7d101cc1SGerry Weißbach            {
622*7d101cc1SGerry Weißbach                $newBase .= '/';
623*7d101cc1SGerry Weißbach            }
624*7d101cc1SGerry Weißbach
625*7d101cc1SGerry Weißbach            $this->debug->message("new Base: ", $newBase, 1);
626*7d101cc1SGerry Weißbach
627*7d101cc1SGerry Weißbach            // Now check from the beginning ...
628*7d101cc1SGerry Weißbach            return $newBase . $file;
629*7d101cc1SGerry Weißbach        }
630*7d101cc1SGerry Weißbach
631*7d101cc1SGerry Weißbach        return $origReplaceID;
632*7d101cc1SGerry Weißbach    }
633*7d101cc1SGerry Weißbach}
634*7d101cc1SGerry Weißbach
635*7d101cc1SGerry Weißbach?>