[ Index ]

PHP Cross Reference of WordPress Trunk (Updated Daily)

Search

title

Body

[close]

/wp-includes/ -> block-editor.php (source)

   1  <?php
   2  /**
   3   * Block Editor API.
   4   *
   5   * @package WordPress
   6   * @subpackage Editor
   7   * @since 5.8.0
   8   */
   9  
  10  /**
  11   * Returns the list of default categories for block types.
  12   *
  13   * @since 5.8.0
  14   * @since 6.3.0 Reusable Blocks renamed to Patterns.
  15   *
  16   * @return array[] Array of categories for block types.
  17   */
  18  function get_default_block_categories() {
  19      return array(
  20          array(
  21              'slug'  => 'text',
  22              'title' => _x( 'Text', 'block category' ),
  23              'icon'  => null,
  24          ),
  25          array(
  26              'slug'  => 'media',
  27              'title' => _x( 'Media', 'block category' ),
  28              'icon'  => null,
  29          ),
  30          array(
  31              'slug'  => 'design',
  32              'title' => _x( 'Design', 'block category' ),
  33              'icon'  => null,
  34          ),
  35          array(
  36              'slug'  => 'widgets',
  37              'title' => _x( 'Widgets', 'block category' ),
  38              'icon'  => null,
  39          ),
  40          array(
  41              'slug'  => 'theme',
  42              'title' => _x( 'Theme', 'block category' ),
  43              'icon'  => null,
  44          ),
  45          array(
  46              'slug'  => 'embed',
  47              'title' => _x( 'Embeds', 'block category' ),
  48              'icon'  => null,
  49          ),
  50          array(
  51              'slug'  => 'reusable',
  52              'title' => _x( 'Patterns', 'block category' ),
  53              'icon'  => null,
  54          ),
  55      );
  56  }
  57  
  58  /**
  59   * Returns all the categories for block types that will be shown in the block editor.
  60   *
  61   * @since 5.0.0
  62   * @since 5.8.0 It is possible to pass the block editor context as param.
  63   *
  64   * @param WP_Post|WP_Block_Editor_Context $post_or_block_editor_context The current post object or
  65   *                                                                      the block editor context.
  66   *
  67   * @return array[] Array of categories for block types.
  68   */
  69  function get_block_categories( $post_or_block_editor_context ) {
  70      $block_categories     = get_default_block_categories();
  71      $block_editor_context = $post_or_block_editor_context instanceof WP_Post ?
  72          new WP_Block_Editor_Context(
  73              array(
  74                  'post' => $post_or_block_editor_context,
  75              )
  76          ) : $post_or_block_editor_context;
  77  
  78      /**
  79       * Filters the default array of categories for block types.
  80       *
  81       * @since 5.8.0
  82       *
  83       * @param array[]                 $block_categories     Array of categories for block types.
  84       * @param WP_Block_Editor_Context $block_editor_context The current block editor context.
  85       */
  86      $block_categories = apply_filters( 'block_categories_all', $block_categories, $block_editor_context );
  87  
  88      if ( ! empty( $block_editor_context->post ) ) {
  89          $post = $block_editor_context->post;
  90  
  91          /**
  92           * Filters the default array of categories for block types.
  93           *
  94           * @since 5.0.0
  95           * @deprecated 5.8.0 Use the {@see 'block_categories_all'} filter instead.
  96           *
  97           * @param array[] $block_categories Array of categories for block types.
  98           * @param WP_Post $post             Post being loaded.
  99           */
 100          $block_categories = apply_filters_deprecated( 'block_categories', array( $block_categories, $post ), '5.8.0', 'block_categories_all' );
 101      }
 102  
 103      return $block_categories;
 104  }
 105  
 106  /**
 107   * Gets the list of allowed block types to use in the block editor.
 108   *
 109   * @since 5.8.0
 110   *
 111   * @param WP_Block_Editor_Context $block_editor_context The current block editor context.
 112   * @return bool|string[] Array of block type slugs, or boolean to enable/disable all.
 113   */
 114  function get_allowed_block_types( $block_editor_context ) {
 115      $allowed_block_types = true;
 116  
 117      /**
 118       * Filters the allowed block types for all editor types.
 119       *
 120       * @since 5.8.0
 121       *
 122       * @param bool|string[]           $allowed_block_types  Array of block type slugs, or boolean to enable/disable all.
 123       *                                                      Default true (all registered block types supported).
 124       * @param WP_Block_Editor_Context $block_editor_context The current block editor context.
 125       */
 126      $allowed_block_types = apply_filters( 'allowed_block_types_all', $allowed_block_types, $block_editor_context );
 127  
 128      if ( ! empty( $block_editor_context->post ) ) {
 129          $post = $block_editor_context->post;
 130  
 131          /**
 132           * Filters the allowed block types for the editor.
 133           *
 134           * @since 5.0.0
 135           * @deprecated 5.8.0 Use the {@see 'allowed_block_types_all'} filter instead.
 136           *
 137           * @param bool|string[] $allowed_block_types Array of block type slugs, or boolean to enable/disable all.
 138           *                                           Default true (all registered block types supported)
 139           * @param WP_Post       $post                The post resource data.
 140           */
 141          $allowed_block_types = apply_filters_deprecated( 'allowed_block_types', array( $allowed_block_types, $post ), '5.8.0', 'allowed_block_types_all' );
 142      }
 143  
 144      return $allowed_block_types;
 145  }
 146  
 147  /**
 148   * Returns the default block editor settings.
 149   *
 150   * @since 5.8.0
 151   *
 152   * @return array The default block editor settings.
 153   */
 154  function get_default_block_editor_settings() {
 155      // Media settings.
 156  
 157      // wp_max_upload_size() can be expensive, so only call it when relevant for the current user.
 158      $max_upload_size = 0;
 159      if ( current_user_can( 'upload_files' ) ) {
 160          $max_upload_size = wp_max_upload_size();
 161          if ( ! $max_upload_size ) {
 162              $max_upload_size = 0;
 163          }
 164      }
 165  
 166      /** This filter is documented in wp-admin/includes/media.php */
 167      $image_size_names = apply_filters(
 168          'image_size_names_choose',
 169          array(
 170              'thumbnail' => __( 'Thumbnail' ),
 171              'medium'    => __( 'Medium' ),
 172              'large'     => __( 'Large' ),
 173              'full'      => __( 'Full Size' ),
 174          )
 175      );
 176  
 177      $available_image_sizes = array();
 178      foreach ( $image_size_names as $image_size_slug => $image_size_name ) {
 179          $available_image_sizes[] = array(
 180              'slug' => $image_size_slug,
 181              'name' => $image_size_name,
 182          );
 183      }
 184  
 185      $default_size       = get_option( 'image_default_size', 'large' );
 186      $image_default_size = isset( $image_size_names[ $default_size ] ) ? $default_size : 'large';
 187  
 188      $image_dimensions = array();
 189      $all_sizes        = wp_get_registered_image_subsizes();
 190      foreach ( $available_image_sizes as $size ) {
 191          $key = $size['slug'];
 192          if ( isset( $all_sizes[ $key ] ) ) {
 193              $image_dimensions[ $key ] = $all_sizes[ $key ];
 194          }
 195      }
 196  
 197      // These styles are used if the "no theme styles" options is triggered or on
 198      // themes without their own editor styles.
 199      $default_editor_styles_file = ABSPATH . WPINC . '/css/dist/block-editor/default-editor-styles.css';
 200  
 201      static $default_editor_styles_file_contents = false;
 202      if ( ! $default_editor_styles_file_contents && file_exists( $default_editor_styles_file ) ) {
 203          $default_editor_styles_file_contents = file_get_contents( $default_editor_styles_file );
 204      }
 205  
 206      $default_editor_styles = array();
 207      if ( $default_editor_styles_file_contents ) {
 208          $default_editor_styles = array(
 209              array( 'css' => $default_editor_styles_file_contents ),
 210          );
 211      }
 212  
 213      $editor_settings = array(
 214          'alignWide'                        => get_theme_support( 'align-wide' ),
 215          'allowedBlockTypes'                => true,
 216          'allowedMimeTypes'                 => get_allowed_mime_types(),
 217          /*
 218           * Attaching media to a post moves its attachment page URL, and the old URL then returns a 404.
 219           * Only attach on save when attachment pages are disabled, since they then redirect to the file.
 220           */
 221          'autoAttachMediaEnabled'           => ! get_option( 'wp_attachment_pages_enabled' ),
 222          'defaultEditorStyles'              => $default_editor_styles,
 223          'blockCategories'                  => get_default_block_categories(),
 224          'isRTL'                            => is_rtl(),
 225          'imageDefaultSize'                 => $image_default_size,
 226          'imageDimensions'                  => $image_dimensions,
 227          'imageEditing'                     => true,
 228          'imageSizes'                       => $available_image_sizes,
 229          'maxUploadFileSize'                => $max_upload_size,
 230          '__experimentalDashboardLink'      => admin_url( '/' ),
 231          // The following flag is required to enable the new Gallery block format on the mobile apps in 5.9.
 232          '__unstableGalleryWithImageBlocks' => true,
 233      );
 234  
 235      $theme_settings = get_classic_theme_supports_block_editor_settings();
 236      foreach ( $theme_settings as $key => $value ) {
 237          $editor_settings[ $key ] = $value;
 238      }
 239  
 240      return $editor_settings;
 241  }
 242  
 243  /**
 244   * Returns the block editor settings needed to use the Legacy Widget block which
 245   * is not registered by default.
 246   *
 247   * @since 5.8.0
 248   *
 249   * @return array Settings to be used with get_block_editor_settings().
 250   */
 251  function get_legacy_widget_block_editor_settings() {
 252      $editor_settings = array();
 253  
 254      /**
 255       * Filters the list of widget-type IDs that should **not** be offered by the
 256       * Legacy Widget block.
 257       *
 258       * Returning an empty array will make all widgets available.
 259       *
 260       * @since 5.8.0
 261       *
 262       * @param string[] $widgets An array of excluded widget-type IDs.
 263       */
 264      $editor_settings['widgetTypesToHideFromLegacyWidgetBlock'] = apply_filters(
 265          'widget_types_to_hide_from_legacy_widget_block',
 266          array(
 267              'pages',
 268              'calendar',
 269              'archives',
 270              'media_audio',
 271              'media_image',
 272              'media_gallery',
 273              'media_video',
 274              'search',
 275              'text',
 276              'categories',
 277              'recent-posts',
 278              'recent-comments',
 279              'rss',
 280              'tag_cloud',
 281              'custom_html',
 282              'block',
 283          )
 284      );
 285  
 286      return $editor_settings;
 287  }
 288  
 289  /**
 290   * Collect the block editor assets that need to be loaded into the editor's iframe.
 291   *
 292   * @since 6.0.0
 293   * @access private
 294   *
 295   * @global WP_Styles  $wp_styles  The WP_Styles current instance.
 296   * @global WP_Scripts $wp_scripts The WP_Scripts current instance.
 297   *
 298   * @return array {
 299   *     The block editor assets.
 300   *
 301   *     @type string|false $styles  String containing the HTML for styles.
 302   *     @type string|false $scripts String containing the HTML for scripts.
 303   * }
 304   */
 305  function _wp_get_iframed_editor_assets() {
 306      global $wp_styles, $wp_scripts;
 307  
 308      // Keep track of the styles and scripts instance to restore later.
 309      $current_wp_styles  = $wp_styles;
 310      $current_wp_scripts = $wp_scripts;
 311  
 312      // Create new instances to collect the assets.
 313      $wp_styles  = new WP_Styles();
 314      $wp_scripts = new WP_Scripts();
 315  
 316      /*
 317       * Register all currently registered styles and scripts. The actions that
 318       * follow enqueue assets, but don't necessarily register them.
 319       */
 320      $wp_styles->registered  = $current_wp_styles->registered;
 321      $wp_scripts->registered = $current_wp_scripts->registered;
 322  
 323      /*
 324       * We generally do not need reset styles for the iframed editor.
 325       * However, if it's a classic theme, margins will be added to every block,
 326       * which is reset specifically for list items, so classic themes rely on
 327       * these reset styles.
 328       */
 329      $wp_styles->done =
 330          wp_theme_has_theme_json() ? array( 'wp-reset-editor-styles' ) : array();
 331  
 332      wp_enqueue_script( 'wp-polyfill' );
 333      // Enqueue the `editorStyle` handles for all core block, and dependencies.
 334      wp_enqueue_style( 'wp-edit-blocks' );
 335  
 336      if ( current_theme_supports( 'wp-block-styles' ) ) {
 337          wp_enqueue_style( 'wp-block-library-theme' );
 338      }
 339  
 340      /*
 341       * We don't want to load EDITOR scripts in the iframe, only enqueue
 342       * front-end assets for the content.
 343       */
 344      add_filter( 'should_load_block_editor_scripts_and_styles', '__return_false' );
 345      /** This action is documented in wp-includes/script-loader.php */
 346      do_action( 'enqueue_block_assets' );
 347      remove_filter( 'should_load_block_editor_scripts_and_styles', '__return_false' );
 348  
 349      $block_registry = WP_Block_Type_Registry::get_instance();
 350  
 351      /*
 352       * Additionally, do enqueue `editorStyle` assets for all blocks, which
 353       * contains editor-only styling for blocks (editor content).
 354       */
 355      foreach ( $block_registry->get_all_registered() as $block_type ) {
 356          if ( isset( $block_type->editor_style_handles ) && is_array( $block_type->editor_style_handles ) ) {
 357              foreach ( $block_type->editor_style_handles as $style_handle ) {
 358                  wp_enqueue_style( $style_handle );
 359              }
 360          }
 361      }
 362  
 363      /**
 364       * Remove the deprecated `print_emoji_styles` handler.
 365       * It avoids breaking style generation with a deprecation message.
 366       */
 367      $has_emoji_styles = has_action( 'wp_print_styles', 'print_emoji_styles' );
 368      if ( $has_emoji_styles ) {
 369          remove_action( 'wp_print_styles', 'print_emoji_styles' );
 370      }
 371  
 372      ob_start();
 373      wp_print_styles();
 374      wp_print_font_faces();
 375      wp_print_font_faces_from_style_variations();
 376      $styles = ob_get_clean();
 377  
 378      if ( $has_emoji_styles ) {
 379          add_action( 'wp_print_styles', 'print_emoji_styles' );
 380      }
 381  
 382      ob_start();
 383      wp_print_head_scripts();
 384      wp_print_footer_scripts();
 385      $scripts = ob_get_clean();
 386  
 387      // Restore the original instances.
 388      $wp_styles  = $current_wp_styles;
 389      $wp_scripts = $current_wp_scripts;
 390  
 391      return array(
 392          'styles'  => $styles,
 393          'scripts' => $scripts,
 394      );
 395  }
 396  
 397  /**
 398   * Finds the first occurrence of a specific block in an array of blocks.
 399   *
 400   * @since 6.3.0
 401   *
 402   * @param array  $blocks     Array of blocks.
 403   * @param string $block_name Name of the block to find.
 404   * @return array Found block, or empty array if none found.
 405   */
 406  function wp_get_first_block( $blocks, $block_name ) {
 407      foreach ( $blocks as $block ) {
 408          if ( $block_name === $block['blockName'] ) {
 409              return $block;
 410          }
 411          if ( ! empty( $block['innerBlocks'] ) ) {
 412              $found_block = wp_get_first_block( $block['innerBlocks'], $block_name );
 413  
 414              if ( ! empty( $found_block ) ) {
 415                  return $found_block;
 416              }
 417          }
 418      }
 419  
 420      return array();
 421  }
 422  
 423  /**
 424   * Retrieves Post Content block attributes from the current post template.
 425   *
 426   * @since 6.3.0
 427   * @since 6.4.0 Return null if there is no post content block.
 428   * @access private
 429   *
 430   * @global int $post_ID
 431   *
 432   * @return array|null Post Content block attributes array or null if Post Content block doesn't exist.
 433   */
 434  function wp_get_post_content_block_attributes() {
 435      global $post_ID;
 436  
 437      $is_block_theme = wp_is_block_theme();
 438  
 439      if ( ! $is_block_theme || ! $post_ID ) {
 440          return null;
 441      }
 442  
 443      $template_slug = get_page_template_slug( $post_ID );
 444  
 445      if ( ! $template_slug ) {
 446          $post_slug      = 'singular';
 447          $page_slug      = 'singular';
 448          $template_types = get_block_templates();
 449  
 450          foreach ( $template_types as $template_type ) {
 451              if ( 'page' === $template_type->slug ) {
 452                  $page_slug = 'page';
 453              }
 454              if ( 'single' === $template_type->slug ) {
 455                  $post_slug = 'single';
 456              }
 457          }
 458  
 459          $what_post_type = get_post_type( $post_ID );
 460          switch ( $what_post_type ) {
 461              case 'page':
 462                  $template_slug = $page_slug;
 463                  break;
 464              default:
 465                  $template_slug = $post_slug;
 466                  break;
 467          }
 468      }
 469  
 470      $current_template = get_block_templates( array( 'slug__in' => array( $template_slug ) ) );
 471  
 472      if ( ! empty( $current_template ) ) {
 473          $template_blocks    = parse_blocks( $current_template[0]->content );
 474          $post_content_block = wp_get_first_block( $template_blocks, 'core/post-content' );
 475  
 476          if ( isset( $post_content_block['attrs'] ) ) {
 477              return $post_content_block['attrs'];
 478          }
 479      }
 480  
 481      return null;
 482  }
 483  
 484  /**
 485   * Returns the contextualized block editor settings for a selected editor context.
 486   *
 487   * @since 5.8.0
 488   *
 489   * @param array                   $custom_settings      Custom settings to use with the given editor type.
 490   * @param WP_Block_Editor_Context $block_editor_context The current block editor context.
 491   * @return array The contextualized block editor settings.
 492   */
 493  function get_block_editor_settings( array $custom_settings, $block_editor_context ) {
 494      $editor_settings = array_merge(
 495          get_default_block_editor_settings(),
 496          array(
 497              'allowedBlockTypes' => get_allowed_block_types( $block_editor_context ),
 498              'blockCategories'   => get_block_categories( $block_editor_context ),
 499          ),
 500          $custom_settings
 501      );
 502  
 503      $editor_settings['__experimentalBlockBindingsSupportedAttributes'] = array();
 504      foreach ( array_keys( WP_Block_Type_Registry::get_instance()->get_all_registered() ) as $block_type ) {
 505          $supported_block_attributes = get_block_bindings_supported_attributes( $block_type );
 506          if ( ! empty( $supported_block_attributes ) ) {
 507              $editor_settings['__experimentalBlockBindingsSupportedAttributes'][ $block_type ] = $supported_block_attributes;
 508          }
 509      }
 510  
 511      $global_styles = array();
 512      $presets       = array(
 513          array(
 514              'css'            => 'variables',
 515              '__unstableType' => 'presets',
 516              'isGlobalStyles' => true,
 517          ),
 518          array(
 519              'css'            => 'presets',
 520              '__unstableType' => 'presets',
 521              'isGlobalStyles' => true,
 522          ),
 523      );
 524      foreach ( $presets as $preset_style ) {
 525          $actual_css = wp_get_global_stylesheet( array( $preset_style['css'] ) );
 526          if ( '' !== $actual_css ) {
 527              $preset_style['css'] = $actual_css;
 528              $global_styles[]     = $preset_style;
 529          }
 530      }
 531  
 532      $block_classes = array(
 533          'css'            => 'styles',
 534          '__unstableType' => 'theme',
 535          'isGlobalStyles' => true,
 536      );
 537      $actual_css    = wp_get_global_stylesheet( array( $block_classes['css'] ) );
 538      if ( '' !== $actual_css ) {
 539          $block_classes['css'] = $actual_css;
 540          $global_styles[]      = $block_classes;
 541      }
 542  
 543      // Get any additional css from the customizer and add it before global styles custom CSS.
 544      $global_styles[] = array(
 545          'css'            => wp_get_custom_css(),
 546          '__unstableType' => 'user',
 547          'isGlobalStyles' => false,
 548      );
 549  
 550      /*
 551       * Add the custom CSS as a separate stylesheet so any invalid CSS
 552       * entered by users does not break other global styles.
 553       */
 554      $global_styles[] = array(
 555          'css'            => wp_get_global_stylesheet( array( 'custom-css' ) ),
 556          '__unstableType' => 'user',
 557          'isGlobalStyles' => true,
 558      );
 559  
 560      $editor_settings['styles'] = array_merge( $global_styles, get_block_editor_theme_styles() );
 561  
 562      $editor_settings['__experimentalFeatures'] = wp_get_global_settings();
 563      // These settings may need to be updated based on data coming from theme.json sources.
 564      if ( isset( $editor_settings['__experimentalFeatures']['color']['palette'] ) ) {
 565          $colors_by_origin          = $editor_settings['__experimentalFeatures']['color']['palette'];
 566          $editor_settings['colors'] = $colors_by_origin['custom'] ?? $colors_by_origin['theme'] ?? $colors_by_origin['default'];
 567      }
 568      if ( isset( $editor_settings['__experimentalFeatures']['color']['gradients'] ) ) {
 569          $gradients_by_origin          = $editor_settings['__experimentalFeatures']['color']['gradients'];
 570          $editor_settings['gradients'] = $gradients_by_origin['custom'] ?? $gradients_by_origin['theme'] ?? $gradients_by_origin['default'];
 571      }
 572      if ( isset( $editor_settings['__experimentalFeatures']['typography']['fontSizes'] ) ) {
 573          $font_sizes_by_origin         = $editor_settings['__experimentalFeatures']['typography']['fontSizes'];
 574          $editor_settings['fontSizes'] = $font_sizes_by_origin['custom'] ?? $font_sizes_by_origin['theme'] ?? $font_sizes_by_origin['default'];
 575      }
 576      if ( isset( $editor_settings['__experimentalFeatures']['color']['custom'] ) ) {
 577          $editor_settings['disableCustomColors'] = ! $editor_settings['__experimentalFeatures']['color']['custom'];
 578          unset( $editor_settings['__experimentalFeatures']['color']['custom'] );
 579      }
 580      if ( isset( $editor_settings['__experimentalFeatures']['color']['customGradient'] ) ) {
 581          $editor_settings['disableCustomGradients'] = ! $editor_settings['__experimentalFeatures']['color']['customGradient'];
 582          unset( $editor_settings['__experimentalFeatures']['color']['customGradient'] );
 583      }
 584      if ( isset( $editor_settings['__experimentalFeatures']['typography']['customFontSize'] ) ) {
 585          $editor_settings['disableCustomFontSizes'] = ! $editor_settings['__experimentalFeatures']['typography']['customFontSize'];
 586          unset( $editor_settings['__experimentalFeatures']['typography']['customFontSize'] );
 587      }
 588      if ( isset( $editor_settings['__experimentalFeatures']['typography']['lineHeight'] ) ) {
 589          $editor_settings['enableCustomLineHeight'] = $editor_settings['__experimentalFeatures']['typography']['lineHeight'];
 590          unset( $editor_settings['__experimentalFeatures']['typography']['lineHeight'] );
 591      }
 592      if ( isset( $editor_settings['__experimentalFeatures']['spacing']['units'] ) ) {
 593          $editor_settings['enableCustomUnits'] = $editor_settings['__experimentalFeatures']['spacing']['units'];
 594          unset( $editor_settings['__experimentalFeatures']['spacing']['units'] );
 595      }
 596      if ( isset( $editor_settings['__experimentalFeatures']['spacing']['padding'] ) ) {
 597          $editor_settings['enableCustomSpacing'] = $editor_settings['__experimentalFeatures']['spacing']['padding'];
 598          unset( $editor_settings['__experimentalFeatures']['spacing']['padding'] );
 599      }
 600      if ( isset( $editor_settings['__experimentalFeatures']['spacing']['customSpacingSize'] ) ) {
 601          $editor_settings['disableCustomSpacingSizes'] = ! $editor_settings['__experimentalFeatures']['spacing']['customSpacingSize'];
 602          unset( $editor_settings['__experimentalFeatures']['spacing']['customSpacingSize'] );
 603      }
 604  
 605      if ( isset( $editor_settings['__experimentalFeatures']['spacing']['spacingSizes'] ) ) {
 606          $spacing_sizes_by_origin         = $editor_settings['__experimentalFeatures']['spacing']['spacingSizes'];
 607          $editor_settings['spacingSizes'] = $spacing_sizes_by_origin['custom'] ?? $spacing_sizes_by_origin['theme'] ?? $spacing_sizes_by_origin['default'];
 608      }
 609  
 610      $editor_settings['__unstableResolvedAssets']         = _wp_get_iframed_editor_assets();
 611      $editor_settings['__unstableIsBlockBasedTheme']      = wp_is_block_theme();
 612      $editor_settings['localAutosaveInterval']            = 15;
 613      $editor_settings['disableLayoutStyles']              = current_theme_supports( 'disable-layout-styles' );
 614      $editor_settings['__experimentalDiscussionSettings'] = array(
 615          'commentOrder'         => get_option( 'comment_order' ),
 616          'commentsPerPage'      => get_option( 'comments_per_page' ),
 617          'defaultCommentsPage'  => get_option( 'default_comments_page' ),
 618          'pageComments'         => get_option( 'page_comments' ),
 619          'threadComments'       => get_option( 'thread_comments' ),
 620          'threadCommentsDepth'  => get_option( 'thread_comments_depth' ),
 621          'defaultCommentStatus' => get_option( 'default_comment_status' ),
 622          'avatarURL'            => get_avatar_url(
 623              '',
 624              array(
 625                  'size'          => 96,
 626                  'force_default' => true,
 627                  'default'       => get_option( 'avatar_default' ),
 628              )
 629          ),
 630      );
 631  
 632      $post_content_block_attributes = wp_get_post_content_block_attributes();
 633  
 634      if ( isset( $post_content_block_attributes ) ) {
 635          $editor_settings['postContentAttributes'] = $post_content_block_attributes;
 636      }
 637  
 638      $editor_settings['canUpdateBlockBindings'] = current_user_can( 'edit_block_binding', $block_editor_context );
 639  
 640      /**
 641       * Filters the settings to pass to the block editor for all editor type.
 642       *
 643       * @since 5.8.0
 644       *
 645       * @param array                   $editor_settings      Default editor settings.
 646       * @param WP_Block_Editor_Context $block_editor_context The current block editor context.
 647       */
 648      $editor_settings = apply_filters( 'block_editor_settings_all', $editor_settings, $block_editor_context );
 649  
 650      if ( ! empty( $block_editor_context->post ) ) {
 651          $post = $block_editor_context->post;
 652  
 653          /**
 654           * Filters the settings to pass to the block editor.
 655           *
 656           * @since 5.0.0
 657           * @deprecated 5.8.0 Use the {@see 'block_editor_settings_all'} filter instead.
 658           *
 659           * @param array   $editor_settings Default editor settings.
 660           * @param WP_Post $post            Post being edited.
 661           */
 662          $editor_settings = apply_filters_deprecated( 'block_editor_settings', array( $editor_settings, $post ), '5.8.0', 'block_editor_settings_all' );
 663      }
 664  
 665      $editor_settings['canEditCSS'] = current_user_can( 'edit_css' );
 666  
 667      return $editor_settings;
 668  }
 669  
 670  /**
 671   * Preloads common data used with the block editor by specifying an array of
 672   * REST API paths that will be preloaded for a given block editor context.
 673   *
 674   * @since 5.8.0
 675   *
 676   * @global WP_Post           $post              Global post object.
 677   * @global WP_Scripts        $wp_scripts        The WP_Scripts object for printing scripts.
 678   * @global WP_Styles         $wp_styles         The WP_Styles object for printing styles.
 679   * @global WP_Script_Modules $wp_script_modules The WP_Script_Modules object for printing script modules.
 680   *
 681   * @param (string|string[])[]     $preload_paths        List of paths to preload.
 682   * @param WP_Block_Editor_Context $block_editor_context The current block editor context.
 683   */
 684  function block_editor_rest_api_preload( array $preload_paths, $block_editor_context ) {
 685      global $post, $wp_scripts, $wp_styles, $wp_script_modules;
 686  
 687      /**
 688       * Filters the array of REST API paths that will be used to preloaded common data for the block editor.
 689       *
 690       * @since 5.8.0
 691       *
 692       * @param (string|string[])[]     $preload_paths        Array of paths to preload.
 693       * @param WP_Block_Editor_Context $block_editor_context The current block editor context.
 694       */
 695      $preload_paths = apply_filters( 'block_editor_rest_api_preload_paths', $preload_paths, $block_editor_context );
 696  
 697      if ( ! empty( $block_editor_context->post ) ) {
 698          $selected_post = $block_editor_context->post;
 699  
 700          /**
 701           * Filters the array of paths that will be preloaded.
 702           *
 703           * Preload common data by specifying an array of REST API paths that will be preloaded.
 704           *
 705           * @since 5.0.0
 706           * @deprecated 5.8.0 Use the {@see 'block_editor_rest_api_preload_paths'} filter instead.
 707           *
 708           * @param (string|string[])[] $preload_paths Array of paths to preload.
 709           * @param WP_Post             $selected_post Post being edited.
 710           */
 711          $preload_paths = apply_filters_deprecated( 'block_editor_preload_paths', array( $preload_paths, $selected_post ), '5.8.0', 'block_editor_rest_api_preload_paths' );
 712      }
 713  
 714      if ( empty( $preload_paths ) ) {
 715          return;
 716      }
 717  
 718      /*
 719       * Ensure the globals $post, $wp_scripts, $wp_styles, and $wp_script_modules
 720       * remain the same after API data is preloaded.
 721       * Because API preloading can call the_content and other filters, plugins
 722       * can unexpectedly modify the global $post or enqueue assets which are not
 723       * intended for the block editor.
 724       *
 725       * Copies are swapped in for the duration of the preload and the original
 726       * instances are restored afterwards, so that hooks and other references
 727       * bound to those instances remain valid.
 728       */
 729      $original_post              = $post;
 730      $original_wp_scripts        = $wp_scripts;
 731      $original_wp_styles         = $wp_styles;
 732      $original_wp_script_modules = $wp_script_modules;
 733  
 734      $post              = ! empty( $post ) ? clone $post : $post;
 735      $wp_scripts        = ! empty( $wp_scripts ) ? clone $wp_scripts : $wp_scripts;
 736      $wp_styles         = ! empty( $wp_styles ) ? clone $wp_styles : $wp_styles;
 737      $wp_script_modules = ! empty( $wp_script_modules ) ? clone $wp_script_modules : $wp_script_modules;
 738  
 739      foreach ( $preload_paths as &$path ) {
 740          if ( is_string( $path ) && ! str_starts_with( $path, '/' ) ) {
 741              $path = '/' . $path;
 742              continue;
 743          }
 744  
 745          if ( is_array( $path ) && is_string( $path[0] ) && ! str_starts_with( $path[0], '/' ) ) {
 746              $path[0] = '/' . $path[0];
 747          }
 748      }
 749  
 750      unset( $path );
 751  
 752      $preload_data = array_reduce(
 753          $preload_paths,
 754          'rest_preload_api_request',
 755          array()
 756      );
 757  
 758      // Restore the original $post, $wp_scripts, $wp_styles, and $wp_script_modules instances.
 759      $post = $original_post;
 760      if ( ! empty( $post ) ) {
 761          setup_postdata( $post );
 762      }
 763      $wp_scripts        = $original_wp_scripts;
 764      $wp_styles         = $original_wp_styles;
 765      $wp_script_modules = $original_wp_script_modules;
 766  
 767      wp_add_inline_script(
 768          'wp-api-fetch',
 769          sprintf(
 770              'wp.apiFetch.use( wp.apiFetch.createPreloadingMiddleware( %s ) );',
 771              wp_json_encode( $preload_data, JSON_HEX_TAG | JSON_UNESCAPED_SLASHES )
 772          ),
 773          'after'
 774      );
 775  }
 776  
 777  /**
 778   * Creates an array of theme styles to load into the block editor.
 779   *
 780   * @since 5.8.0
 781   *
 782   * @global array $editor_styles
 783   *
 784   * @return array An array of theme styles for the block editor.
 785   */
 786  function get_block_editor_theme_styles() {
 787      global $editor_styles;
 788  
 789      $styles = array();
 790  
 791      if ( $editor_styles && current_theme_supports( 'editor-styles' ) ) {
 792          foreach ( $editor_styles as $style ) {
 793              if ( preg_match( '~^(https?:)?//~', $style ) ) {
 794                  $response = wp_remote_get( $style );
 795                  if ( ! is_wp_error( $response ) ) {
 796                      $styles[] = array(
 797                          'css'            => wp_remote_retrieve_body( $response ),
 798                          '__unstableType' => 'theme',
 799                          'isGlobalStyles' => false,
 800                      );
 801                  }
 802              } else {
 803                  $file = get_theme_file_path( $style );
 804                  if ( is_file( $file ) ) {
 805                      $styles[] = array(
 806                          'css'            => file_get_contents( $file ),
 807                          'baseURL'        => get_theme_file_uri( $style ),
 808                          '__unstableType' => 'theme',
 809                          'isGlobalStyles' => false,
 810                      );
 811                  }
 812              }
 813          }
 814      }
 815  
 816      return $styles;
 817  }
 818  
 819  /**
 820   * Returns the classic theme supports settings for block editor.
 821   *
 822   * @since 6.2.0
 823   * @since 6.6.0 Add support for 'editor-spacing-sizes' theme support.
 824   *
 825   * @return array The classic theme supports settings.
 826   */
 827  function get_classic_theme_supports_block_editor_settings() {
 828      $theme_settings = array(
 829          'disableCustomColors'    => get_theme_support( 'disable-custom-colors' ),
 830          'disableCustomFontSizes' => get_theme_support( 'disable-custom-font-sizes' ),
 831          'disableCustomGradients' => get_theme_support( 'disable-custom-gradients' ),
 832          'disableLayoutStyles'    => get_theme_support( 'disable-layout-styles' ),
 833          'enableCustomLineHeight' => get_theme_support( 'custom-line-height' ),
 834          'enableCustomSpacing'    => get_theme_support( 'custom-spacing' ),
 835          'enableCustomUnits'      => get_theme_support( 'custom-units' ),
 836      );
 837  
 838      // Theme settings.
 839      $color_palette = current( (array) get_theme_support( 'editor-color-palette' ) );
 840      if ( false !== $color_palette ) {
 841          $theme_settings['colors'] = $color_palette;
 842      }
 843  
 844      $font_sizes = current( (array) get_theme_support( 'editor-font-sizes' ) );
 845      if ( false !== $font_sizes ) {
 846          $theme_settings['fontSizes'] = $font_sizes;
 847      }
 848  
 849      $gradient_presets = current( (array) get_theme_support( 'editor-gradient-presets' ) );
 850      if ( false !== $gradient_presets ) {
 851          $theme_settings['gradients'] = $gradient_presets;
 852      }
 853  
 854      $spacing_sizes = current( (array) get_theme_support( 'editor-spacing-sizes' ) );
 855      if ( false !== $spacing_sizes ) {
 856          $theme_settings['spacingSizes'] = $spacing_sizes;
 857      }
 858  
 859      return $theme_settings;
 860  }
 861  
 862  /**
 863   * Initialize site preview.
 864   *
 865   * This function sets IFRAME_REQUEST to true if the site preview parameter is set.
 866   *
 867   * @since 6.8.0
 868   */
 869  function wp_initialize_site_preview_hooks() {
 870      if (
 871          ! defined( 'IFRAME_REQUEST' ) &&
 872          isset( $_GET['wp_site_preview'] ) &&
 873          1 === (int) $_GET['wp_site_preview'] &&
 874          current_user_can( 'edit_theme_options' )
 875      ) {
 876          define( 'IFRAME_REQUEST', true );
 877      }
 878  }


Generated : Sun Nov 1 08:20:35 2026 Cross-referenced by PHPXref