xref: /plugin/siteexport/inc/filewriter.php (revision b324a1904db918260ecf6c6ae2a8ee1c5f7c9512)
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     */
117d101cc1SGerry Weißbach    private $pdfGenerator = false;
127d101cc1SGerry Weißbach    private $functions = null;
137d101cc1SGerry Weißbach
14*b324a190SMichael 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    {
257d101cc1SGerry Weißbach        return $this->pdfGenerator !== false;
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
377d101cc1SGerry Weißbach        $tmpFile = tempnam($this->functions->settings->tmpDir, 'siteexport__');
387d101cc1SGerry Weißbach
39e6ebb3b0SGerry Weißbach        @file_put_contents($tmpFile, $DATA);
407d101cc1SGerry Weißbach
417d101cc1SGerry Weißbach        // Add to zip
42e6ebb3b0SGerry Weißbach        if ($JUSTWRITE) {
43e6ebb3b0SGerry Weißbach            $status = $this->__writeFileToZip($tmpFile, $FILENAME, $ZIP);
44e6ebb3b0SGerry Weißbach        } else {
45e6ebb3b0SGerry Weißbach            $status = $this->__addFileToZip($tmpFile, $FILENAME, $ZIP);
46e6ebb3b0SGerry Weißbach        }
477d101cc1SGerry Weißbach        @unlink($tmpFile);
487d101cc1SGerry Weißbach
49e6ebb3b0SGerry Weißbach        return $status;
507d101cc1SGerry Weißbach    }
517d101cc1SGerry Weißbach
527d101cc1SGerry Weißbach    /**
537d101cc1SGerry Weißbach     * Adds a file to the zip file
547d101cc1SGerry Weißbach     * @param $FILE file-name of the zip
557d101cc1SGerry Weißbach     * @param $NAME name of the file that is being added
567d101cc1SGerry Weißbach     * @param $ZIP name of the zip file to which we add
577d101cc1SGerry Weißbach     */
587d101cc1SGerry Weißbach    function __addFileToZip($FILE, $NAME, $ZIP = null) {
597d101cc1SGerry Weißbach
607d101cc1SGerry Weißbach        if ($NAME[0] === "/") {
617d101cc1SGerry Weißbach            $this->functions->debug->message("Weird, the NAME for the ZIP started with a '/'. This may result in wrong links!", null, 3);
627d101cc1SGerry Weißbach            $NAME = substr($NAME, 1);
637d101cc1SGerry Weißbach        }
647d101cc1SGerry Weißbach
657d101cc1SGerry Weißbach        // check for mpdf
667d101cc1SGerry Weißbach        if ($this->canDoPDF()) {
677d101cc1SGerry Weißbach            $this->functions->debug->message("Trying to create PDF from File '$FILE' with name '$NAME' for ZIP '$ZIP'", null, 2);
687d101cc1SGerry Weißbach
69e6ebb3b0SGerry Weißbach            $succeeded = $this->pdfGenerator->createPDFFromFile($FILE, $NAME);
70e6ebb3b0SGerry Weißbach
717d101cc1SGerry Weißbach            if ($this->functions->debug->debugLevel() <= 1) { // 2011-01-12 Write HTML to ZIP for Debug purpose
72e6ebb3b0SGerry Weißbach                $this->__moveDataToZip($succeeded, "_debug/$NAME.html", $ZIP, true);
737d101cc1SGerry Weißbach            }
747d101cc1SGerry Weißbach
75e6ebb3b0SGerry Weißbach            if ($succeeded === false) {
768da901a0SGerry Weißbach                $this->functions->debug->runtimeException("Create PDF from File '$FILE' with name '$NAME' went wrong and is not being added!");
778da901a0SGerry Weißbach                return false;
787d101cc1SGerry Weißbach            }
797d101cc1SGerry Weißbach        }
807d101cc1SGerry Weißbach
817d101cc1SGerry Weißbach        return $this->__writeFileToZip($FILE, $NAME, $ZIP);
827d101cc1SGerry Weißbach    }
837d101cc1SGerry Weißbach
847d101cc1SGerry Weißbach    /**
857d101cc1SGerry Weißbach     * This really writes a file to a zip-file
867d101cc1SGerry Weißbach     * @param $FILE file-name of the zip
877d101cc1SGerry Weißbach     * @param $NAME name of the file that is being added
887d101cc1SGerry Weißbach     * @param $ZIP name of the zip file to which we add
897d101cc1SGerry Weißbach     */
90e77f87a1SGerry Weißbach    private function __writeFileToZip($FILE, $NAME, $ZIPFILE) {
91e77f87a1SGerry Weißbach        if (empty($ZIPFILE)) $ZIPFILE = $this->functions->settings->zipFile;
927d101cc1SGerry Weißbach
937d101cc1SGerry Weißbach        if (!class_exists('ZipArchive')) {
947d101cc1SGerry Weißbach            $this->functions->debug->runtimeException("PHP class 'ZipArchive' does not exist. Please make sure that you have the ziplib extension for PHP installed.");
957d101cc1SGerry Weißbach            return false;
967d101cc1SGerry Weißbach        }
977d101cc1SGerry Weißbach
986792d0cfSGerry Weißbach        $zip = new ZipArchive();
997d101cc1SGerry Weißbach        if (!$zip) {
1007d101cc1SGerry 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.");
1017d101cc1SGerry Weißbach            return false;
1027d101cc1SGerry Weißbach        }
1037d101cc1SGerry Weißbach
104e77f87a1SGerry Weißbach        $code = $zip->open($ZIPFILE, ZipArchive::CREATE);
1057d101cc1SGerry Weißbach        if ($code === TRUE) {
1067d101cc1SGerry Weißbach
1077d101cc1SGerry Weißbach            $this->functions->debug->message("Adding file '$NAME' to ZIP $ZIP", null, 2);
1087d101cc1SGerry Weißbach
1097d101cc1SGerry Weißbach            $zip->addFile($FILE, $NAME);
1107d101cc1SGerry Weißbach            $zip->close();
1117d101cc1SGerry Weißbach
1127d101cc1SGerry Weißbach            // If this has worked out, we may put this version into the cache ... ?
1137d101cc1SGerry Weißbach
1147d101cc1SGerry Weißbach            // ALibi Touching - 2011-09-13 wird nicht gebraucht nach Umstellung
1157d101cc1SGerry Weißbach            // io_saveFile(mediaFN($this->origZipFile), "alibi file");
1167d101cc1SGerry Weißbach
1177d101cc1SGerry Weißbach            return true;
1187d101cc1SGerry Weißbach        }
1197d101cc1SGerry Weißbach
120e77f87a1SGerry Weißbach        $this->functions->debug->runtimeException("Zip Error #{$code} for file {$NAME}");
1217d101cc1SGerry Weißbach        return false;
1227d101cc1SGerry Weißbach    }
1237d101cc1SGerry Weißbach
1247d101cc1SGerry Weißbach    /**
1257d101cc1SGerry Weißbach     * check if a file exists allready
1267d101cc1SGerry Weißbach     * @param $NAME name of the file in the zip
1277d101cc1SGerry Weißbach     */
1287d101cc1SGerry Weißbach    function fileExistsInZip($NAME)
1297d101cc1SGerry Weißbach    {
1306792d0cfSGerry Weißbach        $zip = new ZipArchive();
1317d101cc1SGerry Weißbach        $code = $zip->open($this->functions->settings->zipFile, ZipArchive::CREATE);
1327d101cc1SGerry Weißbach        if ($code === TRUE) {
133e77f87a1SGerry Weißbach            $exists = !($zip->statName($NAME) === FALSE);
134e77f87a1SGerry Weißbach            $zip->close();
135e77f87a1SGerry Weißbach            return $exists;
1367d101cc1SGerry Weißbach        }
1377d101cc1SGerry Weißbach
1387d101cc1SGerry Weißbach        return false;
1397d101cc1SGerry Weißbach    }
1407d101cc1SGerry Weißbach
1417d101cc1SGerry Weißbach    /**
1427d101cc1SGerry Weißbach     * Checks if a valid cache file exists for the given request parameters
1437d101cc1SGerry Weißbach     * @param $requestData
1447d101cc1SGerry Weißbach     */
1457d101cc1SGerry Weißbach    function hasValidCacheFile($requestData, $depends = array())
1467d101cc1SGerry Weißbach    {
1476792d0cfSGerry Weißbach        $pattern = $this->functions->requestParametersToCacheHash($requestData);
1486792d0cfSGerry Weißbach        return $this->hasValidCacheFileForPattern($pattern, $depends);
1496792d0cfSGerry Weißbach    }
1507d101cc1SGerry Weißbach
1516792d0cfSGerry Weißbach    private function hasValidCacheFileForPattern($pattern, $depends = array())
1526792d0cfSGerry Weißbach    {
1536792d0cfSGerry Weißbach        $this->functions->debug->message("HASH-Pattern for CacheFile: ", $pattern, 2);
1546792d0cfSGerry Weißbach        $this->functions->settings->hasValidCacheFile = false; // reset the cache settings
1556792d0cfSGerry Weißbach        $cacheFile = $this->functions->getCacheFileNameForPattern($pattern);
1567d101cc1SGerry Weißbach
1577d101cc1SGerry Weißbach        $mtime = @filemtime($cacheFile); // 0 if not exists
1587d101cc1SGerry Weißbach
1597d101cc1SGerry Weißbach        // Check if the file is expired - if so, just create a new one.
160f8fd18e7SGerry Weißbach        if ($mtime == 0 || $mtime < time()-$this->functions->settings->cachetime)
1617d101cc1SGerry Weißbach        {
1627d101cc1SGerry Weißbach            @unlink($cacheFile);
1637d101cc1SGerry Weißbach            @unlink($this->functions->settings->zipFile);
1647d101cc1SGerry Weißbach            $this->functions->debug->message("New CacheFile because the file was over the cachetime: ", $cacheFile, 2);
1657d101cc1SGerry Weißbach            return false;
1667d101cc1SGerry Weißbach        }
1677d101cc1SGerry Weißbach
1687d101cc1SGerry Weißbach        // Check for dependencies
1697d101cc1SGerry Weißbach        if (!empty($depends))
1707d101cc1SGerry Weißbach        {
171ad37ef9aSGerry Weißbach            $this->functions->debug->message("Checking dependencies: ", $depends, 1);
1727d101cc1SGerry Weißbach            foreach ($depends as $site) {
1737d101cc1SGerry Weißbach
1747d101cc1SGerry Weißbach                if (!page_exists($site['id']))
1757d101cc1SGerry Weißbach                {
176ad37ef9aSGerry Weißbach                    $this->functions->debug->message("File does not exist: ", $site['id'], 2);
1777d101cc1SGerry Weißbach                    continue;
1787d101cc1SGerry Weißbach                }
1797d101cc1SGerry Weißbach
1807d101cc1SGerry Weißbach                if ($mtime < @filemtime(wikiFN($site['id']))) {
1817d101cc1SGerry Weißbach                    @unlink($cacheFile);
1827d101cc1SGerry Weißbach                    @unlink($this->functions->settings->zipFile);
1837d101cc1SGerry Weißbach                    $this->functions->debug->message("New CacheFile, because a page changed: ", $cacheFile, 2);
1847d101cc1SGerry Weißbach                    return false; // cache older than files it depends on?
1857d101cc1SGerry Weißbach                }
1867d101cc1SGerry Weißbach            }
1877d101cc1SGerry Weißbach        }
1887d101cc1SGerry Weißbach
1897d101cc1SGerry Weißbach        $this->functions->debug->message("CacheFile exists: ", $cacheFile, 2);
1907d101cc1SGerry Weißbach        return $this->functions->settings->hasValidCacheFile = true;
1917d101cc1SGerry Weißbach    }
192f3359d31SGerry Weißbach
1936792d0cfSGerry Weißbach    public function getOnlyFileInZip(&$data = null) {
194f3359d31SGerry Weißbach
1956792d0cfSGerry Weißbach        if (is_null($data['file'])) $data['file'] = $this->functions->settings->zipFile;
196f3359d31SGerry Weißbach
197f3359d31SGerry Weißbach        $zip = new ZipArchive();
1986792d0cfSGerry Weißbach        $code = $zip->open($data['file']);
1996792d0cfSGerry Weißbach        if ($code !== TRUE) {
2006792d0cfSGerry Weißbach            $this->functions->debug->message("Can't open the zip-file.", $data['file'], 2);
201f3359d31SGerry Weißbach            return false;
202f3359d31SGerry Weißbach        }
203f3359d31SGerry Weißbach
204f3359d31SGerry Weißbach        if ($zip->numFiles != 1) {
205e77f87a1SGerry Weißbach            $zip->close();
2066792d0cfSGerry Weißbach            $this->functions->debug->message("More than one ({$zip->numFiles}) file in zip.", $data['file'], 2);
207f3359d31SGerry Weißbach            return false;
208f3359d31SGerry Weißbach        }
209f3359d31SGerry Weißbach
210f3359d31SGerry Weißbach        $stat = $zip->statIndex(0);
2116792d0cfSGerry Weißbach        $this->functions->debug->message("Stat.", $stat, 3);
212f3359d31SGerry Weißbach        if (substr($stat['name'], -3) != 'pdf') {
213e77f87a1SGerry Weißbach            $zip->close();
2146792d0cfSGerry Weißbach            $this->functions->debug->message("The file was not a PDF ({$stat['name']}).", $stat['name'], 2);
215f3359d31SGerry Weißbach            return false;
216f3359d31SGerry Weißbach        }
217f3359d31SGerry Weißbach
2186792d0cfSGerry Weißbach        $data['mime'] = 'application/pdf';
219f3359d31SGerry Weißbach
2206792d0cfSGerry Weißbach        // Extract single file.
2216792d0cfSGerry Weißbach        $folder = dirname($data['file']);
2226792d0cfSGerry Weißbach
2236792d0cfSGerry Weißbach        $data['orig'] = utf8_basename($stat['name']);
224f3359d31SGerry Weißbach        $zip->extractTo($folder, $stat['name']);
225f3359d31SGerry Weißbach        $zip->close();
226f3359d31SGerry Weißbach
227f3359d31SGerry Weißbach        sleep(1);
2286792d0cfSGerry Weißbach        $data['file'] .= '.' . cleanID($data['orig']); // Wee need the other file for cache reasons.
2296792d0cfSGerry Weißbach        @rename($folder.'/'.$data['orig'], $data['file']);
230f3359d31SGerry Weißbach        return true;
231f3359d31SGerry Weißbach    }
2327d101cc1SGerry Weißbach}
2337d101cc1SGerry Weißbach
234