Skip to content

Commit c80640f

Browse files
Merge branch 'WordPress:trunk' into trunk
2 parents 301d70f + 319cab0 commit c80640f

File tree

77 files changed

+1324
-344
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

77 files changed

+1324
-344
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
name: Sync Gutenberg plugin assets to WordPress.org plugin repo
2+
3+
on:
4+
push:
5+
branches:
6+
- trunk
7+
paths:
8+
- assets/**
9+
10+
jobs:
11+
sync-assets:
12+
name: Sync assets to WordPress.org plugin repo
13+
runs-on: ubuntu-latest
14+
environment: wp.org plugin
15+
env:
16+
PLUGIN_REPO_URL: 'https://plugins.svn.wordpress.org/gutenberg'
17+
SVN_USERNAME: ${{ secrets.SVN_USERNAME }}
18+
SVN_PASSWORD: ${{ secrets.SVN_PASSWORD }}
19+
20+
steps:
21+
- name: Check out Gutenberg assets folder from WP.org plugin repo
22+
run: |
23+
svn checkout "$PLUGIN_REPO_URL/assets" \
24+
--username "$SVN_USERNAME" --password "$SVN_PASSWORD"
25+
26+
- name: Delete everything
27+
run: find assets -type f -not -path 'assets/.svn/*' -delete
28+
29+
- name: Checkout assets from current release
30+
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
31+
with:
32+
sparse-checkout: |
33+
assets
34+
show-progress: ${{ runner.debug == '1' && 'true' || 'false' }}
35+
path: git
36+
37+
- name: Copy files from git checkout to svn working copy
38+
run: cp -R git/assets/* assets
39+
40+
- name: Commit the updated assets
41+
working-directory: ./assets
42+
run: |
43+
svn st | awk '/^?/ {print $2}' | xargs -r svn add
44+
svn st | awk '/^!/ {print $2}' | xargs -r svn rm
45+
svn commit . \
46+
-m "Sync assets for commit $GITHUB_SHA" \
47+
--no-auth-cache --non-interactive --username "$SVN_USERNAME" --password "$SVN_PASSWORD" \
48+
--config-option=servers:global:http-timeout=600

assets/banner-1544x500.jpg

355 KB
Loading

assets/banner-772x250.jpg

106 KB
Loading

assets/icon-128x128.jpg

36.3 KB
Loading

assets/icon-256x256.jpg

50.5 KB
Loading

backport-changelog/6.8/8014.md

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
https://github.com/WordPress/wordpress-develop/pull/8014
2+
3+
* https://github.com/WordPress/gutenberg/pull/66479

docs/reference-guides/data/data-core-block-editor.md

+4-4
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ _Parameters_
190190

191191
_Returns_
192192

193-
- `Object?`: Block attributes.
193+
- `?Object`: Block attributes.
194194

195195
### getBlockCount
196196

@@ -448,7 +448,7 @@ Determines the items that appear in the available block transforms list.
448448

449449
Each item object contains what's necessary to display a menu item in the transform list and handle its selection.
450450

451-
The 'frecency' property is a heuristic (<https://en.wikipedia.org/wiki/Frecency>) that combines block usage frequenty and recency.
451+
The 'frecency' property is a heuristic (<https://en.wikipedia.org/wiki/Frecency>) that combines block usage frequency and recency.
452452

453453
Items are returned ordered descendingly by their 'frecency'.
454454

@@ -521,7 +521,7 @@ _Properties_
521521

522522
- _name_ `string`: The type of block.
523523
- _attributes_ `?Object`: Attributes to pass to the newly created block.
524-
- _attributesToCopy_ `?Array<string>`: Attributes to be copied from adjecent blocks when inserted.
524+
- _attributesToCopy_ `?Array<string>`: Attributes to be copied from adjacent blocks when inserted.
525525

526526
### getDraggedBlockClientIds
527527

@@ -580,7 +580,7 @@ Determines the items that appear in the inserter. Includes both static items (e.
580580

581581
Each item object contains what's necessary to display a button in the inserter and handle its selection.
582582

583-
The 'frecency' property is a heuristic (<https://en.wikipedia.org/wiki/Frecency>) that combines block usage frequenty and recency.
583+
The 'frecency' property is a heuristic (<https://en.wikipedia.org/wiki/Frecency>) that combines block usage frequency and recency.
584584

585585
Items are returned ordered descendingly by their 'utility' and 'frecency'.
586586

docs/reference-guides/data/data-core-blocks.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ _Parameters_
172172

173173
_Returns_
174174

175-
- `Object?`: Block Type.
175+
- `?Object`: Block Type.
176176

177177
### getBlockTypes
178178

docs/reference-guides/data/data-core-edit-post.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ Retrieves the template of the currently edited post.
6565

6666
_Returns_
6767

68-
- `Object?`: Post Template.
68+
- `?Object`: Post Template.
6969

7070
### getEditorMode
7171

docs/reference-guides/data/data-core-rich-text.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ _Parameters_
4646
4747
_Returns_
4848
49-
- `Object?`: Format type.
49+
- `?Object`: Format type.
5050
5151
### getFormatTypeForBareElement
5252
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
1+
<?php
2+
3+
/**
4+
* Modifies the Post controller endpoint to support orderby_hierarchy.
5+
*
6+
* @package gutenberg
7+
* @since 6.8.0
8+
*/
9+
10+
class Gutenberg_Hierarchical_Sort {
11+
private static $post_ids = array();
12+
private static $levels = array();
13+
private static $instance;
14+
15+
public static function get_instance() {
16+
if ( null === self::$instance ) {
17+
self::$instance = new self();
18+
}
19+
20+
return self::$instance;
21+
}
22+
23+
public function run( $args ) {
24+
$new_args = array_merge(
25+
$args,
26+
array(
27+
'fields' => 'id=>parent',
28+
'posts_per_page' => -1,
29+
)
30+
);
31+
$query = new WP_Query( $new_args );
32+
$posts = $query->posts;
33+
$result = self::sort( $posts );
34+
35+
self::$post_ids = $result['post_ids'];
36+
self::$levels = $result['levels'];
37+
}
38+
39+
/**
40+
* Check if the request is eligible for hierarchical sorting.
41+
*
42+
* @param array $request The request data.
43+
*
44+
* @return bool Return true if the request is eligible for hierarchical sorting.
45+
*/
46+
public static function is_eligible( $request ) {
47+
if ( ! isset( $request['orderby_hierarchy'] ) || true !== $request['orderby_hierarchy'] ) {
48+
return false;
49+
}
50+
51+
return true;
52+
}
53+
54+
public static function get_ancestor( $post_id ) {
55+
return get_post( $post_id )->post_parent ?? 0;
56+
}
57+
58+
/**
59+
* Sort posts by hierarchy.
60+
*
61+
* Takes an array of posts and sorts them based on their parent-child relationships.
62+
* It also tracks the level depth of each post in the hierarchy.
63+
*
64+
* Example input:
65+
* ```
66+
* [
67+
* ['ID' => 4, 'post_parent' => 2],
68+
* ['ID' => 2, 'post_parent' => 0],
69+
* ['ID' => 3, 'post_parent' => 2],
70+
* ]
71+
* ```
72+
*
73+
* Example output:
74+
* ```
75+
* [
76+
* 'post_ids' => [2, 4, 3],
77+
* 'levels' => [0, 1, 1]
78+
* ]
79+
* ```
80+
*
81+
* @param array $posts Array of post objects containing ID and post_parent properties.
82+
*
83+
* @return array {
84+
* Sorted post IDs and their hierarchical levels
85+
*
86+
* @type array $post_ids Array of post IDs
87+
* @type array $levels Array of levels for the corresponding post ID in the same index
88+
* }
89+
*/
90+
public static function sort( $posts ) {
91+
/*
92+
* Arrange pages in two arrays:
93+
*
94+
* - $top_level: posts whose parent is 0
95+
* - $children: post ID as the key and an array of children post IDs as the value.
96+
* Example: $children[10][] contains all sub-pages whose parent is 10.
97+
*
98+
* Additionally, keep track of the levels of each post in $levels.
99+
* Example: $levels[10] = 0 means the post ID is a top-level page.
100+
*
101+
*/
102+
$top_level = array();
103+
$children = array();
104+
foreach ( $posts as $post ) {
105+
if ( empty( $post->post_parent ) ) {
106+
$top_level[] = $post->ID;
107+
} else {
108+
$children[ $post->post_parent ][] = $post->ID;
109+
}
110+
}
111+
112+
$ids = array();
113+
$levels = array();
114+
self::add_hierarchical_ids( $ids, $levels, 0, $top_level, $children );
115+
116+
// Process remaining children.
117+
if ( ! empty( $children ) ) {
118+
foreach ( $children as $parent_id => $child_ids ) {
119+
$level = 0;
120+
$ancestor = $parent_id;
121+
while ( 0 !== $ancestor ) {
122+
++$level;
123+
$ancestor = self::get_ancestor( $ancestor );
124+
}
125+
self::add_hierarchical_ids( $ids, $levels, $level, $child_ids, $children );
126+
}
127+
}
128+
129+
return array(
130+
'post_ids' => $ids,
131+
'levels' => $levels,
132+
);
133+
}
134+
135+
private static function add_hierarchical_ids( &$ids, &$levels, $level, $to_process, $children ) {
136+
foreach ( $to_process as $id ) {
137+
if ( in_array( $id, $ids, true ) ) {
138+
continue;
139+
}
140+
$ids[] = $id;
141+
$levels[ $id ] = $level;
142+
143+
if ( isset( $children[ $id ] ) ) {
144+
self::add_hierarchical_ids( $ids, $levels, $level + 1, $children[ $id ], $children );
145+
unset( $children[ $id ] );
146+
}
147+
}
148+
}
149+
150+
public static function get_post_ids() {
151+
return self::$post_ids;
152+
}
153+
154+
public static function get_levels() {
155+
return self::$levels;
156+
}
157+
}
158+
159+
add_filter(
160+
'rest_page_collection_params',
161+
function ( $params ) {
162+
$params['orderby_hierarchy'] = array(
163+
'description' => 'Sort pages by hierarchy.',
164+
'type' => 'boolean',
165+
'default' => false,
166+
);
167+
return $params;
168+
}
169+
);
170+
171+
add_filter(
172+
'rest_page_query',
173+
function ( $args, $request ) {
174+
if ( ! Gutenberg_Hierarchical_Sort::is_eligible( $request ) ) {
175+
return $args;
176+
}
177+
178+
$hs = Gutenberg_Hierarchical_Sort::get_instance();
179+
$hs->run( $args );
180+
181+
// Reconfigure the args to display only the ids in the list.
182+
$args['post__in'] = $hs->get_post_ids();
183+
$args['orderby'] = 'post__in';
184+
185+
return $args;
186+
},
187+
10,
188+
2
189+
);
190+
191+
add_filter(
192+
'rest_prepare_page',
193+
function ( $response, $post, $request ) {
194+
if ( ! Gutenberg_Hierarchical_Sort::is_eligible( $request ) ) {
195+
return $response;
196+
}
197+
198+
$hs = Gutenberg_Hierarchical_Sort::get_instance();
199+
$response->data['level'] = $hs->get_levels()[ $post->ID ];
200+
201+
return $response;
202+
},
203+
10,
204+
3
205+
);

lib/load.php

+1
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ function gutenberg_is_experiment_enabled( $name ) {
4545
require __DIR__ . '/compat/wordpress-6.8/block-comments.php';
4646
require __DIR__ . '/compat/wordpress-6.8/class-gutenberg-rest-comment-controller-6-8.php';
4747
require __DIR__ . '/compat/wordpress-6.8/class-gutenberg-rest-post-types-controller-6-8.php';
48+
require __DIR__ . '/compat/wordpress-6.8/class-gutenberg-hierarchical-sort.php';
4849
require __DIR__ . '/compat/wordpress-6.8/rest-api.php';
4950

5051
// Plugin specific code.

packages/block-editor/src/components/block-alignment-matrix-control/README.md

+29-6
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,36 @@ const controls = (
4141
/>
4242
</BlockControls>
4343
</>
44-
}
44+
);
4545
```
4646

4747
### Props
4848

49-
| Name | Type | Default | Description |
50-
| ---------- | ---------- | ------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
51-
| `label` | `string` | `Change matrix alignment` | concise description of tool's functionality. |
52-
| `onChange` | `function` | `noop` | the function to execute upon a user's change of the matrix state |
53-
| `value` | `string` | `center` | describes the content alignment location and can be `top`, `right`, `bottom`, `left`, `topRight`, `bottomRight`, `bottomLeft`, `topLeft` |
49+
### `label`
50+
51+
- **Type:** `string`
52+
- **Default:** `'Change matrix alignment'`
53+
54+
Label for the control.
55+
56+
### `onChange`
57+
58+
- **Type:** `Function`
59+
- **Default:** `noop`
60+
61+
Function to execute upon a user's change of the matrix state.
62+
63+
### `value`
64+
65+
- **Type:** `string`
66+
- **Default:** `'center'`
67+
- **Options:** `'center'`, `'center center'`, `'center left'`, `'center right'`, `'top center'`, `'top left'`, `'top right'`, `'bottom center'`, `'bottom left'`, `'bottom right'`
68+
69+
Content alignment location.
70+
71+
### `isDisabled`
72+
73+
- **Type:** `boolean`
74+
- **Default:** `false`
75+
76+
Whether the control should be disabled.

0 commit comments

Comments
 (0)