1<?php 2 3if (!defined('DOKU_PLUGIN')) die('meh'); 4require_once(DOKU_PLUGIN . 'siteexport/inc/pdfgenerator.php'); 5 6class siteexport_zipfilewriter 7{ 8 /** 9 * further classes 10 */ 11 private $pdfGenerator = null; 12 private $functions = null; 13 14 public function __construct($functions = null) 15 { 16 $this->functions = $functions; 17 if (class_exists('siteexport_pdfgenerator')) 18 { 19 $this->pdfGenerator = new siteexport_pdfgenerator($functions); 20 } 21 } 22 23 public function canDoPDF() 24 { 25 return $this->pdfGenerator !== null; 26 } 27 28 29 /** 30 * Wrapper for fetching the Context or the TOC for Eclipse Documentation 31 * This also puts the file into the zip package 32 **/ 33 public function __moveDataToZip($DATA, $FILENAME = 'toc.xml', $ZIP = null, $JUSTWRITE = false) { 34 35 if (empty($DATA)) { return false; } 36 37 $tmpFile = tempnam($this->functions->settings->tmpDir, 'siteexport__') ?: $this->functions->settings->tmpDir . 'siteexport__'; 38 39 if (@file_put_contents($tmpFile, $DATA) === false) { 40 // There was an error here 41 } 42 43 // Add to zip 44 if ($JUSTWRITE) { 45 $status = $this->__writeFileToZip($tmpFile, $FILENAME, $ZIP); 46 } else { 47 $status = $this->__addFileToZip($tmpFile, $FILENAME, $ZIP); 48 } 49 50 if (@unlink($tmpFile) === false) { 51 unset($tmpFile); 52 } 53 54 return $status; 55 } 56 57 /** 58 * Adds a file to the zip file 59 * @param $FILE String file-name of the zip 60 * @param $NAME String name of the file that is being added 61 * @param $ZIP String name of the zip file to which we add 62 */ 63 public function __addFileToZip($FILE, $NAME, $ZIP = null) { 64 65 if ($NAME[0] === "/") { 66 $this->functions->debug->message("Weird, the NAME for the ZIP started with a '/'. This may result in wrong links!", null, 3); 67 $NAME = substr($NAME, 1); 68 } 69 70 // check for mpdf 71 if ($this->canDoPDF()) { 72 $this->functions->debug->message("Trying to create PDF from File '$FILE' with name '$NAME' for ZIP '$ZIP'", null, 2); 73 74 $succeeded = $this->pdfGenerator->createPDFFromFile($FILE, $NAME); 75 76 if ($this->functions->debug->debugLevel() <= 1) { // 2011-01-12 Write HTML to ZIP for Debug purpose 77 $this->__moveDataToZip($succeeded, "_debug/$NAME.html", $ZIP, true); 78 } 79 80 if ($succeeded === false) { 81 $this->functions->debug->runtimeException("Create PDF from File '$FILE' with name '$NAME' went wrong and is not being added!"); 82 return false; 83 } 84 } 85 86 return $this->__writeFileToZip($FILE, $NAME, $ZIP); 87 } 88 89 /** 90 * This really writes a file to a zip-file 91 * @param $FILE String file-name of the zip 92 * @param $NAME String name of the file that is being added 93 * @param $ZIP String name of the zip file to which we add 94 */ 95 private function __writeFileToZip($FILE, $NAME, $ZIPFILE) { 96 if (empty($ZIPFILE)) $ZIPFILE = $this->functions->settings->zipFile; 97 98 if (!class_exists('ZipArchive')) { 99 $this->functions->debug->runtimeException("PHP class 'ZipArchive' does not exist. Please make sure that you have the ziplib extension for PHP installed."); 100 return false; 101 } 102 103 $zip = new ZipArchive(); 104 if (!$zip) { 105 $this->functions->debug->runtimeException("Can't create new instance of 'ZipArchive'. Please make sure that you have the ziplib extension for PHP installed."); 106 return false; 107 } 108 109 $code = $zip->open($ZIPFILE, ZipArchive::CREATE); 110 if ($code === TRUE) { 111 112 $this->functions->debug->message("Adding file '{$NAME}' to ZIP {$ZIPFILE}", null, 2); 113 114 $zip->addFile($FILE, $NAME); 115 $zip->close(); 116 117 // If this has worked out, we may put this version into the cache ... ? 118 119 // ALibi Touching - 2011-09-13 wird nicht gebraucht nach Umstellung 120 121 return true; 122 } 123 124 $this->functions->debug->runtimeException("Zip Error #{$code} for file {$NAME}"); 125 return false; 126 } 127 128 /** 129 * check if a file exists allready 130 * @param $NAME String name of the file in the zip 131 */ 132 public function fileExistsInZip($NAME) 133 { 134 $zip = new ZipArchive(); 135 $code = $zip->open($this->functions->settings->zipFile, ZipArchive::CREATE); 136 if ($code === TRUE) { 137 $exists = !($zip->statName($NAME) === FALSE); 138 $zip->close(); 139 return $exists; 140 } 141 142 return false; 143 } 144 145 /** 146 * Checks if a valid cache file exists for the given request parameters 147 * @param $requestData 148 */ 149 public function hasValidCacheFile($requestData, $depends = array()) 150 { 151 $pattern = $this->functions->requestParametersToCacheHash($requestData); 152 return $this->hasValidCacheFileForPattern($pattern, $depends); 153 } 154 155 private function hasValidCacheFileForPattern($pattern, $depends = array()) 156 { 157 $this->functions->debug->message("HASH-Pattern for CacheFile: ", $pattern, 2); 158 $this->functions->settings->hasValidCacheFile = false; // reset the cache settings 159 $cacheFile = $this->functions->getCacheFileNameForPattern($pattern); 160 161 $mtime = @filemtime($cacheFile); // 0 if not exists 162 163 // Check if the file is expired - if so, just create a new one. 164 if ($mtime == 0 || $mtime < time()-$this->functions->settings->cachetime) 165 { 166 $this->__clearCacheFile( $cacheFile ); 167 $this->functions->debug->message("New CacheFile because the file was over the cachetime: ", $cacheFile, 2); 168 return false; 169 } 170 171 // Check for dependencies 172 if (!empty($depends)) 173 { 174 $this->functions->debug->message("Checking dependencies: ", $depends, 1); 175 foreach ($depends as $site) { 176 177 if (!page_exists($site['id'])) 178 { 179 $this->functions->debug->message("File does not exist: ", $site['id'], 2); 180 continue; 181 } 182 183 if ($mtime < @filemtime(wikiFN($site['id']))) { 184 $this->__clearCacheFile( $cacheFile ); 185 $this->functions->debug->message("New CacheFile, because a page changed: ", $cacheFile, 2); 186 return false; // cache older than files it depends on? 187 } 188 } 189 } 190 191 $this->functions->debug->message("CacheFile exists: ", $cacheFile, 2); 192 return $this->functions->settings->hasValidCacheFile = true; 193 } 194 195 private function __clearCacheFile( $cacheFile ) { 196 if ( @unlink($cacheFile) === false || 197 @unlink($this->functions->settings->zipFile) === false ) { 198 $this->functions->debug->message("Cannot remove cache Files: ", $cacheFile, 2); 199 } 200 } 201 202 public function getOnlyFileInZip(&$data = null) { 203 204 if (is_null($data['file'])) $data['file'] = $this->functions->settings->zipFile; 205 206 $zip = new ZipArchive(); 207 $code = $zip->open($data['file']); 208 if ($code !== TRUE) { 209 $this->functions->debug->message("Can't open the zip-file.", $data['file'], 2); 210 return false; 211 } 212 213 if ($zip->numFiles != 1) { 214 $zip->close(); 215 $this->functions->debug->message("More than one ({$zip->numFiles}) file in zip.", $data['file'], 2); 216 return false; 217 } 218 219 $stat = $zip->statIndex(0); 220 $this->functions->debug->message("Stat.", $stat, 3); 221 if (substr($stat['name'], -3) != 'pdf') { 222 $zip->close(); 223 $this->functions->debug->message("The file was not a PDF ({$stat['name']}).", $stat['name'], 2); 224 return false; 225 } 226 227 $data['mime'] = 'application/pdf'; 228 229 // Extract single file. 230 $folder = dirname($data['file']); 231 232 $data['orig'] = utf8_basename($stat['name']); 233 $zip->extractTo($folder, $stat['name']); 234 $zip->close(); 235 236 sleep(1); 237 $data['file'] .= '.' . cleanID($data['orig']); // Wee need the other file for cache reasons. 238 return (@rename($folder.'/'.$data['orig'], $data['file'])) === true; 239 } 240} 241 242