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