Passed
Push — master ( 623939...7130c9 )
by Dominik
09:56 queued 05:47
created

getRelativeUploadDir()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 0
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Flynt\TimberDynamicResize;
4
5
use Twig_SimpleFilter;
6
use Timber;
7
use Routes;
8
9
const DB_VERSION = '1.1';
10
const TABLE_NAME = 'resized_images';
11
const IMAGE_ROUTE = 'dynamic-images';
12
const IMAGE_PATH_SEPARATOR = 'dynamic';
13
14
function getTableName()
15
{
16
    global $wpdb;
17
    return $wpdb->prefix . TABLE_NAME;
18
}
19
20
call_user_func(function () {
21
    $optionName = TABLE_NAME . '_db_version';
22
23
    $installedVersion = get_option($optionName);
24
25
    if ($installedVersion !== DB_VERSION) {
26
        global $wpdb;
27
        $tableName = getTableName();
28
29
        $charsetCollate = $wpdb->get_charset_collate();
30
31
        $sql = "CREATE TABLE $tableName (
32
            url varchar(511),
33
            arguments text
34
        ) $charsetCollate;";
35
36
        require_once ABSPATH . 'wp-admin/includes/upgrade.php';
37
        dbDelta($sql);
38
39
        update_option($optionName, DB_VERSION);
40
    }
41
});
42
43
function getRelativeUploadDir()
44
{
45
    $uploadDir = wp_upload_dir();
46
    return $uploadDir['relative'];
47
}
48
49
add_action('timber/twig/filters', function ($twig) {
50
    $twig->addFilter(
51
        new Twig_SimpleFilter('resizeDynamic', function (
0 ignored issues
show
Deprecated Code introduced by
The class Twig_SimpleFilter has been deprecated: since Twig 2.7, use "Twig\TwigFilter" instead ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

51
        /** @scrutinizer ignore-deprecated */ new Twig_SimpleFilter('resizeDynamic', function (
Loading history...
52
            $src,
53
            $w,
54
            $h = 0,
55
            $crop = 'default',
56
            $force = false
57
        ) {
58
            $resizeOp = new Timber\Image\Operation\Resize($w, $h, $crop);
59
            $fileinfo = pathinfo($src);
60
            $resizedUrl = $resizeOp->filename(
61
                $fileinfo['dirname'] . '/' . $fileinfo['filename'],
62
                $fileinfo['extension']
63
            );
64
65
            $arguments = [
66
                'src' => $src,
67
                'w' => $w,
68
                'h' => $h,
69
                'crop' => $crop,
70
                'force' => $force
71
            ];
72
73
            global $wpdb;
74
            $tableName = getTableName();
75
            $wpdb->query(
76
                $wpdb->prepare("REPLACE INTO {$tableName} VALUES (%s, %s)", [
77
                    $resizedUrl,
78
                    json_encode($arguments)
79
                ])
80
            );
81
82
            $uploadDirRelative = getRelativeUploadDir();
83
84
            return str_replace(
85
                $uploadDirRelative,
86
                trailingslashit($uploadDirRelative) . IMAGE_PATH_SEPARATOR,
87
                $resizedUrl
88
            );
89
        })
90
    );
91
92
    return $twig;
93
});
94
95
Routes::map(IMAGE_ROUTE, function () {
96
    $uploadDirRelative = getRelativeUploadDir();
97
    $src = str_replace(
98
        trailingslashit($uploadDirRelative) . IMAGE_PATH_SEPARATOR,
99
        $uploadDirRelative,
100
        home_url($_GET['src'] ?? '')
101
    );
102
103
    global $wpdb;
104
    $tableName = getTableName();
105
    $resizedImage = $wpdb->get_row(
106
        $wpdb->prepare("SELECT * FROM {$tableName} WHERE url = %s", $src)
107
    );
108
109
    if (empty($resizedImage)) {
110
        header("HTTP/1.0 404 Not Found");
111
        exit();
112
    }
113
    $urlParts = wp_parse_url($src);
114
    $homeUrl = home_url();
115
    $localDev = parse_url($homeUrl)['host'] !== $urlParts['host'];
116
    if ($localDev) {
117
        $src = http_build_url($homeUrl, ['path' => $urlParts['path']]);
0 ignored issues
show
Unused Code introduced by
The assignment to $src is dead and can be removed.
Loading history...
118
    }
119
    $moveImageFunction = function ($location) use ($uploadDirRelative) {
120
        return str_replace(
121
            $uploadDirRelative,
122
            trailingslashit($uploadDirRelative) . IMAGE_PATH_SEPARATOR,
123
            $location
124
        );
125
    };
126
    add_filter('timber/image/new_url', $moveImageFunction);
127
    add_filter('timber/image/new_path', $moveImageFunction);
128
    $arguments = json_decode($resizedImage->arguments, true);
129
    $url = Timber\ImageHelper::resize(
130
        $arguments['src'],
131
        (int) $arguments['w'],
132
        (int) $arguments['h'],
133
        $arguments['crop'],
134
        false
135
    );
136
137
    remove_filter('timber/image/new_url', $moveImageFunction);
138
    remove_filter('timber/image/new_path', $moveImageFunction);
139
140
    Timber\ImageHelper::img_to_webp($url);
141
142
    if ($localDev) {
143
        unset($urlParts['path']);
144
        $url = http_build_url($url, $urlParts);
145
    }
146
    header("Location: {$url}", true, 301);
147
    exit();
148
});
149
150
function addRewriteRule($rules)
151
{
152
    $imageRoute = IMAGE_ROUTE;
153
    $uploadDirRelative = trailingslashit(getRelativeUploadDir());
154
    $dynamicImageDir = trailingslashit($uploadDirRelative . IMAGE_PATH_SEPARATOR);
155
    $dynamicImageRule = <<<EOD
156
\n# BEGIN Flynt dynamic images
157
RewriteEngine On
158
RewriteCond %{REQUEST_URI} ^{$dynamicImageDir}
159
RewriteCond %{REQUEST_FILENAME} !-f
160
RewriteCond %{REQUEST_FILENAME} !-d
161
RewriteRule ^(.*)$ /{$imageRoute}?src=$1 [L,R]
162
163
<IfModule mod_setenvif.c>
164
# Vary: Accept for all the requests to jpeg and png
165
SetEnvIf Request_URI "\.(jpe?g|png)$" REQUEST_image
166
</IfModule>
167
168
<IfModule mod_rewrite.c>
169
RewriteEngine On
170
171
# Check if browser supports WebP images
172
RewriteCond %{HTTP_ACCEPT} image/webp
173
174
# Check if WebP replacement image exists
175
RewriteCond %{DOCUMENT_ROOT}/$1.webp -f
176
177
# Serve WebP image instead
178
RewriteRule (.+)\.(jpe?g|png)$ $1.webp [T=image/webp]
179
</IfModule>
180
181
<IfModule mod_headers.c>
182
Header append Vary Accept env=REQUEST_image
183
</IfModule>
184
185
<IfModule mod_mime.c>
186
AddType image/webp .webp
187
</IfModule>
188
# END Flynt dynamic images\n\n
189
EOD;
190
    return $dynamicImageRule . $rules;
191
}
192
193
add_filter('mod_rewrite_rules', 'Flynt\\TimberDynamicResize\\addRewriteRule');
194
195
add_action('after_switch_theme', function () {
196
    add_action('shutdown', 'flush_rewrite_rules');
197
});
198
199
add_action('switch_theme', function () {
200
    remove_filter('mod_rewrite_rules', 'Flynt\\TimberDynamicResize\\addRewriteRule');
201
    flush_rewrite_rules();
202
});
203