PluginProbe
Offload, AI & Optimize with Cloudflare Images / trunk
Offload, AI & Optimize with Cloudflare Images vtrunk
1.10.3 trunk 1.0.2 1.0.3 1.1.0 1.1.1 1.1.2 1.1.3 1.1.4 1.1.5 1.1.5-beta.1 1.10.0 1.10.1 1.10.2 1.2.0 1.3.0 1.4.0 1.4.1 1.5.0 1.5.1 1.6.0 1.7.0 1.7.1 1.8.0 1.9.0 All 33 releases
cf-images / app / modules / class-module.php

class-module.php in Offload, AI & Optimize with Cloudflare Images trunk, at app/modules/class-module.php

218 lines 5.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Abstract module class
4 *
5 * This class defines all the base code, which is inherited by stand-alone classes.
6 *
7 * @link https://vcore.au
8 *
9 * @package CF_Images
10 * @subpackage CF_Images/App/Modules
11 * @author Anton Vanyukov <a.vanyukov@vcore.ru>
12 * @since 1.3.0
13 */
14
15 namespace CF_Images\App\Modules;
16
17 use CF_Images\App\Settings;
18 use CF_Images\App\Traits\Helpers;
19
20 if ( ! defined( 'WPINC' ) ) {
21 die;
22 }
23
24 /**
25 * Abstract Module class.
26 *
27 * @since 1.3.0
28 */
29 abstract class Module {
30 use Helpers;
31
32 /**
33 * This is a core module, meaning it can't be enabled/disabled via options.
34 *
35 * @since 1.3.0
36 *
37 * @var bool
38 */
39 protected $core = false;
40
41 /**
42 * Module ID.
43 *
44 * @since 1.3.0
45 * @access protected
46 *
47 * @var string $module
48 */
49 protected $module = '';
50
51 /**
52 * Should the module only run on front-end?
53 *
54 * @since 1.3.0
55 * @access protected
56 *
57 * @var bool $only_frontend
58 */
59 protected $only_frontend = false;
60
61 /**
62 * Module constructor.
63 *
64 * @since 1.3.0
65 *
66 * @param string $module Module ID.
67 */
68 public function __construct( string $module ) {
69 $this->module = $module;
70 $this->pre_init();
71
72 add_filter( 'cf_images_module_enabled', array( $this, 'is_module_enabled' ), 10, 2 );
73
74 if ( ! $this->is_set_up() || ! $this->is_module_enabled() ) {
75 return;
76 }
77
78 // Some modules are front-end only, make sure we can run them.
79 if ( $this->only_frontend && ( is_admin() || ! $this->can_run() ) ) {
80 return;
81 }
82
83 $this->init();
84 }
85
86 /**
87 * Module init.
88 *
89 * @since 1.3.0
90 */
91 abstract public function init();
92
93 /**
94 * Module pre-init actions.
95 *
96 * @since 1.2.1
97 */
98 protected function pre_init() {}
99
100 /**
101 * Check if we can run the plugin. Not all images should be converted, for example,
102 * SEO images from meta tags should be left untouched.
103 *
104 * @since 1.1.3
105 *
106 * @param int $attachment_id Optional. Attachment ID.
107 *
108 * @return bool
109 */
110 protected function can_run( int $attachment_id = 0 ): bool {
111 if ( $this->is_rest_request( $attachment_id ) || wp_doing_cron() ) {
112 return false;
113 }
114
115 if ( apply_filters( 'cf_images_skip_image', false ) ) {
116 return false;
117 }
118
119 if ( doing_action( 'wp_head' ) && ! $this->is_module_enabled( false, 'process-head' ) ) {
120 return false;
121 }
122
123 if ( did_action( 'wp' ) && ! $this->is_module_enabled( false, 'rss-feeds' ) && is_feed() ) {
124 return false;
125 }
126
127 return true;
128 }
129
130 /**
131 * This is how WordPress treats us developers - doesn't give a sh*t about is_admin(), so we have to do these
132 * custom checks to make sure we don't break the admin area.
133 *
134 * @since 1.2.0
135 *
136 * @param int $attachment_id Optional. Attachment ID.
137 *
138 * @return bool
139 */
140 private function is_rest_request( int $attachment_id = 0 ): bool {
141 if ( $attachment_id ) {
142 // We must rely on the REST API endpoints if full offload is enabled.
143 $deleted = get_post_meta( $attachment_id, '_cloudflare_image_offloaded', true );
144 if ( $deleted && apply_filters( 'cf_images_module_enabled', false, 'full-offload' ) ) {
145 return false;
146 }
147 }
148
149 $wordpress_has_no_logic = filter_input( INPUT_GET, '_wp-find-template' );
150 $wordpress_has_no_logic = sanitize_key( $wordpress_has_no_logic );
151
152 if ( ! empty( $wordpress_has_no_logic ) && 'true' === $wordpress_has_no_logic ) {
153 // And if below was not enough - we also need to check this bs...
154 return true;
155 }
156
157 $rest_url_prefix = rest_get_url_prefix();
158 if ( empty( $rest_url_prefix ) ) {
159 return false;
160 }
161
162 $request_uri = isset( $_SERVER['REQUEST_URI'] ) ? sanitize_text_field( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : '';
163
164 $is_rest_request = strpos( $request_uri, $rest_url_prefix ) !== false;
165 return apply_filters( 'cf_images_is_rest_request', $is_rest_request, $attachment_id );
166 }
167
168 /**
169 * Filter callback to check if a specific module is enabled.
170 *
171 * @since 1.4.0
172 *
173 * @param bool $fallback Default status.
174 * @param string $module Module ID.
175 *
176 * @return bool
177 */
178 public function is_module_enabled( bool $fallback = false, string $module = '' ): bool {
179 // Core modules cannot be disabled.
180 if ( $this->core && empty( $module ) ) {
181 return apply_filters( 'cf_images_core_module_status', true, $this->module );
182 }
183
184 if ( empty( $module ) ) {
185 $module = $this->module;
186 }
187
188 $settings = apply_filters( 'cf_images_settings', get_option( 'cf-images-settings', Settings::get_defaults() ) );
189
190 return apply_filters( 'cf_images_module_status', $settings[ $module ] ?? $fallback, $module );
191 }
192
193 /**
194 * In certain cases offloading should be disabled.
195 *
196 * @since 1.9.0
197 *
198 * @return bool
199 */
200 public function can_offload(): bool {
201 if ( filter_input( INPUT_GET, 'cf-images-disable' ) ) {
202 return false;
203 }
204
205 // Full offload overrides all other settings, because there are no local images available.
206 if ( $this->is_module_enabled( false, 'full-offload' ) ) {
207 return true;
208 }
209
210 if ( $this->is_module_enabled( false, 'no-offload-user' ) && defined( 'LOGGED_IN_COOKIE' ) ) {
211 // Check logged-in user cookie.
212 return empty( $_COOKIE[ LOGGED_IN_COOKIE ] );
213 }
214
215 return true;
216 }
217 }
218