1<?php 2require_once DOKU_PLUGIN.'nsexport/packer/ziphtml/compressor.php'; 3require_once DOKU_PLUGIN.'nsexport/packer/ziphtml/compress/ziplib.php'; 4require_once DOKU_PLUGIN.'nsexport/packer/ziphtml/renderer.php'; 5require_once DOKU_PLUGIN.'nsexport/packer/packer.php'; 6 7class plugin_nsexport_packer_ziphtml extends plugin_nsexport_packer { 8 public $ext = 'zip'; 9 10 public function init_packing($pages) { 11 global $conf; 12 // early check if the zip executable is available 13 $packer = $conf['plugin']['nsexport']['packer_ziphtml_zip']; 14 if (!file_exists($packer) || !is_file($packer)) { 15 return false; 16 } 17 18 // prepare some basic settings 19 $this->tmp = io_mktmpdir(); 20 if ($this->tmp === false) { 21 // no tmpdir 22 return false; 23 } 24 25 $this->media = array(); 26 27 // begin data collecting 28 // add CSS 29 $http = new DokuHTTPClient(); 30 $css = $http->get(DOKU_URL.'lib/exe/css.php?s=all&t='.$conf['template']); 31 $this->_addFile('all.css',$css); 32 $css = $http->get(DOKU_URL.'lib/exe/css.php?t='.$conf['template']); 33 $this->_addFile('screen.css',$css); 34 $css = $http->get(DOKU_URL.'lib/exe/css.php?s=print&t='.$conf['template']); 35 $this->_addFile('print.css',$css); 36 $css = io_readFile(dirname(__FILE__).'/export.css',false); 37 $this->_addFile('export.css',$css); 38 39 return parent::init_packing($pages); 40 } 41 42 public function pack_page($ID_PAGE) { 43 global $conf; 44 global $lang; 45 global $ID; 46 47 $ID = $ID_PAGE; 48 49 // create relative path to top directory 50 $deep = substr_count($ID,':'); 51 $ref = ''; 52 for($i=0; $i<$deep; $i++) $ref .= '../'; 53 54 // create the output 55 $this->Renderer = new renderer_plugin_nsexport_xhtml; 56 57 $this->Renderer->smileys = getSmileys(); 58 $this->Renderer->entities = getEntities(); 59 $this->Renderer->acronyms = getAcronyms(); 60 $this->Renderer->interwiki = getInterwiki(); 61 62 $instructions = p_cached_instructions(wikiFN($ID,''),false,$ID); 63 foreach ( $instructions as $instruction ) { 64 // Execute the callback against the Renderer 65 call_user_func_array(array(&$this->Renderer, $instruction[0]), 66 $instruction[1]); 67 } 68 $html = $this->Renderer->doc; 69 70 $output = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"'.DOKU_LF; 71 $output .= ' "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">'.DOKU_LF; 72 $output .= '<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="'.$conf['lang'].'"'.DOKU_LF; 73 $output .= ' lang="'.$conf['lang'].'" dir="'.$lang['direction'].'">' . DOKU_LF; 74 $output .= '<head>'.DOKU_LF; 75 $output .= ' <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />'.DOKU_LF; 76 $output .= ' <title>'.$ID.'</title>'.DOKU_LF; 77 $output .= ' <link rel="stylesheet" media="all" type="text/css" href="'.$ref.'all.css" />'.DOKU_LF; 78 $output .= ' <link rel="stylesheet" media="screen" type="text/css" href="'.$ref.'screen.css" />'.DOKU_LF; 79 $output .= ' <link rel="stylesheet" media="print" type="text/css" href="'.$ref.'print.css" />'.DOKU_LF; 80 $output .= ' <link rel="stylesheet" media="all" type="text/css" href="'.$ref.'export.css" />'.DOKU_LF; 81 $output .= '</head>'.DOKU_LF; 82 $output .= '<body>'.DOKU_LF; 83 $output .= '<div class="dokuwiki export">' . DOKU_LF; 84 $output .= tpl_toc(true); 85 $output .= $html; 86 $output .= '</div>'; 87 $output .= '</body>'.DOKU_LF; 88 $output .= '</html>'.DOKU_LF; 89 90 $this->_addFile(str_replace(':','/',$ID).'.html',$output); 91 $this->media = array_merge($this->media, $this->Renderer->_media); 92 } 93 94 public function finish_packing() { 95 global $conf; 96 97 // now embed the media 98 $this->media = array_map('cleanID',$this->media); 99 $this->media = array_unique($this->media); 100 foreach($this->media as $id) { 101 if( auth_quickaclcheck($id) < AUTH_READ ) continue; 102 @set_time_limit(30); 103 $this->_addFile('_media/'.str_replace(':','/',$id),io_readFile(mediaFN($id),false)); 104 } 105 106 // add the merge directory contents 107 $this->recursive_add(dirname(__FILE__).'/merge'); 108 109 // finished data collecting 110 $to = $conf['tmpdir'] . '/wrk-' . $this->fileid . '.zip'; 111 112 // append wiki export 113 $zipper = new nsexport_ziplib(); 114 $zipper->setup($this); 115 $zipper->compress($this->tmp, $to); 116 117 // cleanup 118 $this->rmdirr($this->tmp); 119 120 // rename so ajax can find it 121 rename($to, $this->result_filename()); 122 } 123 124 /** 125 * add a single file. 126 * 127 * @param string $filename filename to store 128 * @param string $content the file content 129 */ 130 public function _addFile($filename, $content) { 131 $filename = $this->tmp . "/$filename"; 132 io_makeFileDir($filename); 133 file_put_contents($filename , $content); 134 } 135 136 /** 137 * add a whole dir with subdirs. 138 */ 139 public function recursive_add($base, $dir='') { 140 $fh = @opendir("$base/$dir"); 141 if(!$fh) return; 142 while(false !== ($file = readdir($fh))) { 143 @set_time_limit(30); 144 if($file === '..' || $file[0] === '.') continue; 145 if(is_dir("$base/$dir/$file")) { 146 $this->recursive_add($base,"$dir/$file"); 147 }else { 148 $this->_addFile("$dir/$file",io_readFile("$base/$dir/$file",false)); 149 } 150 } 151 closedir($fh); 152 } 153 154 /** 155 * Delete a file, or a folder and its contents (recursive algorithm) 156 * 157 * @author Aidan Lister <aidan@php.net> 158 * @version 1.0.3 159 * @link http://aidanlister.com/repos/v/function.rmdirr.php 160 * @param string $dirname Directory to delete 161 * @return bool Returns TRUE on success, FALSE on failure 162 */ 163 public function rmdirr($dirname) { 164 // Sanity check 165 if (!file_exists($dirname)) { 166 return false; 167 } 168 169 // Simple delete for a file 170 if (is_file($dirname) || is_link($dirname)) { 171 return unlink($dirname); 172 } 173 174 // Loop through the folder 175 $dir = dir($dirname); 176 while (false !== $entry = $dir->read()) { 177 // Skip pointers 178 if ($entry === '.' || $entry === '..') { 179 continue; 180 } 181 182 // Recurse 183 $this->rmdirr($dirname . DIRECTORY_SEPARATOR . $entry); 184 } 185 186 // Clean up 187 $dir->close(); 188 return rmdir($dirname); 189 } 190 191} 192