PluginProbe
Imagify Image Optimization: Optimize Images | Compress & Convert to WebP/AVIF / 2.1.1
Imagify Image Optimization: Optimize Images | Compress & Convert to WebP/AVIF v2.1.1
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.1.1, at classes/WriteFile/AbstractWriteDirConfFile.php

396 lines 9.3 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_name = $this->filesystem->make_path_relative( $file_path );
102
103 if ( 'edition_disabled' === $result->get_error_code() ) {
104 return new \WP_Error(
105 'edition_disabled',
106 sprintf(
107 /* translators: %s is a file name. */
108 __( 'Imagify did not remove the contents from the %s file, as its edition is disabled.', 'imagify' ),
109 $file_name
110 )
111 );
112 }
113
114 return new \WP_Error(
115 'add_contents_failure',
116 sprintf(
117 /* translators: 1 is a file name, 2 is an error message. */
118 __( 'Imagify could not remove contents from the %1$s file: %2$s', 'imagify' ),
119 $file_name,
120 $result->get_error_message()
121 ),
122 [ 'code' => $result->get_error_code() ]
123 );
124 }
125
126 /**
127 * Get the path to the file.
128 *
129 * @since 1.9
130 * @access public
131 * @author Grégory Viguier
132 *
133 * @return string
134 */
135 public function get_file_path() {
136 $file_path = $this->get_raw_file_path();
137
138 /**
139 * Filter the path to the directory conf file.
140 *
141 * @since 1.9
142 * @author Grégory Viguier
143 *
144 * @param string $file_path Path to the file.
145 */
146 $new_file_path = apply_filters( 'imagify_dir_conf_path', $file_path );
147
148 if ( $new_file_path && is_string( $new_file_path ) ) {
149 return $new_file_path;
150 }
151
152 return $file_path;
153 }
154
155 /**
156 * Tell if the file is writable.
157 *
158 * @since 1.9
159 * @access public
160 * @author Grégory Viguier
161 *
162 * @return bool|\WP_Error True if writable. A \WP_Error object if not.
163 */
164 public function is_file_writable() {
165 $file_path = $this->get_file_path();
166 $file_name = $this->filesystem->make_path_relative( $file_path );
167
168 if ( $this->is_conf_edition_disabled() ) {
169 return new \WP_Error(
170 'edition_disabled',
171 sprintf(
172 /* translators: %s is a file name. */
173 __( 'Edition of the %s file is disabled.', 'imagify' ),
174 '<code>' . esc_html( $file_name ) . '</code>'
175 )
176 );
177 }
178
179 if ( ! $this->filesystem->exists( $file_path ) ) {
180 $dir_path = $this->filesystem->dir_path( $file_path );
181
182 $this->filesystem->make_dir( $dir_path );
183
184 if ( ! $this->filesystem->is_writable( $dir_path ) ) {
185 return new \WP_Error(
186 'parent_not_writable',
187 sprintf(
188 /* translators: %s is a file name. */
189 __( '%s’s parent folder is not writable.', 'imagify' ),
190 '<code>' . esc_html( $file_name ) . '</code>'
191 )
192 );
193 }
194 if ( ! $this->filesystem->touch( $file_path ) ) {
195 return new \WP_Error(
196 'not_created',
197 sprintf(
198 /* translators: %s is a file name. */
199 __( 'The %s file could not be created.', 'imagify' ),
200 '<code>' . esc_html( $file_name ) . '</code>'
201 )
202 );
203 }
204 } elseif ( ! $this->filesystem->is_writable( $file_path ) ) {
205 return new \WP_Error(
206 'not_writable',
207 sprintf(
208 /* translators: %s is a file name. */
209 __( 'The %s file is not writable.', 'imagify' ),
210 '<code>' . esc_html( $file_name ) . '</code>'
211 )
212 );
213 }
214
215 return true;
216 }
217
218 /**
219 * Get new contents to write into the file.
220 *
221 * @since 1.9
222 * @access public
223 * @author Grégory Viguier
224 *
225 * @return string
226 */
227 public function get_new_contents() {
228 $contents = $this->get_raw_new_contents();
229
230 /**
231 * Filter the contents to add to the directory conf file.
232 *
233 * @since 1.9
234 * @author Grégory Viguier
235 *
236 * @param string $contents The contents.
237 */
238 $new_contents = apply_filters( 'imagify_dir_conf_contents', $contents );
239
240 if ( $new_contents && is_string( $new_contents ) ) {
241 return $new_contents;
242 }
243
244 return $contents;
245 }
246
247 /** ----------------------------------------------------------------------------------------- */
248 /** ABSTRACT METHODS ======================================================================== */
249 /** ----------------------------------------------------------------------------------------- */
250
251 /**
252 * Insert new contents into the directory conf file.
253 * Replaces existing marked info. Creates file if none exists.
254 *
255 * @since 1.9
256 * @access protected
257 * @author Grégory Viguier
258 *
259 * @param string $new_contents Contents to insert.
260 * @return bool|\WP_Error True on write success, a \WP_Error object on failure.
261 */
262 abstract protected function insert_contents( $new_contents );
263
264 /**
265 * Get the unfiltered path to the file.
266 *
267 * @since 1.9
268 * @access protected
269 * @author Grégory Viguier
270 *
271 * @return string
272 */
273 abstract protected function get_raw_file_path();
274
275 /**
276 * Get unfiltered new contents to write into the file.
277 *
278 * @since 1.9
279 * @access protected
280 * @author Grégory Viguier
281 *
282 * @return string
283 */
284 abstract protected function get_raw_new_contents();
285
286 /** ----------------------------------------------------------------------------------------- */
287 /** OTHER TOOLS ============================================================================= */
288 /** ----------------------------------------------------------------------------------------- */
289
290 /**
291 * Get the file contents.
292 *
293 * @since 1.9
294 * @access protected
295 * @author Grégory Viguier
296 *
297 * @return mixed|\WP_Error The file contents on success, a \WP_Error object on failure.
298 */
299 protected function get_file_contents() {
300 $writable = $this->is_file_writable();
301
302 if ( is_wp_error( $writable ) ) {
303 return $writable;
304 }
305
306 $file_path = $this->get_file_path();
307
308 if ( ! $this->filesystem->exists( $file_path ) ) {
309 // This should not happen.
310 return '';
311 }
312
313 $contents = $this->filesystem->get_contents( $file_path );
314
315 if ( false === $contents ) {
316 return new \WP_Error(
317 'not_read',
318 sprintf(
319 /* translators: %s is a file name. */
320 __( 'The %s file could not be read.', 'imagify' ),
321 '<code>' . esc_html( $file_name ) . '</code>'
322 )
323 );
324 }
325
326 return $contents;
327 }
328
329 /**
330 * Put new contents into the file.
331 *
332 * @since 1.9
333 * @access protected
334 * @author Grégory Viguier
335 *
336 * @param string $contents New contents to add to the file.
337 * @return bool|\WP_Error True on success, a \WP_Error object on failure.
338 */
339 protected function put_file_contents( $contents ) {
340 $file_path = $this->get_file_path();
341 $result = $this->filesystem->put_contents( $file_path, $contents );
342
343 if ( $result ) {
344 return true;
345 }
346
347 $file_name = $this->filesystem->make_path_relative( $file_path );
348
349 return new \WP_Error(
350 'edition_failed',
351 sprintf(
352 /* translators: %s is a file name. */
353 __( 'Could not write into the %s file.', 'imagify' ),
354 '<code>' . esc_html( $file_name ) . '</code>'
355 )
356 );
357 }
358
359 /**
360 * Tell if edition of the directory conf file is disabled.
361 *
362 * @since 1.9
363 * @access public
364 * @author Grégory Viguier
365 *
366 * @return bool True to disable, false otherwise.
367 */
368 protected function is_conf_edition_disabled() {
369 /**
370 * Disable directory conf edition.
371 *
372 * @since 1.9
373 * @author Grégory Viguier
374 *
375 * @param bool $disable True to disable, false otherwise.
376 */
377 return (bool) apply_filters( 'imagify_disable_dir_conf_edition', false );
378 }
379
380 /**
381 * Get a regex pattern to be used to match the supported file extensions.
382 *
383 * @since 1.9
384 * @access protected
385 * @author Grégory Viguier
386 *
387 * @return string
388 */
389 protected function get_extensions_pattern() {
390 $extensions = imagify_get_mime_types( 'image' );
391 $extensions = array_keys( $extensions );
392
393 return implode( '|', $extensions );
394 }
395 }
396