Skip to content

Commit 4d7fb82

Browse files
authored
Merge branch 'trunk' into add/threads-oembed-provider
2 parents c1a5fb4 + e753781 commit 4d7fb82

11 files changed

Lines changed: 319 additions & 48 deletions

File tree

src/wp-admin/css/dashboard.css

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -570,7 +570,7 @@
570570
}
571571

572572
.community-events ul {
573-
background-color: #f6f7f7;
573+
background-color: rgba(var(--wp-admin-theme-color--rgb),.08);
574574
padding-left: 0;
575575
padding-right: 0;
576576
padding-bottom: 0;
@@ -582,15 +582,15 @@
582582
color: #2c3338;
583583
}
584584
.community-events li:first-child {
585-
border-top: 1px solid #f0f0f1;
585+
border-top: 1px solid #e9e9ed;
586586
}
587587

588588
.community-events li ~ li {
589-
border-top: 1px solid #f0f0f1;
589+
border-top: 1px solid #e9e9ed;
590590
}
591591

592592
.community-events .activity-block.last {
593-
border-bottom: 1px solid #f0f0f1;
593+
border-bottom: 1px solid #e9e9ed;
594594
padding-top: 0;
595595
margin-top: -1px;
596596
}

src/wp-admin/includes/image.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1088,11 +1088,16 @@ function wp_read_image_metadata( $file ) {
10881088
function wp_get_image_alttext( $file ) {
10891089
$alt_text = '';
10901090
$img_contents = file_get_contents( $file );
1091+
1092+
if ( false === $img_contents ) {
1093+
return $alt_text;
1094+
}
1095+
10911096
// Find the start and end positions of the XMP metadata.
10921097
$xmp_start = strpos( $img_contents, '<x:xmpmeta' );
10931098
$xmp_end = strpos( $img_contents, '</x:xmpmeta>' );
10941099

1095-
if ( ! $xmp_start || ! $xmp_end ) {
1100+
if ( false === $xmp_start || false === $xmp_end ) {
10961101
// No XMP metadata found.
10971102
return $alt_text;
10981103
}

src/wp-admin/users.php

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -143,13 +143,18 @@
143143
wp_die( __( 'Sorry, you are not allowed to edit this user.' ), 403 );
144144
}
145145

146-
// The new role of the current user must also have the promote_users cap or be a multisite super admin.
147-
if ( $id === $current_user->ID
148-
&& ! $wp_roles->role_objects[ $role ]->has_cap( 'promote_users' )
149-
&& ! ( is_multisite() && current_user_can( 'manage_network_users' ) )
150-
) {
151-
$update = 'err_admin_role';
146+
// The new role of the current user must also have the promote_users cap, be a multisite super admin and must not be empty.
147+
if ( $id === $current_user->ID ) {
148+
if ( '' === $role ) {
149+
wp_die( __( 'Sorry, you cannot remove your own role.' ), 403 );
150+
}
151+
152+
if ( $wp_roles->role_objects[ $role ]->has_cap( 'promote_users' ) || ( is_multisite() && current_user_can( 'manage_network_users' ) ) ) {
152153
continue;
154+
}
155+
156+
$update = 'err_admin_role';
157+
continue;
153158
}
154159

155160
// If the user doesn't already belong to the blog, bail.

src/wp-includes/admin-bar.php

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1437,3 +1437,49 @@ function _get_admin_bar_pref( $context = 'front', $user = 0 ) {
14371437

14381438
return 'true' === $pref;
14391439
}
1440+
1441+
/**
1442+
* Adds CSS from the administration color scheme stylesheet on the front end.
1443+
*
1444+
* @since 7.0.0
1445+
*
1446+
* @global array $_wp_admin_css_colors Registered administration color schemes.
1447+
*/
1448+
function wp_admin_bar_add_color_scheme_to_front_end() {
1449+
if ( is_admin() ) {
1450+
return;
1451+
}
1452+
1453+
global $_wp_admin_css_colors;
1454+
1455+
if ( empty( $_wp_admin_css_colors ) ) {
1456+
register_admin_color_schemes();
1457+
}
1458+
1459+
$color_scheme = get_user_option( 'admin_color' );
1460+
1461+
if ( empty( $color_scheme ) || ! isset( $_wp_admin_css_colors[ $color_scheme ] ) ) {
1462+
$color_scheme = 'modern';
1463+
}
1464+
1465+
$color = $_wp_admin_css_colors[ $color_scheme ] ?? null;
1466+
$url = $color->url ?? '';
1467+
1468+
if ( $url ) {
1469+
$response = wp_remote_get( $url );
1470+
if ( ! is_wp_error( $response ) ) {
1471+
$css = $response['body'];
1472+
if ( is_string( $css ) && str_contains( $css, '#wpadminbar' ) ) {
1473+
$start_position = strpos( $css, '#wpadminbar' );
1474+
$end_position = strpos( $css, '.wp-pointer' );
1475+
if ( false !== $end_position && $end_position > $start_position ) {
1476+
$css = substr( $css, $start_position, $end_position - $start_position );
1477+
if ( SCRIPT_DEBUG ) {
1478+
$css = str_replace( '/* Pointers */', '', $css );
1479+
}
1480+
}
1481+
wp_add_inline_style( 'admin-bar', $css );
1482+
}
1483+
}
1484+
}
1485+
}

src/wp-includes/cache-compat.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -327,11 +327,11 @@ function wp_cache_set_multiple_salted( $data, $group, $salt, $expire = 0 ) {
327327
*
328328
* @param int $blog_id Site ID.
329329
*/
330-
function wp_cache_switch_to_blog( $blog_id ) {
330+
function wp_cache_switch_to_blog( $blog_id ): void {
331331
global $wp_object_cache;
332332

333333
// Attempt to use the drop-in object cache method if it exists.
334-
if ( method_exists( $wp_object_cache, 'switch_to_blog' ) ) {
334+
if ( is_object( $wp_object_cache ) && method_exists( $wp_object_cache, 'switch_to_blog' ) ) {
335335
$wp_object_cache->switch_to_blog( $blog_id );
336336
return;
337337
}
@@ -340,6 +340,6 @@ function wp_cache_switch_to_blog( $blog_id ) {
340340
* Perform a fallback blog switch, which will reinitialize the caches
341341
* for the new blog ID.
342342
*/
343-
wp_cache_switch_to_blog_fallback( $blog_id );
343+
wp_cache_switch_to_blog_fallback();
344344
}
345345
endif;

src/wp-includes/class-avif-info.php

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
* Media Patent License 1.0 was not distributed with this source code in the
1010
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
1111
*
12-
* Note: this class is from libavifinfo - https://aomedia.googlesource.com/libavifinfo/+/refs/heads/main/avifinfo.php at f509487.
12+
* Note: this class is from libavifinfo - https://aomedia.googlesource.com/libavifinfo/+/refs/heads/main/avifinfo.php at 2b924de.
1313
* It is used as a fallback to parse AVIF files when the server doesn't support AVIF,
1414
* primarily to identify the width and height of the image.
1515
*
@@ -109,7 +109,7 @@ class Features {
109109
public $primary_item_id;
110110
public $primary_item_features = array( // Deduced from the data below.
111111
'width' => UNDEFINED, // In number of pixels.
112-
'height' => UNDEFINED, // Ignores mirror and rotation.
112+
'height' => UNDEFINED, // Ignores crop and rotation.
113113
'bit_depth' => UNDEFINED, // Likely 8, 10 or 12 bits per channel per pixel.
114114
'num_channels' => UNDEFINED // Likely 1, 2, 3 or 4 channels:
115115
// (1 monochrome or 3 colors) + (0 or 1 alpha)
@@ -256,6 +256,10 @@ public function parse( $handle, &$num_parsed_boxes, $num_remaining_bytes = MAX_S
256256
// Read the 32 least-significant bits.
257257
$this->size = read_big_endian( substr( $data, 4, 4 ), 4 );
258258
} else if ( $this->size == 0 ) {
259+
// ISO/IEC 14496-12 4.2.2:
260+
// if size is 0, then this box shall be in a top-level box
261+
// (i.e. not contained in another box)
262+
// Unfortunately the presence of a parent box is unknown here.
259263
$this->size = $num_remaining_bytes;
260264
}
261265
if ( $this->size < $header_size ) {
@@ -265,6 +269,9 @@ public function parse( $handle, &$num_parsed_boxes, $num_remaining_bytes = MAX_S
265269
return INVALID;
266270
}
267271

272+
// 16 bytes of usertype should be read here if the box type is 'uuid'.
273+
// 'uuid' boxes are skipped so usertype is part of the skipped body.
274+
268275
$has_fullbox_header = $this->type == 'meta' || $this->type == 'pitm' ||
269276
$this->type == 'ipma' || $this->type == 'ispe' ||
270277
$this->type == 'pixi' || $this->type == 'iref' ||
@@ -302,7 +309,7 @@ public function parse( $handle, &$num_parsed_boxes, $num_remaining_bytes = MAX_S
302309
( $this->type == 'auxC' && $this->version <= 0 );
303310
// Instead of considering this file as invalid, skip unparsable boxes.
304311
if ( !$is_parsable ) {
305-
$this->type = 'unknownversion';
312+
$this->type = 'skip'; // FreeSpaceBox. To be ignored by readers.
306313
}
307314
}
308315
// print_r( $this ); // Uncomment to print all boxes.
@@ -483,7 +490,7 @@ private function parse_ipco( $num_remaining_bytes ) {
483490
/**
484491
* Parses an "iprp" box.
485492
*
486-
* The "ipco" box contain the properties which are linked to items by the "ipma" box.
493+
* The "ipco" box contains the properties which are linked to items by the "ipma" box.
487494
*
488495
* @param stream $handle The resource the box will be parsed from.
489496
* @param int $num_remaining_bytes The number of bytes that should be available from the resource.
@@ -596,7 +603,7 @@ private function parse_iprp( $num_remaining_bytes ) {
596603
* @return Status FOUND on success or an error on failure.
597604
*/
598605
private function parse_iref( $num_remaining_bytes ) {
599-
do {
606+
while ( $num_remaining_bytes > 0 ) {
600607
$box = new Box();
601608
$status = $box->parse( $this->handle, $this->num_parsed_boxes, $num_remaining_bytes );
602609
if ( $status != FOUND ) {
@@ -656,7 +663,7 @@ private function parse_iref( $num_remaining_bytes ) {
656663
}
657664
}
658665
$num_remaining_bytes -= $box->size;
659-
} while ( $num_remaining_bytes > 0 );
666+
}
660667
return NOT_FOUND;
661668
}
662669

src/wp-includes/class-wp-connector-registry.php

Lines changed: 46 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
<?php
22
/**
3-
* Connectors API
4-
*
5-
* Defines WP_Connector_Registry class.
3+
* Connectors API: WP_Connector_Registry class.
64
*
75
* @package WordPress
86
* @subpackage Connectors
@@ -12,9 +10,23 @@
1210
/**
1311
* Manages the registration and lookup of connectors.
1412
*
13+
* This is an internal class. Use the public API functions to interact with connectors:
14+
*
15+
* - `wp_is_connector_registered()` — check if a connector exists.
16+
* - `wp_get_connector()` — retrieve a single connector's data.
17+
* - `wp_get_connectors()` — retrieve all registered connectors.
18+
*
19+
* Plugins receive the registry instance via the `wp_connectors_init` action
20+
* to register or override connectors directly.
21+
*
1522
* @since 7.0.0
1623
* @access private
1724
*
25+
* @see wp_is_connector_registered()
26+
* @see wp_get_connector()
27+
* @see wp_get_connectors()
28+
* @see _wp_connectors_init()
29+
*
1830
* @phpstan-type Connector array{
1931
* name: non-empty-string,
2032
* description: non-empty-string,
@@ -53,10 +65,22 @@ final class WP_Connector_Registry {
5365
/**
5466
* Registers a new connector.
5567
*
68+
* Validates the provided arguments and stores the connector in the registry.
69+
* For connectors with `api_key` authentication, a `setting_name` is automatically
70+
* generated using the pattern `connectors_ai_{$id}_api_key` (e.g., connector ID
71+
* `openai` produces `connectors_ai_openai_api_key`). This setting name is used
72+
* for the Settings API registration and REST API exposure.
73+
*
74+
* Registering a connector with an ID that is already registered will trigger a
75+
* `_doing_it_wrong()` notice and return `null`. To override an existing connector,
76+
* call `unregister()` first.
77+
*
5678
* @since 7.0.0
5779
*
58-
* @param string $id The unique connector identifier. Must contain only lowercase
59-
* alphanumeric characters and underscores.
80+
* @see WP_Connector_Registry::unregister()
81+
*
82+
* @param string $id The unique connector identifier. Must match the pattern
83+
* `/^[a-z0-9_]+$/` (lowercase alphanumeric and underscores only).
6084
* @param array $args {
6185
* An associative array of arguments for the connector.
6286
*
@@ -175,8 +199,17 @@ public function register( string $id, array $args ): ?array {
175199
/**
176200
* Unregisters a connector.
177201
*
202+
* Returns the connector data on success, which can be modified and passed
203+
* back to `register()` to override a connector's metadata.
204+
*
205+
* Triggers a `_doing_it_wrong()` notice if the connector is not registered.
206+
* Use `is_registered()` to check first when the connector may not exist.
207+
*
178208
* @since 7.0.0
179209
*
210+
* @see WP_Connector_Registry::register()
211+
* @see WP_Connector_Registry::is_registered()
212+
*
180213
* @param string $id The connector identifier.
181214
* @return array|null The unregistered connector data on success, null on failure.
182215
*
@@ -237,6 +270,9 @@ public function is_registered( string $id ): bool {
237270
*
238271
* Do not use this method directly. Instead, use the `wp_get_connector()` function.
239272
*
273+
* Triggers a `_doing_it_wrong()` notice if the connector is not registered.
274+
* Use `is_registered()` to check first when the connector may not exist.
275+
*
240276
* @since 7.0.0
241277
*
242278
* @see wp_get_connector()
@@ -272,9 +308,14 @@ public static function get_instance(): ?self {
272308
/**
273309
* Sets the main instance of the registry class.
274310
*
311+
* Called by `_wp_connectors_init()` during the `init` action. Must not be
312+
* called outside of that context.
313+
*
275314
* @since 7.0.0
276315
* @access private
277316
*
317+
* @see _wp_connectors_init()
318+
*
278319
* @param WP_Connector_Registry $registry The registry instance.
279320
*/
280321
public static function set_instance( WP_Connector_Registry $registry ): void {

0 commit comments

Comments
 (0)