class-auxels-admin-assets.php
5 months ago
class-auxels-archive-menu-links.php
5 months ago
class-auxels-envato-elements.php
5 months ago
class-auxels-import-parser.php
3 years ago
class-auxels-import.php
3 years ago
class-auxels-search-post-type.php
5 months ago
class-auxels-wc-attribute-nav-menu.php
5 months ago
class-auxin-admin-dashboard.php
5 months ago
class-auxin-demo-importer.php
10 hours ago
class-auxin-dependency-sorting.php
3 years ago
class-auxin-import.php
5 months ago
class-auxin-install.php
5 months ago
class-auxin-master-nav-menu-admin.php
5 months ago
class-auxin-page-template.php
5 months ago
class-auxin-permalink.php
5 months ago
class-auxin-plugin-requirements.php
3 years ago
class-auxin-post-type-base.php
5 months ago
class-auxin-svg-support-allowedattributes.php
7 years ago
class-auxin-svg-support-allowedtags.php
7 years ago
class-auxin-svg-support.php
1 year ago
class-auxin-walker-nav-menu-back.php
5 months ago
class-auxin-welcome-sections.php
1 year ago
class-auxin-welcome.php
1 month ago
class-auxin-whitelabel.php
3 years ago
class-auxin-widget-indie.php
5 months ago
class-auxin-widget-shortcode-map.php
5 months ago
class-auxin-widget.php
5 months ago
class-auxin-plugin-requirements.php
444 lines
| 1 | <?php |
| 2 | |
| 3 | if( ! class_exists( 'Auxin_Plugin_Requirements' ) ){ |
| 4 | |
| 5 | /** |
| 6 | * Checks the requirements for a plugin |
| 7 | * |
| 8 | */ |
| 9 | class Auxin_Plugin_Requirements { |
| 10 | |
| 11 | /** |
| 12 | * An array containing the list of requirements |
| 13 | * |
| 14 | * @var array |
| 15 | */ |
| 16 | public $requirements = array(); |
| 17 | |
| 18 | /** |
| 19 | * Whether the requirements are available or not |
| 20 | * |
| 21 | * @var boolean |
| 22 | */ |
| 23 | private $requirements_passed = true; |
| 24 | |
| 25 | /** |
| 26 | * Collects error notices |
| 27 | * |
| 28 | * @var array |
| 29 | */ |
| 30 | public $admin_notices = array(); |
| 31 | |
| 32 | |
| 33 | |
| 34 | public function __construct(){ |
| 35 | global $auxin_plugins_dependency_map; |
| 36 | |
| 37 | if( empty( $auxin_plugins_dependency_map ) ){ |
| 38 | $auxin_plugins_dependency_map = array(); |
| 39 | } |
| 40 | |
| 41 | if( is_admin() ){ |
| 42 | add_action( 'admin_notices' , array( $this, 'admin_notices' ) ); |
| 43 | add_action( 'activated_plugin' , array( $this, 'update_plugins_dependencies' ) ); |
| 44 | } else { |
| 45 | add_action( 'auxin_after_inner_body_open', array( $this, 'front_notices' ) ); |
| 46 | } |
| 47 | |
| 48 | } |
| 49 | |
| 50 | /** |
| 51 | * Make sure the client has the requirements, otherwise, throw a notice in admin |
| 52 | * |
| 53 | * @return void |
| 54 | */ |
| 55 | public function admin_notices( $pop_notice = '' ){ |
| 56 | if( $this->admin_notices = array_filter( $this->admin_notices ) ) { |
| 57 | echo '<div class="error aux-admin-error">'; |
| 58 | echo $this->get_notices( $pop_notice ); |
| 59 | echo '</div>'; |
| 60 | } |
| 61 | } |
| 62 | |
| 63 | /** |
| 64 | * Make sure the client has the requirements, otherwise, throw a notice |
| 65 | * |
| 66 | * @return void |
| 67 | */ |
| 68 | public function get_notices( $pop_notice = '' ){ |
| 69 | $the_notice = ''; |
| 70 | |
| 71 | if( $this->admin_notices && $notices = implode( '</li><li>', $this->admin_notices ) ) { |
| 72 | $the_notice .= '<p>' . $pop_notice; |
| 73 | $the_notice .= sprintf( |
| 74 | esc_html__( '%s plugin has been disabled automatically due to following reason:', 'auxin-elements' ), |
| 75 | '<strong>'. $this->requirements['config']['plugin_name'] . '</strong>' |
| 76 | ); |
| 77 | $the_notice .= '<ul><li>'. $notices . '</li></ul></p>'; |
| 78 | } |
| 79 | |
| 80 | if( $this->requirements['config']['debug'] || ( defined( 'AUXIN_DEBUG' ) && AUXIN_DEBUG ) ){ |
| 81 | $active_plugins = get_option( 'active_plugins' ); |
| 82 | $the_notice .= "<pre>"; $the_notice .= print_r( $active_plugins, true ); $the_notice .= "</pre>"; |
| 83 | } |
| 84 | |
| 85 | return $the_notice; |
| 86 | } |
| 87 | |
| 88 | /** |
| 89 | * Make sure the client has the requirements, otherwise, throw a notice in frontend for administrator |
| 90 | * |
| 91 | * @return void |
| 92 | */ |
| 93 | public function front_notices(){ |
| 94 | $this->admin_notices = array_filter( $this->admin_notices ); |
| 95 | |
| 96 | if( $this->admin_notices && current_user_can( 'edit_theme_options' ) ) { |
| 97 | $pop_notice = '<strong>' . __( 'Note for admin', 'auxin-elements' ) . '</strong>: '; |
| 98 | echo '<div class="aux-front-error aux-front-notice aux-fold">'; |
| 99 | echo $this->get_notices( $pop_notice ); |
| 100 | echo '</div>'; |
| 101 | } |
| 102 | } |
| 103 | |
| 104 | /** |
| 105 | * Wrapper around the core WP get_plugins function, making sure it's actually available. |
| 106 | * |
| 107 | * @return array Array of installed plugins with plugin information. |
| 108 | */ |
| 109 | public function get_plugins() { |
| 110 | if ( ! function_exists( 'get_plugins' ) ) { |
| 111 | require_once ABSPATH . 'wp-admin/includes/plugin.php'; |
| 112 | } |
| 113 | |
| 114 | return get_plugins(); |
| 115 | } |
| 116 | |
| 117 | /** |
| 118 | * Check whether a plugin is active. |
| 119 | * |
| 120 | * @param string $plugin Base plugin path from plugins directory. |
| 121 | * |
| 122 | * @return bool True, if in the active plugins list. False, not in the list. |
| 123 | */ |
| 124 | public function is_plugin_active( $plugin ) { |
| 125 | |
| 126 | if ( ! function_exists( 'is_plugin_active' ) ) { |
| 127 | require_once ABSPATH . 'wp-admin/includes/plugin.php'; |
| 128 | } |
| 129 | return is_plugin_active( $plugin ); |
| 130 | |
| 131 | } |
| 132 | |
| 133 | /** |
| 134 | * Load the dependency plugins before the current plugin |
| 135 | * |
| 136 | * @return void |
| 137 | */ |
| 138 | public function update_plugins_dependencies(){ |
| 139 | |
| 140 | // Flush the rewrite rules on plugin activation |
| 141 | flush_rewrite_rules(); |
| 142 | |
| 143 | if( empty( $this->requirements['plugins'] ) ){ |
| 144 | return; |
| 145 | } |
| 146 | |
| 147 | if( $plugin_requirements = $this->requirements['plugins'] ){ |
| 148 | |
| 149 | global $auxin_plugins_dependency_map; |
| 150 | |
| 151 | if( ! class_exists( 'Auxin_Dependency_Sorting' ) ){ |
| 152 | require_once( 'class-auxin-dependency-sorting.php' ); |
| 153 | } |
| 154 | |
| 155 | // Whether new dependency to dependency graph added or not |
| 156 | $has_new_dependency = false; |
| 157 | |
| 158 | // Walk through the plugins and collect the dependencies |
| 159 | foreach ( $plugin_requirements as $plugin_requirement ) { |
| 160 | |
| 161 | // Make sure if the plugin is expected to be loaded prior to our main plugin |
| 162 | if( ! empty( $plugin_requirement['dependency'] ) && true == $plugin_requirement['dependency'] && $this->is_plugin_active( $plugin_requirement['basename'] ) ){ |
| 163 | // Add current plugin dependencies to main plugins dependency graph |
| 164 | $auxin_plugins_dependency_map[ $this->requirements['config']['plugin_basename'] ][] = $plugin_requirement['basename']; |
| 165 | // If at least one plugin with required dependency detected |
| 166 | $has_new_dependency = true; |
| 167 | } |
| 168 | |
| 169 | } |
| 170 | |
| 171 | |
| 172 | if( $has_new_dependency ){ |
| 173 | |
| 174 | // Sort the plugins based on the dependencies |
| 175 | $dependency_resolver = new Auxin_Dependency_Sorting(); |
| 176 | $resolved_plugins_load_order = $dependency_resolver->resolve( $auxin_plugins_dependency_map ); |
| 177 | |
| 178 | // Get all activated plugins |
| 179 | $active_plugins = get_option( 'active_plugins' ); |
| 180 | |
| 181 | // Change the plugins load order |
| 182 | $active_plugins_reordered = $resolved_plugins_load_order; |
| 183 | foreach( $active_plugins as $plugin_basename ) { |
| 184 | if ( !in_array( $plugin_basename, $active_plugins_reordered ) ) { |
| 185 | $active_plugins_reordered[] = $plugin_basename; |
| 186 | } |
| 187 | } |
| 188 | |
| 189 | update_option( 'active_plugins', $active_plugins_reordered ); |
| 190 | } |
| 191 | |
| 192 | } |
| 193 | |
| 194 | } |
| 195 | |
| 196 | |
| 197 | /** |
| 198 | * Check plugin requirements |
| 199 | * |
| 200 | * @return void |
| 201 | */ |
| 202 | public function check_plugins_requirement(){ |
| 203 | |
| 204 | // check if oxygen builder is active then bypass loading auxin elements |
| 205 | if( $this->is_plugin_active( 'oxygen/functions.php' ) ){ |
| 206 | $this->requirements_passed = false; |
| 207 | return; |
| 208 | } |
| 209 | |
| 210 | if( empty( $this->requirements['plugins'] ) ){ |
| 211 | return; |
| 212 | } |
| 213 | |
| 214 | if( $plugin_requirements = $this->requirements['plugins'] ){ |
| 215 | if ( ! wp_installing() || 'wp-activate.php' === $pagenow ) { |
| 216 | |
| 217 | // Walk through the plugins |
| 218 | foreach ( $plugin_requirements as $plugin_requirement ) { |
| 219 | |
| 220 | // check if the plugin is active |
| 221 | $is_plugin_active = $this->is_plugin_active( $plugin_requirement['basename'] ); |
| 222 | |
| 223 | // if activating the plugin is required |
| 224 | if( |
| 225 | ( ! empty( $plugin_requirement['required'] ) && true == $plugin_requirement['required'] && ! $is_plugin_active ) || |
| 226 | ( ! empty( $plugin_requirement['is_callable'] ) && ! function_exists( $plugin_requirement['is_callable'] ) ) |
| 227 | ){ |
| 228 | |
| 229 | $this->admin_notices[] = sprintf( |
| 230 | __( '%s plugin is required in order to use this plugin. Please install and activate the plugin.', 'auxin-elements' ). |
| 231 | ' <a href="https://docs.phlox.pro/article/210-update-phlox-pro/" target="_blank">'. __('How to upgrade', 'auxin-elements') . '</a>', |
| 232 | '<strong>'. $plugin_requirement['name'] . '</strong>' |
| 233 | ); |
| 234 | |
| 235 | $this->requirements_passed = false; |
| 236 | |
| 237 | // if minimum plugin version was specified |
| 238 | } elseif( ! empty( $plugin_requirement['version'] ) && $is_plugin_active ){ |
| 239 | |
| 240 | $all_plugins = $this->get_plugins(); |
| 241 | |
| 242 | if( empty( $all_plugins[ $plugin_requirement['basename'] ]['Version'] ) ){ |
| 243 | continue; |
| 244 | } |
| 245 | |
| 246 | $current_plugin_version = $all_plugins[ $plugin_requirement['basename'] ]['Version']; |
| 247 | |
| 248 | if ( version_compare( $current_plugin_version, $plugin_requirement['version'], '<' ) ) { |
| 249 | |
| 250 | $this->admin_notices[] = sprintf( |
| 251 | __( 'The plugin requires %s plugin version %s or higher (current version is %s). Please update it to the latest version.', 'auxin-elements' ), |
| 252 | '<strong>'. $plugin_requirement['name'] . '</strong>', |
| 253 | '<strong>'. $plugin_requirement['version'] . '</strong>', |
| 254 | '<strong>'. $current_plugin_version . '</strong>' |
| 255 | ); |
| 256 | |
| 257 | $this->requirements_passed = false; |
| 258 | } |
| 259 | |
| 260 | } |
| 261 | |
| 262 | } |
| 263 | |
| 264 | } |
| 265 | |
| 266 | } |
| 267 | |
| 268 | } |
| 269 | |
| 270 | /** |
| 271 | * Check them requirements |
| 272 | * |
| 273 | * @return void |
| 274 | */ |
| 275 | public function check_theme_requirement(){ |
| 276 | |
| 277 | if( empty( $this->requirements['themes'] ) ){ |
| 278 | return; |
| 279 | } |
| 280 | |
| 281 | $this->admin_notices['theme'] = ''; |
| 282 | |
| 283 | if( $theme_requirements = $this->requirements['themes'] ){ |
| 284 | |
| 285 | // Walk through the themes |
| 286 | foreach ( $theme_requirements as $theme_requirement ) { |
| 287 | |
| 288 | if( ! isset( $theme_requirement['id'] ) ){ |
| 289 | $theme_requirement['id'] = str_replace( ' ', '-', strtolower( $theme_requirement['name'] ) ); |
| 290 | } |
| 291 | $theme_requirement = apply_filters( 'auxin_plugin_requirements_theme_dependency', $theme_requirement, $theme_requirement['id'] ); |
| 292 | |
| 293 | if ( ! empty( $theme_requirement['file_required'] ) ){ |
| 294 | if( is_array( $theme_requirement['file_required'] ) ){ |
| 295 | |
| 296 | foreach ( $theme_requirement['file_required'] as $the_required_file_path ) { |
| 297 | |
| 298 | if( file_exists( $the_required_file_path ) ){ |
| 299 | require_once( $the_required_file_path ); |
| 300 | } else { |
| 301 | $this->requirements_passed = false; |
| 302 | continue 2; |
| 303 | } |
| 304 | } |
| 305 | |
| 306 | } elseif( file_exists( $theme_requirement['file_required'] ) ){ |
| 307 | require_once( $theme_requirement['file_required'] ); |
| 308 | } else { |
| 309 | $this->requirements_passed = false; |
| 310 | continue; |
| 311 | } |
| 312 | } else { |
| 313 | $this->requirements_passed = false; |
| 314 | continue; |
| 315 | } |
| 316 | |
| 317 | if( THEME_ID !== $theme_requirement['id'] ){ |
| 318 | $this->requirements_passed = false; |
| 319 | continue; |
| 320 | } |
| 321 | |
| 322 | if( ! empty( $theme_requirement['theme_requires_const'] ) && defined( $theme_requirement['theme_requires_const'] ) ){ |
| 323 | |
| 324 | $all_plugins = $this->get_plugins(); |
| 325 | |
| 326 | if( ! empty( $all_plugins[ $this->requirements['config']['plugin_basename'] ]['Version'] ) ){ |
| 327 | $plugin_info = $all_plugins[ $this->requirements['config']['plugin_basename'] ]; |
| 328 | |
| 329 | if( version_compare( $plugin_info['Version'], constant( $theme_requirement['theme_requires_const'] ), '<' ) ){ |
| 330 | $this->admin_notices['theme'] .= sprintf( |
| 331 | __( '%s theme requires %s plugin version %s or higher in order to function property. Your current plugin version is %s, please update it to latest version.', 'auxin-elements' ). |
| 332 | ' <a href="https://docs.phlox.pro/article/210-update-phlox-pro/" target="_blank">'. __('How to upgrade', 'auxin-elements') . '</a>', |
| 333 | THEME_NAME_I18N, |
| 334 | '<strong>'. $plugin_info['Name'] . '</strong>', |
| 335 | '<strong>'. constant( $theme_requirement['theme_requires_const'] ) . '</strong>', |
| 336 | '<strong>'. $plugin_info['Version'] . '</strong>' |
| 337 | ); |
| 338 | |
| 339 | $this->requirements_passed = false; |
| 340 | continue; |
| 341 | } |
| 342 | } |
| 343 | } |
| 344 | |
| 345 | if ( $theme_requirement['version'] ){ |
| 346 | |
| 347 | $theme_data = wp_get_theme(); |
| 348 | $theme_data = $theme_data->parent() ? $theme_data->parent() : $theme_data; |
| 349 | |
| 350 | if ( version_compare( $theme_data->Version, $theme_requirement['version'], '<' ) ) { |
| 351 | |
| 352 | $theme_requirement['update_anchor_start'] = ! empty( $theme_requirement['update_link'] ) ? '<a target="_blank" href="'. admin_url( $theme_requirement['update_link'] ).'">' : ''; |
| 353 | $theme_requirement['update_anchor_end'] = ! empty( $theme_requirement['update_link'] ) ? '</a>' : ''; |
| 354 | |
| 355 | $this->admin_notices['theme'] .= sprintf( |
| 356 | __( 'The plugin requires %s theme version %s or higher in order to function property. Your current theme version is %s, please %s update to latest version %s.', 'auxin-elements' ). |
| 357 | ' <a href="https://docs.phlox.pro/article/210-update-phlox-pro/" target="_blank">'. __('How to upgrade', 'auxin-elements') . '</a>', |
| 358 | '<strong>'. $theme_requirement['name'] . '</strong>', |
| 359 | '<strong>'. $theme_requirement['version'] . '</strong>', |
| 360 | '<strong>'. $theme_data->Version . '</strong>', |
| 361 | $theme_requirement['update_anchor_start'], |
| 362 | $theme_requirement['update_anchor_end'] |
| 363 | ); |
| 364 | |
| 365 | if( defined( 'AUXIN_DEBUG' ) && AUXIN_DEBUG ){ |
| 366 | if( ! empty( $theme_requirement['file_exists'] ) ){ |
| 367 | $this->admin_notices['theme'] .= sprintf( |
| 368 | __( '%s path while checking the availability of theme not found.', 'auxin-elements' ), |
| 369 | '<code>'. $theme_requirement['file_exists'] . '</code>' |
| 370 | ); |
| 371 | } elseif( ! empty( $theme_requirement['is_callable'] ) ){ |
| 372 | $this->admin_notices['theme'] .= sprintf( |
| 373 | __( '%s function callback while checking the availability of theme not found.', 'auxin-elements' ), |
| 374 | '<code>'. $theme_requirement['file_exists'] . '</code>' |
| 375 | ); |
| 376 | } |
| 377 | } |
| 378 | |
| 379 | $this->requirements_passed = false; |
| 380 | continue; |
| 381 | } |
| 382 | |
| 383 | } |
| 384 | |
| 385 | unset( $this->admin_notices['theme'] ); |
| 386 | $this->requirements_passed = true; |
| 387 | return; |
| 388 | } |
| 389 | |
| 390 | $this->requirements_passed = false; |
| 391 | return; |
| 392 | } |
| 393 | |
| 394 | } |
| 395 | |
| 396 | /** |
| 397 | * Check PHP requirements |
| 398 | * |
| 399 | * @return void |
| 400 | */ |
| 401 | function check_php_requirement(){ |
| 402 | |
| 403 | if( empty( $this->requirements['php']['version'] ) ){ |
| 404 | return; |
| 405 | } |
| 406 | |
| 407 | if ( version_compare( PHP_VERSION, $this->requirements['php']['version'], '<' ) ) { |
| 408 | |
| 409 | $this->admin_notices[] = sprintf( |
| 410 | __( 'PHP version %s or above is required for this plugin while your the current PHP version is %s.', 'auxin-elements' ), |
| 411 | '<strong>'. $this->requirements['php']['version'] . '</strong>', |
| 412 | '<strong>'. PHP_VERSION . '</strong>' |
| 413 | ); |
| 414 | |
| 415 | $this->requirements_passed = false; |
| 416 | return; |
| 417 | } |
| 418 | |
| 419 | } |
| 420 | |
| 421 | /** |
| 422 | * Checks all requirements |
| 423 | * |
| 424 | * @return string|boolean True if all requirements are passed, false or error message on failure |
| 425 | */ |
| 426 | public function validate(){ |
| 427 | |
| 428 | $this->check_php_requirement(); |
| 429 | |
| 430 | if( true !== $this->requirements_passed ){ return $this->requirements_passed; } |
| 431 | |
| 432 | $this->check_theme_requirement(); |
| 433 | |
| 434 | if( true !== $this->requirements_passed ){ return $this->requirements_passed; } |
| 435 | |
| 436 | $this->check_plugins_requirement(); |
| 437 | |
| 438 | return $this->requirements_passed; |
| 439 | } |
| 440 | |
| 441 | } |
| 442 | |
| 443 | } |
| 444 |