џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ€!Lмџџџџ€>•|€Р!Lм№cелџџџџF ›|€`!LмџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџР Lмџџџџ€>•|€@!LмЈrјлџџџџF ›|€@ Lмџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ п_мџџџџ€>•|€рп_м` глџџџџF ›|€ п_мџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџРо_мџџџџ€>•|€п_мРн_мџџџџF ›|€@о_мџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ н_мџџџџ€>•|€`н_мШOілџџџџF ›|€н_мџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ€м_мџџџџ€>•|€рм_м глџџџџF ›|€Рл_мџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџл_мџџџџ€>•|€`л_мxeелџџџџF ›|€рк_мџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ к_мџџџџ€>•|€Рк_м€|ФлџџџџF ›|€@к_мџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџк_мџџџџ€>•|€ к_мQілџџџџF ›|€рй_мџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџРй_мџџџџ€>•|€€й_мXfелџџџџF ›|€ й_мџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ й_мџџџџ€>•|€@й_м€WілџџџџF ›|€й_мџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџРи_мџџџџ€>•|€ри_мР глџџџџF ›|€`и_мџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ $namespace, '/block_styles/(?P\d+)', array( array( 'methods' => \WP_REST_Server::EDITABLE, 'callback' => array( $this, 'save_block_meta' ), 'args' => array( 'id' => array( 'type' => 'integer', 'required' => true, 'description' => __( 'ID of the Reusable Block.', 'blocks-css' ), 'validate_callback' => function ( $param, $request, $key ) { return is_numeric( $param ); }, ), ), 'permission_callback' => function ( $request ) { return current_user_can( 'edit_post', $request->get_param( 'id' ) ); }, ), ) ); register_rest_route( $namespace, '/widget_styles', array( array( 'methods' => \WP_REST_Server::EDITABLE, 'callback' => array( $this, 'save_widgets_styles_rest' ), 'permission_callback' => function () { return current_user_can( 'edit_theme_options' ); }, ), ) ); } /** * When in REST API context, autoload widgets used so that all css data is updated. * * @param \WP_REST_Request $request The request object. * * @return \WP_REST_Response | \WP_Error */ public function save_widgets_styles_rest( \WP_REST_Request $request ) { $this->register_used_widgets(); $response = $this->save_widgets_styles(); if ( is_null( $response ) ) { $response = true; } return rest_ensure_response( $response ); } /** * Function to save post CSS. * * @param \WP_REST_Request $request Rest request. * * @return mixed * @since 1.3.0 * @access public */ public function save_post_meta( \WP_REST_Request $request ) { if ( ! current_user_can( 'edit_posts' ) ) { return false; } $post_id = $request->get_param( 'id' ); self::generate_css_file( $post_id ); self::mark_review_block_metadata( $post_id ); return rest_ensure_response( array( 'message' => __( 'CSS updated.', 'blocks-css' ) ) ); } /** * Generate CSS file. * * @param int $post_id Post id. */ public static function generate_css_file( $post_id ) { $css = self::instance()->get_blocks_css( $post_id ); self::save_css_file( $post_id, $css ); } /** * Get CSS url for post. * * @param int|string $type Post ID or Widget. * * @return string|false File url. */ public static function get_css_url( $type = 'widgets' ) { $file_name = ''; if ( 'widgets' === $type ) { $file_name = get_option( 'themeisle_blocks_widgets_css_file' ); } else { $file_name = get_post_meta( $type, '_themeisle_gutenberg_block_stylesheet', true ); } if ( empty( $file_name ) ) { return false; } $wp_upload_dir = wp_upload_dir( null, false ); $baseurl = $wp_upload_dir['baseurl'] . '/themeisle-gutenberg/'; return $baseurl . $file_name . '.css'; } /** * Check if we have a CSS file for this post. * * @param int|string $type Post ID or Widget. * * @return bool */ public static function has_css_file( $type = 'widgets' ) { $file_name = ''; if ( 'widgets' === $type ) { $file_name = get_option( 'themeisle_blocks_widgets_css_file' ); } else { $file_name = get_post_meta( $type, '_themeisle_gutenberg_block_stylesheet', true ); } if ( empty( $file_name ) ) { return false; } $wp_upload_dir = wp_upload_dir( null, false ); $basedir = $wp_upload_dir['basedir'] . '/themeisle-gutenberg/'; $file_path = $basedir . $file_name . '.css'; return is_file( $file_path ); } /** * Function to save reusable block CSS. * * @param \WP_REST_Request $request Rest request. * * @return mixed * @since 1.3.0 * @access public */ public function save_block_meta( \WP_REST_Request $request ) { if ( ! current_user_can( 'edit_posts' ) ) { return false; } $post_id = $request->get_param( 'id' ); $css = $this->get_reusable_block_css( $post_id ); self::save_css_file( $post_id, $css ); self::mark_review_block_metadata( $post_id ); return rest_ensure_response( array( 'message' => __( 'CSS updated.', 'blocks-css' ) ) ); } /** * Function to save CSS into WordPress Filesystem. * * @param int $post_id Post id. * @param string $css CSS string. * * @since 1.3.0 * @access public */ public static function save_css_file( $post_id, $css ) { if ( empty( $css ) ) { return self::delete_css_file( $post_id ); } global $wp_filesystem; require_once ABSPATH . '/wp-admin/includes/file.php'; WP_Filesystem(); $file_name = 'post-v2-' . $post_id . '-' . time(); $wp_upload_dir = wp_upload_dir( null, false ); $upload_dir = $wp_upload_dir['basedir'] . '/themeisle-gutenberg/'; $file_path = $upload_dir . $file_name . '.css'; $css = wp_filter_nohtml_kses( $css ); $css = self::compress( $css ); update_post_meta( $post_id, '_themeisle_gutenberg_block_styles', $css ); $existing_file = get_post_meta( $post_id, '_themeisle_gutenberg_block_stylesheet', true ); $existing_file_path = $upload_dir . $existing_file . '.css'; if ( $existing_file && is_file( $existing_file_path ) ) { self::delete_css_file( $post_id ); } if ( count( self::$google_fonts ) > 0 ) { update_post_meta( $post_id, '_themeisle_gutenberg_block_fonts', self::$google_fonts ); } else { if ( get_post_meta( $post_id, '_themeisle_gutenberg_block_fonts', true ) ) { delete_post_meta( $post_id, '_themeisle_gutenberg_block_fonts' ); } } if ( self::is_writable() ) { $target_dir = $wp_filesystem->is_dir( $upload_dir ); if ( ! $wp_filesystem->is_writable( $wp_upload_dir['basedir'] ) ) { return false; } if ( ! $target_dir ) { wp_mkdir_p( $upload_dir ); } $wp_filesystem->put_contents( $file_path, stripslashes( $css ), FS_CHMOD_FILE ); if ( file_exists( $file_path ) ) { update_post_meta( $post_id, '_themeisle_gutenberg_block_stylesheet', $file_name ); } } } /** * Function to delete CSS from WordPress Filesystem. * * @param int $post_id Post id. * * @since 1.3.0 * @access public */ public static function delete_css_file( $post_id ) { global $wp_filesystem; if ( ! current_user_can( 'edit_posts' ) ) { return false; } require_once ABSPATH . '/wp-admin/includes/file.php'; WP_Filesystem(); $wp_upload_dir = wp_upload_dir( null, false ); if ( ! $wp_filesystem->is_writable( $wp_upload_dir['basedir'] ) ) { return; } $file_name = get_post_meta( $post_id, '_themeisle_gutenberg_block_stylesheet', true ); if ( $file_name ) { delete_post_meta( $post_id, '_themeisle_gutenberg_block_stylesheet' ); } $upload_dir = $wp_upload_dir['basedir'] . '/themeisle-gutenberg/'; $file_path = $upload_dir . $file_name . '.css'; if ( ! file_exists( $file_path ) || ! self::is_writable() ) { return; } $wp_filesystem->delete( $file_path, true ); } /** * Function to save/resave widget styles. * * @since 1.7.0 * @access public */ public static function save_widgets_styles() { global $wp_filesystem; require_once ABSPATH . '/wp-admin/includes/file.php'; WP_Filesystem(); $css = self::instance()->get_widgets_css(); if ( empty( $css ) ) { $file_path = get_option( 'themeisle_blocks_widgets_css_file' ); if ( ! file_exists( $file_path ) ) { return false; } delete_option( 'themeisle_blocks_widgets_css_file' ); delete_option( 'themeisle_blocks_widgets_css' ); return $wp_filesystem->delete( $file_path, true ); } if ( count( self::$google_fonts ) > 0 ) { update_option( 'themeisle_blocks_widgets_fonts', self::$google_fonts ); } else { if ( get_option( 'themeisle_blocks_widgets_fonts' ) ) { delete_option( 'themeisle_blocks_widgets_fonts' ); } } $file_name = 'widgets-' . time(); $wp_upload_dir = wp_upload_dir( null, false ); $upload_dir = $wp_upload_dir['basedir'] . '/themeisle-gutenberg/'; $file_path = $upload_dir . $file_name . '.css'; $css = wp_filter_nohtml_kses( $css ); $css = self::compress( $css ); update_option( 'themeisle_blocks_widgets_css', $css ); if ( self::is_writable() ) { $existing_file = get_option( 'themeisle_blocks_widgets_css_file' ); $existing_file_path = $upload_dir . $existing_file . '.css'; if ( $existing_file && is_file( $existing_file_path ) ) { $wp_filesystem->delete( $existing_file_path, true ); } $target_dir = $wp_filesystem->is_dir( $upload_dir ); if ( ! $wp_filesystem->is_writable( $wp_upload_dir['basedir'] ) ) { return false; } if ( ! $target_dir ) { wp_mkdir_p( $upload_dir ); } $wp_filesystem->put_contents( $file_path, stripslashes( $css ), FS_CHMOD_FILE ); if ( file_exists( $file_path ) ) { update_option( 'themeisle_blocks_widgets_css_file', $file_name ); } } } /** * Check if the path is writable. * * @return boolean * @since 2.0.0 * @access public */ public static function is_writable() { global $wp_filesystem; include_once ABSPATH . 'wp-admin/includes/file.php'; WP_Filesystem(); $wp_upload_dir = wp_upload_dir( null, false ); $upload_dir = $wp_upload_dir['basedir']; if ( ! function_exists( 'WP_Filesystem' ) ) { return false; } $writable = WP_Filesystem( false, $upload_dir ); return $writable && 'direct' === $wp_filesystem->method; } /** * Compress CSS * * @param string $css Compress css. * * @return string Compressed css. * @since 1.3.0 * @access public */ public static function compress( $css ) { $compressor = new CSSmin(); // Override any PHP configuration options before calling run(). $compressor->setMemoryLimit( '256M' ); $compressor->setMaxExecutionTime( 120 ); $compressor->setPcreBacktrackLimit( 3000000 ); $compressor->setPcreRecursionLimit( 150000 ); $css = htmlspecialchars_decode( $css ); $css = $compressor->run( $css ); return $css; } /** * Mark in post meta if the post has a review block. * * @param int $post_id Post ID. * @since 2.4.0 * @access public */ public static function mark_review_block_metadata( $post_id ) { if ( empty( $post_id ) ) { return; } $content = get_the_content( '', false, $post_id ); $saved_value = boolval( get_post_meta( $post_id, '_themeisle_gutenberg_block_has_review', true ) ); if ( empty( $content ) ) { if ( true === $saved_value ) { delete_post_meta( $post_id, '_themeisle_gutenberg_block_has_review' ); } return; } $has_review = false !== strpos( $content, '