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