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