Parsed: 129698

  protected static function sanitize( $input, $valid_block_names, $valid_element_names, $valid_variations ) {

    $output = array();

    if ( ! is_array( $input ) ) {
      return $output;
    }

    // Preserve only the top most level keys.
    $output = array_intersect_key( $input, array_flip( static::VALID_TOP_LEVEL_KEYS ) );

    /*
		 * Remove any rules that are annotated as "top" in VALID_STYLES constant.
		 * Some styles are only meant to be available at the top-level (e.g.: blockGap),
		 * hence, the schema for blocks & elements should not have them.
		 */
    $styles_non_top_level = static::VALID_STYLES;
    foreach ( array_keys( $styles_non_top_level ) as $section ) {
      // array_key_exists() needs to be used instead of isset() because the value can be null.
      if ( array_key_exists( $section, $styles_non_top_level ) && is_array( $styles_non_top_level[ $section ] ) ) {
        foreach ( array_keys( $styles_non_top_level[ $section ] ) as $prop ) {
          if ( 'top' === $styles_non_top_level[ $section ][ $prop ] ) {
            unset( $styles_non_top_level[ $section ][ $prop ] );
          }
        }
      }
    }

    // Build the schema based on valid block & element names.
    $schema                 = array();
    $schema_styles_elements = array();

    /*
		 * Set allowed element pseudo selectors based on per element allow list.
		 * Target data structure in schema:
		 * e.g.
		 * - top level elements: `$schema['styles']['elements']['link'][':hover']`.
		 * - block level elements: `$schema['styles']['blocks']['core/button']['elements']['link'][':hover']`.
		 */
    foreach ( $valid_element_names as $element ) {
      $schema_styles_elements[ $element ] = $styles_non_top_level;

      if ( isset( static::VALID_ELEMENT_PSEUDO_SELECTORS[ $element ] ) ) {
        foreach ( static::VALID_ELEMENT_PSEUDO_SELECTORS[ $element ] as $pseudo_selector ) {
          $schema_styles_elements[ $element ][ $pseudo_selector ] = $styles_non_top_level;
        }
      }
    }

    $schema_styles_blocks   = array();
    $schema_settings_blocks = array();
    foreach ( $valid_block_names as $block ) {
      // Build the schema for each block style variation.
      $style_variation_names = array();
      if (
        ! empty( $input['styles']['blocks'][ $block ]['variations'] ) &&
        is_array( $input['styles']['blocks'][ $block ]['variations'] ) &&
        isset( $valid_variations[ $block ] )
      ) {
        $style_variation_names = array_intersect(
          array_keys( $input['styles']['blocks'][ $block ]['variations'] ),
          $valid_variations[ $block ]
        );
      }

      $schema_styles_variations = array();
      if ( ! empty( $style_variation_names ) ) {
        $schema_styles_variations = array_fill_keys( $style_variation_names, $styles_non_top_level );
      }

      $schema_settings_blocks[ $block ]             = static::VALID_SETTINGS;
      $schema_styles_blocks[ $block ]               = $styles_non_top_level;
      $schema_styles_blocks[ $block ]['elements']   = $schema_styles_elements;
      $schema_styles_blocks[ $block ]['variations'] = $schema_styles_variations;
    }

    $schema['styles']             = static::VALID_STYLES;
    $schema['styles']['blocks']   = $schema_styles_blocks;
    $schema['styles']['elements'] = $schema_styles_elements;
    $schema['settings']           = static::VALID_SETTINGS;
    $schema['settings']['blocks'] = $schema_settings_blocks;

    // Remove anything that's not present in the schema.
    foreach ( array( 'styles', 'settings' ) as $subtree ) {
      if ( ! isset( $input[ $subtree ] ) ) {
        continue;
      }

      if ( ! is_array( $input[ $subtree ] ) ) {
        unset( $output[ $subtree ] );
        continue;
      }

      $result = static::remove_keys_not_in_schema( $input[ $subtree ], $schema[ $subtree ] );

      if ( empty( $result ) ) {
        unset( $output[ $subtree ] );
      } else {
        $output[ $subtree ] = static::resolve_custom_css_format( $result );
      }
    }

    return $output;
  }