xref: /plugin/siteexport/inc/filewriter.php (revision 51a384e16e91ea63f9e96325107613ae603cfb26)
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     */
11a8c17ab5Si-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    {
25a8c17ab5Si-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
37a8c17ab5Si-net /// software        $tmpFile = tempnam($this->functions->settings->tmpDir, 'siteexport__') ?: $this->functions->settings->tmpDir . 'siteexport__';
387d101cc1SGerry Weißbach
39a8c17ab5Si-net /// software        if (@file_put_contents($tmpFile, $DATA) === false) {
40a8c17ab5Si-net /// software            // There was an error here
41a8c17ab5Si-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        }
49a8c17ab5Si-net /// software
50a8c17ab5Si-net /// software        if (@unlink($tmpFile) === false) {
51a8c17ab5Si-net /// software            unset($tmpFile);
52a8c17ab5Si-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
59a8c17ab5Si-net /// software     * @param $FILE String file-name of the zip
60a8c17ab5Si-net /// software     * @param $NAME String name of the file that is being added
61a8c17ab5Si-net /// software     * @param $ZIP String name of the zip file to which we add
627d101cc1SGerry Weißbach     */
63a8c17ab5Si-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
91a8c17ab5Si-net /// software     * @param $FILE String file-name of the zip
92a8c17ab5Si-net /// software     * @param $NAME String name of the file that is being added
93a8c17ab5Si-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
112a8c17ab5Si-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
130a8c17ab5Si-net /// software     * @param $NAME String name of the file in the zip
1317d101cc1SGerry Weißbach     */
132a8c17ab5Si-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     */
149a8c17ab5Si-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*51a384e1Si-net /// software            $this->__clearCacheFile( $cacheFile );
1677d101cc1SGerry Weißbach            $this->functions->debug->message("New CacheFile because the file was over the cachetime: ", $cacheFile, 2);
1687d101cc1SGerry Weißbach            return false;
1697d101cc1SGerry Weißbach        }
1707d101cc1SGerry Weißbach
1717d101cc1SGerry Weißbach        // Check for dependencies
1727d101cc1SGerry Weißbach        if (!empty($depends))
1737d101cc1SGerry Weißbach        {
174ad37ef9aSGerry Weißbach            $this->functions->debug->message("Checking dependencies: ", $depends, 1);
1757d101cc1SGerry Weißbach            foreach ($depends as $site) {
1767d101cc1SGerry Weißbach
1777d101cc1SGerry Weißbach                if (!page_exists($site['id']))
1787d101cc1SGerry Weißbach                {
179ad37ef9aSGerry Weißbach                    $this->functions->debug->message("File does not exist: ", $site['id'], 2);
1807d101cc1SGerry Weißbach                    continue;
1817d101cc1SGerry Weißbach                }
1827d101cc1SGerry Weißbach
1837d101cc1SGerry Weißbach                if ($mtime < @filemtime(wikiFN($site['id']))) {
184*51a384e1Si-net /// software                    $this->__clearCacheFile( $cacheFile );
1857d101cc1SGerry Weißbach                    $this->functions->debug->message("New CacheFile, because a page changed: ", $cacheFile, 2);
1867d101cc1SGerry Weißbach                    return false; // cache older than files it depends on?
1877d101cc1SGerry Weißbach                }
1887d101cc1SGerry Weißbach            }
1897d101cc1SGerry Weißbach        }
1907d101cc1SGerry Weißbach
1917d101cc1SGerry Weißbach        $this->functions->debug->message("CacheFile exists: ", $cacheFile, 2);
1927d101cc1SGerry Weißbach        return $this->functions->settings->hasValidCacheFile = true;
1937d101cc1SGerry Weißbach    }
194f3359d31SGerry Weißbach
195*51a384e1Si-net /// software    private function __clearCacheFile( $cacheFile ) {
196*51a384e1Si-net /// software        if ( @unlink($cacheFile) === false ||
197*51a384e1Si-net /// software             @unlink($this->functions->settings->zipFile) === false ) {
198*51a384e1Si-net /// software             $this->functions->debug->message("Cannot remove cache Files: ", $cacheFile, 2);
199*51a384e1Si-net /// software        }
200*51a384e1Si-net /// software    }
201*51a384e1Si-net /// software
2026792d0cfSGerry Weißbach    public function getOnlyFileInZip(&$data = null) {
203f3359d31SGerry Weißbach
2046792d0cfSGerry Weißbach        if (is_null($data['file'])) $data['file'] = $this->functions->settings->zipFile;
205f3359d31SGerry Weißbach
206f3359d31SGerry Weißbach        $zip = new ZipArchive();
2076792d0cfSGerry Weißbach        $code = $zip->open($data['file']);
2086792d0cfSGerry Weißbach        if ($code !== TRUE) {
2096792d0cfSGerry Weißbach            $this->functions->debug->message("Can't open the zip-file.", $data['file'], 2);
210f3359d31SGerry Weißbach            return false;
211f3359d31SGerry Weißbach        }
212f3359d31SGerry Weißbach
213f3359d31SGerry Weißbach        if ($zip->numFiles != 1) {
214e77f87a1SGerry Weißbach            $zip->close();
2156792d0cfSGerry Weißbach            $this->functions->debug->message("More than one ({$zip->numFiles}) file in zip.", $data['file'], 2);
216f3359d31SGerry Weißbach            return false;
217f3359d31SGerry Weißbach        }
218f3359d31SGerry Weißbach
219f3359d31SGerry Weißbach        $stat = $zip->statIndex(0);
2206792d0cfSGerry Weißbach        $this->functions->debug->message("Stat.", $stat, 3);
221f3359d31SGerry Weißbach        if (substr($stat['name'], -3) != 'pdf') {
222e77f87a1SGerry Weißbach            $zip->close();
2236792d0cfSGerry Weißbach            $this->functions->debug->message("The file was not a PDF ({$stat['name']}).", $stat['name'], 2);
224f3359d31SGerry Weißbach            return false;
225f3359d31SGerry Weißbach        }
226f3359d31SGerry Weißbach
2276792d0cfSGerry Weißbach        $data['mime'] = 'application/pdf';
228f3359d31SGerry Weißbach
2296792d0cfSGerry Weißbach        // Extract single file.
2306792d0cfSGerry Weißbach        $folder = dirname($data['file']);
2316792d0cfSGerry Weißbach
2326792d0cfSGerry Weißbach        $data['orig'] = utf8_basename($stat['name']);
233f3359d31SGerry Weißbach        $zip->extractTo($folder, $stat['name']);
234f3359d31SGerry Weißbach        $zip->close();
235f3359d31SGerry Weißbach
236f3359d31SGerry Weißbach        sleep(1);
2376792d0cfSGerry Weißbach        $data['file'] .= '.' . cleanID($data['orig']); // Wee need the other file for cache reasons.
238a8c17ab5Si-net /// software        return (@rename($folder.'/'.$data['orig'], $data['file'])) === true;
239f3359d31SGerry Weißbach    }
2407d101cc1SGerry Weißbach}
2417d101cc1SGerry Weißbach
242