'desktop', 'screen_size' => '', ]; private $media_tab = [ 'name' => 'tab', 'screen_size' => 1024, ]; private $media_mobile = [ 'name' => 'mobile', 'screen_size' => 767, ]; private $eb_prefix = 'eb-style'; public function __construct() { add_action( 'admin_enqueue_scripts', [ $this, 'notificationx_pro_blocks_edit_post' ] ); add_action( 'wp_ajax_notificationx_pro_write_block_css', [ $this, 'write_block_css' ] ); add_action( 'wp_enqueue_scripts', [ $this, 'enqueue_frontend_css' ] ); } /** * Enqueue a script in the WordPress admin on edit.php. * * @param int $hook Hook suffix for the current admin page. */ public function notificationx_pro_blocks_edit_post( $hook ) { $current_screen = get_current_screen(); $post_type = !empty( $current_screen->post_type ) ? $current_screen->post_type : ''; $dir = dirname( __FILE__ ); if ( ($hook == 'post-new.php' || $hook == 'post.php') && $post_type == 'nx_bar_eb' ) { wp_enqueue_script( 'notificationx-pro-blocks-edit-post', NOTIFICATIONX_URL . 'blocks/style-handler/style-handler.js', array( 'lodash', 'wp-i18n', 'wp-element', 'wp-hooks', 'wp-util', 'wp-components', 'wp-blocks', 'wp-editor', 'wp-block-editor', 'wp-edit-post', ), filemtime( NOTIFICATIONX_PATH . 'blocks/style-handler/style-handler.js' ), true ); wp_localize_script('notificationx-pro-blocks-edit-post', 'nx_style_handler', [ 'sth_nonce' => wp_create_nonce( 'nx_style_handler_nonce' ), 'editor_type' => 'edit-post', ] ); } elseif ( $hook == 'site-editor.php' ) { wp_enqueue_script( 'notificationx-pro-blocks-edit-post', NOTIFICATIONX_URL . 'blocks/style-handler/style-handler.js', array( 'lodash', 'wp-i18n', 'wp-element', 'wp-hooks', 'wp-util', 'wp-components', 'wp-blocks', 'wp-editor', 'wp-block-editor', 'wp-edit-site', ), filemtime( NOTIFICATIONX_PATH . 'blocks/style-handler/style-handler.js' ), true ); wp_localize_script('notificationx-pro-blocks-edit-post', 'nx_style_handler', [ 'sth_nonce' => wp_create_nonce( 'nx_style_handler_nonce' ), 'editor_type' => 'edit-site', ] ); // Override the default 'edit-post' global (set on the controls handle // in Blocks.php) so the inline block reads the core/edit-site store // when used inside the Full Site Editor. wp_localize_script('notificationx-block-controls', 'nx_style_handler', [ 'sth_nonce' => wp_create_nonce( 'nx_style_handler_nonce' ), 'editor_type' => 'edit-site', ] ); } } /** * Ajax callback to write css in upload directory * * @retun void * @since 1.0.2 */ public function write_block_css() { if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['nonce'] ) ), 'nx_style_handler_nonce' ) || ! current_user_can( 'manage_options' ) ) { echo 'Invalid request'; wp_die(); } // The payload is a JSON blob of block styles, so it cannot be run through a // scalar sanitiser without destroying it. It is decoded structurally below and // this endpoint is already gated on a nonce plus manage_options above. // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized $block_styles = isset( $_POST['data'] ) ? (array) json_decode( wp_unslash( $_POST['data'] ) ) : array(); $editor_type = isset( $_POST['editorType'] ) ? sanitize_key( wp_unslash( $_POST['editorType'] ) ) : ''; if ( $editor_type === 'edit-site' ) { $upload_dir = wp_upload_dir()['basedir'] . '/nx-style/'; $editSiteCssPath = $upload_dir . 'nx-style-' . $editor_type . '.min.css'; if ( file_exists( $editSiteCssPath ) ) { $existingCss = file_get_contents( $editSiteCssPath ); $pattern = '~\/\*(.*?)\*\/~'; preg_match_all( $pattern, $existingCss, $result, PREG_PATTERN_ORDER ); $allComments = $result[0]; $seperatedIds = array(); foreach ( $allComments as $comment ) { $id = preg_replace( '/[^A-Za-z0-9\-]|Ends|Starts/', '', $comment ); if ( strpos( $comment, 'Starts' ) ) { $seperatedIds[ $id ]['start'] = $comment; } elseif ( strpos( $comment, 'Ends' ) ) { $seperatedIds[ $id ]['end'] = $comment; } } $seperateStyles = array(); foreach ( $seperatedIds as $key => $ids ) { $data = $this->get_between_data( $existingCss, $ids['start'], $ids['end'] ); $seperateStyles[ $key ] = $data; } $finalCSSArray = array_merge( $seperateStyles, $block_styles ); if ( ! empty( $css = $this->build_css( $finalCSSArray ) ) ) { $upload_dir = wp_upload_dir()['basedir'] . '/nx-style/'; if ( ! file_exists( $upload_dir ) ) { wp_mkdir_p( $upload_dir ); } file_put_contents( $editSiteCssPath, $css ); } } else { if ( ! empty( $css = $this->build_css( $block_styles ) ) ) { $upload_dir = wp_upload_dir()['basedir'] . '/nx-style/'; if ( ! file_exists( $upload_dir ) ) { wp_mkdir_p( $upload_dir ); } file_put_contents( $editSiteCssPath, $css ); } } } else { if ( ! empty( $css = $this->build_css( $block_styles ) ) ) { $upload_dir = wp_upload_dir()['basedir'] . '/nx-style/'; if ( ! file_exists( $upload_dir ) ) { wp_mkdir_p( $upload_dir ); } $style_id = isset( $_POST['id'] ) ? absint( wp_unslash( $_POST['id'] ) ) : 0; file_put_contents( $upload_dir . 'nx-style-' . $style_id . '.min.css', $css ); } } wp_die(); } /** * Enqueue frontend css for post if have one * * @return void * @since 1.0.2 */ public function enqueue_frontend_css() { global $post; if ( ! empty( $post ) && ! empty( $post->ID ) ) { $upload_dir = wp_upload_dir(); $args = [ 'enabled' => true, 'source' => 'press_bar', 'updated_at' => ['<=', current_time('mysql') ] ]; $pressbar_notifications = \NotificationX\Core\PostType::get_instance()->get_posts($args); foreach ($pressbar_notifications as $pressbar) { if( !empty( $pressbar['gutenberg_id'] ) ) { $style_file = $upload_dir['basedir'] . DIRECTORY_SEPARATOR . 'eb-style' . DIRECTORY_SEPARATOR . $this->eb_prefix . '-' . $pressbar['gutenberg_id'] . '.min.css'; $style_url = set_url_scheme($upload_dir['baseurl']) . '/' . 'eb-style' . '/' . $this->eb_prefix . '-' . $pressbar['gutenberg_id'] . '.min.css'; if (file_exists($style_file)) { wp_enqueue_style( 'nx-style-' . $pressbar['gutenberg_id'], // Handle based only on post ID $style_url, [], filemtime($style_file) // Cache busting with last modified time ); } } } if ( file_exists( $upload_dir['basedir'] . '/nx-style/nx-style-' . $post->ID . '.min.css' ) ) { wp_enqueue_style( 'nx-block-style-' . $post->ID, $upload_dir['baseurl'] . '/nx-style/nx-style-' . $post->ID . '.min.css', [], substr( md5( microtime( true ) ), 0, 10 ) ); } elseif ( function_exists( 'icl_object_id' ) ) { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- Reviewed for the NotificationX codebase: acceptable in this context. $default_language = apply_filters( 'wpml_default_language', null ); $english_version = icl_object_id( $post->ID, 'post', false, $default_language ); if ( file_exists( $upload_dir['basedir'] . '/nx-style/nx-style-' . $english_version . '.min.css' ) ) { wp_enqueue_style( 'nx-block-style-' . $english_version, $upload_dir['baseurl'] . '/nx-style/nx-style-' . $english_version . '.min.css', [], substr( md5( microtime( true ) ), 0, 10 ) ); } } if ( function_exists( 'wp_is_block_theme' ) && wp_is_block_theme() && file_exists( $upload_dir['basedir'] . '/nx-style/nx-style-edit-site.min.css' ) ) { wp_enqueue_style( 'nx-fullsite-style', $upload_dir['baseurl'] . '/nx-style/nx-style-edit-site.min.css', [], substr( md5( microtime( true ) ), 0, 10 ) ); } } } /** * Enqueue frontend css for post if have one * * @param string * @return string * @since 1.0.2 */ private function build_css( $style_object ) { // $block_styles = (array)json_decode(stripslashes($style_object)); $block_styles = $style_object; $css = ''; foreach ( $block_styles as $block_style_key => $block_style ) { if ( ! empty( $block_css = (array) $block_style ) ) { $css .= sprintf( '/* %1$s Starts */', $block_style_key ); foreach ( $block_css as $media => $style ) { switch ( $media ) { case $this->media_desktop['name']: $css .= preg_replace( '/\s+/', ' ', $style ); break; case $this->media_tab['name']: $css .= ' @media(max-width: 1024px){'; $css .= preg_replace( '/\s+/', ' ', $style ); $css .= '}'; break; case $this->media_mobile['name']: $css .= ' @media(max-width: 767px){'; $css .= preg_replace( '/\s+/', ' ', $style ); $css .= '}'; break; } } $css .= sprintf( '/* =%1$s= Ends */', $block_style_key ); } } return trim( $css ); } /** * Helper function to get string between 2 string * * @since 3.3.0 */ private function get_between_data( $string, $start, $end ) { $pos_string = stripos( $string, $start ); $substr_data = substr( $string, $pos_string ); $string_two = substr( $substr_data, strlen( $start ) ); $second_pos = stripos( $string_two, $end ); $string_three = substr( $string_two, 0, $second_pos ); // remove whitespaces from result $result_unit = trim( $string_three ); // return result_unit return $result_unit; } }