Introduces `WP_Connector_Registry` class and a `wp_connectors_init` action hook so plugins can register their own connectors alongside the built-in defaults (Anthropic, Google, OpenAI).
Key changes:
* `WP_Connector_Registry` — A `final` singleton class managing connector registration and lookup, with validation for IDs, required fields, and authentication methods.
* `wp_connectors_init` action — Fired during `init` after built-in connectors are registered. Passes the registry instance so plugins call `$registry->register()` directly.
* `_wp_connectors_init()` — Private function that creates the registry, merges hardcoded defaults with AI Client registry data, registers them, then fires the action.
* Public read-only functions — `wp_is_connector_registered()`, `wp_get_connector()`, `wp_get_connectors()` for querying the registry after initialization.
* Logo URL support — Connectors can include an optional `logo_url` field resolved from plugin directories via `_wp_connectors_resolve_ai_provider_logo_url()`.
* Timing guards — `set_instance()` rejects calls after `init` completes. Registration is only possible during `wp_connectors_init`.
* Connector API key settings are now only registered when the provider exists in the AI Client registry.
* Refactors `_wp_connectors_get_connector_settings()` to read from the registry via `wp_get_connectors()`.
Developed in https://github.com/WordPress/wordpress-develop/pull/11175
Props gziolo, flixos90, mukesh27, westonruter.
Fixes#64791.
Built from https://develop.svn.wordpress.org/trunk@61943
git-svn-id: http://core.svn.wordpress.org/trunk@61225 1a063a9b-81f0-0310-95a4-ce76da25c4cd
Adds `wp-includes/connectors.php` (loaded from `wp-settings.php`) and registers
a Settings > Connectors submenu when the AI client and Connectors admin page
renderer are available.
Registers connector API key settings in `/wp/v2/settings`, masks key values on
option reads, validates keys against provider configuration, and returns
`invalid_key` for explicitly requested connector fields when validation fails.
Stored connector keys are also passed to the AI client registry on init.
Gutenberg PR at https://github.com/WordPress/gutenberg/pull/75833.
Developed in https://github.com/WordPress/wordpress-develop/pull/11056.
Props jorgefilipecosta, gziolo, flixos90, justlevine, westonruter, jeffpaul, JasonTheAdams, audrasjb, shaunandrews, noruzzaman, mukesh27.
Fixes#64730.
Built from https://develop.svn.wordpress.org/trunk@61749
git-svn-id: http://core.svn.wordpress.org/trunk@61055 1a063a9b-81f0-0310-95a4-ce76da25c4cd
The WordPress AI Client is a provider-agnostic API for WordPress code to call generative AI models via a consistent interface. Plugins and Core can use it to provide AI driven features for users, while users maintain full autonomy in choosing which AI provider(s) they want to rely on and how they configure them.
This changeset merges the technical foundation for the WordPress AI Client into Core. This foundation was originally implemented in the https://github.com/WordPress/wp-ai-client package, which will be sunset going forward. The underlying https://github.com/WordPress/php-ai-client package is bundled with this changeset and will remain a separate library maintained by the WordPress project, for WordPress Core and the PHP ecosystem.
No AI providers are bundled out of the box. Without explicit configuration and explicit calling code, WordPress will not send prompts or data to any external service. Site owners will be able to install plugins to enable usage of specific AI providers, built on top of this foundation.
This is the first changeset of two that are most relevant for the AI Client feature. The subsequent change will introduce a configuration screen for different AI providers, where users can install provider plugins, configure their credentials, and enable the canonical WordPress AI plugin. Together, this infrastructure and UI will enable the WordPress ecosystem to build AI features in a seamless and interoperable way.
Original merge proposal: https://make.wordpress.org/core/2026/02/03/proposal-for-merging-wp-ai-client-into-wordpress-7-0/
Props jason_the_adams, flixos90, desrosj, dkotter, jorgefilipecosta, peterwilsoncc, johnbillion, jorbin, swissspidy, isotropic.
See #64591.
Built from https://develop.svn.wordpress.org/trunk@61700
git-svn-id: http://core.svn.wordpress.org/trunk@61008 1a063a9b-81f0-0310-95a4-ce76da25c4cd
Syncs/merges the PHP changes from the Gutenberg PR https://github.com/WordPress/gutenberg/pull/75366.
In Gutenberg, we have added support for real-time collaboration using CRDT documents (via the [Yjs library](https://yjs.dev/)). This work has suggested the following additions to WordPress:
1. A default "sync provider" based on HTTP polling that allows collaborators to share updates with each other. Previously, we relied on WebRTC connections between collaborators for this purpose, but it proved unreliable under many network conditions.
- Our solution is designed to work on any WordPress installation.
- HTTP polling is the transport we identified as most likely to work universally.
- Given the isolation and lifecycle of PHP processes, updates must be stored centrally in order to be shared among peers. We have chosen to store updates in post meta against a special post type, but alternate storage mechanisms are possible.
- Collaborative editing can involve syncing multiple CRDT documents. To limit the number of connections consumed by this provider, requests are batched.
- To prevent unbounded linear growth, updates are periodically compacted.
- To avoid excessive load on lower-resourced hosts, this provider will benefit from usage limits (e.g., a maximum of three connected collaborators) enforced by the client (Gutenberg).
2. A new registered post meta that allows Gutenberg to persist CRDT documents alongside posts.
- This provides all collaborators with a "shared starting point" for the collaborative session, which avoids duplicate updates.
- Content stored in the WordPress database always remains the source of truth. If the content differs from the persisted CRDT document, the CRDT document is updated to match the database.
3. A new Writing setting that allows users to opt-in to real-time collaboration.
- Enabling real-time collaboration disables post lock functionality and connects users to the sync provider.
4. A behavior change to autosaves is needed. When the the original author is editing a draft post (post_status == 'draft' OR 'auto-draft') and they hold the post lock, the autosave targets the actual post instead of an autosave revision. This puts the post data and the persisted CRDT document out of sync and leads to duplicate updates. When real-time collaboration is enabled, all collaborators must autosave in the same way.
This PR provides a proposed implementation of the changes above. This corresponding Gutenberg PR moves the work from the `experimental` directory to `lib/compat`:
https://github.com/WordPress/gutenberg/pull/75366
Cumulative work to add this functionality can be found using this label:
https://github.com/WordPress/gutenberg/issues?q=label%3A%22%5BFeature%5D%20Real-time%20Collaboration%22%20is%3Apr
Developed https://github.com/WordPress/wordpress-develop/pull/10894.
Props czarate, paulkevan, ellatrix, timothyblynjacobs, westonruter, jorgefilipecosta, mindctrl.
Fixes#64622.
Built from https://develop.svn.wordpress.org/trunk@61689
git-svn-id: http://core.svn.wordpress.org/trunk@60997 1a063a9b-81f0-0310-95a4-ce76da25c4cd
Introduces a registry class to mediate access to a library of SVG icons. These
icons can be queried by directly interfacing with the singleton class
`WP_Icons_Registry`, or via the REST API using the following GET endpoints:
- /wp/v2/icons
- /wp/v2/icons/$name, e.g. /wp/v2/icons/core/audio
Modifies the Gutenberg-to-Core copy process to copy from `@wordpress/icons`:
- the icons (SVG files) to `wp-includes/icons/library/*.svg`
- the manifest file to `wp-includes/icons/manifest.php`
For 7.0, the registry remains closed to third-party icons, serving only core
icons per the manifest file.
Together, these APIs power the new Icon block.
Developed in https://github.com/WordPress/gutenberg/pull/72215
Developed in https://github.com/WordPress/gutenberg/pull/74943
Developed in https://github.com/WordPress/wordpress-develop/pull/10909
Props mcsf, wildworks, fabiankaegy, joen, jorgefilipecosta, ntsekouras.
Fixes#64651.
Built from https://develop.svn.wordpress.org/trunk@61674
git-svn-id: http://core.svn.wordpress.org/trunk@60982 1a063a9b-81f0-0310-95a4-ce76da25c4cd
The work in [61438] for Core-64393 removed the block parser classes from Core, which caused numerous scripts to fail because they were missing. Conditional checks were added in [61492] which left WordPress in an inoperable state.
This patch restores the block parser in Core, in preparation for work to remove it from Gutenberg (in a separate patch).
Ironically, the files were removed because the new build was copying them over from Gutenberg and the intent was to avoid having two sources of truth, but this was previously the existing mechanism, so having done nothing to the parser files would have left the status quo. This patch removes the problems originally created by removing the files. They will not be copied from Gutenberg any more and the only source of truth will be Core.
Until removed from Gutenberg, because of the build changes, any changes made on the Gutenberg side will be lost unless manually copied over.
Developed in: https://github.com/WordPress/wordpress-develop/pull/10761
Discussed in: https://core.trac.wordpress.org/ticket/64521
Follow-up to [61438], [61492].
Props dmsnell, mcsf, mukesh27, youknowriad.
Fixes#64521.
Built from https://develop.svn.wordpress.org/trunk@61504
git-svn-id: http://core.svn.wordpress.org/trunk@60815 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This changeset improves the Gutenberg build integration to simplify the developer workflow and reinstore a flow similar to how package dependencies worked before the Gutenberg checkout-and-build approach was introduced.
Key improvements:
* Automatic rebuild on ref change: Adds a new `gutenberg:sync` script that stores a hash of the built ref in `.gutenberg-hash` and only rebuilds when the ref changes.
* Full integration on `npm install`: Running `npm install` now produces a fully working development environment with Gutenberg assets in `src/`.
* Clean Gutenberg checkout: Restores Gutenberg's `package.json` after the build completes.
* Stops copying `.js.map` files to `wp-includes/js/dist` since they reference non-existent paths.
* Remove package.json files from the build folder.
* Avoid closures and use prefixed functions.
* Updates build checks to use `jquery.js` instead of `edit-post.js` as the build indicator.
Props youknowriad, ellatrix, mcsf, dmsnell, ntsekouras, jorgefilipecosta, tobiasbg, peterwilsoncc.
Fixes#64393.
Built from https://develop.svn.wordpress.org/trunk@61492
git-svn-id: http://core.svn.wordpress.org/trunk@60803 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This changeset enables smooth transitions between the different admin screens. For the admin menu items, distinct view transition names are used to facilitate a simple visual slide effect when the active submenu changes between screens.
Props westonruter, mukesh27, joedolson.
Fixes#64470.
Built from https://develop.svn.wordpress.org/trunk@61491
git-svn-id: http://core.svn.wordpress.org/trunk@60802 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This changes WordPress Core's Gutenberg integration from npm packages to checking out and building Gutenberg directly. Instead of syncing individual npm packages, Core now checks out the Gutenberg repository, builds it, and copies the build artifacts.
This enables Core to use Gutenberg's advanced features like route-based navigation, full-page rendering, and the Font Library, while also streamlining future updates.
New commands:
* `npm run gutenberg:checkout` - Clones Gutenberg at a specified ref
* `npm run gutenberg:build` - Runs Gutenberg's build process
* `npm run gutenberg:copy` - Copies and transforms build output to Core
* `npm run gutenberg:integrate` - Runs all three steps
Main changes:
* Removes webpack configs replaced by Gutenberg's build (blocks.js, packages.js, script-modules.js, development.js, vendors.js)
* Adds Font Library page (`/wp-admin/font-library.php`)
* Adds copy scripts to transform Gutenberg plugin paths to Core paths
* Moves vendor copy step from webpack to Gruntfile
New year, new process. Happy New Year!
Props youknowriad, ellatrix, sirreal, westonruter, desrosj, tellthemachines.
Fixes#64393.
Built from https://develop.svn.wordpress.org/trunk@61438
git-svn-id: http://core.svn.wordpress.org/trunk@60750 1a063a9b-81f0-0310-95a4-ce76da25c4cd
Without this patch we would introduce the Abilities API without any core abilities being registered.
This patch includes the following initial abilities:
- core/get-bloginfo - Retrieve individual site information fields (name, description, url, wpurl, admin_email, charset, language, version).
- core/get-current-user-info - Get current authenticated user data (id, display_name, user_nicename, user_login, roles, locale).
- core/get-environment-type - Get WordPress environment type (production, staging, development, local).
Developed in #10411.
Follow-up [64098].
Props gziolo, jorgefilipecosta, mukesh27, isotropic, jorbin, justlevine, jason_the_adams.
Fixes#64146.
Built from https://develop.svn.wordpress.org/trunk@61063
git-svn-id: http://core.svn.wordpress.org/trunk@60399 1a063a9b-81f0-0310-95a4-ce76da25c4cd
Introduces a new REST API endpoint at `wp-abilities/v1/categories` to expose
ability categories through the WordPress REST API.
The new `WP_REST_Abilities_V1_Categories_Controller` provides:
- GET `/wp-abilities/v1/categories` - Lists all ability categories with pagination
- GET `/wp-abilities/v1/categories/{slug}` - Retrieves a single category by slug
Both endpoints require the `read` capability and return category data including
slug, label, description, and metadata. The collection endpoint supports pagination
with `page` and `per_page` parameters (default: 50, max: 100).
Developed in https://github.com/WordPress/wordpress-develop/pull/10380.
Follow-up [61032].
Props gziolo, jason_the_adams, timothyblynjacobs.
Fixes#64098.
Built from https://develop.svn.wordpress.org/trunk@61045
git-svn-id: http://core.svn.wordpress.org/trunk@60381 1a063a9b-81f0-0310-95a4-ce76da25c4cd
* Adds the `active_templates` setting, which is an object holding the template slug as a key and template post ID as the value.
* To maintain backwards compatibility, any `wp_template` (post type) not created through the new API will be activated.
* `get_block_template` and `get_block_templates` have been adjusted to check `active_templates`. These functions should never return inactive templates, just like before, to maintain backwards compatibility.
* The pre-existing `/templates` endpoint and sub-endpoints remain and work exactly as before.
* A new endpoint `/wp_template` has been added, but this is just a regular posts controller (`WP_REST_Posts_Controller`). We do register an additional `theme` field and expose the `is_wp_suggestion` meta.
* Another new endpoint `/wp_registered_template` has been added, which is read-only and lists the registered templates from themes and plugin (un-edited, without activations applied).
These changes are to be iterated on.
See https://github.com/WordPress/wordpress-develop/pull/8063.
Props ellatrix, shailu25, ntsekouras.
Fixes#62755.
Built from https://develop.svn.wordpress.org/trunk@61029
git-svn-id: http://core.svn.wordpress.org/trunk@60365 1a063a9b-81f0-0310-95a4-ce76da25c4cd
Add a new `core/term-data` source to make information about a taxonomy term available for use in Block Bindings.
Additionally, expose a post object's permalink through the `core/post-data` source.
Props bernhard-reiter, get_dave, jeryj, cbravobernal.
Fixes#64107.
Built from https://develop.svn.wordpress.org/trunk@60946
git-svn-id: http://core.svn.wordpress.org/trunk@60282 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This is the fourth in a series of patches to modernize and standardize UTF-8 handling.
`wp_check_invalid_utf8()` has long been dependent on the runtime configuration of the system running it. This has led to hard-to-diagnose issues with text containing invalid UTF-8. The function has also had an apparent defect since its inception: when requesting to strip invalid bytes it returns an empty string.
This patch updates the function to remove all dependency on the system running it. It defers to the `mbstring` extension if that’s available, falling back to the new UTF-8 scanning pipeline.
To support this work, `wp_scrub_utf8()` is created with a proper fallback so that the remaining logic inside of `wp_check_invalid_utf8()` can be minimized. The defect in this function has been fixed, but instead of stripping the invalid bytes it will replace them with the Unicode replacement character for stronger security guarantees.
Developed in https://github.com/WordPress/wordpress-develop/pull/9498
Discussed in https://core.trac.wordpress.org/ticket/63837
Follow-up to: [60768].
Props askapache, chriscct7, Cyrille37, desrosj, dmsnell, helen, jonsurrell, kitchin, miqrogroove, pbearne, shailu25.
Fixes#63837, #29717.
See #63863.
Built from https://develop.svn.wordpress.org/trunk@60793
git-svn-id: http://core.svn.wordpress.org/trunk@60129 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This is the second in a series of patches to modernize and standardize UTF-8 handling.
When the fallback UTF-8 validation code was added it was placed inside formatting.php; however, that validation logic can be reused for a number of related UTF-8 functions. To faciliate this it should move into a new location and be loaded early. This patch is the first half of doing that, whereby the original fallback function is moved unchanged to the `compat-utf8.php` module. The follow-up patch will abstract the UTF-8 scanning logic for reuse. Splitting this into a move and a separate change involves an extra step, but faciliates tracking the heritage of the code through the changes.
Developed in https://github.com/WordPress/wordpress-develop/pull/9825
Discussed in https://core.trac.wordpress.org/ticket/63863
Follow-up to: [60630].
See #63863.
Built from https://develop.svn.wordpress.org/trunk@60743
git-svn-id: http://core.svn.wordpress.org/trunk@60079 1a063a9b-81f0-0310-95a4-ce76da25c4cd
Add a new Block Bindings source, `core/post-data`, which exposes `date` and `modified` fields for now -- reflecting the publish date and the last modified date of the post, respectively. The source could be subsequently extended to include other fields associated with a post object, such as title, featured image, etc.
Props bernhard-reiter.
Closes#63741.
Built from https://develop.svn.wordpress.org/trunk@60539
git-svn-id: http://core.svn.wordpress.org/trunk@59875 1a063a9b-81f0-0310-95a4-ce76da25c4cd
Adds server-side registration for `ariaLabel` block support and its required fields. Fully enabling feature support for dynamic blocks and consumers using `ServerSideRender` component.
Props wildworks, fabiankaegy, joemcgill, poena.
Fixes#62919.
Built from https://develop.svn.wordpress.org/trunk@59925
git-svn-id: http://core.svn.wordpress.org/trunk@59267 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This changeset adds support for the Speculation Rules API and configures it by default to `prefetch` certain links with an eagerness of `conservative`, leading to improved performance by starting to load URLs before the user lands on them.
The new `WP_Speculation_Rules` class is a container class representing the set of used speculation rules. By default, WordPress Core will only add a single speculation rule, which results in most links being prefetched conservatively.
The behavior of that main speculation rule can be altered by using the new `wp_speculation_rules_configuration` filter, which receives an associative array with `mode` and `eagerness` keys, or `null`. Both `mode` and `eagerness` have a default value of `auto`, which for now will result in the aforementioned behavior. The value `null` is used by default in certain scenarios such as when the current user is logged in. Developers can explicitly provide supported mode values (`prefetch` or `prerender`) and other supported eagerness values (`conservative`, `moderate`, or `eager`) to override and enforce the respective behaviors, or return `null` to disable speculative loading feature (either unconditionally or for certain situations). The Speculative Loading feature plugin for example, which this feature is based on, will make use of this filter to continue to use mode `prerender` and eagerness `moderate` by default. Developers can call the `wp_get_speculation_rules_configuration()` function to check how speculative loading is configured on the WordPress site.
Another important filter introduced is `wp_speculation_rules_href_exclude_paths`, which allows to expand the list of URL patterns that are excluded from being prefetched or prerendered per WordPress Core's main speculation rule configuration. Several URL patterns such `/wp-admin/*` (any URL within WP Admin) or `/*\\?(.+)` (any URL that includes query parameters) are already excluded by default. Plugins that use content that would be preferable not to prefetch or prerender can use the filter to provide corresponding URL patterns.
More advanced customization is possible by adding further speculation rules that will be loaded in addition to WordPress Core's main speculation rule. This can be achieved via the new `wp_load_speculation_rules` action, which receives the `WP_Speculation_Rules` class instance and can amend it as needed.
Props flixos90, westonruter, joemcgill, desrosj, mukesh27, tunetheweb, thelovekesh, adamsilverstein, swissspidy, domenicdenicola, jeremyroman.
Fixes#62503.
Built from https://develop.svn.wordpress.org/trunk@59837
git-svn-id: http://core.svn.wordpress.org/trunk@59179 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This extension provides the `hash()` function and support for the SHA-256 algorithm, both of which are required for upcoming security related changes. This extension is almost universally enabled, however it is technically possible to disable it on PHP 7.2 and 7.3, hence the introduction of this requirement and the corresponding requirement checks prior to installing or upgrading WordPress.
Props peterwilsoncc, ayeshrajans, dd32, SergeyBiryukov, johnbillion.
Fixes#60638, #62815, #56017
See #21022
Built from https://develop.svn.wordpress.org/trunk@59803
git-svn-id: http://core.svn.wordpress.org/trunk@59145 1a063a9b-81f0-0310-95a4-ce76da25c4cd
Partially reverts [59479] and [59461], which previously tried to move some functions from `wp-admin/includes/plugin.php` to `wp-includes/functions.php` so they are available early, so that `get_plugin_data()` can be used.
However, other functions from that file are often used by plugins without necessarily checking whether they are available, easily causing fatal errors. Requiring this file directly is a safer approach to avoid such errors.
Props peterwilsoncc, dd32, swissspidy, johnbillion.
Fixes#62244.
Built from https://develop.svn.wordpress.org/trunk@59488
git-svn-id: http://core.svn.wordpress.org/trunk@58874 1a063a9b-81f0-0310-95a4-ce76da25c4cd
The file could declare its own `$theme` variable, which would override the one used in the `foreach` loop.
To prevent this, call `wp_get_theme()` before loading the file and store the instance in a different variable.
Props neo2k23, swissspidy.
See #62244.
Built from https://develop.svn.wordpress.org/trunk@59466
git-svn-id: http://core.svn.wordpress.org/trunk@58852 1a063a9b-81f0-0310-95a4-ce76da25c4cd
In #34114, just-in-time (JIT) translation loading was implemented for projects hosted on WordPress.org. This is now expanded to all other plugins/themes.
Projects with a custom `Text Domain` and `Domain Path` header no longer need to call `load_plugin_textdomain()` or `load_theme_textdomain()`.
This reduces the risk of calling them too late, after some translation calls already happened, and generally makes it easier to properly internationalize a plugin or theme.
This moves the `get_plugin_data()` from `wp-admin/includes/plugin.php` to `wp-includes/functions.php` so it's available during the plugin loading process.
Props swissspidy.
Fixes#62244.
Built from https://develop.svn.wordpress.org/trunk@59461
git-svn-id: http://core.svn.wordpress.org/trunk@58847 1a063a9b-81f0-0310-95a4-ce76da25c4cd
Typically, when registering a new block type, its metadata is read from the provided `block.json` file. The more block types are registered on a site, the more costly becomes this process, as it involves filesystem reads and parsing JSON.
WordPress Core's built-in blocks have in the past worked around that by having a auto-generated PHP manifest file that includes the already parsed JSON data for all blocks. This changeset effectively allows plugins to do the same, by introducing a new API function `wp_register_block_metadata_collection()`. The WordPress Core block manifest is now handled using this API as well, rather than custom logic baked into `register_block_type_from_metadata()`.
The `wp_register_block_metadata_collection()` function requires two parameters:
* `$path`: The base path in which block files for the collection reside.
* `$manifest`: The path to the manifest file for the collection.
Every `block.json` file that is supposed to be part of the collection must reside within the provided `$path`, within its own block-specific directory matching the block name (without the block namespace). For example, for a collection `$path` of `/wp-content/plugins/test-plugin` and a block `test-plugin/testimonial`, the block file could be `/wp-content/plugins/test-plugins/blocks/testimonial/block.json`.
It is recommended that plugins use the new API function for enhanced performance, especially if they register several block types. However, the use of the function is entirely optional. Not using it will not result in any difference in user-facing behavior.
Props mreishus, flixos90, gziolo, spacedmonkey, azaozz, mukesh27.
Fixes#62002.
Built from https://develop.svn.wordpress.org/trunk@59132
git-svn-id: http://core.svn.wordpress.org/trunk@58528 1a063a9b-81f0-0310-95a4-ce76da25c4cd
PHP 8.4 deprecates the use of `trigger_errror()` with `E_USER_ERROR` as the error level, as there are a number of gotchas to this way of creating a `Fatal Error` (`finally` blocks not executing, destructors not executing). The recommended replacements are either to use exceptions or to do a hard `exit`.
WP has its own `wp_trigger_error()` function, which under the hood calls `trigger_error()`. If passed `E_USER_ERROR` as the `$error_level`, this will hit the PHP 8.4 deprecation.
Now, there were basically three options:
* Silence the deprecation until PHP 9.0 and delay properly solving this until then. This would lead to an awkward solution, as prior to PHP 8.0, error silencing would apply to all errors, while, as of PHP 8.0, it will no longer apply to fatal errors. It also would only buy us some time and wouldn't actually solve anything.
* Use `exit($status)` when `wp_trigger_error()` is called with `E_USER_ERROR`. This would make the code untestable and would disable handling of these errors via custom error handlers, which makes this an undesirable solution.
* Throw an exception when `wp_trigger_error()` is called with `E_USER_ERROR`. This makes for the most elegant solution with the least BC-breaking impact, though it does open it up to the error potential being "caught" via a `try-catch`. That's not actually a bad thing and is likely to only happen for those errors which can be worked around, in which case, it's a bonus that that's now possible.
The third option is implemented which:
* Introduces a new `WP_Exception` class.
* Starts using `WP_Exception` in the `wp_trigger_error()` function when the `$error_level` is set to `E_USER_ERROR`.
This change is covered by pre-existing tests, which have been updated to expect the exception instead of a PHP error.
Why not use `WP_Error`?
Well, for one, this would lead to completely different behaviour (BC).
As `WP_Error` doesn't extend `Exception`, the program would not be stopped, but would continue running, which would be a much bigger breaking change and carries security risks. `WP_Error` also doesn't natively trigger displaying/logging of the error message, so in that case, it would still need an `exit` with the error message, bringing us back to point 2 above.
Introducing `WP_Exception` provides (essentially) the same behaviour in that it retains the fatal error and error message displaying/logging behaviors. It also introduces a base Exception class, from which future exception classes can extend.
References:
* https://wiki.php.net/rfc/deprecations_php_8_4#deprecate_passing_e_user_error_to_trigger_error
* https://www.php.net/manual/en/migration80.incompatible.php
Follow-up to [56530].
Props jrf, hellofromTonya.
See #62061.
Built from https://develop.svn.wordpress.org/trunk@59107
git-svn-id: http://core.svn.wordpress.org/trunk@58503 1a063a9b-81f0-0310-95a4-ce76da25c4cd
HTML is a kind of short-hand for a DOM structure. This means that there are
many cases in HTML where an element's opening tag or closing tag is missing (or
both). This is because many of the parsing rules imply creating elements in the
DOM which may not exist in the text of the HTML.
The HTML Processor, being the higher-level counterpart to the Tag Processor, is
already aware of these nodes, but since it's inception has not paused on them
when scanning through a document. Instead, these are visible when pausing on a
child of such an element, but otherwise not seen.
In this patch the HTML Processor starts exposing those implicitly-created nodes,
including opening tags, and closing tags, that aren't foudn in the text content
of the HTML input document.
Previously, the sequence of matched tokens when scanning with
`WP_HTML_Processor::next_token()` would depend on how the HTML document was written,
but with this patch, all semantically equal HTML documents will parse and scan in
the same exact manner, presenting an idealized or "perfect" view of the document
the same way as would occur when traversing a DOM in a browser.
Developed in https://github.com/WordPress/wordpress-develop/pull/6348
Discussed in https://core.trac.wordpress.org/ticket/61348
Props audrasjb, dmsnell, gziolo, jonsurrell.
Fixes#61348.
Built from https://develop.svn.wordpress.org/trunk@58304
git-svn-id: http://core.svn.wordpress.org/trunk@57761 1a063a9b-81f0-0310-95a4-ce76da25c4cd
Provides a custom decoder for strings coming from HTML attributes and
markup. This custom decoder is necessary because of deficiencies in
PHP's `html_entity_decode()` function:
- It isn't aware of 720 of the possible named character references in
HTML, leaving many out that should be translated.
- It isn't aware of the ambiguous ampersand rule, which allows
conversion of character references in certain contexts when they
are missing their closing `;`.
- It doesn't draw a distinction for the ambiguous ampersand rule
when decoding attribute values instead of markup values.
- Use of `html_entity_decode()` requires manually passing non-default
paramter values to ensure it decodes properly.
This decoder also provides some conveniences, such as making a
single-pass and interruptable decode operation possible. This will
provide a number of opportunities to optimize detection and decoding
of things like value prefixes, and whether a value contains a given
substring.
Developed in https://github.com/WordPress/wordpress-develop/pull/6387
Discussed in https://core.trac.wordpress.org/ticket/61072
Props dmsnell, gziolo, jonsurrell, jorbin, westonruter, zieladam.
Fixes#61072.
Built from https://develop.svn.wordpress.org/trunk@58281
git-svn-id: http://core.svn.wordpress.org/trunk@57741 1a063a9b-81f0-0310-95a4-ce76da25c4cd
Updated the global styles endpoints in the REST API to extend from existing posts and revisions controllers. This reduces duplicated code and inconsistencies. The revisions controller is now a subclass of the `WP_REST_Revisions_Controller`. Related redundant methods were removed and schema generation and collection parameters were adjusted to suit the global styles context. Updated permission checks, constructor, and collection parameters accordingly. This change allows for easy override of these classes using the `register_post_type_args` filter.
This reintroduces [57624] (reverted in [57628]) with improved backward compatibility and further enhancements.
Props ramonopoly, spacedmonkey, mukesh27, swissspidy.
Fixes#60131.
Built from https://develop.svn.wordpress.org/trunk@58225
git-svn-id: http://core.svn.wordpress.org/trunk@57688 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This caused issues in maintenance mode, and it's not warranted to have
its own module. This will live alongside `_canonical_charset()`, it's
partner function.
Fixes: #61182.
Props: dmsnell, sergeybiryukov, swisspiddy.
Follow-up to: [58148].
Built from https://develop.svn.wordpress.org/trunk@58169
git-svn-id: http://core.svn.wordpress.org/trunk@57632 1a063a9b-81f0-0310-95a4-ce76da25c4cd
There are several exist places in Core that attempt to detect if a blog charset
is UTF-8. Each place attempts to perform the same check, except the logic is
spread throughout and there's no single method provided to make this
determination in a consistent way. The `_canonical_charset()` method exists,
but is marked private for use.
In this patch the new `unicode` module provides `is_utf8_charset()` as a method
taking an optional charset slug and indicating if it represents UTF-8,
examining all of the allowable variants of that slug. Associated code is
updated to use this new function, including `_canonical_charset()`. If no slug
is provided, it will look up the current `get_option( 'blog_charset' )`.
Finally, the test functions governing `_canonical_charset()` have been
rewritten as a single test with a data provider instead of as separate test
functions.
Developed in https://github.com/WordPress/wordpress-develop/pull/6535
Discussed in https://core.trac.wordpress.org/ticket/61182Fixes#61182.
Props dmsnell, jonsurrell.
Built from https://develop.svn.wordpress.org/trunk@58147
git-svn-id: http://core.svn.wordpress.org/trunk@57612 1a063a9b-81f0-0310-95a4-ce76da25c4cd
Removes the `WP_Translation_Controller::set_locale()` call from `wp-settings.php`, which happened before the current user was loaded.
That caused translations to be missing when the site locale and user locale were different, as the translation was associated with the wrong locale.
Turns out this call was not needed at all, as the locale will be set/updated when calling `load_textdomain()` anyway.
Props oglekler.
See #59656.
Built from https://develop.svn.wordpress.org/trunk@57704
git-svn-id: http://core.svn.wordpress.org/trunk@57205 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This fixes a bug introduced by [57129] and [56635] in which deprecating the previous `TEMPLATEPATH` and `STYLESHEETPATH` constants in favor of `get_template_directory()` and `get_stylesheet_directory()` functions caused the active theme template path to change when using `switch_to_blog()`.
This introduces a new function, `wp_set_template_globals()`, which is called during the bootstrap process to store the template paths to new globals values `$wp_template_path` and `$wp_stylesheet_path`. This restores behavior to how things worked prior to [56635] but retains the ability for template values to be reset for better testability.
Related #18298, #60025.
Props joemcgill, flixos90, mukesh27, swissspidy, manfcarlo, metropolis_john, jeremyfelt.
Fixes#60290.
Built from https://develop.svn.wordpress.org/trunk@57685
git-svn-id: http://core.svn.wordpress.org/trunk@57186 1a063a9b-81f0-0310-95a4-ce76da25c4cd
Ensures that `wp_is_block_theme()` is not called too early before the themes are fully setup.
This addresses an issue where a parent theme was mistakenly marked as being missing.
Props scruffian, youknowriad, swissspidy, poena, dennysdionigi, bgardner, westonruter.
Fixes#60411.
Built from https://develop.svn.wordpress.org/trunk@57661
git-svn-id: http://core.svn.wordpress.org/trunk@57162 1a063a9b-81f0-0310-95a4-ce76da25c4cd