-
Notifications
You must be signed in to change notification settings - Fork 7
/
intervention-wrapper.php
185 lines (130 loc) · 4.72 KB
/
intervention-wrapper.php
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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
<?php
use Intervention\Image\ImageManagerStatic as Image;
class Intervention_Wrapper {
private $src;
private $intervention_args;
private $options;
private $cache_file_path;
private $intervention_instance;
function __construct( $src=null, $intervention_args=array(), $options=array() ) {
if ( empty( $src ) ) {
return new WP_Error( 'No image source provided' );
}
// Main image src provided by user
$this->src = $src;
// Intervention args
// image.intervention.io
$this->intervention_args = $intervention_args;
// Allow defaults to be overriden on a global basis
$default_options = apply_filters('wpi_default_options', array(
'quality' => 80,
'cache' => true
));
// Set the options
$this->options = array_merge( $default_options, $options);
}
public function process( $return_instance = false ) {
// Cache the setting of the cache path
$this->set_cache_file_path();
// If we have a cache of this image then just return that directly
if ( $this->options['cache'] && $this->check_cache() ) {
return $this->get_cache_file_path( 'uri' ); // return a URI not a DIR
}
// Initialise Intervention.io
// only do this if we absolutely have to as even initialisation introduces
// significant overheads and will damage performance
Image::configure( array(
'driver' => apply_filters('wpi_driver', 'gd' )
) );
$this->intervention_instance = Image::make( $this->src );
// Proxy all args to underlying Intevention library
// note: args will be called in order defined in the
// $intervention_args array
foreach ($this->intervention_args as $sFn => $aFnArgs)
{
if (!is_array($aFnArgs))
{
$aFnArgs = [ $aFnArgs ];
}
call_user_func_array([$this->intervention_instance, $sFn], $aFnArgs);
}
// Save resulting file to cache dir
$this->save_image();
// If user has requested the raw Intervention instance then return that
if ($return_instance) {
return $this->intervention_instance;
}
// ...otherwise, return a public URL to the image
return $this->get_cache_file_path( 'uri' );
}
private function check_cache() {
$cache_file_path = $this->get_cache_file_path();
if ( file_exists( $cache_file_path ) ) {
// Update the timestamp on the file to show it's been accessed
touch( $cache_file_path );
return $cache_file_path;
}
}
private function get_cache_file_path( $type='directory' ) {
$cache_file_path;
if ( empty( $this->cache_file_path ) ) {
$this->set_cache_file_path();
}
$cache_file_path = $this->cache_file_path;
// TODO: account for situations where user has filtered the cache path
// we can't reply on str_replace or upload dir...
if ( $type === 'uri' ) {
$upload_dir = WP_Intervention::upload_dir();
$cache_file_path = str_replace( $upload_dir['basedir'], $upload_dir['baseurl'], $this->cache_file_path );
}
return $cache_file_path;
}
private function set_cache_file_path() {
// Strip PHP callables out of the args
$args = $this->strip_callables($this->intervention_args);
// Sort the array by key to ensure consistency of caching filename
ksort($args);
$file_pathinfo = pathinfo($this->src);
$ext = $file_pathinfo['extension'];
$new_filename = $file_pathinfo['filename'] . '-' . crc32( $this->r_implode( $args, '-') ) . "." . $ext;
// Enable filtering of the filename on a per file basis
$new_filename = apply_filters('wpi_cache_file_name', $new_filename, $file_pathinfo['filename'], $ext, $args);
$this->cache_file_path = WP_Intervention::get_cache_dir() . $new_filename;
}
private function save_image() {
$rtn = $this->intervention_instance->save( $this->get_cache_file_path(), $this->options['quality'] );
return $rtn;
}
/**
* RECURSIVE IMPLODE
* @param array $pieces the array to implode
* @param string $glue the string to used when combining the array
* @return string the imploded array
*/
private function r_implode( $pieces, $glue ) {
$retVal = array_map(function($item) use ($glue) {
if( is_array( $item ) ) {
return $this->r_implode( $item, $glue );
} else {
return $item;
}
}, $pieces);
return implode( $glue, $retVal );
}
/**
* Recursively strips PHP callables out of an array, so we can serialize it nicely.
*
* @param $args the array from which to strip callables
* @return the passed array, with all callables removed
*/
private function strip_callables($args) {
// 1. recurse
$args = array_map(function($arg) {
return (is_array($arg)) ? $this->strip_callables($arg) : $arg;
}, $args);
// 2. strip all the things
return array_filter($args, function($arg) {
return !is_callable($arg);
});
}
}