[ Index ]

PHP Cross Reference of WordPress Trunk (Updated Daily)

Search

title

Body

[close]

/wp-includes/rest-api/endpoints/ -> class-wp-rest-view-config-controller.php (source)

   1  <?php
   2  /**
   3   * REST API: WP_REST_View_Config_Controller class
   4   *
   5   * @package    WordPress
   6   * @subpackage REST_API
   7   * @since      7.1.0
   8   */
   9  
  10  /**
  11   * Controller which provides a REST endpoint for retrieving the default
  12   * view configuration for a given entity type.
  13   *
  14   * @since 7.1.0
  15   *
  16   * @see WP_REST_Controller
  17   */
  18  class WP_REST_View_Config_Controller extends WP_REST_Controller {
  19  
  20      /**
  21       * Constructor.
  22       *
  23       * @since 7.1.0
  24       */
  25  	public function __construct() {
  26          $this->namespace = 'wp/v2';
  27          $this->rest_base = 'view-config';
  28      }
  29  
  30      /**
  31       * Registers the routes for the controller.
  32       *
  33       * @since 7.1.0
  34       */
  35  	public function register_routes() {
  36          register_rest_route(
  37              $this->namespace,
  38              '/' . $this->rest_base,
  39              array(
  40                  array(
  41                      'methods'             => WP_REST_Server::READABLE,
  42                      'callback'            => array( $this, 'get_items' ),
  43                      'permission_callback' => array( $this, 'get_items_permissions_check' ),
  44                      'args'                => array(
  45                          'kind' => array(
  46                              'description' => __( 'Entity kind.' ),
  47                              'type'        => 'string',
  48                              'required'    => true,
  49                          ),
  50                          'name' => array(
  51                              'description' => __( 'Entity name.' ),
  52                              'type'        => 'string',
  53                              'required'    => true,
  54                          ),
  55                      ),
  56                  ),
  57                  'schema' => array( $this, 'get_public_item_schema' ),
  58              )
  59          );
  60      }
  61  
  62      /**
  63       * Checks if a given request has access to read view config.
  64       *
  65       * @since 7.1.0
  66       *
  67       * @param WP_REST_Request $request Full details about the request.
  68       * @return true|WP_Error True if the request has read access, WP_Error object otherwise.
  69       */
  70  	public function get_items_permissions_check( $request ) {
  71          $kind = $request->get_param( 'kind' );
  72          $name = $request->get_param( 'name' );
  73  
  74          $capability = $this->get_required_capability( $kind, $name );
  75  
  76          if ( null === $capability ) {
  77              return new WP_Error(
  78                  'rest_view_config_invalid_entity',
  79                  __( 'Invalid entity kind or name.' ),
  80                  array( 'status' => 404 )
  81              );
  82          }
  83  
  84          if ( ! current_user_can( $capability ) ) {
  85              return new WP_Error(
  86                  'rest_cannot_read',
  87                  __( 'Sorry, you are not allowed to read view config.' ),
  88                  array( 'status' => rest_authorization_required_code() )
  89              );
  90          }
  91  
  92          return true;
  93      }
  94  
  95      /**
  96       * Resolves the capability required to read the view config for an entity.
  97       *
  98       * Known kinds map to the capability that gates managing that entity's list:
  99       * post types use their own `edit_posts` capability (which honors custom
 100       * `capability_type` registrations), taxonomies use `manage_terms`, and
 101       * root-level entities use `manage_options`. A post type or taxonomy that is
 102       * not registered, or not exposed to the REST API, resolves to `null` so the
 103       * request is treated as referencing an unknown entity.
 104       *
 105       * Any other kind falls back to `edit_posts`. This keeps entities registered
 106       * through the `get_entity_view_config_{$kind}_{$name}` filter readable behind
 107       * a baseline capability.
 108       *
 109       * @since 7.1.0
 110       *
 111       * @param string $kind The entity kind (e.g. `postType`).
 112       * @param string $name The entity name (e.g. `page`).
 113       * @return string|null Capability required to read the config, or null if the
 114       *                     entity is not registered.
 115       */
 116  	protected function get_required_capability( $kind, $name ) {
 117          switch ( $kind ) {
 118              case 'postType':
 119                  $post_type = get_post_type_object( $name );
 120                  if ( $post_type && $post_type->show_in_rest ) {
 121                      return $post_type->cap->edit_posts;
 122                  }
 123                  return null;
 124  
 125              case 'taxonomy':
 126                  $taxonomy = get_taxonomy( $name );
 127                  if ( $taxonomy && $taxonomy->show_in_rest ) {
 128                      return $taxonomy->cap->manage_terms;
 129                  }
 130                  return null;
 131  
 132              case 'root':
 133                  return 'manage_options';
 134          }
 135  
 136          return 'edit_posts';
 137      }
 138  
 139      /**
 140       * Returns the default view configuration for the given entity type.
 141       *
 142       * @since 7.1.0
 143       *
 144       * @param WP_REST_Request $request Full details about the request.
 145       * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
 146       */
 147  	public function get_items( $request ) {
 148          $kind = $request->get_param( 'kind' );
 149          $name = $request->get_param( 'name' );
 150  
 151          $config = wp_get_entity_view_config( $kind, $name );
 152          $schema = $this->get_item_schema();
 153  
 154          $response = array(
 155              'kind'            => $kind,
 156              'name'            => $name,
 157              'version'         => WP_View_Config_Data::LATEST_VERSION,
 158              'default_view'    => wp_prepare_json_value_for_client( $config['default_view'], $schema['properties']['default_view'] ),
 159              'default_layouts' => wp_prepare_json_value_for_client( $config['default_layouts'], $schema['properties']['default_layouts'] ),
 160              'view_list'       => wp_prepare_json_value_for_client( $config['view_list'], $schema['properties']['view_list'] ),
 161              'form'            => wp_prepare_json_value_for_client( $config['form'], $schema['properties']['form'] ),
 162          );
 163  
 164          return rest_ensure_response( $response );
 165      }
 166  
 167      /**
 168       * Recursively casts empty arrays to objects where the schema types them as
 169       * objects.
 170       *
 171       * @since 7.1.0
 172       * @since 7.2.0 Uses wp_prepare_json_value_for_client().
 173       *
 174       * @see wp_prepare_json_value_for_client()
 175       *
 176       * @param mixed $value  The value to normalize.
 177       * @param array $schema The schema node describing the value.
 178       * @return mixed The normalized value, with empty object-typed arrays cast to objects.
 179       */
 180  	protected function cast_empty_objects( $value, $schema ) {
 181          return is_array( $schema ) ? wp_prepare_json_value_for_client( $value, $schema ) : $value;
 182      }
 183  
 184      /**
 185       * Retrieves the item's schema, conforming to JSON Schema.
 186       *
 187       * @since 7.1.0
 188       *
 189       * @return array Item schema data.
 190       */
 191  	public function get_item_schema() {
 192          if ( $this->schema ) {
 193              return $this->add_additional_fields_schema( $this->schema );
 194          }
 195  
 196          $view_base_properties = $this->get_view_base_schema();
 197  
 198          $this->schema = array(
 199              '$schema'    => 'http://json-schema.org/draft-04/schema#',
 200              'title'      => 'view-config',
 201              'type'       => 'object',
 202              'properties' => array(
 203                  'kind'            => array(
 204                      'description' => __( 'Entity kind.' ),
 205                      'type'        => 'string',
 206                      'readonly'    => true,
 207                  ),
 208                  'name'            => array(
 209                      'description' => __( 'Entity name.' ),
 210                      'type'        => 'string',
 211                      'readonly'    => true,
 212                  ),
 213                  'version'         => array(
 214                      'description' => __( 'The schema version of the configuration.' ),
 215                      'type'        => 'integer',
 216                      'readonly'    => true,
 217                  ),
 218                  'default_view'    => array(
 219                      'description' => __( 'Default view configuration.' ),
 220                      'type'        => 'object',
 221                      'readonly'    => true,
 222                      'properties'  => array_merge(
 223                          array(
 224                              'type'   => array(
 225                                  'type' => 'string',
 226                              ),
 227                              'layout' => $this->get_combined_layout_schema(),
 228                          ),
 229                          $view_base_properties
 230                      ),
 231                  ),
 232                  'default_layouts' => array(
 233                      'description' => __( 'Default layout configurations.' ),
 234                      'type'        => 'object',
 235                      'readonly'    => true,
 236                      'properties'  => array(
 237                          'table'       => array(
 238                              'type'       => 'object',
 239                              'properties' => array_merge(
 240                                  $view_base_properties,
 241                                  array(
 242                                      'layout' => $this->get_table_layout_schema(),
 243                                  )
 244                              ),
 245                          ),
 246                          'list'        => array(
 247                              'type'       => 'object',
 248                              'properties' => array_merge(
 249                                  $view_base_properties,
 250                                  array(
 251                                      'layout' => $this->get_list_layout_schema(),
 252                                  )
 253                              ),
 254                          ),
 255                          'grid'        => array(
 256                              'type'       => 'object',
 257                              'properties' => array_merge(
 258                                  $view_base_properties,
 259                                  array(
 260                                      'layout' => $this->get_grid_layout_schema(),
 261                                  )
 262                              ),
 263                          ),
 264                          'activity'    => array(
 265                              'type'       => 'object',
 266                              'properties' => array_merge(
 267                                  $view_base_properties,
 268                                  array(
 269                                      'layout' => $this->get_list_layout_schema(),
 270                                  )
 271                              ),
 272                          ),
 273                          'pickerGrid'  => array(
 274                              'type'       => 'object',
 275                              'properties' => array_merge(
 276                                  $view_base_properties,
 277                                  array(
 278                                      'layout' => $this->get_grid_layout_schema(),
 279                                  )
 280                              ),
 281                          ),
 282                          'pickerTable' => array(
 283                              'type'       => 'object',
 284                              'properties' => array_merge(
 285                                  $view_base_properties,
 286                                  array(
 287                                      'layout' => $this->get_table_layout_schema(),
 288                                  )
 289                              ),
 290                          ),
 291                      ),
 292                  ),
 293                  'view_list'       => array(
 294                      'description' => __( 'List of default views.' ),
 295                      'type'        => 'array',
 296                      'readonly'    => true,
 297                      'items'       => array(
 298                          'type'       => 'object',
 299                          'properties' => array(
 300                              'title' => array(
 301                                  'type' => 'string',
 302                              ),
 303                              'slug'  => array(
 304                                  'type' => 'string',
 305                              ),
 306                              'view'  => array(
 307                                  'type'       => 'object',
 308                                  'properties' => array_merge(
 309                                      array(
 310                                          'type'   => array(
 311                                              'type' => 'string',
 312                                          ),
 313                                          'layout' => $this->get_combined_layout_schema(),
 314                                      ),
 315                                      $view_base_properties
 316                                  ),
 317                              ),
 318                          ),
 319                      ),
 320                  ),
 321                  'form'            => array(
 322                      'description' => __( 'Default form configuration.' ),
 323                      'type'        => 'object',
 324                      'readonly'    => true,
 325                      'properties'  => $this->get_form_schema(),
 326                  ),
 327              ),
 328          );
 329  
 330          return $this->add_additional_fields_schema( $this->schema );
 331      }
 332  
 333      /**
 334       * Returns the schema properties shared by all view types (ViewBase), excluding 'type'.
 335       *
 336       * Note that `search` and `page` are not part of the schema: they are managed
 337       * via the URL, which is their only source of truth.
 338       *
 339       * @since 7.1.0
 340       *
 341       * @return array Schema properties for the base view configuration.
 342       */
 343  	protected function get_view_base_schema() {
 344          return array(
 345              'filters'               => array(
 346                  'type'  => 'array',
 347                  'items' => array(
 348                      'type'       => 'object',
 349                      'properties' => array(
 350                          'field'    => array(
 351                              'type' => 'string',
 352                          ),
 353                          'operator' => array(
 354                              'type' => 'string',
 355                              'enum' => array(
 356                                  'is',
 357                                  'isNot',
 358                                  'isAny',
 359                                  'isNone',
 360                                  'isAll',
 361                                  'isNotAll',
 362                                  'lessThan',
 363                                  'greaterThan',
 364                                  'lessThanOrEqual',
 365                                  'greaterThanOrEqual',
 366                                  'before',
 367                                  'after',
 368                              ),
 369                          ),
 370                          'value'    => array(),
 371                          'isLocked' => array(
 372                              'type' => 'boolean',
 373                          ),
 374                      ),
 375                  ),
 376              ),
 377              'sort'                  => array(
 378                  'type'       => 'object',
 379                  'properties' => array(
 380                      'field'     => array(
 381                          'type' => 'string',
 382                      ),
 383                      'direction' => array(
 384                          'type' => 'string',
 385                          'enum' => array( 'asc', 'desc' ),
 386                      ),
 387                  ),
 388              ),
 389              'perPage'               => array(
 390                  'type' => 'integer',
 391              ),
 392              'fields'                => array(
 393                  'type'  => 'array',
 394                  'items' => array(
 395                      'type' => 'string',
 396                  ),
 397              ),
 398              'titleField'            => array(
 399                  'type' => 'string',
 400              ),
 401              'mediaField'            => array(
 402                  'type' => 'string',
 403              ),
 404              'descriptionField'      => array(
 405                  'type' => 'string',
 406              ),
 407              'showTitle'             => array(
 408                  'type' => 'boolean',
 409              ),
 410              'showMedia'             => array(
 411                  'type' => 'boolean',
 412              ),
 413              'showDescription'       => array(
 414                  'type' => 'boolean',
 415              ),
 416              'showLevels'            => array(
 417                  'type' => 'boolean',
 418              ),
 419              'groupBy'               => array(
 420                  'type'       => 'object',
 421                  'properties' => array(
 422                      'field'     => array(
 423                          'type' => 'string',
 424                      ),
 425                      'direction' => array(
 426                          'type' => 'string',
 427                          'enum' => array( 'asc', 'desc' ),
 428                      ),
 429                      'showLabel' => array(
 430                          'type'    => 'boolean',
 431                          'default' => true,
 432                      ),
 433                  ),
 434              ),
 435              'infiniteScrollEnabled' => array(
 436                  'type' => 'boolean',
 437              ),
 438          );
 439      }
 440  
 441      /**
 442       * Returns the schema for the ColumnStyle type.
 443       *
 444       * @since 7.1.0
 445       *
 446       * @return array Schema for a column style object.
 447       */
 448  	protected function get_column_style_schema() {
 449          return array(
 450              'type'       => 'object',
 451              'properties' => array(
 452                  'width'    => array(
 453                      'description' => __( 'The width of the column.' ),
 454                      'type'        => array( 'string', 'number' ),
 455                  ),
 456                  'maxWidth' => array(
 457                      'description' => __( 'The maximum width of the column.' ),
 458                      'type'        => array( 'string', 'number' ),
 459                  ),
 460                  'minWidth' => array(
 461                      'description' => __( 'The minimum width of the column.' ),
 462                      'type'        => array( 'string', 'number' ),
 463                  ),
 464                  'align'    => array(
 465                      'description' => __( 'The horizontal alignment of the column content.' ),
 466                      'type'        => 'string',
 467                      'enum'        => array( 'start', 'center', 'end' ),
 468                  ),
 469              ),
 470          );
 471      }
 472  
 473      /**
 474       * Returns the layout schema for table-type views (ViewTable, ViewPickerTable).
 475       *
 476       * @since 7.1.0
 477       *
 478       * @return array Schema for a table layout object.
 479       */
 480  	protected function get_table_layout_schema() {
 481          return array(
 482              'type'       => 'object',
 483              'properties' => array(
 484                  'styles'       => array(
 485                      'description'          => __( 'Column styles keyed by field id, for the columns listed in the view fields. The primary column (title, media, and description fields) ignores these styles; in the table layout it takes the width left over by the other columns, or the last column does when there is no primary column.' ),
 486                      'type'                 => 'object',
 487                      'additionalProperties' => $this->get_column_style_schema(),
 488                  ),
 489                  'density'      => array(
 490                      'type' => 'string',
 491                      'enum' => array( 'compact', 'balanced', 'comfortable' ),
 492                  ),
 493                  'enableMoving' => array(
 494                      'type' => 'boolean',
 495                  ),
 496              ),
 497          );
 498      }
 499  
 500      /**
 501       * Returns the layout schema for list-type views (ViewList, ViewActivity).
 502       *
 503       * @since 7.1.0
 504       *
 505       * @return array Schema for a list layout object.
 506       */
 507  	protected function get_list_layout_schema() {
 508          return array(
 509              'type'       => 'object',
 510              'properties' => array(
 511                  'density' => array(
 512                      'type' => 'string',
 513                      'enum' => array( 'compact', 'balanced', 'comfortable' ),
 514                  ),
 515              ),
 516          );
 517      }
 518  
 519      /**
 520       * Returns a combined layout schema that accepts properties from all view types.
 521       *
 522       * This is useful for contexts where the view type is not known ahead of time
 523       * (e.g. the `view` override in a view list item), so all possible layout
 524       * properties must be accepted.
 525       *
 526       * @since 7.1.0
 527       *
 528       * @return array Schema for a combined layout object.
 529       */
 530  	protected function get_combined_layout_schema() {
 531          return array(
 532              'type'       => 'object',
 533              'properties' => array_merge(
 534                  $this->get_table_layout_schema()['properties'],
 535                  $this->get_grid_layout_schema()['properties'],
 536                  $this->get_list_layout_schema()['properties']
 537              ),
 538          );
 539      }
 540  
 541      /**
 542       * Returns the layout schema for grid-type views (ViewGrid, ViewPickerGrid).
 543       *
 544       * @since 7.1.0
 545       *
 546       * @return array Schema for a grid layout object.
 547       */
 548  	protected function get_grid_layout_schema() {
 549          return array(
 550              'type'       => 'object',
 551              'properties' => array(
 552                  'badgeFields' => array(
 553                      'type'  => 'array',
 554                      'items' => array(
 555                          'type' => 'string',
 556                      ),
 557                  ),
 558                  'previewSize' => array(
 559                      'type' => 'number',
 560                  ),
 561                  'density'     => array(
 562                      'type' => 'string',
 563                      'enum' => array( 'compact', 'balanced', 'comfortable' ),
 564                  ),
 565              ),
 566          );
 567      }
 568  
 569      /**
 570       * Returns the schema for a form layout object as a discriminated union.
 571       *
 572       * Each variant is discriminated by a single-value enum on its `type` property,
 573       * matching the TypeScript Layout union in dataviews/src/types/dataform.ts.
 574       *
 575       * @since 7.1.0
 576       * @since 7.2.0 Added the `showPlaceholderIfEmpty` property to the panel layout.
 577       *
 578       * @return array Schema for a form layout object.
 579       */
 580  	protected function get_form_layout_schema() {
 581          return array(
 582              'oneOf' => array(
 583                  // RegularLayout.
 584                  array(
 585                      'type'       => 'object',
 586                      'properties' => array(
 587                          'type'          => array(
 588                              'type' => 'string',
 589                              'enum' => array( 'regular' ),
 590                          ),
 591                          'labelPosition' => array(
 592                              'type' => 'string',
 593                              'enum' => array( 'top', 'side', 'none' ),
 594                          ),
 595                      ),
 596                  ),
 597                  // PanelLayout.
 598                  array(
 599                      'type'       => 'object',
 600                      'properties' => array(
 601                          'type'                   => array(
 602                              'type' => 'string',
 603                              'enum' => array( 'panel' ),
 604                          ),
 605                          'labelPosition'          => array(
 606                              'type' => 'string',
 607                              'enum' => array( 'top', 'side', 'none' ),
 608                          ),
 609                          'openAs'                 => array(
 610                              'oneOf' => array(
 611                                  array(
 612                                      'type' => 'string',
 613                                      'enum' => array( 'dropdown', 'modal' ),
 614                                  ),
 615                                  array(
 616                                      'type'       => 'object',
 617                                      'properties' => array(
 618                                          'type'        => array(
 619                                              'type' => 'string',
 620                                              'enum' => array( 'dropdown', 'modal' ),
 621                                          ),
 622                                          'applyLabel'  => array(
 623                                              'type' => 'string',
 624                                          ),
 625                                          'cancelLabel' => array(
 626                                              'type' => 'string',
 627                                          ),
 628                                      ),
 629                                  ),
 630                              ),
 631                          ),
 632                          'summary'                => array(
 633                              'oneOf' => array(
 634                                  array( 'type' => 'string' ),
 635                                  array(
 636                                      'type'  => 'array',
 637                                      'items' => array(
 638                                          'type' => 'string',
 639                                      ),
 640                                  ),
 641                              ),
 642                          ),
 643                          'editVisibility'         => array(
 644                              'type' => 'string',
 645                              'enum' => array( 'always', 'on-hover' ),
 646                          ),
 647                          'showPlaceholderIfEmpty' => array(
 648                              'type' => 'boolean',
 649                          ),
 650                      ),
 651                  ),
 652                  // CardLayout.
 653                  array(
 654                      'type'       => 'object',
 655                      'properties' => array(
 656                          'type'          => array(
 657                              'type' => 'string',
 658                              'enum' => array( 'card' ),
 659                          ),
 660                          'withHeader'    => array(
 661                              'type' => 'boolean',
 662                          ),
 663                          'isOpened'      => array(
 664                              'type' => 'boolean',
 665                          ),
 666                          'isCollapsible' => array(
 667                              'type' => 'boolean',
 668                          ),
 669                          'summary'       => array(
 670                              'oneOf' => array(
 671                                  array( 'type' => 'string' ),
 672                                  array(
 673                                      'type'  => 'array',
 674                                      'items' => array(
 675                                          'oneOf' => array(
 676                                              array( 'type' => 'string' ),
 677                                              array(
 678                                                  'type' => 'object',
 679                                                  'properties' => array(
 680                                                      'id' => array(
 681                                                          'type' => 'string',
 682                                                      ),
 683                                                      'visibility' => array(
 684                                                          'type' => 'string',
 685                                                          'enum' => array( 'always', 'when-collapsed' ),
 686                                                      ),
 687                                                  ),
 688                                              ),
 689                                          ),
 690                                      ),
 691                                  ),
 692                              ),
 693                          ),
 694                      ),
 695                  ),
 696                  // RowLayout.
 697                  array(
 698                      'type'       => 'object',
 699                      'properties' => array(
 700                          'type'      => array(
 701                              'type' => 'string',
 702                              'enum' => array( 'row' ),
 703                          ),
 704                          'alignment' => array(
 705                              'type' => 'string',
 706                              'enum' => array( 'start', 'center', 'end' ),
 707                          ),
 708                          'styles'    => array(
 709                              'type'                 => 'object',
 710                              'additionalProperties' => array(
 711                                  'type'       => 'object',
 712                                  'properties' => array(
 713                                      'flex' => array(
 714                                          'type' => array( 'string', 'number' ),
 715                                      ),
 716                                  ),
 717                              ),
 718                          ),
 719                      ),
 720                  ),
 721                  // DetailsLayout.
 722                  array(
 723                      'type'       => 'object',
 724                      'properties' => array(
 725                          'type'    => array(
 726                              'type' => 'string',
 727                              'enum' => array( 'details' ),
 728                          ),
 729                          'summary' => array(
 730                              'type' => 'string',
 731                          ),
 732                      ),
 733                  ),
 734              ),
 735          );
 736      }
 737  
 738      /**
 739       * Returns the schema for a form field item (string or object).
 740       *
 741       * @since 7.1.0
 742       *
 743       * @return array Schema for a form field.
 744       */
 745  	protected function get_form_field_schema() {
 746          return array(
 747              'oneOf' => array(
 748                  array( 'type' => 'string' ),
 749                  array(
 750                      'type'       => 'object',
 751                      'properties' => array(
 752                          'id'          => array(
 753                              'type' => 'string',
 754                          ),
 755                          'label'       => array(
 756                              'type' => 'string',
 757                          ),
 758                          'description' => array(
 759                              'type' => 'string',
 760                          ),
 761                          'layout'      => $this->get_form_layout_schema(),
 762                          'children'    => array(
 763                              'type'  => 'array',
 764                              'items' => array(
 765                                  'oneOf' => array(
 766                                      array( 'type' => 'string' ),
 767                                      // This object can have the shape of a form field itself,
 768                                      // allowing for recursive nesting of form fields.
 769                                      // There's no easy way to codify this recursion via the JSON Schema draft-04
 770                                      // supported by the REST API.
 771                                      array( 'type' => 'object' ),
 772                                  ),
 773                              ),
 774                          ),
 775                      ),
 776                  ),
 777              ),
 778          );
 779      }
 780  
 781      /**
 782       * Returns the schema for the form configuration object.
 783       *
 784       * @since 7.1.0
 785       *
 786       * @return array Schema properties for the form configuration.
 787       */
 788  	protected function get_form_schema() {
 789          return array(
 790              'layout' => $this->get_form_layout_schema(),
 791              'fields' => array(
 792                  'type'  => 'array',
 793                  'items' => $this->get_form_field_schema(),
 794              ),
 795          );
 796      }
 797  }


Generated : Sat Oct 24 08:20:34 2026 Cross-referenced by PHPXref