xref: /dokuwiki/lib/plugins/styling/admin.php (revision 7ef28ec151e9f703bc839869e4336ba860b54356)
1<?php
2/**
3 * DokuWiki Plugin styling (Admin Component)
4 *
5 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
6 * @author  Andreas Gohr <andi@splitbrain.org>
7 */
8class admin_plugin_styling extends DokuWiki_Admin_Plugin
9{
10
11    public $ispopup = false;
12
13    /**
14     * @return int sort number in admin menu
15     */
16    public function getMenuSort()
17    {
18        return 1000;
19    }
20
21    /**
22     * @return bool true if only access for superuser, false is for superusers and moderators
23     */
24    public function forAdminOnly()
25    {
26        return true;
27    }
28
29    /**
30     * handle the different actions (also called from ajax)
31     */
32    public function handle()
33    {
34        global $INPUT;
35        $run = $INPUT->extract('run')->str('run');
36        if (!$run) return;
37        $run = 'run'.ucfirst($run);
38        $this->$run();
39    }
40
41    /**
42     * Render HTML output, e.g. helpful text and a form
43     */
44    public function html()
45    {
46        $class = 'nopopup';
47        if ($this->ispopup) $class = 'ispopup page';
48
49        echo '<div id="plugin__styling" class="'.$class.'">';
50        ptln('<h1>'.$this->getLang('menu').'</h1>');
51        $this->form();
52        echo '</div>';
53    }
54
55    /**
56     * Create the actual editing form
57     */
58    public function form()
59    {
60        global $conf;
61        global $ID;
62
63        $styleUtil = new \dokuwiki\StyleUtils($conf['template'], true);
64        $styleini     = $styleUtil->cssStyleini();
65        $replacements = $styleini['replacements'];
66
67        if ($this->ispopup) {
68            $target = DOKU_BASE.'lib/plugins/styling/popup.php';
69        } else {
70            $target = wl($ID, array('do' => 'admin', 'page' => 'styling'));
71        }
72
73        if (empty($replacements)) {
74            echo '<p class="error">'.$this->getLang('error').'</p>';
75        } else {
76            echo $this->locale_xhtml('intro');
77
78            echo '<form class="styling" method="post" action="'.$target.'">';
79
80            echo '<table><tbody>';
81            foreach ($replacements as $key => $value) {
82                $name = tpl_getLang($key);
83                if (empty($name)) $name = $this->getLang($key);
84                if (empty($name)) $name = $key;
85
86                echo '<tr>';
87                echo '<td><label for="tpl__'.hsc($key).'">'.$name.'</label></td>';
88                echo '<td><input type="'.$this->colorType($key).'" name="tpl['.hsc($key).']" id="tpl__'.hsc($key).'"
89                    value="'.hsc($this->colorValue($value)).'" dir="ltr" /></td>';
90                echo '</tr>';
91            }
92            echo '</tbody></table>';
93
94            echo '<p>';
95            echo '<button type="submit" name="run[preview]" class="btn_preview primary">'.
96                $this->getLang('btn_preview').'</button> ';
97            #FIXME only if preview.ini exists:
98            echo '<button type="submit" name="run[reset]">'.$this->getLang('btn_reset').'</button>';
99            echo '</p>';
100
101            echo '<p>';
102            echo '<button type="submit" name="run[save]" class="primary">'.$this->getLang('btn_save').'</button>';
103            echo '</p>';
104
105            echo '<p>';
106            #FIXME only if local.ini exists:
107            echo '<button type="submit" name="run[revert]">'.$this->getLang('btn_revert').'</button>';
108            echo '</p>';
109
110            echo '</form>';
111
112            echo tpl_locale_xhtml('style');
113        }
114    }
115
116    /**
117     * Adjust three char color codes to the 6 char one supported by browser's color input
118     *
119     * @param string $value
120     * @return string
121     */
122    protected function colorValue($value)
123    {
124        if (preg_match('/^#([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])$/', $value, $match)) {
125            return '#' . $match[1] . $match[1] . $match[2] . $match[2] . $match[3] . $match[3];
126        }
127        return $value;
128    }
129
130    /**
131     * Decide the input type based on the key name
132     *
133     * @param string $key
134     * @return string color|text
135     */
136    protected function colorType($key)
137    {
138        static $colors = array(
139            'text',
140            'background',
141            'text_alt',
142            'background_alt',
143            'text_neu',
144            'background_neu',
145            'border',
146            'highlight',
147            'background_site',
148            'link',
149            'existing',
150            'missing',
151        );
152
153        if (preg_match('/colou?r/', $key) || in_array(trim($key, '_'), $colors)) {
154            return 'color';
155        } else {
156            return 'text';
157        }
158    }
159
160    /**
161     * saves the preview.ini (alos called from ajax directly)
162     */
163    public function runPreview()
164    {
165        global $conf;
166        $ini = $conf['cachedir'].'/preview.ini';
167        io_saveFile($ini, $this->makeini());
168    }
169
170    /**
171     * deletes the preview.ini
172     */
173    protected function runReset()
174    {
175        global $conf;
176        $ini = $conf['cachedir'].'/preview.ini';
177        io_saveFile($ini, '');
178    }
179
180    /**
181     * deletes the local style.ini replacements
182     */
183    protected function runRevert()
184    {
185        $this->replaceIni('');
186        $this->runReset();
187    }
188
189    /**
190     * save the local style.ini replacements
191     */
192    protected function runSave()
193    {
194        $this->replaceIni($this->makeini());
195        $this->runReset();
196    }
197
198    /**
199     * create the replacement part of a style.ini from submitted data
200     *
201     * @return string
202     */
203    protected function makeini()
204    {
205        global $INPUT;
206
207        $ini = "[replacements]\n";
208        $ini .= ";These overwrites have been generated from the Template styling Admin interface\n";
209        $ini .= ";Any values in this section will be overwritten by that tool again\n";
210        foreach ($INPUT->arr('tpl') as $key => $val) {
211            $ini .= $key.' = "'.addslashes($val).'"'."\n";
212        }
213
214        return $ini;
215    }
216
217    /**
218     * replaces the replacement parts in the local ini
219     *
220     * @param string $new the new ini contents
221     */
222    protected function replaceIni($new)
223    {
224        global $conf;
225        $ini = DOKU_CONF."tpl/".$conf['template']."/style.ini";
226        if (file_exists($ini)) {
227            $old = io_readFile($ini);
228            $old = preg_replace('/\[replacements\]\n.*?(\n\[.*]|$)/s', '\\1', $old);
229            $old = trim($old);
230        } else {
231            $old = '';
232        }
233
234        io_makeFileDir($ini);
235        io_saveFile($ini, "$old\n\n$new");
236    }
237}
238
239// vim:ts=4:sw=4:et:
240