xref: /plugin/siteexport/inc/filewriter.php (revision a8c17ab5b37308343f86651acb8c4a1b3f36f0ae)
17d101cc1SGerry Weißbach<?php
27d101cc1SGerry Weißbach
37d101cc1SGerry Weißbachif (!defined('DOKU_PLUGIN')) die('meh');
47d101cc1SGerry Weißbachrequire_once(DOKU_PLUGIN . 'siteexport/inc/pdfgenerator.php');
57d101cc1SGerry Weißbach
67d101cc1SGerry Weißbachclass siteexport_zipfilewriter
77d101cc1SGerry Weißbach{
87d101cc1SGerry Weißbach    /**
97d101cc1SGerry Weißbach     * further classes
107d101cc1SGerry Weißbach     */
11*a8c17ab5Si-net /// software    private $pdfGenerator = null;
127d101cc1SGerry Weißbach    private $functions = null;
137d101cc1SGerry Weißbach
14b324a190SMichael Hamann    public function __construct($functions = null)
157d101cc1SGerry Weißbach    {
167d101cc1SGerry Weißbach        $this->functions = $functions;
177d101cc1SGerry Weißbach        if (class_exists('siteexport_pdfgenerator'))
187d101cc1SGerry Weißbach        {
197d101cc1SGerry Weißbach            $this->pdfGenerator = new siteexport_pdfgenerator($functions);
207d101cc1SGerry Weißbach        }
217d101cc1SGerry Weißbach    }
227d101cc1SGerry Weißbach
237d101cc1SGerry Weißbach    public function canDoPDF()
247d101cc1SGerry Weißbach    {
25*a8c17ab5Si-net /// software        return $this->pdfGenerator !== null;
267d101cc1SGerry Weißbach    }
277d101cc1SGerry Weißbach
287d101cc1SGerry Weißbach
297d101cc1SGerry Weißbach    /**
307d101cc1SGerry Weißbach     * Wrapper for fetching the Context or the TOC for Eclipse Documentation
317d101cc1SGerry Weißbach     * This also puts the file into the zip package
327d101cc1SGerry Weißbach     **/
33e6ebb3b0SGerry Weißbach    public function __moveDataToZip($DATA, $FILENAME = 'toc.xml', $ZIP = null, $JUSTWRITE = false) {
347d101cc1SGerry Weißbach
357d101cc1SGerry Weißbach        if (empty($DATA)) { return false; }
367d101cc1SGerry Weißbach
37*a8c17ab5Si-net /// software        $tmpFile = tempnam($this->functions->settings->tmpDir, 'siteexport__') ?: $this->functions->settings->tmpDir . 'siteexport__';
387d101cc1SGerry Weißbach
39*a8c17ab5Si-net /// software        if (@file_put_contents($tmpFile, $DATA) === false) {
40*a8c17ab5Si-net /// software            // There was an error here
41*a8c17ab5Si-net /// software        }
427d101cc1SGerry Weißbach
437d101cc1SGerry Weißbach        // Add to zip
44e6ebb3b0SGerry Weißbach        if ($JUSTWRITE) {
45e6ebb3b0SGerry Weißbach            $status = $this->__writeFileToZip($tmpFile, $FILENAME, $ZIP);
46e6ebb3b0SGerry Weißbach        } else {
47e6ebb3b0SGerry Weißbach            $status = $this->__addFileToZip($tmpFile, $FILENAME, $ZIP);
48e6ebb3b0SGerry Weißbach        }
49*a8c17ab5Si-net /// software
50*a8c17ab5Si-net /// software        if (@unlink($tmpFile) === false) {
51*a8c17ab5Si-net /// software            unset($tmpFile);
52*a8c17ab5Si-net /// software        }
537d101cc1SGerry Weißbach
54e6ebb3b0SGerry Weißbach        return $status;
557d101cc1SGerry Weißbach    }
567d101cc1SGerry Weißbach
577d101cc1SGerry Weißbach    /**
587d101cc1SGerry Weißbach     * Adds a file to the zip file
59*a8c17ab5Si-net /// software     * @param $FILE String file-name of the zip
60*a8c17ab5Si-net /// software     * @param $NAME String name of the file that is being added
61*a8c17ab5Si-net /// software     * @param $ZIP String name of the zip file to which we add
627d101cc1SGerry Weißbach     */
63*a8c17ab5Si-net /// software    public function __addFileToZip($FILE, $NAME, $ZIP = null) {
647d101cc1SGerry Weißbach
657d101cc1SGerry Weißbach        if ($NAME[0] === "/") {
667d101cc1SGerry Weißbach            $this->functions->debug->message("Weird, the NAME for the ZIP started with a '/'. This may result in wrong links!", null, 3);
677d101cc1SGerry Weißbach            $NAME = substr($NAME, 1);
687d101cc1SGerry Weißbach        }
697d101cc1SGerry Weißbach
707d101cc1SGerry Weißbach        // check for mpdf
717d101cc1SGerry Weißbach        if ($this->canDoPDF()) {
727d101cc1SGerry Weißbach            $this->functions->debug->message("Trying to create PDF from File '$FILE' with name '$NAME' for ZIP '$ZIP'", null, 2);
737d101cc1SGerry Weißbach
74e6ebb3b0SGerry Weißbach            $succeeded = $this->pdfGenerator->createPDFFromFile($FILE, $NAME);
75e6ebb3b0SGerry Weißbach
767d101cc1SGerry Weißbach            if ($this->functions->debug->debugLevel() <= 1) { // 2011-01-12 Write HTML to ZIP for Debug purpose
77e6ebb3b0SGerry Weißbach                $this->__moveDataToZip($succeeded, "_debug/$NAME.html", $ZIP, true);
787d101cc1SGerry Weißbach            }
797d101cc1SGerry Weißbach
80e6ebb3b0SGerry Weißbach            if ($succeeded === false) {
818da901a0SGerry Weißbach                $this->functions->debug->runtimeException("Create PDF from File '$FILE' with name '$NAME' went wrong and is not being added!");
828da901a0SGerry Weißbach                return false;
837d101cc1SGerry Weißbach            }
847d101cc1SGerry Weißbach        }
857d101cc1SGerry Weißbach
867d101cc1SGerry Weißbach        return $this->__writeFileToZip($FILE, $NAME, $ZIP);
877d101cc1SGerry Weißbach    }
887d101cc1SGerry Weißbach
897d101cc1SGerry Weißbach    /**
907d101cc1SGerry Weißbach     * This really writes a file to a zip-file
91*a8c17ab5Si-net /// software     * @param $FILE String file-name of the zip
92*a8c17ab5Si-net /// software     * @param $NAME String name of the file that is being added
93*a8c17ab5Si-net /// software     * @param $ZIP String name of the zip file to which we add
947d101cc1SGerry Weißbach     */
95e77f87a1SGerry Weißbach    private function __writeFileToZip($FILE, $NAME, $ZIPFILE) {
96e77f87a1SGerry Weißbach        if (empty($ZIPFILE)) $ZIPFILE = $this->functions->settings->zipFile;
977d101cc1SGerry Weißbach
987d101cc1SGerry Weißbach        if (!class_exists('ZipArchive')) {
997d101cc1SGerry Weißbach            $this->functions->debug->runtimeException("PHP class 'ZipArchive' does not exist. Please make sure that you have the ziplib extension for PHP installed.");
1007d101cc1SGerry Weißbach            return false;
1017d101cc1SGerry Weißbach        }
1027d101cc1SGerry Weißbach
1036792d0cfSGerry Weißbach        $zip = new ZipArchive();
1047d101cc1SGerry Weißbach        if (!$zip) {
1057d101cc1SGerry Weißbach            $this->functions->debug->runtimeException("Can't create new instance of 'ZipArchive'. Please make sure that you have the ziplib extension for PHP installed.");
1067d101cc1SGerry Weißbach            return false;
1077d101cc1SGerry Weißbach        }
1087d101cc1SGerry Weißbach
109e77f87a1SGerry Weißbach        $code = $zip->open($ZIPFILE, ZipArchive::CREATE);
1107d101cc1SGerry Weißbach        if ($code === TRUE) {
1117d101cc1SGerry Weißbach
112*a8c17ab5Si-net /// software            $this->functions->debug->message("Adding file '{$NAME}' to ZIP {$ZIPFILE}", null, 2);
1137d101cc1SGerry Weißbach
1147d101cc1SGerry Weißbach            $zip->addFile($FILE, $NAME);
1157d101cc1SGerry Weißbach            $zip->close();
1167d101cc1SGerry Weißbach
1177d101cc1SGerry Weißbach            // If this has worked out, we may put this version into the cache ... ?
1187d101cc1SGerry Weißbach
1197d101cc1SGerry Weißbach            // ALibi Touching - 2011-09-13 wird nicht gebraucht nach Umstellung
1207d101cc1SGerry Weißbach
1217d101cc1SGerry Weißbach            return true;
1227d101cc1SGerry Weißbach        }
1237d101cc1SGerry Weißbach
124e77f87a1SGerry Weißbach        $this->functions->debug->runtimeException("Zip Error #{$code} for file {$NAME}");
1257d101cc1SGerry Weißbach        return false;
1267d101cc1SGerry Weißbach    }
1277d101cc1SGerry Weißbach
1287d101cc1SGerry Weißbach    /**
1297d101cc1SGerry Weißbach     * check if a file exists allready
130*a8c17ab5Si-net /// software     * @param $NAME String name of the file in the zip
1317d101cc1SGerry Weißbach     */
132*a8c17ab5Si-net /// software    public function fileExistsInZip($NAME)
1337d101cc1SGerry Weißbach    {
1346792d0cfSGerry Weißbach        $zip = new ZipArchive();
1357d101cc1SGerry Weißbach        $code = $zip->open($this->functions->settings->zipFile, ZipArchive::CREATE);
1367d101cc1SGerry Weißbach        if ($code === TRUE) {
137e77f87a1SGerry Weißbach            $exists = !($zip->statName($NAME) === FALSE);
138e77f87a1SGerry Weißbach            $zip->close();
139e77f87a1SGerry Weißbach            return $exists;
1407d101cc1SGerry Weißbach        }
1417d101cc1SGerry Weißbach
1427d101cc1SGerry Weißbach        return false;
1437d101cc1SGerry Weißbach    }
1447d101cc1SGerry Weißbach
1457d101cc1SGerry Weißbach    /**
1467d101cc1SGerry Weißbach     * Checks if a valid cache file exists for the given request parameters
1477d101cc1SGerry Weißbach     * @param $requestData
1487d101cc1SGerry Weißbach     */
149*a8c17ab5Si-net /// software    public function hasValidCacheFile($requestData, $depends = array())
1507d101cc1SGerry Weißbach    {
1516792d0cfSGerry Weißbach        $pattern = $this->functions->requestParametersToCacheHash($requestData);
1526792d0cfSGerry Weißbach        return $this->hasValidCacheFileForPattern($pattern, $depends);
1536792d0cfSGerry Weißbach    }
1547d101cc1SGerry Weißbach
1556792d0cfSGerry Weißbach    private function hasValidCacheFileForPattern($pattern, $depends = array())
1566792d0cfSGerry Weißbach    {
1576792d0cfSGerry Weißbach        $this->functions->debug->message("HASH-Pattern for CacheFile: ", $pattern, 2);
1586792d0cfSGerry Weißbach        $this->functions->settings->hasValidCacheFile = false; // reset the cache settings
1596792d0cfSGerry Weißbach        $cacheFile = $this->functions->getCacheFileNameForPattern($pattern);
1607d101cc1SGerry Weißbach
1617d101cc1SGerry Weißbach        $mtime = @filemtime($cacheFile); // 0 if not exists
1627d101cc1SGerry Weißbach
1637d101cc1SGerry Weißbach        // Check if the file is expired - if so, just create a new one.
164f8fd18e7SGerry Weißbach        if ($mtime == 0 || $mtime < time()-$this->functions->settings->cachetime)
1657d101cc1SGerry Weißbach        {
166*a8c17ab5Si-net /// software            if ( @unlink($cacheFile) === false ||
167*a8c17ab5Si-net /// software                 @unlink($this->functions->settings->zipFile) === false ) {
168*a8c17ab5Si-net /// software                 $this->functions->debug->message("Cannot remove cache Files: ", $cacheFile, 2);
169*a8c17ab5Si-net /// software            }
1707d101cc1SGerry Weißbach            $this->functions->debug->message("New CacheFile because the file was over the cachetime: ", $cacheFile, 2);
1717d101cc1SGerry Weißbach            return false;
1727d101cc1SGerry Weißbach        }
1737d101cc1SGerry Weißbach
1747d101cc1SGerry Weißbach        // Check for dependencies
1757d101cc1SGerry Weißbach        if (!empty($depends))
1767d101cc1SGerry Weißbach        {
177ad37ef9aSGerry Weißbach            $this->functions->debug->message("Checking dependencies: ", $depends, 1);
1787d101cc1SGerry Weißbach            foreach ($depends as $site) {
1797d101cc1SGerry Weißbach
1807d101cc1SGerry Weißbach                if (!page_exists($site['id']))
1817d101cc1SGerry Weißbach                {
182ad37ef9aSGerry Weißbach                    $this->functions->debug->message("File does not exist: ", $site['id'], 2);
1837d101cc1SGerry Weißbach                    continue;
1847d101cc1SGerry Weißbach                }
1857d101cc1SGerry Weißbach
1867d101cc1SGerry Weißbach                if ($mtime < @filemtime(wikiFN($site['id']))) {
187*a8c17ab5Si-net /// software                    if ( @unlink($cacheFile) === false ||
188*a8c17ab5Si-net /// software                         @unlink($this->functions->settings->zipFile) === false ) {
189*a8c17ab5Si-net /// software                         $this->functions->debug->message("Cannot remove cache Files: ", $cacheFile, 2);
190*a8c17ab5Si-net /// software                    }
1917d101cc1SGerry Weißbach                    $this->functions->debug->message("New CacheFile, because a page changed: ", $cacheFile, 2);
1927d101cc1SGerry Weißbach                    return false; // cache older than files it depends on?
1937d101cc1SGerry Weißbach                }
1947d101cc1SGerry Weißbach            }
1957d101cc1SGerry Weißbach        }
1967d101cc1SGerry Weißbach
1977d101cc1SGerry Weißbach        $this->functions->debug->message("CacheFile exists: ", $cacheFile, 2);
1987d101cc1SGerry Weißbach        return $this->functions->settings->hasValidCacheFile = true;
1997d101cc1SGerry Weißbach    }
200f3359d31SGerry Weißbach
2016792d0cfSGerry Weißbach    public function getOnlyFileInZip(&$data = null) {
202f3359d31SGerry Weißbach
2036792d0cfSGerry Weißbach        if (is_null($data['file'])) $data['file'] = $this->functions->settings->zipFile;
204f3359d31SGerry Weißbach
205f3359d31SGerry Weißbach        $zip = new ZipArchive();
2066792d0cfSGerry Weißbach        $code = $zip->open($data['file']);
2076792d0cfSGerry Weißbach        if ($code !== TRUE) {
2086792d0cfSGerry Weißbach            $this->functions->debug->message("Can't open the zip-file.", $data['file'], 2);
209f3359d31SGerry Weißbach            return false;
210f3359d31SGerry Weißbach        }
211f3359d31SGerry Weißbach
212f3359d31SGerry Weißbach        if ($zip->numFiles != 1) {
213e77f87a1SGerry Weißbach            $zip->close();
2146792d0cfSGerry Weißbach            $this->functions->debug->message("More than one ({$zip->numFiles}) file in zip.", $data['file'], 2);
215f3359d31SGerry Weißbach            return false;
216f3359d31SGerry Weißbach        }
217f3359d31SGerry Weißbach
218f3359d31SGerry Weißbach        $stat = $zip->statIndex(0);
2196792d0cfSGerry Weißbach        $this->functions->debug->message("Stat.", $stat, 3);
220f3359d31SGerry Weißbach        if (substr($stat['name'], -3) != 'pdf') {
221e77f87a1SGerry Weißbach            $zip->close();
2226792d0cfSGerry Weißbach            $this->functions->debug->message("The file was not a PDF ({$stat['name']}).", $stat['name'], 2);
223f3359d31SGerry Weißbach            return false;
224f3359d31SGerry Weißbach        }
225f3359d31SGerry Weißbach
2266792d0cfSGerry Weißbach        $data['mime'] = 'application/pdf';
227f3359d31SGerry Weißbach
2286792d0cfSGerry Weißbach        // Extract single file.
2296792d0cfSGerry Weißbach        $folder = dirname($data['file']);
2306792d0cfSGerry Weißbach
2316792d0cfSGerry Weißbach        $data['orig'] = utf8_basename($stat['name']);
232f3359d31SGerry Weißbach        $zip->extractTo($folder, $stat['name']);
233f3359d31SGerry Weißbach        $zip->close();
234f3359d31SGerry Weißbach
235f3359d31SGerry Weißbach        sleep(1);
2366792d0cfSGerry Weißbach        $data['file'] .= '.' . cleanID($data['orig']); // Wee need the other file for cache reasons.
237*a8c17ab5Si-net /// software        return (@rename($folder.'/'.$data['orig'], $data['file'])) === true;
238f3359d31SGerry Weißbach    }
2397d101cc1SGerry Weißbach}
2407d101cc1SGerry Weißbach
241