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