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> </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 →</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 →</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> </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">← %s</button> ', $lang['btn_back']); 224 echo sprintf('<button type="submit" name="cmd[export]" class="btn btn-primary primary">%s →</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