1<?php
2/**
3 * Helper class handling ODT plugin configuration stuff.
4 *
5 * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
6 * @author     LarsDW223
7 */
8
9// must be run within Dokuwiki
10if (!defined('DOKU_INC')) die();
11
12/**
13 * Class helper_plugin_odt_config
14 *
15 * @package helper\config
16 */
17class helper_plugin_odt_config extends DokuWiki_Plugin {
18    /** @var array Central storage for config parameters. */
19    protected $config = array();
20    protected $mode = null;
21    protected $messages = null;
22    protected $convert_to = null;
23
24    /**
25     * @return array
26     */
27    function getMethods() {
28        $result = array();
29        $result[] = array(
30                'name'   => 'setParam',
31                'desc'   => 'set config param $name to $value.',
32                'params' => array('name' => 'string', 'value' => 'mixed'),
33                );
34        $result[] = array(
35                'name'   => 'getParam',
36                'desc'   => 'returns the current value for config param $value',
37                'params' => array('name' => 'string'),
38                'return' => array('value' => 'mixed'),
39                );
40        $result[] = array(
41                'name'   => 'isParam',
42                'desc'   => 'Is $name a known config param?',
43                'params' => array('name' => 'string'),
44                'return' => array('isParam' => 'bool'),
45                );
46        $result[] = array(
47                'name'   => 'isRefreshable',
48                'desc'   => 'Is $name a refreshable config param?',
49                'params' => array('name' => 'string'),
50                'return' => array('isRefreshable' => 'bool'),
51                );
52        $result[] = array(
53                'name'   => 'hasDWGlobalSetting',
54                'desc'   => 'Does param $name have a corresponding global DW param to inherit from?',
55                'params' => array('name' => 'string'),
56                'return' => array('hasDWGlobalSetting' => 'bool'),
57                );
58        $result[] = array(
59                'name'   => 'isGlobalSetting',
60                'desc'   => 'Does param $name have a global config setting?',
61                'params' => array('name' => 'string'),
62                'return' => array('isGlobalSetting' => 'bool'),
63                );
64        $result[] = array(
65                'name'   => 'isURLSetting',
66                'desc'   => 'Does param $name have a URL setting?',
67                'params' => array('name' => 'string'),
68                'return' => array('isURLSetting' => 'bool'),
69                );
70        $result[] = array(
71                'name'   => 'isMetaSetting',
72                'desc'   => 'Does param $name have a Metadata setting?',
73                'params' => array('name' => 'string'),
74                'return' => array('isMetaSetting' => 'bool'),
75                );
76        $result[] = array(
77                'name'   => 'addingToMetaIsAllowed',
78                'desc'   => 'Is it allowed to add $name (at position $pos) to the meta data?',
79                'params' => array('name' => 'string', 'pos' => 'integer'),
80                'return' => array('addingAllowed' => 'bool'),
81                );
82        $result[] = array(
83                'name'   => 'load',
84                'desc'   => 'Load the corrent settings from the global config, URL params or syntax tags/meta data',
85                'params' => array('warnings' => 'string'),
86                'return' => array('mode' => 'string'),
87                );
88        $result[] = array(
89                'name'   => 'refresh',
90                'desc'   => 'Refresh the corrent settings from the global config, URL params or syntax tags/meta data',
91                );
92        $result[] = array(
93                'name'   => 'hash',
94                'desc'   => 'Get MD5 hash of currently stored settings.',
95                'return' => array('hash' => 'string'),
96                );
97        return $result;
98    }
99
100    /**
101     * Constructor. Loads helper plugins.
102     */
103    public function __construct() {
104        // Set up empty array with known config parameters
105
106        // Option 'dformat', taken from global value.
107        $this->config ['dformat'] =
108            array('value'              => NULL,
109                  'DWGlobalName'       => 'dformat',
110                  'hasGlobal'          => false,
111                  'hasURL'             => false,
112                  'hasMeta'            => false,
113                  'addMetaAtStartOnly' => false,
114                  'refresh'            => false);
115        // Option 'useheading', taken from global value.
116        $this->config ['useheading'] =
117            array('value'              => NULL,
118                  'DWGlobalName'       => 'useheading',
119                  'hasGlobal'          => false,
120                  'hasURL'             => false,
121                  'hasMeta'            => false,
122                  'addMetaAtStartOnly' => false,
123                  'refresh'            => false);
124        // Temp directory, taken from global value.
125        $this->config ['tmpdir'] =
126            array('value'              => NULL,
127                  'DWGlobalName'       => 'tmpdir',
128                  'hasGlobal'          => false,
129                  'hasURL'             => false,
130                  'hasMeta'            => false,
131                  'addMetaAtStartOnly' => false,
132                  'refresh'            => false);
133        // Media directory, taken from global value.
134        $this->config ['mediadir'] =
135            array('value'              => NULL,
136                  'DWGlobalName'       => 'mediadir',
137                  'hasGlobal'          => false,
138                  'hasURL'             => false,
139                  'hasMeta'            => false,
140                  'addMetaAtStartOnly' => false,
141                  'refresh'            => false);
142        // Data directory, taken from global value.
143        $this->config ['datadir'] =
144            array('value'              => NULL,
145                  'DWGlobalName'       => 'datadir',
146                  'hasGlobal'          => false,
147                  'hasURL'             => false,
148                  'hasMeta'            => false,
149                  'addMetaAtStartOnly' => false,
150                  'refresh'            => false);
151        // Save directory, taken from global value.
152        $this->config ['savedir'] =
153            array('value'              => NULL,
154                  'DWGlobalName'       => 'savedir',
155                  'hasGlobal'          => false,
156                  'hasURL'             => false,
157                  'hasMeta'            => false,
158                  'addMetaAtStartOnly' => false,
159                  'refresh'            => false);
160        // Option 'showexportbutton'
161        $this->config ['showexportbutton'] =
162            array('value'              => NULL,
163                  'DWGlobalName'       => NULL,
164                  'hasGlobal'          => true,
165                  'hasURL'             => false,
166                  'hasMeta'            => false,
167                  'addMetaAtStartOnly' => false,
168                  'refresh'            => false);
169        // Option 'showpdfexportbutton'
170        $this->config ['showpdfexportbutton'] =
171            array('value'              => NULL,
172                  'DWGlobalName'       => NULL,
173                  'hasGlobal'          => true,
174                  'hasURL'             => false,
175                  'hasMeta'            => false,
176                  'addMetaAtStartOnly' => false,
177                  'refresh'            => false);
178        // Template directory.
179        $this->config ['tpl_dir'] =
180            array('value'              => NULL,
181                  'DWGlobalName'       => NULL,
182                  'hasGlobal'          => true,
183                  'hasURL'             => false,
184                  'hasMeta'            => false,
185                  'addMetaAtStartOnly' => false,
186                  'refresh'            => false);
187        // ODT template.
188        $this->config ['odt_template'] =
189            array('value'              => NULL,
190                  'DWGlobalName'       => NULL,
191                  'hasGlobal'          => true,
192                  'hasURL'             => true,
193                  'hasMeta'            => true,
194                  'addMetaAtStartOnly' => false,
195                  'refresh'            => false);
196        // Template =ODT template, old parameter,
197        // included for backwards compatibility.
198        $this->config ['template'] =
199            array('value'              => NULL,
200                  'DWGlobalName'       => NULL,
201                  'hasGlobal'          => true,
202                  'hasURL'             => true,
203                  'hasMeta'            => true,
204                  'addMetaAtStartOnly' => false,
205                  'refresh'            => false);
206        // CSS usage.
207        $this->config ['css_usage'] =
208            array('value'              => NULL,
209                  'DWGlobalName'       => NULL,
210                  'hasGlobal'          => true,
211                  'hasURL'             => true,
212                  'hasMeta'            => true,
213                  'addMetaAtStartOnly' => false,
214                  'refresh'            => false);
215        // CSS template.
216        $this->config ['css_template'] =
217            array('value'              => NULL,
218                  'DWGlobalName'       => NULL,
219                  'hasGlobal'          => true,
220                  'hasURL'             => true,
221                  'hasMeta'            => true,
222                  'addMetaAtStartOnly' => false,
223                  'refresh'            => false);
224        // CSS media selector (screen or print)
225        $this->config ['media_sel'] =
226            array('value'              => NULL,
227                  'DWGlobalName'       => NULL,
228                  'hasGlobal'          => true,
229                  'hasURL'             => true,
230                  'hasMeta'            => true,
231                  'addMetaAtStartOnly' => false,
232                  'refresh'            => false);
233        // Standard font size for CSS import = value for 1em/100%
234        $this->config ['css_font_size'] =
235            array('value'              => NULL,
236                  'DWGlobalName'       => NULL,
237                  'hasGlobal'          => true,
238                  'hasURL'             => true,
239                  'hasMeta'            => true,
240                  'addMetaAtStartOnly' => false,
241                  'refresh'            => false);
242        // Apply CSS font size to ODT template styles/scratch styles
243        $this->config ['apply_fs_to_non_css'] =
244            array('value'              => NULL,
245                  'DWGlobalName'       => NULL,
246                  'hasGlobal'          => true,
247                  'hasURL'             => true,
248                  'hasMeta'            => true,
249                  'addMetaAtStartOnly' => false,
250                  'refresh'            => false);
251        // Twips per pixel x and y
252        $this->config ['twips_per_pixel_x'] =
253            array('value'              => NULL,
254                  'DWGlobalName'       => NULL,
255                  'hasGlobal'          => true,
256                  'hasURL'             => true,
257                  'hasMeta'            => true,
258                  'addMetaAtStartOnly' => false,
259                  'refresh'            => false);
260        $this->config ['twips_per_pixel_y'] =
261            array('value'              => NULL,
262                  'DWGlobalName'       => NULL,
263                  'hasGlobal'          => true,
264                  'hasURL'             => true,
265                  'hasMeta'            => true,
266                  'addMetaAtStartOnly' => false,
267                  'refresh'            => false);
268        // Page format, orientation and margins
269        //
270        // This settings also have a syntax tag changing the page format
271        // and introducing a pagebreak. The meta setting changes the start
272        // page format and may only be set if at the start of the document.
273        // Otherwise changing the page fomat in the document would also
274        // change the format of the first page!
275        $this->config ['format']        =
276            array('value'              => NULL,
277                  'DWGlobalName'       => NULL,
278                  'hasGlobal'          => true,
279                  'hasURL'             => true,
280                  'hasMeta'            => true,
281                  'addMetaAtStartOnly' => true,
282                  'refresh'            => false);
283        $this->config ['orientation']   =
284            array('value'              => NULL,
285                  'DWGlobalName'       => NULL,
286                  'hasGlobal'          => true,
287                  'hasURL'             => true,
288                  'hasMeta'            => true,
289                  'addMetaAtStartOnly' => true,
290                  'refresh'            => false);
291        $this->config ['margin_top']    =
292            array('value'              => NULL,
293                  'DWGlobalName'       => NULL,
294                  'hasGlobal'          => true,
295                  'hasURL'             => true,
296                  'hasMeta'            => true,
297                  'addMetaAtStartOnly' => true,
298                  'refresh'            => false);
299        $this->config ['margin_right']  =
300            array('value'              => NULL,
301                  'DWGlobalName'       => NULL,
302                  'hasGlobal'          => true,
303                  'hasURL'             => true,
304                  'hasMeta'            => true,
305                  'addMetaAtStartOnly' => true,
306                  'refresh'            => false);
307        $this->config ['margin_bottom'] =
308            array('value'              => NULL,
309                  'DWGlobalName'       => NULL,
310                  'hasGlobal'          => true,
311                  'hasURL'             => true,
312                  'hasMeta'            => true,
313                  'addMetaAtStartOnly' => true,
314                  'refresh'            => false);
315        $this->config ['margin_left']   =
316            array('value'              => NULL,
317                  'DWGlobalName'       => NULL,
318                  'hasGlobal'          => true,
319                  'hasURL'             => true,
320                  'hasMeta'            => true,
321                  'addMetaAtStartOnly' => true,
322                  'refresh'            => false);
323        $this->config ['page']          =
324            array('value'              => NULL,
325                  'DWGlobalName'       => NULL,
326                  'hasGlobal'          => false,
327                  'hasURL'             => true,
328                  'hasMeta'            => true,
329                  'addMetaAtStartOnly' => true,
330                  'refresh'            => false);
331        // Disable links
332        $this->config ['disable_links'] =
333            array('value'              => NULL,
334                  'DWGlobalName'       => NULL,
335                  'hasGlobal'          => true,
336                  'hasURL'             => true,
337                  'hasMeta'            => true,
338                  'addMetaAtStartOnly' => false,
339                  'refresh'            => true);
340        // TOC: maxlevel
341        $this->config ['toc_maxlevel'] =
342            array('value'              => NULL,
343                  'DWGlobalName'       => 'maxtoclevel',
344                  'hasGlobal'          => true,
345                  'hasURL'             => true,
346                  'hasMeta'            => true,
347                  'addMetaAtStartOnly' => false,
348                  'refresh'            => false);
349        // TOC: toc_leader_sign
350        $this->config ['toc_leader_sign'] =
351            array('value'              => NULL,
352                  'DWGlobalName'       => NULL,
353                  'hasGlobal'          => true,
354                  'hasURL'             => true,
355                  'hasMeta'            => true,
356                  'addMetaAtStartOnly' => false,
357                  'refresh'            => false);
358        // TOC: toc_indents
359        $this->config ['toc_indents'] =
360            array('value'              => NULL,
361                  'DWGlobalName'       => NULL,
362                  'hasGlobal'          => true,
363                  'hasURL'             => true,
364                  'hasMeta'            => true,
365                  'addMetaAtStartOnly' => false,
366                  'refresh'            => false);
367        // TOC: toc_pagebreak
368        $this->config ['toc_pagebreak'] =
369            array('value'              => NULL,
370                  'DWGlobalName'       => NULL,
371                  'hasGlobal'          => true,
372                  'hasURL'             => true,
373                  'hasMeta'            => true,
374                  'addMetaAtStartOnly' => false,
375                  'refresh'            => false);
376        // TOC-Style (default, assigned to each level)
377        $this->config ['toc_style'] =
378            array('value'              => NULL,
379                  'DWGlobalName'       => NULL,
380                  'hasGlobal'          => true,
381                  'hasURL'             => true,
382                  'hasMeta'            => true,
383                  'addMetaAtStartOnly' => false,
384                  'refresh'            => false);
385        // Index display in browser
386        $this->config ['index_in_browser'] =
387            array('value'              => NULL,
388                  'DWGlobalName'       => NULL,
389                  'hasGlobal'          => true,
390                  'hasURL'             => true,
391                  'hasMeta'            => true,
392                  'addMetaAtStartOnly' => false,
393                  'refresh'            => false);
394        // Index display in browser
395        $this->config ['outline_list_style'] =
396            array('value'              => NULL,
397                  'DWGlobalName'       => NULL,
398                  'hasGlobal'          => true,
399                  'hasURL'             => true,
400                  'hasMeta'            => true,
401                  'addMetaAtStartOnly' => false,
402                  'refresh'            => false);
403        // Command line template for pdf conversion
404        $this->config ['convert_to_pdf']  =
405            array('value'              => NULL,
406                  'DWGlobalName'       => NULL,
407                  'hasGlobal'          => true,
408                  'hasURL'             => true,
409                  'hasMeta'            => false,
410                  'addMetaAtStartOnly' => false,
411                  'refresh'            => false);
412        // List-Label-Alignment (ordered lists)
413        $this->config ['olist_label_align'] =
414            array('value'              => NULL,
415                  'DWGlobalName'       => NULL,
416                  'hasGlobal'          => true,
417                  'hasURL'             => true,
418                  'hasMeta'            => true,
419                  'addMetaAtStartOnly' => false,
420                  'refresh'            => false);
421    }
422
423    /**
424     * Set a config parameter.
425     * @param string $name Name of the config param
426     * @param string $value Value to be set
427     */
428    public function setParam($name, $value) {
429        if (!empty($name)) {
430            $this->config [$name]['value'] = $value;
431        }
432    }
433
434    /**
435     * Get a config parameter.
436     *
437     * @param string $name Name of the config param
438     * @return mixed Current value of param $name
439     */
440    public function getParam($name) {
441        return $this->config [$name]['value'];
442    }
443
444    /**
445     * Is the $name specified the name of a ODT plugin config parameter?
446     *
447     * @param string $name Name of the config param
448     * @return bool Is it a config parameter?
449     */
450    public function isParam($name) {
451        if (!empty($name)) {
452            return array_key_exists($name, $this->config);
453        }
454        return false;
455    }
456
457    /**
458     * Does the config parameter need a refresh?
459     *
460     * @param string $name Name of the config param
461     * @return bool is refreshable
462     */
463    public function isRefreshable($name) {
464        if (!empty($name)) {
465            return $this->config [$name]['refresh'];
466        }
467        return false;
468    }
469
470    /**
471     * Does the config parameter have a DokuWiki global config setting?
472     *
473     * @param string $name Name of the config param
474     * @return string Name of global DokuWiki option or NULL
475     */
476    public function hasDWGlobalSetting($name) {
477        if (!empty($name)) {
478            return $this->config [$name]['DWGlobalName'];
479        }
480        return false;
481    }
482
483    /**
484     * Does the config parameter have a global config setting?
485     *
486     * @param string $name Name of the config param
487     * @return bool is global setting
488     */
489    public function isGlobalSetting($name) {
490        if (!empty($name)) {
491            return $this->config [$name]['hasGlobal'];
492        }
493        return false;
494    }
495
496    /**
497     * Does the config parameter have a URL config setting?
498     *
499     * @param string $name Name of the config param
500     * @return bool is URL Setting
501     */
502    public function isURLSetting($name) {
503        if (!empty($name)) {
504            return $this->config [$name]['hasURL'];
505        }
506        return false;
507    }
508
509    /**
510     * Does the config parameter have a Meta-Data config setting?
511     *
512     * @param string $name Name of the config param
513     * @return bool is Meta Setting
514     */
515    public function isMetaSetting($name) {
516        if (!empty($name)) {
517            return $this->config [$name]['hasMeta'];
518        }
519        return false;
520    }
521
522    /**
523     * May the parameter be added to the Meta data?
524     *
525     * @param string $name Name of the config param
526     * @param string $pos  Poistion in wiki page
527     * @return bool
528     */
529    public function addingToMetaIsAllowed($name, $pos) {
530        if (!empty($name) and $this->isMetaSetting($name)) {
531            if ($pos != 0 and $this->config [$name]['addMetaAtStartOnly']) {
532                return false;
533            }
534            return true;
535        }
536        return false;
537    }
538
539    /**
540     * Load all config parameters: global config options, URL and syntax tag.
541     * Check export mode: scratch, ODT template or CSS template?
542     *
543     * @param string $warning (reference) warning message
544     * @return string Export mode to be used
545     */
546    protected function loadIntern(&$warning, $refresh) {
547        global $conf, $ID, $INPUT;
548
549        if ( !isset($this->mode) ) {
550            $this->mode = 'scratch';
551        }
552
553        // Get all known config parameters, see __construct().
554        $odt_meta = p_get_metadata($ID, 'relation odt');
555        foreach ($this->config as $name => $value) {
556            if ( !$refresh || $this->isRefreshable($name) ) {
557                $value = $this->getParam ($name);
558
559                // Check DokuWiki global configuration.
560                $dw_name = $this->hasDWGlobalSetting ($name);
561                if (!$value && isset($conf[$dw_name])) {
562                    $this->setParam ($name, $conf[$dw_name]);
563                }
564
565                // Check plugin configuration.
566                if (!$value && $this->isGlobalSetting($name) && $this->getConf($name)) {
567                    $this->setParam ($name, $this->getConf($name));
568                }
569
570                // Check if parameter is provided in the URL.
571                $url_param = $INPUT->get->str($name, $value, true);
572                if ($this->isURLSetting($name) && isset($url_param)) {
573                    $this->setParam ($name, $url_param);
574                }
575
576                // Check meta data in case syntax tags have written
577                // the config parameters to it.
578                unset($value);
579                if (isset($odt_meta[$name])) $value = $odt_meta[$name];
580                if($this->isMetaSetting($name) && !empty($value)) {
581                    $this->setParam ($name, $value);
582                }
583
584                // ODT-Template based export required?
585                // (old parameter)
586                $template = $this->getParam ('template');
587                if ( $name == 'template' && !empty($template) ) {
588                    // ODT-Template chosen
589                    if (file_exists($this->getParam('mediadir').'/'.$this->getParam('tpl_dir')."/".$this->getParam ('template'))) {
590                        //template found
591                        $this->mode = 'ODT template';
592                    } else {
593                        // template chosen but not found : warn the user and use the default template
594                        $warning = sprintf($this->getLang('tpl_not_found'),$this->getParam ('template'),$this->getParam ('tpl_dir'));
595                        $this->messages .= $warning;
596                    }
597                }
598
599                // ODT-Template based export required?
600                $odt_template = $this->getParam ('odt_template');
601                if ( $name == 'odt_template' && !empty($odt_template) ) {
602                    // ODT-Template chosen
603                    if (file_exists($this->getParam('mediadir').'/'.$this->getParam('tpl_dir')."/".$this->getParam ('odt_template'))) {
604                        // Template found: ODT or CSS?
605                        if ( strpos ($odt_template, '.css') === false ) {
606                            $this->mode = 'ODT template';
607                        } else {
608                            $this->mode = 'CSS template';
609                        }
610                    } else {
611                        // template chosen but not found : warn the user and use the default template
612                        $warning = sprintf($this->getLang('tpl_not_found'),$this->getParam ('odt_template'),$this->getParam ('tpl_dir'));
613                    }
614                }
615
616                // Convert Yes/No-String in 'disable_links' to boolean.
617                if ( $name == 'disable_links' ) {
618                    $temp = $this->getParam ('disable_links');
619                    if ( strcasecmp($temp, 'Yes') != 0 && $temp !== true ) {
620                        $this->setParam ('disable_links', false);
621                    } else {
622                        $this->setParam ('disable_links', true);
623                    }
624                }
625
626                // Convert Yes/No-String in 'toc_pagebreak' to boolean.
627                if ( $name == 'toc_pagebreak' ) {
628                    $temp = $this->getParam ('toc_pagebreak');
629                    if ( strcasecmp($temp, 'Yes') == 0 || $temp === true ) {
630                        $this->setParam ('toc_pagebreak', true);
631                    } else {
632                        $this->setParam ('toc_pagebreak', false);
633                    }
634                }
635            }
636        }
637
638        $template = $this->getParam ('template');
639        $odt_template = $this->getParam ('odt_template');
640        if (!empty($template) && empty($odt_template)) {
641            $this->setParam ('odt_template', $this->getParam ('template'));
642        }
643
644        return $this->mode;
645    }
646
647    /**
648     * Load config parameters. See loadIntern().
649     *
650     * @param string $warning (reference) warning message
651     * @return string Export mode to be used
652     */
653    public function load(&$warning) {
654        return $this->loadIntern($warning, false);
655    }
656
657    /**
658     * Refresh config parameters. See loadIntern().
659     */
660    public function refresh() {
661        $this->loadIntern($warning, true);
662    }
663
664    /**
665     * Get hash for current config content.
666     *
667     * @return string The calculated hash
668     */
669    public function hash() {
670        $content = '';
671
672        // Get all known config parameters in one string
673        foreach ($this->config as $name => $value) {
674            $content .= $name.'='.$this->getParam ($name).';';
675        }
676
677        // Return the md5 hash for it.
678        return hash('md5', $content);
679    }
680
681    /**
682     * Get warning messages from loading the config which
683     * can be presented to the user.
684     *
685     * @return string Collected messages.
686     */
687    public function getMessages() {
688        return $this->messages;
689    }
690
691    /**
692     * Set conversion option.
693     *
694     * @param string $format Conversion format (e.g. 'pdf')
695     */
696    public function setConvertTo($format) {
697        $this->convert_to = $format;
698    }
699
700    /**
701     * Set conversion option.
702     *
703     * @return string Currently set conversion option
704     *                or NULL (output ODT format)
705     */
706    public function getConvertTo() {
707        return ($this->convert_to);
708    }
709}
710