| @@ -1,204 +1,280 @@ | ||
| 1 | 1 | <?php |
| 2 | + | |
| 3 | +namespace wpCloud\StatelessMedia; | |
| 4 | + | |
| 2 | 5 | /** |
| 3 | - * Compatibility with other plugins. | |
| 4 | - * | |
| 5 | - * This class serves as compatibility getway. | |
| 6 | - * Initiate all compatibility modules. | |
| 7 | - * | |
| 8 | - * @class Compatibility | |
| 6 | + * Compatibility abstract class | |
| 7 | + * Must be extends in every compatibility module. | |
| 9 | 8 | */ |
| 9 | +abstract class Compatibility { | |
| 10 | + protected $id = ''; | |
| 11 | + protected $title = ''; | |
| 10 | 12 | |
| 11 | -namespace wpCloud\StatelessMedia { | |
| 13 | + /** | |
| 14 | + * // Type String or Array. | |
| 15 | + * | |
| 16 | + * Single constant: | |
| 17 | + * example "WP_STATELESS_COMPATIBILITY_EDD" | |
| 18 | + * | |
| 19 | + * Multiple constant: | |
| 20 | + * [Constant, Another_Constant, ....] | |
| 21 | + * ['WP_STATELESS_MEDIA_ON_FLY', 'WP_STATELESS_DYNAMIC_IMAGE_SUPPORT'] | |
| 22 | + * | |
| 23 | + * Deprecated constant: | |
| 24 | + * [Old Constant => New Constant, ...] | |
| 25 | + * ['WP_STATELESS_MEDIA_ON_FLY' => 'WP_STATELESS_DYNAMIC_IMAGE_SUPPORT'] | |
| 26 | + */ | |
| 27 | + protected $constant = ''; | |
| 28 | + protected $enabled = true; | |
| 29 | + protected $description = ''; | |
| 30 | + protected $plugin_file = null; | |
| 31 | + protected $theme_name = null; | |
| 32 | + protected $first_party = false; | |
| 33 | + protected $non_library_sync = false; | |
| 34 | + protected $server_constant = false; | |
| 35 | + protected $sm_mode_required = ''; | |
| 36 | + protected $sm_mode_not_supported = []; | |
| 37 | + protected $is_internal = false; | |
| 12 | 38 | |
| 13 | - class Module { | |
| 39 | + public function __construct() { | |
| 40 | + // Prevent conflict between internal built-in compatibility modules and addon plugins | |
| 41 | + $restrict = apply_filters('wp_stateless_restrict_compatibility', false, $this->id, $this->is_internal); | |
| 42 | + | |
| 43 | + if ($restrict) { | |
| 44 | + $this->enabled = false; | |
| 45 | + return; | |
| 46 | + } | |
| 14 | 47 | |
| 15 | - private static $modules = array(); | |
| 48 | + if ( !$this->is_internal ) { | |
| 49 | + add_filter('wp_stateless_restrict_compatibility', array($this, 'restrict_compatibility'), 10, 3); | |
| 50 | + } | |
| 16 | 51 | |
| 17 | - /** | |
| 18 | - * Object initiated on Bootstrap::__construct | |
| 19 | - * Save module data on admin_init hook. | |
| 20 | - * Initiate all the compatibility modules. | |
| 21 | - */ | |
| 22 | - public function __construct() { | |
| 23 | - add_action( 'admin_init', array( $this, 'save_modules' ), 1 ); | |
| 52 | + $this->init(); | |
| 53 | + } | |
| 24 | 54 | |
| 25 | - /** | |
| 26 | - * ACF image crop addons compatibility. | |
| 27 | - */ | |
| 28 | - new CompatibilityAcfImageCrop(); | |
| 55 | + /** | |
| 56 | + * Checking whether the plugin is active or not. | |
| 57 | + * If the plugin_file is specified then check whether plugin is active or not. | |
| 58 | + * We can't use is_plugin_active function because it's defined later in init. | |
| 59 | + * By default return true. | |
| 60 | + * | |
| 61 | + * @todo caching. | |
| 62 | + */ | |
| 63 | + public function is_plugin_active() { | |
| 64 | + if (!empty($this->theme_name)) { | |
| 65 | + return Helper::is_theme_name($this->theme_name); | |
| 66 | + } | |
| 29 | 67 | |
| 30 | - /** | |
| 31 | - * Support for BuddyBoss | |
| 32 | - */ | |
| 33 | - new BuddyBoss(); | |
| 68 | + if (!empty($this->plugin_file)) { | |
| 69 | + // Converting string to array for foreach | |
| 70 | + if (is_string($this->plugin_file)) { | |
| 71 | + $this->plugin_file = array($this->plugin_file); | |
| 72 | + } | |
| 34 | 73 | |
| 35 | - /** | |
| 36 | - * Support for BuddyPress | |
| 37 | - */ | |
| 38 | - new BuddyPress(); | |
| 74 | + // If multisite then check if plugin is network active | |
| 75 | + if (is_multisite()) { | |
| 76 | + $active_plugins = (array)get_site_option('active_sitewide_plugins'); | |
| 77 | + foreach ($this->plugin_file as $plugin_file) { | |
| 78 | + if (isset($active_plugins[$plugin_file])) { | |
| 79 | + return true; | |
| 80 | + } | |
| 81 | + } | |
| 39 | 82 | |
| 40 | - /** | |
| 41 | - * Support for Divi | |
| 42 | - */ | |
| 43 | - new Divi(); | |
| 83 | + // If we are in network admin then return, unless it will get data from main site. | |
| 84 | + if (is_network_admin()) { | |
| 85 | + return false; | |
| 86 | + } | |
| 87 | + } | |
| 44 | 88 | |
| 45 | - /** | |
| 46 | - * Dynamic Image Support | |
| 47 | - */ | |
| 48 | - new DynamicImageSupport(); | |
| 89 | + $active_plugins = (array)get_option('active_plugins', array()); | |
| 90 | + foreach ($this->plugin_file as $plugin_file) { | |
| 91 | + if (in_array($plugin_file, $active_plugins)) { | |
| 92 | + return true; | |
| 93 | + } | |
| 94 | + } | |
| 49 | 95 | |
| 50 | - /** | |
| 51 | - * Support for Easy Digital Downloads download method | |
| 52 | - */ | |
| 53 | - new EDDDownloadMethod(); | |
| 96 | + return false; | |
| 97 | + } | |
| 54 | 98 | |
| 55 | - /** | |
| 56 | - * Support for Elementor | |
| 57 | - */ | |
| 58 | - new Elementor(); | |
| 99 | + /** | |
| 100 | + * If server constant is set - check if exist it on global $_SERVER | |
| 101 | + */ | |
| 102 | + if (!empty($this->server_constant)) { | |
| 103 | + if (isset($_SERVER[$this->server_constant])) { | |
| 104 | + return true; | |
| 105 | + } | |
| 106 | + return false; | |
| 107 | + } | |
| 59 | 108 | |
| 60 | - /** | |
| 61 | - * EWWW Image Optimizer | |
| 62 | - */ | |
| 63 | - new EWWW(); | |
| 109 | + return true; | |
| 110 | + } | |
| 64 | 111 | |
| 65 | - /** | |
| 66 | - * Google App Engine | |
| 67 | - */ | |
| 68 | - new GoogleAppEngine(); | |
| 112 | + /** | |
| 113 | + * Checking whether current mode is supported. | |
| 114 | + * By default return true. | |
| 115 | + * | |
| 116 | + * @todo caching. | |
| 117 | + */ | |
| 118 | + public function is_mode_supported() { | |
| 119 | + $sm_mode = isset($_POST['sm']['mode']) ? $_POST['sm']['mode'] : ud_get_stateless_media()->get('sm.mode'); | |
| 120 | + if (in_array($sm_mode, $this->sm_mode_not_supported)) { | |
| 121 | + return false; | |
| 122 | + } | |
| 123 | + return true; | |
| 124 | + } | |
| 69 | 125 | |
| 70 | - /** | |
| 71 | - * Support for Gravity Form file upload field | |
| 72 | - */ | |
| 73 | - new GravityForm(); | |
| 126 | + /** | |
| 127 | + * Initialize the module | |
| 128 | + * Check whether plugin is active or not. | |
| 129 | + * Register module. | |
| 130 | + * | |
| 131 | + * Add action for sm::module::init hook for module_init, which is fired(do_action) on Bootstrap::init() | |
| 132 | + */ | |
| 133 | + public function init() { | |
| 134 | + $is_constant = false; | |
| 135 | + $is_network_override = false; | |
| 136 | + $sm_mode = isset($_POST['sm']['mode']) ? $_POST['sm']['mode'] : ud_get_stateless_media()->get('sm.mode'); | |
| 137 | + if (is_network_admin()) { | |
| 138 | + $this->enabled = null; | |
| 139 | + } | |
| 74 | 140 | |
| 75 | - /** | |
| 76 | - * Support for Gravity Forms Signature Add-On | |
| 77 | - */ | |
| 78 | - new GravityFormSignature(); | |
| 141 | + if (is_array($this->constant)) { | |
| 142 | + foreach ($this->constant as $old_const => $new_const) { | |
| 143 | + if (defined($new_const)) { | |
| 144 | + $is_constant = true; | |
| 145 | + $this->enabled = constant($new_const); | |
| 146 | + break; | |
| 147 | + } | |
| 148 | + if (is_string($old_const) && defined($old_const)) { | |
| 149 | + $is_constant = true; | |
| 150 | + $this->enabled = constant($old_const); | |
| 151 | + ud_get_stateless_media()->errors->add(array( | |
| 152 | + 'key' => $this->id, | |
| 153 | + 'title' => sprintf(__("%s: Deprecated Notice (%s)", ud_get_stateless_media()->domain), ud_get_stateless_media()->name, $this->title), | |
| 154 | + 'message' => sprintf(__("<i>%s</i> constant is deprecated, please use <i>%s</i> instead.", ud_get_stateless_media()->domain), $old_const, $new_const), | |
| 155 | + ), 'notice'); | |
| 156 | + break; | |
| 157 | + } | |
| 158 | + } | |
| 159 | + } elseif (defined($this->constant)) { | |
| 160 | + $this->enabled = constant($this->constant); | |
| 161 | + $is_constant = true; | |
| 162 | + } | |
| 79 | 163 | |
| 80 | - /** | |
| 81 | - * Support for Imagify | |
| 82 | - */ | |
| 83 | - new Imagify(); | |
| 164 | + if (!$is_constant) { | |
| 165 | + $modules = get_option('stateless-modules', array()); | |
| 166 | + if (empty($this->enabled)) { | |
| 167 | + $this->enabled = !empty($modules[$this->id]) && $modules[$this->id] == 'true' ? true : false; | |
| 168 | + } | |
| 169 | + if (is_multisite()) { | |
| 170 | + $modules = get_site_option('stateless-modules', array()); | |
| 171 | + if (is_network_admin()) { | |
| 172 | + $this->enabled = !empty($modules[$this->id]) ? ($modules[$this->id] == 'true' ? true : false) : ''; | |
| 173 | + } elseif (!empty($modules[$this->id])) { | |
| 174 | + $this->enabled = !empty($modules[$this->id]) ? ($modules[$this->id] == 'true' ? true : false) : ''; | |
| 175 | + $is_network_override = true; | |
| 176 | + } | |
| 177 | + } | |
| 178 | + } | |
| 84 | 179 | |
| 85 | - /** | |
| 86 | - * Support for LearnDash | |
| 87 | - */ | |
| 88 | - new LearnDash(); | |
| 180 | + if (!is_network_admin() && (!$this->is_plugin_active() || !$this->is_mode_supported())) { | |
| 181 | + $this->enabled = 'inactive'; | |
| 182 | + } | |
| 89 | 183 | |
| 90 | - /** | |
| 91 | - * LiteSpeed Cache | |
| 92 | - */ | |
| 93 | - new LSCacheWP(); | |
| 184 | + /** | |
| 185 | + * Checking whether to show manual sync option. | |
| 186 | + */ | |
| 187 | + if ($this->is_plugin_active() && $this->non_library_sync == true) { | |
| 188 | + global $show_non_library_sync; | |
| 189 | + $show_non_library_sync = true; | |
| 190 | + } | |
| 94 | 191 | |
| 95 | - /** | |
| 96 | - * Polylang Pro | |
| 97 | - */ | |
| 98 | - new Polylang(); | |
| 192 | + Module::register_module(array( | |
| 193 | + 'id' => $this->id, | |
| 194 | + 'self' => $this, | |
| 195 | + 'title' => $this->title, | |
| 196 | + 'enabled' => $this->enabled, | |
| 197 | + 'description' => $this->description, | |
| 198 | + 'is_constant' => $is_constant, | |
| 199 | + 'is_network_override' => $is_network_override, | |
| 200 | + 'is_plugin_active' => $this->is_plugin_active(), | |
| 201 | + 'is_network_admin' => is_network_admin(), | |
| 202 | + 'is_plugin' => !empty($this->plugin_file), | |
| 203 | + 'is_theme' => !empty($this->theme_name), | |
| 204 | + 'is_mode_supported' => $this->is_mode_supported(), | |
| 205 | + 'mode' => ucfirst($sm_mode), | |
| 206 | + 'is_internal' => $this->is_internal, | |
| 207 | + )); | |
| 99 | 208 | |
| 100 | - /** | |
| 101 | - * Support for ShortPixel Image Optimizer | |
| 102 | - */ | |
| 103 | - new ShortPixel(); | |
| 209 | + if ($this->enabled && $this->is_plugin_active() && $this->is_mode_supported()) { | |
| 210 | + add_action('sm::module::init', array($this, 'module_init')); | |
| 211 | + } | |
| 104 | 212 | |
| 105 | - /** | |
| 106 | - * Simple Local Avatars | |
| 107 | - */ | |
| 108 | - new SimpleLocalAvatars(); | |
| 109 | - | |
| 110 | - /** | |
| 111 | - * Support for SiteOrigin CSS files | |
| 112 | - */ | |
| 113 | - new SOCSS(); | |
| 114 | - | |
| 115 | - /** | |
| 116 | - * Support for SiteOrigin widget CSS files | |
| 117 | - */ | |
| 118 | - new SOWidgetCSS(); | |
| 119 | - | |
| 120 | - /** | |
| 121 | - * VidoRev | |
| 122 | - */ | |
| 123 | - new VidoRev(); | |
| 124 | - | |
| 125 | - /** | |
| 126 | - * WP Retina 2x | |
| 127 | - */ | |
| 128 | - new WPRetina2x(); | |
| 129 | - | |
| 130 | - /** | |
| 131 | - * Support for WPForms | |
| 132 | - */ | |
| 133 | - new WPSmush(); | |
| 134 | - | |
| 135 | - /** | |
| 136 | - * Support for WPForms | |
| 137 | - */ | |
| 138 | - new CompatibilityWooExtraProductOptions(); | |
| 139 | - | |
| 140 | - /** | |
| 141 | - * Support for WPBakery Page Builder | |
| 142 | - */ | |
| 143 | - new WPBakeryPageBuilder(); | |
| 144 | - | |
| 145 | - /** | |
| 146 | - * Support for WPForms | |
| 147 | - */ | |
| 148 | - new WPForms(); | |
| 149 | - | |
| 213 | + if (!$this->enabled && !$this->first_party && $this->is_plugin_active()) { | |
| 214 | + ud_get_stateless_media()->errors->add(array( | |
| 215 | + 'key' => $this->id, | |
| 216 | + 'title' => sprintf(__("%s: Compatibility for %s isn't enabled.", ud_get_stateless_media()->domain), ud_get_stateless_media()->name, $this->title), | |
| 217 | + 'button' => __("Enable Compatibility", ud_get_stateless_media()->domain), | |
| 218 | + 'message' => __("Please enable the compatibility to ensure the functionality will work properly between <b>{$this->title}</b> and <b>WP-Stateless</b>.", ud_get_stateless_media()->domain), | |
| 219 | + ), 'notice'); | |
| 150 | 220 | } |
| 151 | 221 | |
| 152 | 222 | /** |
| 153 | - * Register compatibility modules so that we can ues them in settings page. | |
| 154 | - * Called from ICompatibility::init() method. | |
| 223 | + * Check requires WP-Stateless mode | |
| 155 | 224 | */ |
| 156 | - public static function register_module( $args ) { | |
| 157 | - if( empty( $args[ 'id' ] ) ) { | |
| 158 | - return; | |
| 225 | + if (!empty($this->sm_mode_required) && $this->enabled !== 'inactive') { | |
| 226 | + if ($sm_mode !== $this->sm_mode_required) { | |
| 227 | + ud_get_stateless_media()->errors->add(array( | |
| 228 | + 'key' => $this->id, | |
| 229 | + 'title' => sprintf(__("%s: Current Mode is not compatible with %s.", ud_get_stateless_media()->domain), ud_get_stateless_media()->name, $this->title), | |
| 230 | + 'message' => sprintf(__("%s compatibility requires %s in %s mode.", ud_get_stateless_media()->domain), $this->title, ud_get_stateless_media()->name, ucfirst($this->sm_mode_required)), | |
| 231 | + ), 'notice'); | |
| 159 | 232 | } |
| 160 | - if( is_bool( $args[ 'enabled' ] ) ) { | |
| 161 | - $args[ 'enabled' ] = $args[ 'enabled' ] ? 'true' : 'false'; | |
| 162 | - } | |
| 163 | - self::$modules[ $args[ 'id' ] ] = wp_parse_args( $args, array( 'id' => '', 'self' => '', 'title' => '', 'enabled' => false, 'description' => '', 'is_constant' => false, 'is_network' => false, 'is_plugin_active' => false, ) ); | |
| 164 | 233 | } |
| 234 | + } | |
| 165 | 235 | |
| 166 | - /** | |
| 167 | - * Return all the registered modules. | |
| 168 | - * Used in admin_init in bootstrap class as localize_script. | |
| 169 | - */ | |
| 170 | - public static function get_modules() { | |
| 171 | - return self::$modules; | |
| 172 | - } | |
| 236 | + /** | |
| 237 | + * @return bool | |
| 238 | + */ | |
| 239 | + public function enable_compatibility() { | |
| 173 | 240 | |
| 174 | - /** | |
| 175 | - * Return all the registered modules. | |
| 176 | - * Used in admin_init in bootstrap class as localize_script. | |
| 177 | - */ | |
| 178 | - public static function get_module( $id ) { | |
| 179 | - if( !empty( self::$modules[ $id ] ) ) { | |
| 180 | - return self::$modules[ $id ]; | |
| 241 | + if (is_network_admin()) { | |
| 242 | + $modules = get_site_option('stateless-modules', array()); | |
| 243 | + if (empty($modules[$this->id]) || $modules[$this->id] != 'true') { | |
| 244 | + $modules[$this->id] = 'true'; | |
| 245 | + update_site_option('stateless-modules', $modules, true); | |
| 181 | 246 | } |
| 182 | - return false; | |
| 247 | + } else { | |
| 248 | + $modules = get_option('stateless-modules', array()); | |
| 249 | + if (empty($modules[$this->id]) || $modules[$this->id] != 'true') { | |
| 250 | + $modules[$this->id] = 'true'; | |
| 251 | + update_option('stateless-modules', $modules, true); | |
| 252 | + } | |
| 183 | 253 | } |
| 184 | 254 | |
| 185 | - /** | |
| 186 | - * Handles saving module data. | |
| 187 | - * Enable or disable modules from Compatibility tab. | |
| 188 | - */ | |
| 189 | - public function save_modules() { | |
| 190 | - if( isset( $_POST[ 'action' ] ) && $_POST[ 'action' ] == 'stateless_modules' && wp_verify_nonce( $_POST[ '_smnonce' ], 'wp-stateless-modules' ) ) { | |
| 191 | - $modules = !empty( $_POST[ 'stateless-modules' ] ) ? $_POST[ 'stateless-modules' ] : array(); | |
| 192 | - $modules = apply_filters( 'stateless::modules::save', $modules ); | |
| 255 | + return true; | |
| 256 | + } | |
| 193 | 257 | |
| 194 | - if( is_network_admin() ) { | |
| 195 | - update_site_option( 'stateless-modules', $modules ); | |
| 196 | - } else { | |
| 197 | - update_option( 'stateless-modules', $modules, true ); | |
| 198 | - } | |
| 199 | - wp_redirect( $_POST[ '_wp_http_referer' ] ); | |
| 200 | - } | |
| 201 | - } | |
| 258 | + /** | |
| 259 | + * add_webp_mime | |
| 260 | + * @param $t | |
| 261 | + * @param $user | |
| 262 | + * @return mixed | |
| 263 | + */ | |
| 264 | + public function add_webp_mime($t, $user) { | |
| 265 | + $t['webp'] = 'image/webp'; | |
| 266 | + return $t; | |
| 202 | 267 | } |
| 203 | 268 | |
| 204 | -} | |
| 269 | + /** | |
| 270 | + * Restrict internal compatibility. | |
| 271 | + * @param $restrict bool | |
| 272 | + * @param $id string | |
| 273 | + * @param $is_internal bool | |
| 274 | + * @return bool | |
| 275 | + */ | |
| 276 | + public function restrict_compatibility($restrict, $id, $is_internal) { | |
| 277 | + // If we have internal compatibility with the same ID - then disable internal compatibility | |
| 278 | + return $is_internal && $this->id == $id ? true : $restrict; | |
| 279 | + } | |
| 280 | +} | |