xref: /plugin/dw2pdf/DokuPDF.class.php (revision 2585efdfb5b70b0fcfe1fd81bad6fc0a13f16d4b)
1<?php
2/**
3 * Wrapper around the mpdf library class
4 *
5 * This class overrides some functions to make mpdf make use of DokuWiki'
6 * standard tools instead of its own.
7 *
8 * @author Andreas Gohr <andi@splitbrain.org>
9 */
10
11if(!defined('_MPDF_TEMP_PATH')) define('_MPDF_TEMP_PATH', $conf['tmpdir'].'/dwpdf/'.rand(1,1000).'/');
12if(!defined('_MPDF_TTFONTDATAPATH')) define('_MPDF_TTFONTDATAPATH',$conf['cachedir'].'/mpdf_ttf/');
13require_once(dirname(__FILE__)."/mpdf/mpdf.php");
14
15class DokuPDF extends mpdf {
16
17    function __construct(){
18        io_mkdir_p(_MPDF_TTFONTDATAPATH);
19        io_mkdir_p(_MPDF_TEMP_PATH);
20
21        // we're always UTF-8
22        parent::__construct('UTF-8-s');
23        $this->SetAutoFont(AUTOFONT_ALL);
24        $this->ignore_invalid_utf8 = true;
25        $this->tabSpaces = 4;
26    }
27
28    /**
29     * Cleanup temp dir
30     */
31    function __destruct(){
32        $this->deletedir(_MPDF_TEMP_PATH);
33    }
34
35    /**
36     * Recursively delete a directory and its contents
37     *
38     * @link http://de3.php.net/manual/en/function.rmdir.php#108113
39     */
40    function deletedir($dir){
41        foreach(glob($dir . '/*') as $file) {
42            if(is_dir($file))
43                $this->deletedir($file);
44            else
45                @unlink($file);
46        }
47        @rmdir($dir);
48    }
49
50    /**
51     * Decode all paths, since DokuWiki uses XHTML compliant URLs
52     */
53    function GetFullPath(&$path,$basepath=''){
54        $path = htmlspecialchars_decode($path);
55        parent::GetFullPath($path, $basepath);
56    }
57
58    /**
59     * Override the mpdf _getImage function
60     *
61     * This function takes care of gathering the image data from HTTP or
62     * local files before passing the data back to mpdf's original function
63     * making sure that only cached file paths are passed to mpdf. It also
64     * takes care of checking image ACls.
65     */
66    function _getImage(&$file, $firsttime=true, $allowvector=true, $orig_srcpath=false){
67        global $conf;
68        list($ext,$mime) = mimetype($file);
69
70        // build regex to parse URL back to media info
71        $re = preg_quote(ml('xxx123yyy','',true,'&',true),'/');
72        $re = str_replace('xxx123yyy','([^&\?]*)',$re);
73
74        // extract the real media from a fetch.php uri and determine mime
75        if(preg_match("/^$re/",$file,$m) ||
76            preg_match('/[&\?]media=([^&\?]*)/',$file,$m)){
77            $media = rawurldecode($m[1]);
78            list($ext,$mime) = mimetype($media);
79        }else{
80            list($ext,$mime) = mimetype($file);
81        }
82
83        // local files
84        if(substr($file,0,9) == 'dw2pdf://'){
85            // support local files passed from plugins
86            $local = substr($file,9);
87        }elseif(!preg_match('/(\.php|\?)/',$file)){
88            $re = preg_quote(DOKU_URL,'/');
89            // directly access local files instead of using HTTP, skip dynamic content
90            $local = preg_replace("/^$re/i",DOKU_INC,$file);
91        }
92
93        if(substr($mime,0,6) == 'image/'){
94            if(!empty($media)){
95                // any size restrictions?
96                if(preg_match('/[\?&]w=(\d+)/',$file, $m)) $w = $m[1];
97                if(preg_match('/[\?&]h=(\d+)/',$file, $m)) $h = $m[1];
98
99                if(preg_match('/^(https?|ftp):\/\//',$media)){
100                    $local = media_get_from_URL($media,$ext,-1);
101                    if(!$local) $local = $media; // let mpdf try again
102                }else{
103                    $media = cleanID($media);
104                    //check permissions (namespace only)
105                    if(auth_quickaclcheck(getNS($media).':X') < AUTH_READ){
106                        $file = '';
107                    }
108                    $local  = mediaFN($media);
109                }
110
111                //handle image resizing/cropping
112                if($w && file_exists($local)){
113                    if($h){
114                        $local = media_crop_image($local,$ext,$w,$h);
115                    }else{
116                        $local = media_resize_image($local,$ext,$w,$h);
117                    }
118                }
119            }elseif(preg_match('/^(https?|ftp):\/\//',$file)){ // fixed external URLs
120                $local = media_get_from_URL($file,$ext,$conf['cachetime']);
121            }
122
123            if($local){
124                $file = $local;
125                $orig_srcpath = $local;
126            }
127        }
128
129        return parent::_getImage($file, $firsttime, $allowvector, $orig_srcpath);
130    }
131
132}
133