summaryrefslogtreecommitdiff
path: root/plugins/Minify/minify.php
blob: 2de2d6d26f28191e61723f75c9fa9c3a16e50c3b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
<?php
/*
 * StatusNet - the distributed open-source microblogging tool
 * Copyright (C) 2008, 2009, StatusNet, Inc.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); }

// We bundle the minify library...
set_include_path(get_include_path() . PATH_SEPARATOR . dirname(__FILE__) . '/extlib/minify/min/lib');

class MinifyAction extends Action
{
    const TYPE_CSS = 'text/css';
    const TYPE_HTML = 'text/html';
    // there is some debate over the ideal JS Content-Type, but this is the
    // Apache default and what Yahoo! uses..
    const TYPE_JS = 'application/x-javascript';

    const cacheKey = 'minify';

    var $file;

    function isReadOnly($args)
    {
        return true;
    }

    function prepare($args)
    {
        parent::prepare($args);
        $this->v = $args['v'];

        $f = $this->arg('f');
        if(isset($f)) {
            $this->file = INSTALLDIR.'/'.$f;
            if(file_exists($this->file)) {
                return true;
            } else {
                $this->clientError(_('f parameter is not a valid path'),404);
                return false;
            }
        }else{
            $this->clientError(_('f parameter is required'),500);
            return false;
        }
    }

    function etag() 
    {
        if(isset($this->v)) {
            return "\"" . crc32($this->file . $this->v) . "\"";
        }else{
            $stat = stat($this->file);
            return '"' . $stat['ino'] . '-' . $stat['size'] . '-' . $stat['mtime'] . '"';
        }
    }

    function lastModified()
    {
        return filemtime($this->file);
    }

    function handle($args)
    {
        parent::handle($args);
        
        $c = common_memcache();
        if (!empty($c)) {
            $out = $c->get(common_cache_key(self::cacheKey . ':' . $this->file));
        }
        if(empty($out)) {
            $out = $this->minify($this->file);
        }
        if (!empty($c)) {
            $c->set(common_cache_key(self::cacheKey . ':' . $this->file), $out);
        }

        $sec = session_cache_expire() * 60;
        header('Cache-Control: public, max-age=' . $sec);
        header('Pragma: public');
        $this->raw($out);
    }

    function minify($file)
    {
        $info = pathinfo($file);
        switch(strtolower($info['extension'])){
            case 'js':
                require_once('JSMin.php');
                $out = JSMin::minify(file_get_contents($file));
                header('Content-Type: ' . self::TYPE_JS);
                break;
            case 'css':
                require_once('Minify/CSS.php');
                $options = array();
                $options['currentDir'] = dirname($file);
                $options['docRoot'] = INSTALLDIR;
                $out = Minify_CSS::minify(file_get_contents($file),$options);
                header('Content-Type: ' . self::TYPE_CSS);
                break;
            default:
                $this->clientError(_('File type not supported'),500);
                return false;
        }
        return $out;
    }
}