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