Your IP : 216.73.216.1
<?php
// Exit if accessed directly.
use EssentialBlocks\Integrations\AssetGeneration;
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
if ( ! class_exists( 'EbStyleHandler' ) ) {
final class EbStyleHandler
{
private static $instance;
private $prefix = 'eb-style';
private $eb_style_dir;
private $eb_style_url;
/**
* Holds block styles array
*
* @var array
*/
public static $_block_styles = [ ];
public static function init()
{
if ( null === self::$instance ) {
self::$instance = new self;
}
return self::$instance;
}
public function __construct()
{
$upload_dir = wp_upload_dir();
$this->eb_style_dir = $upload_dir[ 'basedir' ] . '/' . $this->prefix . DIRECTORY_SEPARATOR;
$this->eb_style_url = set_url_scheme( $upload_dir[ 'baseurl' ] ) . '/' . $this->prefix . '/';
$this->load_style_handler_dependencies();
// add_action( 'wp_enqueue_scripts', [ $this, 'enqueue_frontend_assets' ], 99 );
add_action( 'wp_enqueue_scripts', [ $this, 'enqueue_frontend_assets' ], 99 );
add_action( 'save_post', [ $this, 'stylehandler_get_post_content' ], 10, 3 );
add_action( 'wp', [ $this, 'stylehandler_generate_post_content' ] );
add_action( 'rest_after_save_widget', [ $this, 'eb_save_widget_action' ], 10, 4 );
add_action( 'eb_after_save_responsiveBreakpoints_settings', [ $this, 'generate_style_for_breakpoint_change' ], 10, 1 );
add_action( 'eb_after_reset_responsiveBreakpoints_settings', [ $this, 'reset_breakpoint' ], 10 );
// FSE assets generation
add_action( 'init', function () {
if ( function_exists( 'wp_is_block_theme' ) && wp_is_block_theme() ) {
add_filter( "404_template", [ $this, 'fse_assets_generation' ], 99, 3 );
add_filter( "archive_template", [ $this, 'fse_assets_generation' ], 99, 3 );
add_filter( "category_template", [ $this, 'fse_assets_generation' ], 99, 3 );
add_filter( "frontpage_template", [ $this, 'fse_assets_generation' ], 99, 3 );
add_filter( "home_template", [ $this, 'fse_assets_generation' ], 99, 3 );
add_filter( "index_template", [ $this, 'fse_assets_generation' ], 99, 3 );
add_filter( "page_template", [ $this, 'fse_assets_generation' ], 99, 3 );
add_filter( "search_template", [ $this, 'fse_assets_generation' ], 99, 3 );
add_filter( "single_template", [ $this, 'fse_assets_generation' ], 99, 3 );
add_filter( "singular_template", [ $this, 'fse_assets_generation' ], 99, 3 );
add_filter( "tag_template", [ $this, 'fse_assets_generation' ], 99, 3 );
add_filter( "taxonomy_template", [ $this, 'fse_assets_generation' ], 99, 3 );
}
}, 999 );
}
/**
* Generate FSE Assets
*/
public function fse_assets_generation( $template, $type, $templates )
{
$block_template = resolve_block_template( $type, $templates, $template );
if ( ! empty( $block_template ) ) {
$parsed_content = parse_blocks( $block_template->content );
if ( is_array( $parsed_content ) && ! empty( $parsed_content ) ) {
foreach ( $parsed_content as $content ) {
if ( ( 'core/template-part' == $content[ 'blockName' ] ) || ( 'core/template' == $content[ 'blockName' ] ) ) {
$post_ids = isset( $content[ 'attrs' ][ 'slug' ] ) ? self::eb_get_post_content_by_post_name( $content[ 'attrs' ][ 'slug' ] ) : [ ];
if ( ! empty( $post_ids ) ) {
foreach ( $post_ids as $id ) {
$post_id = (int) $id[ 'ID' ];
$post = get_post( $post_id );
$parsed_content = parse_blocks( $post->post_content );
$this->eb_write_css_from_content( $post, $post_id, $parsed_content );
}
}
} else {
$post_ids = self::eb_get_post_content_by_post_name( $block_template->slug );
if ( ! empty( $post_ids ) ) {
foreach ( $post_ids as $id ) {
$post_id = (int) $id[ 'ID' ];
$post = get_post( $post_id );
$parsed_content = parse_blocks( $post->post_content );
$this->eb_write_css_from_content( $post, $post_id, $parsed_content );
}
}
}
}
}
}
return $template;
}
/**
* Write CSS
*/
public function eb_write_css_from_content( $post, $post_id, $parsed_content )
{
$eb_blocks = [ ];
$recursive_response = EbStyleHandlerParseCss::eb_block_style_recursive( $parsed_content, $eb_blocks );
$reusable_Blocks = ! empty( $recursive_response[ 'reusableBlocks' ] ) ? $recursive_response[ 'reusableBlocks' ] : [ ];
// remove empty reusable blocks
$reusable_Blocks = array_filter( $reusable_Blocks, function ( $v ) {
return ! empty( $v );
} );
unset( $recursive_response[ "reusableBlocks" ] );
$style = EbStyleHandlerParseCss::blocks_to_style_array( $recursive_response );
$reusableIds = $reusable_Blocks && is_array( $reusable_Blocks ) ? array_keys( $reusable_Blocks ) : [ ];
if ( ! empty( $reusableIds ) ) {
update_option( '_eb_reusable_block_ids', $reusableIds );
}
update_post_meta( $post_id, '_eb_reusable_block_ids', $reusableIds );
$this->write_block_css( $style, $post ); //Write CSS file for this page
if ( ! empty( $reusable_Blocks ) ) {
foreach ( $reusable_Blocks as $blockId => $block ) {
$style = EbStyleHandlerParseCss::blocks_to_style_array( $block );
$this->write_reusable_block_css( $style, $blockId );
}
}
}
/**
* Save Widget CSS when Widget is saved
* @return void
* @since 3.5.3
*/
public function eb_save_widget_action( $id, $sidebar_id, $request, $creating )
{
$parsed_content = isset( $request[ 'instance' ][ 'raw' ][ 'content' ] ) ? parse_blocks( $request[ 'instance' ][ 'raw' ][ 'content' ] ) : [ ];
if ( is_array( $parsed_content ) && ! empty( $parsed_content ) ) {
$eb_blocks = [ ];
$recursive_response = EbStyleHandlerParseCss::eb_block_style_recursive( $parsed_content, $eb_blocks );
unset( $recursive_response[ "reusableBlocks" ] );
$style = EbStyleHandlerParseCss::blocks_to_style_array( $recursive_response );
//Write CSS file for Widget
$this->single_file_css_generator( $style, $this->eb_style_dir, $this->prefix . '-widget.min.css' );
}
}
/**
* Load Dependencies
*/
private function load_style_handler_dependencies()
{
require_once plugin_dir_path( __FILE__ ) . 'includes/class-parse-css.php';
}
/**
* Enqueue frontend css for post if have one
* @return void
* @since 1.0.2
*/
public function enqueue_frontend_assets()
{
global $post;
$deps = apply_filters( 'eb_generated_css_frontend_deps', [ ] );
// generatepress elements
if ( in_array( 'gp-premium/gp-premium.php', apply_filters( 'active_plugins', get_option( 'active_plugins' ) ) ) ) {
$gp_elements = get_posts( [ 'post_type' => 'gp_elements' ] );
if ( is_array( $gp_elements ) && ! empty( $gp_elements ) ) {
foreach ( $gp_elements as $element ) {
if ( file_exists( $this->eb_style_dir . $this->prefix . '-' . $element->ID . '.min.css' ) ) {
wp_enqueue_style(
'eb-block-style-' . $element->ID,
$this->eb_style_url . $this->prefix . '-' . $element->ID . '.min.css',
$deps,
substr( md5( microtime( true ) ), 0, 10 )
);
}
}
}
}
if ( ! empty( $post ) && ! empty( $post->ID ) ) {
//Page/Post Style Enqueue
if ( file_exists( $this->eb_style_dir . $this->prefix . '-' . $post->ID . '.min.css' ) ) {
wp_enqueue_style(
'eb-block-style-' . $post->ID,
$this->eb_style_url . $this->prefix . '-' . $post->ID . '.min.css',
$deps,
substr( md5( microtime( true ) ), 0, 10 )
);
}
// Reusable block Style Enqueues
$reusableIds = get_post_meta( $post->ID, '_eb_reusable_block_ids', true );
$reusableIds = ! empty( $reusableIds ) ? $reusableIds : [ ];
$templateReusableIds = get_option( '_eb_reusable_block_ids', [ ] );
$reusableIds = array_unique( array_merge( $reusableIds, $templateReusableIds ) );
if ( ! empty( $reusableIds ) && is_array( $reusableIds ) ) {
foreach ( $reusableIds as $reusableId ) {
if ( file_exists( $this->eb_style_dir . 'reusable-blocks/eb-reusable-' . $reusableId . '.min.css' ) ) {
wp_enqueue_style( 'eb-reusable-block-style-' . $reusableId, $this->eb_style_url . 'reusable-blocks/eb-reusable-' . $reusableId . '.min.css', $deps, substr( md5( microtime( true ) ), 0, 10 ) );
}
}
}
}
//Widget Style Enqueue
if ( file_exists( $this->eb_style_dir . $this->prefix . '-widget.min.css' ) ) {
wp_enqueue_style( 'eb-widget-style', $this->eb_style_url . $this->prefix . '-widget.min.css', $deps, substr( md5( microtime( true ) ), 0, 10 ) );
}
//FSE Style Enqueue
if ( function_exists( 'wp_is_block_theme' ) && wp_is_block_theme() && file_exists( $this->eb_style_dir . $this->prefix . '-edit-site.min.css' ) ) {
wp_enqueue_style( 'eb-fullsite-style', $this->eb_style_url . $this->prefix . '-edit-site.min.css', $deps, substr( md5( microtime( true ) ), 0, 10 ) );
}
/**
* Hooks assets for enqueue in frontend
* @param $path string
* @param $url string
* @since 3.0.0
*/
do_action( 'eb_frontend_assets', $this->eb_style_dir, $this->eb_style_url );
}
/**
* Get post content when page is saved
*/
public function stylehandler_get_post_content( $post_id, $post, $update )
{
$post_type = get_post_type( $post_id );
//If This page is draft, return
if ( isset( $post->post_status ) && 'auto-draft' == $post->post_status ) {
return;
}
// Autosave, do nothing
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
return;
}
// Return if it's a post revision
if ( false !== wp_is_post_revision( $post_id ) ) {
return;
}
if ( $post_type === 'wp_template_part' || $post_type === 'wp_template' ) {
$post = get_post( $post_id );
$parsed_content = parse_blocks( $post->post_content );
} else {
$parsed_content = parse_blocks( $post->post_content );
}
if ( empty( $parsed_content ) ) {
delete_post_meta( $post_id, '_eb_reusable_block_ids' );
}
if ( is_array( $parsed_content ) && ! empty( $parsed_content ) ) {
$this->eb_write_css_from_content( $post, $post_id, $parsed_content );
}
}
/**
* Get post content when page is load in frontend
*/
public function stylehandler_generate_post_content()
{
$post_id = get_the_ID();
if ( $post_id ) {
$post_type = get_post_type( $post_id );
$post = get_post( $post_id );
//If This page is draft, return
if ( isset( $post->post_status ) && 'auto-draft' == $post->post_status ) {
return;
}
// Return if it's a post revision
if ( false !== wp_is_post_revision( $post_id ) ) {
return;
}
if ( $post_type === 'wp_template_part' || $post_type === 'wp_template' ) {
// Todo: have to do something for FSE
$post = get_post( $post_id );
$parsed_content = parse_blocks( $post->post_content );
} else {
$parsed_content = parse_blocks( $post->post_content );
}
if ( empty( $parsed_content ) ) {
delete_post_meta( $post_id, '_eb_reusable_block_ids' );
}
if ( is_array( $parsed_content ) && ! empty( $parsed_content ) ) {
$eb_blocks = [ ];
$recursive_response = EbStyleHandlerParseCss::eb_block_style_recursive( $parsed_content, $eb_blocks );
$reusable_Blocks = ! empty( $recursive_response[ 'reusableBlocks' ] ) ? $recursive_response[ 'reusableBlocks' ] : [ ];
// remove empty reusable blocks
$reusable_Blocks = array_filter( $reusable_Blocks, function ( $v ) {
return ! empty( $v );
} );
unset( $recursive_response[ "reusableBlocks" ] );
$style = EbStyleHandlerParseCss::blocks_to_style_array( $recursive_response );
$reusableIds = $reusable_Blocks && is_array( $reusable_Blocks ) ? array_keys( $reusable_Blocks ) : [ ];
if ( ! empty( $reusableIds ) ) {
update_option( '_eb_reusable_block_ids', $reusableIds );
}
update_post_meta( $post_id, '_eb_reusable_block_ids', $reusableIds );
$this->write_block_css( $style, $post ); //Write CSS file for this page
if ( ! empty( $reusable_Blocks ) ) {
foreach ( $reusable_Blocks as $blockId => $block ) {
$style = EbStyleHandlerParseCss::blocks_to_style_array( $block );
$this->write_reusable_block_css( $style, $blockId );
}
}
}
}
}
/**
* Ajax callback to write css in upload directory
* @retun void
* @since 1.0.2
*/
private function write_block_css( $block_styles, $post )
{
//Write CSS for FSE
if ( isset( $post->post_type ) && ( $post->post_type === "wp_template_part" || $post->post_type === "wp_template" && ! empty( $block_styles ) ) ) {
$this->single_file_css_generator( $block_styles, $this->eb_style_dir, $this->prefix . '-edit-site.min.css' );
}
// Write CSS for Page/Posts
else {
if ( ! empty( $css = EbStyleHandlerParseCss::build_css( $block_styles ) ) ) {
if ( ! file_exists( $this->eb_style_dir ) ) {
mkdir( $this->eb_style_dir );
}
file_put_contents( $this->eb_style_dir . $this->prefix . '-' . abs( $post->ID ) . '.min.css', $css );
}
}
}
/**
* Write css for Reusable block
* @retun void
* @since 3.4.0
*/
private function write_reusable_block_css( $block_styles, $id )
{
if ( isset( $block_styles ) && is_array( $block_styles ) ) {
if ( ! empty( $css = EbStyleHandlerParseCss::build_css( $block_styles ) ) ) {
$upload_dir = $this->eb_style_dir . 'reusable-blocks/';
if ( ! file_exists( $upload_dir ) ) {
mkdir( $upload_dir, 0777, true );
}
file_put_contents( $upload_dir . '/' . 'eb-reusable-' . abs( $id ) . '.min.css', $css );
}
}
}
/**
* Single file css generator
* @retun void
* @since 3.5.3
*/
private function single_file_css_generator( $block_styles, $upload_dir, $filename )
{
$editSiteCssPath = $upload_dir . $filename;
if ( file_exists( $editSiteCssPath ) ) {
$existingCss = file_get_contents( $editSiteCssPath );
$pattern = "~\/\*(.*?)\*\/~";
preg_match_all( $pattern, $existingCss, $result, PREG_PATTERN_ORDER );
$allComments = $result[ 0 ];
$seperatedIds = [ ];
foreach ( $allComments as $comment ) {
$id = preg_replace( '/[^A-Za-z0-9\-]|Ends|Starts/', '', $comment );
if ( strpos( $comment, "Starts" ) ) {
$seperatedIds[ $id ][ 'start' ] = $comment;
} else if ( strpos( $comment, "Ends" ) ) {
$seperatedIds[ $id ][ 'end' ] = $comment;
}
}
$seperateStyles = [ ];
foreach ( $seperatedIds as $key => $ids ) {
$seperateStyles[ ][ $key ] = isset( $block_styles[ $key ] ) ? $block_styles[ $key ] : [ ];
}
self::$_block_styles = array_merge( self::$_block_styles, $block_styles );
if ( ! empty( $css = EbStyleHandlerParseCss::build_css( self::$_block_styles ) ) ) {
if ( ! file_exists( $upload_dir ) ) {
mkdir( $upload_dir );
}
file_put_contents( $editSiteCssPath, $css );
}
} else {
if ( ! empty( $css = EbStyleHandlerParseCss::build_css( $block_styles ) ) ) {
if ( ! file_exists( $this->eb_style_dir ) ) {
mkdir( $this->eb_style_dir );
}
file_put_contents( $editSiteCssPath, $css );
}
}
}
/**
* Get post id by post_name for template
*/
public static function eb_get_post_content_by_post_name( $post_name )
{
global $wpdb;
$sql = $wpdb->prepare( "SELECT ID FROM {$wpdb->prefix}posts WHERE post_name = %s", $post_name );
return $wpdb->get_results( $sql, ARRAY_A );
}
/**
* Generate all assets after custom breakpoint change
* @since 4.5.0
* @param string $breakpoints
* @return void
*/
public function generate_style_for_breakpoint_change( $breakpoints )
{
if ( is_dir( $this->eb_style_dir ) ) {
AssetGeneration::remove_directory_files( $this->eb_style_dir );
}
$breakpoints = json_decode( stripslashes( $breakpoints ), true );
if ( file_exists( ESSENTIAL_BLOCKS_DIR_PATH . '/dist/style.css' ) ) {
$css = file_get_contents( ESSENTIAL_BLOCKS_DIR_PATH . '/dist/style.css' );
// define possible breakpoints
$all_breakpoints = [
'1024' => $breakpoints[ 'tablet' ],
'1023' => $breakpoints[ 'tablet' ] - 1,
'1025' => $breakpoints[ 'tablet' ] + 1,
'767' => $breakpoints[ 'mobile' ],
'768' => $breakpoints[ 'mobile' ] + 1
];
// $pattern = '/@media[^{]+\{/';
// preg_match_all( $pattern, $css, $matches );
// $modifiedValues = [ ];
// foreach ( $matches[ 0 ] as $index => $media ) {
// $modified = preg_replace_callback( '/:(\d+)px/', function ( $matches ) use ( $all_breakpoints ) {
// $newValue = isset( $all_breakpoints[ $matches[ 1 ] ] ) ? $all_breakpoints[ $matches[ 1 ] ] : $matches[ 1 ];
// return ":{$newValue}px";
// }, $media );
// $modifiedValues[ ] = $modified;
// }
// $css = str_replace( $matches[ 0 ], $modifiedValues, $css );
// error_log( $css );
foreach ( $all_breakpoints as $old => $new ) {
$css = preg_replace( "/(@media[^{]+)width:\s*" . preg_quote( $old ) . "px/", "$1width:" . $new . "px", $css, -1, $count );
}
if ( ! file_exists( $this->eb_style_dir ) ) {
mkdir( $this->eb_style_dir );
if ( ! file_exists( $this->eb_style_dir . 'frontend' ) ) {
mkdir( $this->eb_style_dir . 'frontend' );
}
file_put_contents( $this->eb_style_dir . 'frontend/style.css', $css );
}
}
}
public function reset_breakpoint()
{
$frontend_style_dir = $this->eb_style_dir . 'frontend';
if ( is_dir( $frontend_style_dir ) ) {
AssetGeneration::remove_directory_files( $frontend_style_dir );
}
}
}
EbStyleHandler::init();
}