PluginProbe
Imagify Image Optimization: Optimize Images | Compress & Convert to WebP/AVIF / 2.3.3
Imagify Image Optimization: Optimize Images | Compress & Convert to WebP/AVIF v2.3.3
2.3.4 2.3.3 2.3.2 2.3.1 2.3.0 2.2.9 2.2.8 trunk 1.10 1.3.3 1.3.4 1.3.5 1.3.5.1 1.3.5.2 1.3.6 1.3.6.1 1.4 1.4.1 1.4.2 1.4.3 1.4.4 1.4.5 1.4.6 1.4.7 1.5 All 103 releases
imagify / classes / WriteFile / AbstractWriteDirConfFile.php

AbstractWriteDirConfFile.php in Imagify Image Optimization: Optimize Images | Compress & Convert to WebP/AVIF 2.3.3, at classes/WriteFile/AbstractWriteDirConfFile.php

398 lines 9.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 namespace Imagify\WriteFile;
3
4 defined( 'ABSPATH' ) || die( 'Cheatin’ uh?' );
5
6 /**
7 * Abstract class used to add and remove contents to a directory conf file (.htaccess, etc).
8 *
9 * @since 1.9
10 * @author Grégory Viguier
11 */
12 abstract class AbstractWriteDirConfFile implements WriteFileInterface {
13
14 /**
15 * Name of the tag used as block delemiter.
16 *
17 * @var string
18 * @since 1.9
19 * @author Grégory Viguier
20 */
21 const TAG_NAME = 'Imagify ###';
22
23 /**
24 * Filesystem object.
25 *
26 * @var \Imagify_Filesystem
27 * @since 1.9
28 * @access protected
29 * @author Grégory Viguier
30 */
31 protected $filesystem;
32
33 /**
34 * Constructor.
35 *
36 * @since 1.9
37 * @access public
38 * @author Grégory Viguier
39 */
40 public function __construct() {
41 $this->filesystem = \Imagify_Filesystem::get_instance();
42 }
43
44 /**
45 * Add new contents to the file.
46 *
47 * @since 1.9
48 * @access public
49 * @author Grégory Viguier
50 *
51 * @return bool|\WP_Error True on success. A \WP_Error object on error.
52 */
53 public function add() {
54 $result = $this->insert_contents( $this->get_new_contents() );
55
56 if ( ! is_wp_error( $result ) ) {
57 return true;
58 }
59 $file_path = $this->get_file_path();
60 $file_name = $this->filesystem->make_path_relative( $file_path );
61
62 if ( 'edition_disabled' === $result->get_error_code() ) {
63 return new \WP_Error(
64 'edition_disabled',
65 sprintf(
66 /* translators: %s is a file name. */
67 __( 'Imagify did not add contents to the %s file, as its edition is disabled.', 'imagify' ),
68 $file_name
69 )
70 );
71 }
72
73 return new \WP_Error(
74 'add_contents_failure',
75 sprintf(
76 /* translators: 1 is a file name, 2 is an error message. */
77 __( 'Imagify could not insert contents into the %1$s file: %2$s', 'imagify' ),
78 $file_name,
79 $result->get_error_message()
80 ),
81 [ 'code' => $result->get_error_code() ]
82 );
83 }
84
85 /**
86 * Remove the related contents from the file.
87 *
88 * @since 1.9
89 * @access public
90 * @author Grégory Viguier
91 *
92 * @return bool|\WP_Error True on success. A \WP_Error object on error.
93 */
94 public function remove() {
95 $result = $this->insert_contents( '' );
96
97 if ( ! is_wp_error( $result ) ) {
98 return true;
99 }
100
101 $file_path = $this->get_file_path();
102 $file_name = $this->filesystem->make_path_relative( $file_path );
103
104 if ( 'edition_disabled' === $result->get_error_code() ) {
105 return new \WP_Error(
106 'edition_disabled',
107 sprintf(
108 /* translators: %s is a file name. */
109 __( 'Imagify did not remove the contents from the %s file, as its edition is disabled.', 'imagify' ),
110 $file_name
111 )
112 );
113 }
114
115 return new \WP_Error(
116 'add_contents_failure',
117 sprintf(
118 /* translators: 1 is a file name, 2 is an error message. */
119 __( 'Imagify could not remove contents from the %1$s file: %2$s', 'imagify' ),
120 $file_name,
121 $result->get_error_message()
122 ),
123 [ 'code' => $result->get_error_code() ]
124 );
125 }
126
127 /**
128 * Get the path to the file.
129 *
130 * @since 1.9
131 * @access public
132 * @author Grégory Viguier
133 *
134 * @return string
135 */
136 public function get_file_path() {
137 $file_path = $this->get_raw_file_path();
138
139 /**
140 * Filter the path to the directory conf file.
141 *
142 * @since 1.9
143 * @author Grégory Viguier
144 *
145 * @param string $file_path Path to the file.
146 */
147 $new_file_path = apply_filters( 'imagify_dir_conf_path', $file_path );
148
149 if ( $new_file_path && is_string( $new_file_path ) ) {
150 return $new_file_path;
151 }
152
153 return $file_path;
154 }
155
156 /**
157 * Tell if the file is writable.
158 *
159 * @since 1.9
160 * @access public
161 * @author Grégory Viguier
162 *
163 * @return bool|\WP_Error True if writable. A \WP_Error object if not.
164 */
165 public function is_file_writable() {
166 $file_path = $this->get_file_path();
167 $file_name = $this->filesystem->make_path_relative( $file_path );
168
169 if ( $this->is_conf_edition_disabled() ) {
170 return new \WP_Error(
171 'edition_disabled',
172 sprintf(
173 /* translators: %s is a file name. */
174 __( 'Edition of the %s file is disabled.', 'imagify' ),
175 '<code>' . esc_html( $file_name ) . '</code>'
176 )
177 );
178 }
179
180 if ( ! $this->filesystem->exists( $file_path ) ) {
181 $dir_path = $this->filesystem->dir_path( $file_path );
182
183 $this->filesystem->make_dir( $dir_path );
184
185 if ( ! $this->filesystem->is_writable( $dir_path ) ) {
186 return new \WP_Error(
187 'parent_not_writable',
188 sprintf(
189 /* translators: %s is a file name. */
190 __( '%s’s parent folder is not writable.', 'imagify' ),
191 '<code>' . esc_html( $file_name ) . '</code>'
192 )
193 );
194 }
195 if ( ! $this->filesystem->touch( $file_path ) ) {
196 return new \WP_Error(
197 'not_created',
198 sprintf(
199 /* translators: %s is a file name. */
200 __( 'The %s file could not be created.', 'imagify' ),
201 '<code>' . esc_html( $file_name ) . '</code>'
202 )
203 );
204 }
205 } elseif ( ! $this->filesystem->is_writable( $file_path ) ) {
206 return new \WP_Error(
207 'not_writable',
208 sprintf(
209 /* translators: %s is a file name. */
210 __( 'The %s file is not writable.', 'imagify' ),
211 '<code>' . esc_html( $file_name ) . '</code>'
212 )
213 );
214 }
215
216 return true;
217 }
218
219 /**
220 * Get new contents to write into the file.
221 *
222 * @since 1.9
223 * @access public
224 * @author Grégory Viguier
225 *
226 * @return string
227 */
228 public function get_new_contents() {
229 $contents = $this->get_raw_new_contents();
230
231 /**
232 * Filter the contents to add to the directory conf file.
233 *
234 * @since 1.9
235 * @author Grégory Viguier
236 *
237 * @param string $contents The contents.
238 */
239 $new_contents = apply_filters( 'imagify_dir_conf_contents', $contents );
240
241 if ( $new_contents && is_string( $new_contents ) ) {
242 return $new_contents;
243 }
244
245 return $contents;
246 }
247
248 /** ----------------------------------------------------------------------------------------- */
249 /** ABSTRACT METHODS ======================================================================== */
250 /** ----------------------------------------------------------------------------------------- */
251
252 /**
253 * Insert new contents into the directory conf file.
254 * Replaces existing marked info. Creates file if none exists.
255 *
256 * @since 1.9
257 * @access protected
258 * @author Grégory Viguier
259 *
260 * @param string $new_contents Contents to insert.
261 * @return bool|\WP_Error True on write success, a \WP_Error object on failure.
262 */
263 abstract protected function insert_contents( $new_contents );
264
265 /**
266 * Get the unfiltered path to the file.
267 *
268 * @since 1.9
269 * @access protected
270 * @author Grégory Viguier
271 *
272 * @return string
273 */
274 abstract protected function get_raw_file_path();
275
276 /**
277 * Get unfiltered new contents to write into the file.
278 *
279 * @since 1.9
280 * @access protected
281 * @author Grégory Viguier
282 *
283 * @return string
284 */
285 abstract protected function get_raw_new_contents();
286
287 /** ----------------------------------------------------------------------------------------- */
288 /** OTHER TOOLS ============================================================================= */
289 /** ----------------------------------------------------------------------------------------- */
290
291 /**
292 * Get the file contents.
293 *
294 * @since 1.9
295 * @access protected
296 * @author Grégory Viguier
297 *
298 * @return mixed|\WP_Error The file contents on success, a \WP_Error object on failure.
299 */
300 protected function get_file_contents() {
301 $writable = $this->is_file_writable();
302
303 if ( is_wp_error( $writable ) ) {
304 return $writable;
305 }
306
307 $file_path = $this->get_file_path();
308 $file_name = $this->filesystem->make_path_relative( $file_path );
309
310 if ( ! $this->filesystem->exists( $file_path ) ) {
311 // This should not happen.
312 return '';
313 }
314
315 $contents = $this->filesystem->get_contents( $file_path );
316
317 if ( false === $contents ) {
318 return new \WP_Error(
319 'not_read',
320 sprintf(
321 /* translators: %s is a file name. */
322 __( 'The %s file could not be read.', 'imagify' ),
323 '<code>' . esc_html( $file_name ) . '</code>'
324 )
325 );
326 }
327
328 return $contents;
329 }
330
331 /**
332 * Put new contents into the file.
333 *
334 * @since 1.9
335 * @access protected
336 * @author Grégory Viguier
337 *
338 * @param string $contents New contents to add to the file.
339 * @return bool|\WP_Error True on success, a \WP_Error object on failure.
340 */
341 protected function put_file_contents( $contents ) {
342 $file_path = $this->get_file_path();
343 $result = $this->filesystem->put_contents( $file_path, $contents );
344
345 if ( $result ) {
346 return true;
347 }
348
349 $file_name = $this->filesystem->make_path_relative( $file_path );
350
351 return new \WP_Error(
352 'edition_failed',
353 sprintf(
354 /* translators: %s is a file name. */
355 __( 'Could not write into the %s file.', 'imagify' ),
356 '<code>' . esc_html( $file_name ) . '</code>'
357 )
358 );
359 }
360
361 /**
362 * Tell if edition of the directory conf file is disabled.
363 *
364 * @since 1.9
365 * @access public
366 * @author Grégory Viguier
367 *
368 * @return bool True to disable, false otherwise.
369 */
370 protected function is_conf_edition_disabled() {
371 /**
372 * Disable directory conf edition.
373 *
374 * @since 1.9
375 * @author Grégory Viguier
376 *
377 * @param bool $disable True to disable, false otherwise.
378 */
379 return (bool) apply_filters( 'imagify_disable_dir_conf_edition', false );
380 }
381
382 /**
383 * Get a regex pattern to be used to match the supported file extensions.
384 *
385 * @since 1.9
386 * @access protected
387 * @author Grégory Viguier
388 *
389 * @return string
390 */
391 protected function get_extensions_pattern() {
392 $extensions = imagify_get_mime_types( 'image' );
393 $extensions = array_keys( $extensions );
394
395 return implode( '|', $extensions );
396 }
397 }
398