1<?php
2
3/**
4 * Dokuwiki Advanced Import/Export Plugin
5 *
6 * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
7 * @author     Giuseppe Di Terlizzi <giuseppe.diterlizzi@gmail.com>
8 */
9
10
11
12class admin_plugin_advanced_export extends DokuWiki_Admin_Plugin
13{
14
15    /**
16     * @return int sort number in admin menu
17     */
18    public function getMenuSort()
19    {
20        return 2;
21    }
22
23    public function getMenuIcon()
24    {
25        return dirname(__FILE__) . '/../svg/export.svg';
26    }
27
28    public function forAdminOnly()
29    {
30        return false;
31    }
32
33    public function getMenuText($language)
34    {
35        return $this->getLang('menu_export');
36    }
37
38    public function handle()
39    {
40        global $INPUT;
41
42        if (!$INPUT->has('cmd')) {
43            return;
44        }
45
46        if (!checkSecurityToken()) {
47            return;
48        }
49
50        $cmd = $INPUT->extract('cmd')->str('cmd');
51
52        if ($cmd) {
53            $cmd = "cmd_$cmd";
54            $this->$cmd();
55        }
56
57    }
58
59    public function html()
60    {
61
62        global $INPUT;
63        global $lang;
64        global $conf;
65        global $ID;
66
67        $lang['toc'] = $this->getLang('menu_export');
68
69        echo '<div id="plugin_advanced_export">';
70        echo $this->locale_xhtml('export');
71
72        echo '<form action="" method="post" class="form-inline">';
73
74        $this->steps_dispatcher();
75
76        formSecurityToken();
77
78        echo '<input type="hidden" name="do" value="admin" />';
79        echo '<input type="hidden" name="page" value="advanced_export" />';
80
81        echo '</form>';
82        echo '</div>';
83
84    }
85
86    private function steps_dispatcher()
87    {
88
89        global $INPUT;
90
91        $step = $INPUT->extract('export')->str('export');
92
93        if (!$step) {
94            return $this->step_select_ns();
95        }
96
97        return call_user_func(array($this, "step_$step"));
98
99    }
100
101    private function step_select_ns()
102    {
103
104        global $conf;
105        global $lang;
106
107        $namespaces = array();
108        $options    = array();
109
110        search($namespaces, $conf['datadir'], 'search_namespaces', $options, '');
111
112        echo sprintf('<h3>%s</h3>', $this->getLang('exp_select_namespace'));
113
114        echo '<p><select name="ns" class="form-control">';
115        echo '<option value="">' . $this->getLang('exp_select_namespace') . '</option>';
116        echo '<option value="(root)">(root)</option>';
117
118        foreach ($namespaces as $namespace) {
119            echo sprintf('<option value="%s">%s</option>', $namespace['id'], $namespace['id']);
120        }
121
122        echo '</select></p>';
123        echo '<p>&nbsp;</p>';
124
125        echo '<input type="hidden" name="step" value="select-ns" />';
126
127        echo '<p class="pull-right">';
128        echo sprintf('<label><input type="checkbox" name="include-sub-ns" /> %s</label> ', $this->getLang('exp_include_sub_namespaces'));
129        echo sprintf('<button type="submit" name="cmd[export]" class="btn btn-default">%s &rarr;</button> ', $this->getLang('exp_export_all_pages_in_namespace'));
130        echo sprintf('<button type="submit" name="export[select_pages]" class="btn btn-primary primary">%s &rarr;</button> ', $this->getLang('exp_select_pages'));
131        echo '</p>';
132
133    }
134
135    private function getPagesFromNamespace($ns, $follow_ns = 0)
136    {
137
138        global $conf;
139
140        $depth = ($follow_ns ? 0 : 2);
141
142        if ($ns == '(root)') {
143            $ns    = '';
144            $depth = ($follow_ns ? 2 : 1);
145        }
146
147        $pages     = array();
148        $namespace = str_replace(':', '/', $ns);
149        $options   = array('depth' => $depth);
150
151        search($pages, $conf['datadir'], 'search_allpages', $options, $namespace);
152
153        return $pages;
154
155    }
156
157    private function step_select_pages()
158    {
159
160        global $INPUT;
161        global $conf;
162        global $lang;
163
164        $pages     = array();
165        $namespace = str_replace(':', '/', $INPUT->str('ns'));
166
167        if (!$namespace) {
168            msg($this->getLang('exp_no_namespace_selected'), -1);
169            $this->step_select_ns();
170            return 0;
171        }
172
173        $pages = $this->getPagesFromNamespace($INPUT->str('ns'), ($INPUT->str('include-sub-ns') ? 1 : 0));
174
175        echo sprintf('<h3>%s</h3>', $this->getLang('exp_select_pages'));
176        echo sprintf('<input type="hidden" value="%s" name="ns" />', $INPUT->str('ns'));
177
178        echo '<table class="table inline pages" width="100%">';
179        echo '<thead>
180      <tr>
181        <th width="10"><input type="checkbox" class="export-all-pages" title="' . $this->getLang('select_all_pages') . '" /></th>
182        <th>Page</th>
183        <th>Created</th>
184        <th>Modified</th>
185        <th>Size</th>
186      </tr>
187    </thead>';
188        echo '<tbody>';
189
190        foreach ($pages as $page) {
191
192            $page_id       = $page['id'];
193            $page_title    = p_get_first_heading($page_id);
194            $page_size     = filesize_h($page['size']);
195            $create_user   = editorinfo(p_get_metadata($page_id, 'user'));
196            $modified_user = editorinfo(p_get_metadata($page_id, 'last_change user'));
197            $create_date   = dformat(p_get_metadata($page_id, 'date created'));
198            $modified_date = dformat(p_get_metadata($page_id, 'date modified'));
199
200            echo sprintf('
201        <tr>
202          <td><input type="checkbox" name="pages[%s]" class="export-page" /></td>
203          <td>%s<br/><small>%s</small></td>
204          <td>%s<br/>%s</td>
205          <td>%s<br/>%s</td>
206          <td>%s</td>
207        </tr>',
208                $page_id,
209                $page_id, $page_title,
210                $create_user, $create_date,
211                $modified_user, $modified_date,
212                $page_size);
213
214        }
215
216        echo '</tbody>';
217        echo '</table>';
218
219        echo '<p>&nbsp;</p>';
220        echo '<input type="hidden" name="step" value="select-pages" />';
221
222        echo '<p class="pull-right">';
223        echo sprintf('<button type="submit" name="export[select_ns]" class="btn btn-default">&larr; %s</button> ', $lang['btn_back']);
224        echo sprintf('<button type="submit" name="cmd[export]" class="btn btn-primary primary">%s &rarr;</button>', $this->getLang('btn_export'));
225        echo '</p>';
226
227    }
228
229    private function cmd_export()
230    {
231
232        global $INPUT;
233        global $conf;
234
235        $pages = array();
236
237        switch ($INPUT->str('step')) {
238
239            case 'select-ns':
240
241                foreach ($this->getPagesFromNamespace($INPUT->str('ns'), ($INPUT->str('include-sub-ns') ? 1 : 0)) as $page) {
242                    $pages[] = $page['id'];
243                }
244
245                break;
246
247            case 'select-pages':
248                $pages = array_keys($INPUT->arr('pages'));
249                break;
250
251        }
252
253        if (!count($pages)) {
254            msg('No page selected for export!', -1);
255            return 0;
256        }
257
258        $namespace = str_replace(':', '-', str_replace('(root)', 'ROOT', $INPUT->str('ns')));
259        $timestamp = date('Ymd-His');
260
261        $Zip = new \splitbrain\PHPArchive\Zip;
262        $Zip->create();
263
264        foreach ($pages as $page) {
265
266            $file_fullpath = wikiFN($page);
267            $file_path     = str_replace($conf['datadir'], '', $file_fullpath);
268            $file_content  = io_readFile($file_fullpath);
269
270            $Zip->addData($file_path, $file_content);
271
272        }
273
274        header("Content-Type: application/zip");
275        header("Content-Transfer-Encoding: Binary");
276        header("Content-Disposition: attachment; filename=DokuWiki-export-$namespace-$timestamp.zip");
277
278        echo $Zip->getArchive();
279        die();
280
281    }
282
283}
284