balmet.com

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

class-redux-enable-gutenberg.php (15597B)


      1 <?php
      2 /**
      3  * Redux Enable Gutenberg Class
      4  *
      5  * @class   Redux_Enable_Gutenberg
      6  * @version 4.0.0
      7  * @package Redux Framework
      8  * @author  Dovy Pauksts of Redux.io
      9  */
     10 
     11 // Exit if accessed directly.
     12 defined( 'ABSPATH' ) || exit;
     13 
     14 
     15 if ( ! class_exists( 'Redux_Enable_Gutenberg', false ) ) {
     16 
     17 	/**
     18 	 * Main Feedback Notice Class
     19 	 */
     20 	class Redux_Enable_Gutenberg {
     21 
     22 		/**
     23 		 * Slug.
     24 		 *
     25 		 * @var string $slug
     26 		 */
     27 		private $slug;
     28 
     29 		/**
     30 		 * No Bug Option.
     31 		 *
     32 		 * @var string $nobug_option
     33 		 */
     34 		public $nobug_option;
     35 
     36 		/**
     37 		 * Auto Enable Option.
     38 		 *
     39 		 * @var string $autoenable_option
     40 		 */
     41 		public $autoenable_option;
     42 
     43 		/**
     44 		 * Auto deactivate Option.
     45 		 *
     46 		 * @var string $decativate_option
     47 		 */
     48 		public $decativate_option;
     49 
     50 		/**
     51 		 * Nonce string.
     52 		 *
     53 		 * @var string $nonce
     54 		 */
     55 		public $nonce;
     56 
     57 		/**
     58 		 * Disabled by the theme.
     59 		 *
     60 		 * @var bool
     61 		 */
     62 		protected static $theme_disabled = false;
     63 
     64 		/**
     65 		 * Disabled at all.
     66 		 *
     67 		 * @var bool
     68 		 */
     69 		public static $is_disabled = false;
     70 
     71 		/**
     72 		 * Quick fix known plugins that disable.
     73 		 *
     74 		 * @var array
     75 		 */
     76 		protected static $known_plugins = array();
     77 
     78 		/**
     79 		 * Class constructor.
     80 		 *
     81 		 * @param array $args Arguments.
     82 		 */
     83 		public function __construct( array $args = array() ) {
     84 			global $pagenow;
     85 
     86 			$defaults = array(
     87 				'slug' => '',
     88 				'name' => '',
     89 			);
     90 			$args     = wp_parse_args( $args, $defaults );
     91 
     92 			if ( empty( $args['slug'] ) ) {
     93 				echo 'You must pass a slug to the Redux_Enable_Gutenberg() constructor.';
     94 
     95 				return;
     96 			}
     97 
     98 			if ( strpos( $args['slug'], 'gutenberg' ) === false ) {
     99 				$args['slug'] .= '-gutenberg';
    100 			}
    101 			$this->slug              = $args['slug'];
    102 			$this->nobug_option      = $this->slug . '-no-bug';
    103 			$this->nonce             = $this->slug . '-nonce';
    104 			$this->autoenable_option = $this->slug . '-force-enable';
    105 			$this->decativate_option = $this->slug . '-deactivate-plugins';
    106 
    107 			if ( is_admin() && ! self::$is_disabled && ( 'post-new.php' === $pagenow || 'post.php' === $pagenow ) && ! get_site_option( $this->nobug_option ) ) {
    108 				// We only want to do this for posts or pages.
    109 				if ( ! isset( $_GET['post_type'] ) || ( isset( $_GET['post_type'] ) && 'page' === $_GET['post_type'] ) ) { // phpcs:ignore
    110 					add_action( 'init', array( $this, 'check_init' ), 998 );
    111 					add_action( 'init', array( $this, 'run_user_actions' ), 999 );
    112 					if ( ! get_site_option( $this->nobug_option ) ) {
    113 						add_action( 'plugins_loaded', array( $this, 'check_plugin' ), 999 );
    114 						add_action( 'after_setup_theme', array( $this, 'check_theme' ), 999 );
    115 						add_action( 'admin_notices', array( $this, 'display_admin_notice' ) );
    116 					}
    117 				}
    118 			}
    119 		}
    120 
    121 		/**
    122 		 * Cleanup for plugin deactivation.
    123 		 *
    124 		 * @param string $slug Slug for instance.
    125 		 */
    126 		public static function cleanup_options( string $slug = '' ) {
    127 			if ( ! empty( $slug ) ) {
    128 				$obj = new Redux_Enable_Gutenberg(
    129 					array(
    130 						'slug' => $slug,
    131 						'name' => '',
    132 					)
    133 				);
    134 				delete_site_option( $obj->autoenable_option );
    135 				delete_site_option( $obj->nobug_option );
    136 			}
    137 		}
    138 
    139 		/**
    140 		 * Display the admin notice.
    141 		 */
    142 		public function display_admin_notice() {
    143 			if ( ! self::$is_disabled ) {
    144 				return;
    145 			}
    146 			global $pagenow;
    147 
    148 			$clean_get = $_GET; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
    149 			if ( isset( $clean_get[ $this->nobug_option ] ) ) {
    150 				unset( $clean_get[ $this->nobug_option ] );
    151 			}
    152 			if ( isset( $clean_get[ $this->autoenable_option ] ) ) {
    153 				unset( $clean_get[ $this->autoenable_option ] );
    154 			}
    155 			if ( isset( $clean_get[ $this->decativate_option ] ) ) {
    156 				unset( $clean_get[ $this->decativate_option ] );
    157 			}
    158 			$base_url = admin_url( add_query_arg( $clean_get, $pagenow ) );
    159 
    160 			$no_bug_url      = wp_nonce_url( add_query_arg( $this->nobug_option, true, $base_url ), $this->nonce );
    161 			$auto_enable_url = wp_nonce_url( add_query_arg( $this->autoenable_option, true, $base_url ), $this->nonce );
    162 			$deativate_url   = wp_nonce_url( add_query_arg( $this->decativate_option, true, $base_url ), $this->nonce );
    163 
    164 			$data = array(
    165 				'url'     => '',
    166 				'content' => '',
    167 				'header'  => __( 'Gutenberg is currently disabled!', 'redux-framework' ),
    168 				'button'  => '',
    169 			);
    170 
    171 			if ( isset( $_GET[ $this->decativate_option ] ) || empty( self::$known_plugins ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
    172 
    173 				if ( isset( $_GET[ $this->decativate_option ] ) ) {  // phpcs:ignore WordPress.Security.NonceVerification.Recommended
    174 					// That didn't work.
    175 					$data['header']  = __( 'Hmm, it seems something else is disabling Gutenberg...', 'redux-framework' );
    176 					$data['content'] = sprintf( '<p>' . esc_html( "Well seems like we have more to do. Don't worry, we can still fix this! Click the $1%sEnable Gutenberg$2%s button and Redux will enable Gutenberg for you." ) . '</p>', '<strong>', '</strong>' );
    177 				} elseif ( self::$theme_disabled ) {
    178 					$data['header']   = __( 'Your theme author has disabled Gutenberg!', 'redux-framework' );
    179 					$data['content'] .= sprintf( '<p>' . esc_html( "It looks like your theme has disabled Gutenberg. Don\'t panic though! Click the $1%sEnable Gutenberg$2%s button to the right and Redux will enable Gutenberg for you." ) . '</p>', '<strong>', '</strong>' );
    180 				} else {
    181 					$data['header']   = __( 'Looks like something has disabled Gutenberg?', 'redux-framework' );
    182 					$data['content'] .= sprintf( '<p>' . esc_html( "Did you know that Gutenberg is disabled? If that\'s intended you can dismiss this notice, not what you intended? Click $1%sEnable Gutenberg$2%s and Redux will automatically fix this for you." ) . '</p>', '<strong>', '</strong>' );
    183 				}
    184 
    185 				$data['url']    = $auto_enable_url;
    186 				$data['button'] = __( 'Enable Gutenberg', 'redux-framework' );
    187 
    188 			} elseif ( empty( self::$known_plugins ) ) {
    189 				// Disabled by the theme or other.
    190 				$data['header'] = __( 'Your theme', 'redux-framework' );
    191 				$data['url']    = $auto_enable_url;
    192 				$data['button'] = __( 'Enable Gutenberg', 'redux-framework' );
    193 			} else {
    194 				// Disable Plugins!
    195 				$all_plugins = get_plugins();
    196 
    197 				$plugins = '';
    198 
    199 				foreach ( self::$known_plugins as $slug ) {
    200 					if ( isset( $all_plugins[ $slug ] ) ) {
    201 						if ( ! empty( $plugins ) ) {
    202 							$plugins .= ', ';
    203 						}
    204 						$plugins .= '<code>' . esc_html( $all_plugins[ $slug ]['Name'] ) . '</code>';
    205 					}
    206 				}
    207 
    208 				$data['url'] = $deativate_url;
    209 				if ( 1 === count( self::$known_plugins ) ) {
    210 					$data['button']  = __( 'Disable Plugin', 'redux-framework' );
    211 					$data['content'] = sprintf( '<p>The following plugin is preventing Gutenberg from working: %s. To automatically fix the issue click the <strong>Disable Plugin</strong> button on the right and Redux will enable it for you.</p>', $plugins, esc_url( 'https://kinsta.com/blog/gutenberg-wordpress-editor/' ) );
    212 				} else {
    213 					$data['button']  = __( 'Disable Plugins', 'redux-framework' );
    214 					$data['content'] = sprintf( '<p>The following plugin is preventing Gutenberg from working: %s. To automatically fix the issue click the <strong>Disable Plugins</strong> button on the right and Redux will enable it for you.</p>', $plugins, esc_url( 'https://kinsta.com/blog/gutenberg-wordpress-editor/' ) );
    215 				}
    216 			}
    217 
    218 			?>
    219 			<style>
    220 				.notice.redux-notice {
    221 					border-left-color: #24b0a6 !important;
    222 					padding: 20px;
    223 				}
    224 
    225 				.rtl .notice.redux-notice {
    226 					border-right-color: #19837c !important;
    227 				}
    228 
    229 				.notice.notice.redux-notice .redux-notice-inner {
    230 					display: table;
    231 					width: 100%;
    232 				}
    233 
    234 				.notice.redux-notice .redux-notice-inner .redux-notice-icon,
    235 				.notice.redux-notice .redux-notice-inner .redux-notice-content,
    236 				.notice.redux-notice .redux-notice-inner .redux-install-now {
    237 					display: table-cell;
    238 					vertical-align: middle;
    239 				}
    240 
    241 				.notice.redux-notice .redux-notice-icon {
    242 					color: #509ed2;
    243 					font-size: 13px;
    244 					width: 60px;
    245 				}
    246 
    247 				.notice.redux-notice .redux-notice-icon img {
    248 					width: 64px;
    249 				}
    250 
    251 				.notice.redux-notice .redux-notice-content {
    252 					padding: 0 40px 0 20px;
    253 				}
    254 
    255 				.notice.redux-notice p {
    256 					padding: 0;
    257 					margin: 0;
    258 				}
    259 
    260 				.notice.redux-notice h3 {
    261 					margin: 0 0 5px;
    262 				}
    263 
    264 				.notice.redux-notice .redux-install-now {
    265 					text-align: center;
    266 					width: 20%;
    267 				}
    268 
    269 				.notice.redux-notice .redux-install-now .redux-install-button {
    270 					padding: 6px 50px;
    271 					height: auto;
    272 					line-height: 20px;
    273 					background: #24b0a6;
    274 					border-color: transparent;
    275 					font-weight: bold;
    276 				}
    277 
    278 				.notice.redux-notice .redux-install-now .redux-install-button:hover {
    279 					background: #19837c;
    280 				}
    281 
    282 				.notice.redux-notice a.no-thanks {
    283 					display: block;
    284 					margin-top: 10px;
    285 					color: #72777c;
    286 					text-decoration: none;
    287 				}
    288 
    289 				.notice.redux-notice a.no-thanks:hover {
    290 					color: #444;
    291 				}
    292 
    293 				@media (max-width: 767px) {
    294 
    295 					.notice.notice.redux-notice .redux-notice-inner {
    296 						display: block;
    297 					}
    298 
    299 					.notice.redux-notice {
    300 						padding: 20px !important;
    301 					}
    302 
    303 					.notice.redux-noticee .redux-notice-inner {
    304 						display: block;
    305 					}
    306 
    307 					.notice.redux-notice .redux-notice-inner .redux-notice-content {
    308 						display: block;
    309 						padding: 0;
    310 					}
    311 
    312 					.notice.redux-notice .redux-notice-inner .redux-notice-icon {
    313 						display: none;
    314 					}
    315 
    316 					.notice.redux-notice .redux-notice-inner .redux-install-now {
    317 						margin-top: 20px;
    318 						display: block;
    319 						text-align: left;
    320 					}
    321 
    322 					.notice.redux-notice .redux-notice-inner .no-thanks {
    323 						display: inline-block;
    324 						margin-left: 15px;
    325 					}
    326 				}
    327 			</style>
    328 			<div class="notice updated redux-notice">
    329 				<div class="redux-notice-inner">
    330 					<div class="redux-notice-icon">
    331 						<?php /* translators: 1. Name */ ?>
    332 						<img src="<?php echo esc_url( Redux_Core::$url . '/assets/img/icon--color.svg' ); ?>" alt="<?php echo esc_attr__( 'Redux WordPress Plugin', 'redux-framework' ); ?>"/>
    333 					</div>
    334 					<div class="redux-notice-content">
    335 						<?php /* translators: 1. Name */ ?>
    336 						<h3><?php printf( esc_html( $data['header'] ) ); ?></h3>
    337 						<?php printf( $data['content'] ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
    338 					</div>
    339 					<div class="redux-install-now">
    340 						<?php printf( '<a href="%1$s" class="button button-primary redux-install-button">%2$s</a>', esc_url( $data['url'] ), esc_html( $data['button'] ) ); ?>
    341 						<a href="<?php echo esc_url( $no_bug_url ); ?>" class="no-thanks"><?php echo esc_html__( 'No Thanks', 'redux-framework' ); ?></a>
    342 					</div>
    343 				</div>
    344 			</div>
    345 			<?php
    346 		}
    347 
    348 		/**
    349 		 * Set the plugin to no longer bug users if user asks not to be.
    350 		 */
    351 		public function run_user_actions() {
    352 			// Bail out if not on correct page.
    353 			// phpcs:ignore
    354 			if ( ! isset( $_GET['_wpnonce'] ) || ( ! wp_verify_nonce( $_GET['_wpnonce'], $this->nonce ) || ! is_admin() || ! current_user_can( 'manage_options' ) ) ) {
    355 				return;
    356 			}
    357 
    358 			if ( isset( $_GET[ $this->nobug_option ] ) ) { // User doesn't want to see this anymore.
    359 				add_site_option( $this->nobug_option, true );
    360 			} elseif ( isset( $_GET[ $this->autoenable_option ] ) ) { // User has opted to just auto-enable Gutenberg.
    361 				unset( $_GET[ $this->autoenable_option ] );
    362 				add_site_option( $this->autoenable_option, true );
    363 			} elseif ( isset( $_GET[ $this->decativate_option ] ) && ! empty( self::$known_plugins ) ) { // User has opted to disable known gutenberg plugins.
    364 				deactivate_plugins( self::$known_plugins );
    365 			}
    366 			global $pagenow;
    367 			unset( $_GET['_wpnonce'] );
    368 			$url = admin_url( add_query_arg( $_GET, $pagenow ) );
    369 			wp_safe_redirect( $url );
    370 
    371 			exit();
    372 
    373 		}
    374 
    375 		/**
    376 		 * Set the plugin to no longer bug users if user asks not to be.
    377 		 */
    378 		public function set_auto_disable() {
    379 
    380 			// Bail out if not on correct page.
    381 			// phpcs:ignore
    382 			if ( ! isset( $_GET['_wpnonce'] ) || ( ! wp_verify_nonce( $_GET['_wpnonce'], $this->nonce ) || ! is_admin() || ! isset( $_GET[ $this->autoenable_option ] ) || ! current_user_can( 'manage_options' ) ) ) {
    383 				return;
    384 			}
    385 
    386 			add_site_option( $this->autoenable_option, true );
    387 		}
    388 
    389 		/**
    390 		 * Check for filter method.
    391 		 */
    392 		private function check_for_filter(): bool {
    393 			if ( version_compare( $GLOBALS['wp_version'], '5.0-beta', '>' ) ) {
    394 				if ( has_filter( 'use_block_editor_for_post_type', '__return_false' ) ) {
    395 					return true;
    396 				}
    397 			} else {
    398 				if ( has_filter( 'gutenberg_can_edit_post_type', '__return_false' ) ) {
    399 					return true; // WP < 5 beta.
    400 				}
    401 			}
    402 
    403 			return false;
    404 		}
    405 
    406 		/**
    407 		 * Remove the Gutenberg disable filter for posts and pages only.
    408 		 */
    409 		private function remove_filter() {
    410 			global $pagenow;
    411 
    412 			if ( is_admin() && ( 'post-new.php' === $pagenow || 'post.php' === $pagenow ) ) {
    413 				// We only want to do this for posts or pages.
    414 				if ( ! isset( $_GET['post_type'] ) || ( isset( $_GET['post_type'] ) && 'page' === $_GET['post_type'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
    415 					if ( version_compare( $GLOBALS['wp_version'], '5.0-beta', '>' ) ) {
    416 						// WP > 5 beta.
    417 						remove_filter( 'use_block_editor_for_post_type', '__return_false' );
    418 					} else {
    419 						// WP < 5 beta.
    420 						remove_filter( 'gutenberg_can_edit_post_type', '__return_false' );
    421 					}
    422 				}
    423 			}
    424 		}
    425 
    426 		/**
    427 		 * Quick checks against known plugins for disabling.
    428 		 */
    429 		public function quick_checks() {
    430 			// Testing for known plugins if they're loaded, save on filters and performance.
    431 			if ( class_exists( 'Classic_Editor' ) ) {
    432 				$a                     = new \ReflectionClass( 'Classic_Editor' );
    433 				self::$known_plugins[] = plugin_basename( $a->getFileName() );
    434 			}
    435 
    436 			if ( defined( 'DISABLE_GUTENBERG_FILE' ) ) {
    437 				self::$known_plugins[] = plugin_basename( DISABLE_GUTENBERG_FILE );
    438 			}
    439 
    440 			if ( defined( 'ADE_PLUGIN_DIR_PATH' ) ) {
    441 				if ( class_exists( 'CodePopular_disable_gutenburg' ) ) {
    442 					$a                     = new \ReflectionClass( 'CodePopular_disable_gutenburg' );
    443 					self::$known_plugins[] = plugin_basename( $a->getFileName() );
    444 				} else {
    445 					self::$known_plugins[] = plugin_basename( ADE_PLUGIN_DIR_PATH ) . '/auto-disable-gutenberg.php';
    446 				}
    447 			}
    448 			self::$known_plugins[] = 'no-gutenberg/no-gutenberg.php';
    449 			self::$known_plugins[] = 'enable-classic-editor/enable-classic-editor.php';
    450 
    451 			$plugins             = get_option( 'active_plugins' );
    452 			$results             = array_intersect( $plugins, self::$known_plugins );
    453 			self::$known_plugins = $results;
    454 			if ( ! empty( self::$known_plugins ) ) {
    455 				self::$is_disabled = true;
    456 			}
    457 		}
    458 
    459 		/**
    460 		 * Check if plugins have the disable filter.
    461 		 */
    462 		public function check_plugin() {
    463 			$this->quick_checks();
    464 			if ( ! self::$is_disabled && $this->check_for_filter() ) {
    465 				self::$is_disabled = true;
    466 			}
    467 		}
    468 
    469 		/**
    470 		 * Check if the theme have the disable filter.
    471 		 */
    472 		public function check_theme() {
    473 			if ( ! self::$is_disabled && $this->check_for_filter() ) {
    474 				self::$theme_disabled = true;
    475 				self::$is_disabled    = true;
    476 			}
    477 		}
    478 
    479 		/**
    480 		 * Check if init hook still has the disable filter.
    481 		 */
    482 		public function check_init() {
    483 			if ( ! self::$is_disabled ) {
    484 				if ( $this->check_for_filter() ) {
    485 					self::$is_disabled = true;
    486 				}
    487 			}
    488 
    489 			if ( self::$is_disabled && get_site_option( $this->autoenable_option ) ) {
    490 				$this->remove_filter();
    491 			}
    492 
    493 		}
    494 	}
    495 
    496 	/*
    497 	 * Instantiate the Redux_Enable_Gutenberg class.
    498 	 */
    499 	new Redux_Enable_Gutenberg(
    500 		array(
    501 			'slug' => 'redux-framework',
    502 			'name' => __( 'Redux', 'redux-framework' ),
    503 		)
    504 	);
    505 
    506 }