1<?php 2 3/** 4 * USING 5 * 6 * zip.php <key> <user> <serialized pages> <serialized userinfo[grps]> 7 */ 8 9 10if ('cli' !== php_sapi_name()) die(); 11 12if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../../').'/'); 13define('NOSESSION',1); 14require_once(DOKU_INC.'inc/init.php'); 15require_once(DOKU_INC.'inc/common.php'); 16require_once(DOKU_INC.'inc/parserutils.php'); 17require_once(DOKU_INC.'inc/cliopts.php'); 18require_once(DOKU_INC.'inc/auth.php'); 19require_once(DOKU_INC.'inc/io.php'); 20 21$args = Doku_Cli_Opts::readPHPArgv(); 22 23if (count($args) !== 5) die(-1); 24 25class nsexport_zip { 26 27 public $tmp; 28 29 public function _addFile($filename, $content) { 30 $filename = $this->tmp . "/$filename"; 31 io_makeFileDir($filename); 32 file_put_contents($filename , $content); 33 } 34 35 public function recursive_add($base, $dir=''){ 36 $fh = @opendir("$base/$dir"); 37 if(!$fh) return; 38 while(false !== ($file = readdir($fh))) { 39 @set_time_limit(30); 40 if($file === '..' || $file[0] === '.') continue; 41 if(is_dir("$base/$dir/$file")){ 42 $this->recursive_add($base,"$dir/$file"); 43 }else{ 44 $this->_addFile("$dir/$file",io_readFile(ltrim("$base/$dir/$file",'/'),false)); 45 } 46 } 47 closedir($fh); 48 } 49 50 /** 51 * Delete a file, or a folder and its contents (recursive algorithm) 52 * 53 * @author Aidan Lister <aidan@php.net> 54 * @version 1.0.3 55 * @link http://aidanlister.com/repos/v/function.rmdirr.php 56 * @param string $dirname Directory to delete 57 * @return bool Returns TRUE on success, FALSE on failure 58 */ 59 public function rmdirr($dirname) 60 { 61 // Sanity check 62 if (!file_exists($dirname)) { 63 return false; 64 } 65 66 // Simple delete for a file 67 if (is_file($dirname) || is_link($dirname)) { 68 return unlink($dirname); 69 } 70 71 // Loop through the folder 72 $dir = dir($dirname); 73 while (false !== $entry = $dir->read()) { 74 // Skip pointers 75 if ($entry === '.' || $entry === '..') { 76 continue; 77 } 78 79 // Recurse 80 $this->rmdirr($dirname . DIRECTORY_SEPARATOR . $entry); 81 } 82 83 // Clean up 84 $dir->close(); 85 return rmdir($dirname); 86 } 87 88 public function start($key, $user, $pages, $groups) { 89 global $conf; 90 global $lang; 91 92 $pages = unserialize($pages); 93 94 require_once(DOKU_INC.'inc/HTTPClient.php'); 95 error_reporting(0); 96 97 // check if the 7ip executable is availible 98 // FIXME 99 $packer = $this->getConf('packer_ziphtml_zip'); 100 if (!file_exists($packer) || !is_file($packer)) 101 { 102 return; 103 } 104 105 $media = array(); 106 $tmpdir = io_mktmpdir(); 107 if ($tmpdir === false) { 108 // no tmpdir 109 return; 110 } 111 $this->tmp = $tmpdir; 112 113 114 // add CSS 115 $http = new DokuHTTPClient(); 116 $css = $http->get(DOKU_URL.'lib/exe/css.php?s=all&t='.$conf['template']); 117 $this->_addFile('all.css',$css); 118 $css = $http->get(DOKU_URL.'lib/exe/css.php?t='.$conf['template']); 119 $this->_addFile('screen.css',$css); 120 $css = $http->get(DOKU_URL.'lib/exe/css.php?s=print&t='.$conf['template']); 121 $this->_addFile('print.css',$css); 122 $css = io_readFile(dirname(__FILE__).'/export.css',false); 123 $this->_addFile('export.css',$css); 124 125 unset($html); 126 127 foreach($pages as $ID){ 128 if( auth_aclcheck($ID, $user, $groups) < AUTH_READ ) continue; 129 @set_time_limit(30); 130 131 // create relative path to top directory 132 $deep = substr_count($ID,':'); 133 $ref = ''; 134 for($i=0; $i<$deep; $i++) $ref .= '../'; 135 136 // create the output 137 $html = p_cached_output(wikiFN($ID,''), 'nsexport_xhtml'); 138 139 $output = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"'.DOKU_LF; 140 $output .= ' "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">'.DOKU_LF; 141 $output .= '<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="'.$conf['lang'].'"'.DOKU_LF; 142 $output .= ' lang="'.$conf['lang'].'" dir="'.$lang['direction'].'">' . DOKU_LF; 143 $output .= '<head>'.DOKU_LF; 144 $output .= ' <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />'.DOKU_LF; 145 $output .= ' <title>'.$ID.'</title>'.DOKU_LF; 146 $output .= ' <link rel="stylesheet" media="all" type="text/css" href="'.$ref.'all.css" />'.DOKU_LF; 147 $output .= ' <link rel="stylesheet" media="screen" type="text/css" href="'.$ref.'screen.css" />'.DOKU_LF; 148 $output .= ' <link rel="stylesheet" media="print" type="text/css" href="'.$ref.'print.css" />'.DOKU_LF; 149 $output .= ' <link rel="stylesheet" media="all" type="text/css" href="'.$ref.'export.css" />'.DOKU_LF; 150 $output .= '</head>'.DOKU_LF; 151 $output .= '<body>'.DOKU_LF; 152 $output .= '<div class="dokuwiki export">' . DOKU_LF; 153 $output .= tpl_toc(true); 154 $output .= $html; 155 $output .= '</div>'; 156 $output .= '</body>'.DOKU_LF; 157 $output .= '</html>'.DOKU_LF; 158 159 $this->_addFile(str_replace(':','/',$ID).'.html',$output); 160 $media = array_merge($media,(array) p_get_metadata($ID,'plugin_nsexport')); 161 } 162 163 // now embed the media 164 $media = array_map('cleanID',$media); 165 $media = array_unique($media); 166 foreach($media as $id){ 167 if( auth_quickaclcheck($id) < AUTH_READ ) continue; 168 @set_time_limit(30); 169 $this->_addFile('_media/'.str_replace(':','/',$id),io_readFile(mediaFN($id),false)); 170 } 171 172 173 // add the merge directory contents 174 $this->recursive_add(dirname(__FILE__).'/merge'); 175 176 echo basename($this->tmp); 177 178 } 179 180 /** 181 * Do the action 182 */ 183 public function _export_html($pages){ 184 global $conf; 185 @ignore_user_abort(true); 186 $filename = $conf['tmpdir'].'/offline-'.time().rand(0,99999).'.zip'; 187 $this->zip = $filename; 188 $zfn = preg_replace('/^([a-z]{1}):/i','$1:\\',$filename); 189 $efn = preg_replace('/^([a-z]{1}):/i','$1:\\',$this->tmp.'/'); 190 191 // send to browser 192 header('Content-Type: application/zip'); 193 header('Content-Disposition: attachment; filename="export.zip"'); 194 header('Expires: 0'); 195 header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); 196 header('Content-Transfer-Encoding: binary'); 197 header('Pragma: public'); 198 flush(); 199 @set_time_limit(0); 200 201 chdir($efn); 202 $zip = $this->getConf('packer_ziphtml_zip'); 203 $comp = $this->getConf('packer_ziphtml_compress'); 204 $cmd = "$zip -q -$comp -r - ."; 205 system($cmd); 206 207 // cleanup 208 $this->rmdirr($this->tmp); 209 } 210} 211