Completed
Push — master ( d41bdd...a07feb )
by Dominik
27s queued 11s
created

generateImage()   A

Complexity

Conditions 4
Paths 5

Size

Total Lines 54
Code Lines 39

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 39
nc 5
nop 0
dl 0
loc 54
rs 9.296
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace Flynt\TimberDynamicResize;
4
5
use Twig\TwigFilter;
6
use Timber;
7
8
const DB_VERSION = '1.1';
9
const TABLE_NAME = 'resized_images';
10
const IMAGE_ROUTE = 'dynamic-images';
11
const IMAGE_PATH_SEPARATOR = 'dynamic';
12
13
add_filter('init', 'Flynt\TimberDynamicResize\registerRewriteRule');
14
15
function getTableName()
16
{
17
    global $wpdb;
18
    return $wpdb->prefix . TABLE_NAME;
19
}
20
21
call_user_func(function () {
22
    $optionName = TABLE_NAME . '_db_version';
23
24
    $installedVersion = get_option($optionName);
25
26
    if ($installedVersion !== DB_VERSION) {
27
        global $wpdb;
28
        $tableName = getTableName();
29
30
        $charsetCollate = $wpdb->get_charset_collate();
31
32
        $sql = "CREATE TABLE $tableName (
33
            url varchar(511),
34
            arguments text
35
        ) $charsetCollate;";
36
37
        require_once ABSPATH . 'wp-admin/includes/upgrade.php';
38
        dbDelta($sql);
39
40
        update_option($optionName, DB_VERSION);
41
    }
42
});
43
44
function getRelativeUploadDir()
45
{
46
    $uploadDir = wp_upload_dir();
47
    return $uploadDir['relative'];
48
}
49
50
add_action('timber/twig/filters', function ($twig) {
51
    $twig->addFilter(
52
        new TwigFilter('resizeDynamic', function (
53
            $src,
54
            $w,
55
            $h = 0,
56
            $crop = 'default',
57
            $force = false
58
        ) {
59
            $resizeOp = new Timber\Image\Operation\Resize($w, $h, $crop);
60
            $fileinfo = pathinfo($src);
61
            $resizedUrl = $resizeOp->filename(
62
                $fileinfo['dirname'] . '/' . $fileinfo['filename'],
63
                $fileinfo['extension']
64
            );
65
66
            $arguments = [
67
                'src' => $src,
68
                'w' => $w,
69
                'h' => $h,
70
                'crop' => $crop,
71
                'force' => $force
72
            ];
73
74
            global $flyntResizedImages;
75
            if (empty($flyntResizedImages)) {
76
                add_action('shutdown', function () {
77
                    storeResizedUrls();
78
                }, -1);
79
            }
80
            $flyntResizedImages[$resizedUrl] = json_encode($arguments);
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
function registerRewriteRule()
96
{
97
    $routeName = IMAGE_ROUTE;
98
99
    add_rewrite_rule("{$routeName}/?(.*?)/?$", "index.php?{$routeName}=\$matches[1]", "top");
100
    add_rewrite_tag("%{$routeName}%", "([^&]+)");
101
}
102
103
add_action('parse_request', function ($wp) {
104
    if (isset($wp->query_vars[IMAGE_ROUTE])) {
105
        generateImage();
106
    }
107
});
108
109
function generateImage()
110
{
111
    $uploadDirRelative = getRelativeUploadDir();
112
    $src = str_replace(
113
        trailingslashit($uploadDirRelative) . IMAGE_PATH_SEPARATOR,
114
        $uploadDirRelative,
115
        home_url($_GET['src'] ?? '')
116
    );
117
118
    global $wpdb;
119
    $tableName = getTableName();
120
    $resizedImage = $wpdb->get_row(
121
        $wpdb->prepare("SELECT * FROM {$tableName} WHERE url = %s", $src)
122
    );
123
124
    if (empty($resizedImage)) {
125
        header("HTTP/1.0 404 Not Found");
126
        exit();
127
    }
128
    $urlParts = wp_parse_url($src);
129
    $homeUrl = home_url();
130
    $localDev = parse_url($homeUrl)['host'] !== $urlParts['host'];
131
    if ($localDev) {
132
        $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...
133
    }
134
    $moveImageFunction = function ($location) use ($uploadDirRelative) {
135
        return str_replace(
136
            $uploadDirRelative,
137
            trailingslashit($uploadDirRelative) . IMAGE_PATH_SEPARATOR,
138
            $location
139
        );
140
    };
141
    add_filter('timber/image/new_url', $moveImageFunction);
142
    add_filter('timber/image/new_path', $moveImageFunction);
143
    $arguments = json_decode($resizedImage->arguments, true);
144
    $url = Timber\ImageHelper::resize(
145
        $arguments['src'],
146
        (int) $arguments['w'],
147
        (int) $arguments['h'],
148
        $arguments['crop'],
149
        false
150
    );
151
152
    remove_filter('timber/image/new_url', $moveImageFunction);
153
    remove_filter('timber/image/new_path', $moveImageFunction);
154
155
    Timber\ImageHelper::img_to_webp($url);
156
157
    if ($localDev) {
158
        unset($urlParts['path']);
159
        $url = http_build_url($url, $urlParts);
160
    }
161
    header("Location: {$url}", true, 302);
162
    exit();
163
}
164
165
function addRewriteRule($rules)
166
{
167
    $imageRoute = IMAGE_ROUTE;
168
    $uploadDirRelative = trailingslashit(getRelativeUploadDir());
169
    $dynamicImageDir = trailingslashit($uploadDirRelative . IMAGE_PATH_SEPARATOR);
170
    $dynamicImageRule = <<<EOD
171
\n# BEGIN Flynt dynamic images
172
RewriteEngine On
173
RewriteCond %{REQUEST_URI} ^{$dynamicImageDir}
174
RewriteCond %{REQUEST_FILENAME} !-f
175
RewriteCond %{REQUEST_FILENAME} !-d
176
RewriteRule ^(.*)$ /{$imageRoute}?src=$1 [L,R]
177
178
<IfModule mod_setenvif.c>
179
# Vary: Accept for all the requests to jpeg and png
180
SetEnvIf Request_URI "\.(jpe?g|png)$" REQUEST_image
181
</IfModule>
182
183
<IfModule mod_rewrite.c>
184
RewriteEngine On
185
186
# Check if browser supports WebP images
187
RewriteCond %{HTTP_ACCEPT} image/webp
188
189
# Check if WebP replacement image exists
190
RewriteCond %{DOCUMENT_ROOT}/$1.webp -f
191
192
# Serve WebP image instead
193
RewriteRule (.+)\.(jpe?g|png)$ $1.webp [T=image/webp]
194
</IfModule>
195
196
<IfModule mod_headers.c>
197
Header append Vary Accept env=REQUEST_image
198
</IfModule>
199
200
<IfModule mod_mime.c>
201
AddType image/webp .webp
202
</IfModule>
203
# END Flynt dynamic images\n\n
204
EOD;
205
    return $dynamicImageRule . $rules;
206
}
207
208
add_filter('mod_rewrite_rules', 'Flynt\\TimberDynamicResize\\addRewriteRule');
209
210
add_action('after_switch_theme', function () {
211
    add_action('shutdown', 'flush_rewrite_rules');
212
});
213
214
add_action('switch_theme', function () {
215
    remove_filter('mod_rewrite_rules', 'Flynt\\TimberDynamicResize\\addRewriteRule');
216
    flush_rewrite_rules();
217
});
218
219
global $flyntResizedImages;
220
$flyntResizedImages = [];
221
222
function storeResizedUrls()
223
{
224
    global $wpdb, $flyntResizedImages;
225
    $tableName = getTableName();
226
    $urls = array_keys($flyntResizedImages);
227
    $deletePlaceholders = array_fill(0, count($urls), '%s');
228
    $deletePlaceholdersString = '(' . implode(', ', $deletePlaceholders) . ')';
229
    $wpdb->query(
230
        $wpdb->prepare(
231
            "DELETE FROM {$tableName} WHERE url IN {$deletePlaceholdersString}",
232
            $urls
233
        )
234
    );
235
    $insertPlaceholders = array_fill(0, count($urls), '(%s, %s)');
236
    $insertPlaceholdersString = implode(', ', $insertPlaceholders);
237
    $insertValues = [];
238
    foreach ($urls as $url) {
239
        $insertValues[] = $url;
240
        $insertValues[] = $flyntResizedImages[$url];
241
    }
242
    $wpdb->query(
243
        $wpdb->prepare(
244
            "INSERT INTO {$tableName} (url, arguments) VALUES {$insertPlaceholdersString}",
245
            $insertValues
246
        )
247
    );
248
}
249