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