balmet.com

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

class-gutenberg-custom-css.php (5804B)


      1 <?php
      2 /**
      3  * Load CSS logic.
      4  *
      5  * @package gutenberg-css
      6  */
      7 
      8 namespace ReduxTemplates;
      9 
     10 if ( ! class_exists( '\ReduxTemplates\Gutenberg_Custom_CSS' ) ) {
     11 
     12 	/**
     13 	 * Class GutenbergCSS.
     14 	 */
     15 	class Gutenberg_Custom_CSS {
     16 
     17 		/**
     18 		 * The main instance var.
     19 		 *
     20 		 * @var Gutenberg_Custom_CSS
     21 		 */
     22 		public static $instance = null;
     23 
     24 		/**
     25 		 * Initialize the class
     26 		 */
     27 		public function init() {
     28 			add_action( 'enqueue_block_editor_assets', array( $this, 'enqueue_editor_assets' ) );
     29 			add_action( 'wp_head', array( $this, 'render_server_side_css' ) );
     30 			add_action( 'wp_loaded', array( $this, 'add_attributes_to_blocks' ) );
     31 			add_action( 'plugins_loaded', array( $this, 'remove_themeisle_css' ), 99 );
     32 		}
     33 
     34 		/**
     35 		 * Remove ThemeIsle GutenbergCSS.
     36 		 *
     37 		 * @since   4.0.0
     38 		 * @access  public
     39 		 */
     40 		public function remove_themeisle_css() {
     41 			if ( class_exists( '\ThemeIsle\GutenbergCSS' ) ) {
     42 				$instance = \ThemeIsle\GutenbergCSS::instance();
     43 				remove_action(
     44 					'enqueue_block_editor_assets',
     45 					array(
     46 						$instance,
     47 						'enqueue_editor_assets',
     48 					)
     49 				);
     50 				remove_action( 'wp_head', array( $instance, 'render_server_side_css' ) );
     51 				remove_action( 'wp_loaded', array( $instance, 'add_attributes_to_blocks' ) );
     52 			}
     53 		}
     54 
     55 		/**
     56 		 * Load Gutenberg assets.
     57 		 *
     58 		 * @since   1.0.0
     59 		 * @access  public
     60 		 */
     61 		public function enqueue_editor_assets() {
     62 
     63 			wp_enqueue_code_editor( array( 'type' => 'text/css' ) );
     64 
     65 			wp_add_inline_script(
     66 				'wp-codemirror',
     67 				'window.CodeMirror = wp.CodeMirror;'
     68 			);
     69 
     70 			wp_set_script_translations( 'redux-gutenberg-css', 'redux-framework' );
     71 
     72 		}
     73 
     74 		/**
     75 		 * Parse Blocks for Gutenberg and WordPress 5.0
     76 		 *
     77 		 * @param string $content Content to parse.
     78 		 *
     79 		 * @since   1.0.0
     80 		 * @access  public
     81 		 * @return string
     82 		 */
     83 		public function parse_blocks( $content ) {
     84 			if ( ! function_exists( 'parse_blocks' ) ) {
     85 				return gutenberg_parse_blocks( $content );
     86 			} else {
     87 				return parse_blocks( $content );
     88 			}
     89 		}
     90 
     91 		/**
     92 		 * Render server-side CSS
     93 		 *
     94 		 * @since   1.0.0
     95 		 * @access  public
     96 		 */
     97 		public function render_server_side_css() {
     98 			if ( function_exists( 'has_blocks' ) && has_blocks( get_the_ID() ) ) {
     99 				global $post;
    100 
    101 				if ( ! is_object( $post ) ) {
    102 					return;
    103 				}
    104 
    105 				$blocks = $this->parse_blocks( $post->post_content );
    106 
    107 				if ( ! is_array( $blocks ) || empty( $blocks ) ) {
    108 					return;
    109 				}
    110 
    111 				$style  = "\n" . '<style type="text/css" media="all">' . "\n";
    112 				$style .= $this->cycle_through_blocks( $blocks );
    113 				$style .= "\n" . '</style>' . "\n";
    114 
    115 				echo $style; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
    116 			}
    117 		}
    118 
    119 		/**
    120 		 * Cycle thorugh Blocks
    121 		 *
    122 		 * @param array $inner_blocks Array of blocks.
    123 		 * @since   1.0.0
    124 		 * @access  public
    125 		 * @return string
    126 		 */
    127 		public function cycle_through_blocks( $inner_blocks ) {
    128 			$style = '';
    129 			foreach ( $inner_blocks as $block ) {
    130 				if ( isset( $block['attrs'] ) ) {
    131 					if ( isset( $block['attrs']['hasCustomCSS'] ) && isset( $block['attrs']['customCSS'] ) ) {
    132 						$style .= $block['attrs']['customCSS'];
    133 					}
    134 				}
    135 
    136 				if ( 'core/block' === $block['blockName'] && ! empty( $block['attrs']['ref'] ) ) {
    137 					$reusable_block = get_post( $block['attrs']['ref'] );
    138 
    139 					if ( ! $reusable_block || 'wp_block' !== $reusable_block->post_type ) {
    140 						return;
    141 					}
    142 
    143 					if ( 'publish' !== $reusable_block->post_status || ! empty( $reusable_block->post_password ) ) {
    144 						return;
    145 					}
    146 
    147 					$blocks = $this->parse_blocks( $reusable_block->post_content );
    148 
    149 					$style .= $this->cycle_through_blocks( $blocks );
    150 				}
    151 
    152 				if ( isset( $block['innerBlocks'] ) && ! empty( $block['innerBlocks'] ) && is_array( $block['innerBlocks'] ) ) {
    153 					$style .= $this->cycle_through_blocks( $block['innerBlocks'] );
    154 				}
    155 			}
    156 			return $style;
    157 		}
    158 
    159 		/**
    160 		 * Adds the `hasCustomCSS` and `customCSS` attributes to all blocks, to avoid `Invalid parameter(s): attributes`
    161 		 * error in Gutenberg.
    162 		 *
    163 		 * @since   1.0.3
    164 		 * @access  public
    165 		 */
    166 		public function add_attributes_to_blocks() {
    167 			$registered_blocks = \WP_Block_Type_Registry::get_instance()->get_all_registered();
    168 
    169 			foreach ( $registered_blocks as $name => $block ) {
    170 				$block->attributes['hasCustomCSS'] = array(
    171 					'type'    => 'boolean',
    172 					'default' => false,
    173 				);
    174 
    175 				$block->attributes['customCSS'] = array(
    176 					'type'    => 'string',
    177 					'default' => '',
    178 				);
    179 			}
    180 		}
    181 
    182 		/**
    183 		 * Method to return path to child class in a Reflective Way.
    184 		 *
    185 		 * @since   1.0.0
    186 		 * @access  protected
    187 		 * @return  string
    188 		 */
    189 		protected function get_dir() {
    190 			return dirname( __FILE__ );
    191 		}
    192 
    193 		/**
    194 		 * The instance method for the static class.
    195 		 * Defines and returns the instance of the static class.
    196 		 *
    197 		 * @static
    198 		 * @since 1.0.0
    199 		 * @access public
    200 		 * @return GutenbergCSS
    201 		 */
    202 		public static function instance() {
    203 			if ( is_null( self::$instance ) ) {
    204 				self::$instance = new self();
    205 				self::$instance->init();
    206 			}
    207 
    208 			return self::$instance;
    209 		}
    210 
    211 		/**
    212 		 * Throw error on object clone
    213 		 *
    214 		 * The whole idea of the singleton design pattern is that there is a single
    215 		 * object therefore, we don't want the object to be cloned.
    216 		 *
    217 		 * @access public
    218 		 * @since 1.0.0
    219 		 * @return void
    220 		 */
    221 		public function __clone() {
    222 			// Cloning instances of the class is forbidden.
    223 			_doing_it_wrong( __FUNCTION__, esc_html__( 'Cheatin&#8217; huh?', 'redux-framework' ), '1.0.0' );
    224 		}
    225 
    226 		/**
    227 		 * Disable unserializing of the class
    228 		 *
    229 		 * @access public
    230 		 * @since 1.0.0
    231 		 * @return void
    232 		 */
    233 		public function __wakeup() {
    234 			// Unserializing instances of the class is forbidden.
    235 			_doing_it_wrong( __FUNCTION__, esc_html__( 'Cheatin&#8217; huh?', 'redux-framework' ), '1.0.0' );
    236 		}
    237 	}
    238 }