PHP Native JSON Extension Now Required

The PHPPHP The web scripting language in which WordPress is primarily architected. WordPress requires PHP 7.4 or higher native JSONJSON JSON, or JavaScript Object Notation, is a minimal, readable format for structuring data. It is used primarily to transmit data between a server and web application, as an alternative to XML. extension has been bundled and compiled with PHP by default since 5.2.0 (2006). However, a significant number of PHP installs did not include it. In order to ensure a consistent experience for JSON related functionality in all supported versions of PHP, WordPress CoreCore Core is the set of software required to run WordPress. The Core Development Team builds WordPress. has historically included a large number of workarounds, functions, and polyfills.

In 2011 (WordPress 3.2), an attempt was made to remove JSON related compatibility code. However, it was discovered that a fair number of distributions were still missing the PHP JSON extension by default, and the removed code was restored to ensure compatibility.

In WordPress 5.2, the minimum version of PHP supported was raised from 5.2.6 to 5.6.20. In the 8 year period since the last attempt was made to encourage use of the PHP native JSON extension, the number of distributions with this extension disabled has significantly decreased.

Because of this, the PHP native JSON extension is now required to run WordPress 5.3 and higher.

To prevent compatibility issues, a site that does not have the PHP native JSON extension enabled will see an error message when attempting to upgrade to WordPress 5.3. The update will be cancelled and the site will remain on the current version (see [46455]). This is to prevent potential compatibility issues on servers running custom PHP configurations.

Here’s a summary of what has changed.

Deprecated

The following functions and classes will remain in the code base, but will trigger a deprecated warning when used (see [46205]):

  • The Services_JSON and Services_JSON_Error classes and all methods
  • The wp-includes/class-json.php file
  • The (private) _wp_json_prepare_data() function

Removed

The following functions, and classes have been removed entirely from the code base (see the [46208] changeset):

  • json_encode() function polyfill
  • json_decode() function polyfill
  • _json_decode_object_helper() function polyfill
  • json_last_error_msg() polyfill
  • JsonSerializable interface polyfill
  • $wp_json global variable
  • JSON_PRETTY_PRINT constant polyfill
  • JSON_ERROR_NONE constant polyfill

Unchanged

The wp_json_encode() function will remain with no intention to deprecate it at this time. This function includes an extra sanity check for JSON encoding data and should still be used as the preferred way to encode data into JSON.

For more information about these changes, check out #47699 on TracTrac An open source project by Edgewall Software that serves as a bug tracker and project management tool for WordPress. and the relevant changesets ([46205], [46206], [46208], [46377], and [46455]).

Props @jrf & @jorbin for peer review.

#5-3, #dev-notes, #php

Enhancements to the Network Sites Screen in WordPress 5.3

Changes to the database

The introduction of Site metadata in WordPress 5.1 has opened up a lot of new possibilities for multisitemultisite Used to describe a WordPress installation with a network of multiple blogs, grouped by sites. This installation type has shared users tables, and creates separate database tables for each blog (wp_posts becomes wp_0_posts). See also network, blog, site.

Save database version and date updated in multisite site metaMeta Meta is a term that refers to the inside workings of a group. For us, this is the team that works on internal WordPress sites like WordCamp Central and Make WordPress.

In [46193], the database version and the updated dates are now stored in the blogmeta table.

If your setup of multisite requires the database version to be accessed from a global context, instead of looping around every site with an expensive switch_to_blog call to get_option( 'db_version' ), you maybe want to try a function like the following.

function get_site_versions() {
	global $wpdb;
	$query = $wpdb->prepare( "SELECT blog_id, meta_value FROM $wpdb->blogmeta WHERE meta_key = 'db_version' ORDER BY blog_id DESC");
	return $wpdb->get_results( $query );
}

Remove blog_versions table

Currently, there is a table in multisite called blog_versions. This table stores the database version as a number and the updated date. It was introduced in #11644 and has never been used in CoreCore Core is the set of software required to run WordPress. The Core Development Team builds WordPress. since then.

With the database version and updated date now stored in theblogmeta table, blog_versionstable becomes redundant. In [46194], this table is removed from Core.

Changes to WP_MS_Sites_List_Table

WordPress 5.3 adds several enhancements to the WP_MS_Sites_List_Table class that allows pluginPlugin A plugin is a piece of software containing a group of functions that can be added to a WordPress website. They can extend functionality or add new features to your WordPress websites. WordPress plugins are written in the PHP programming language and integrate seamlessly with WordPress. These can be free in the WordPress.org Plugin Directory https://wordpress.org/plugins/ or can be cost-based plugin from a third-party authors to take advantage of Site metadata to provide a richer experience for multisite administrators on the Networknetwork (versus site, blog) Adminadmin (and super admin) Sites screen.

These enhancements will be very familiar to those who have used and/or customized the All Posts screen.

Site Status Views

The Network Sites screen now displays a list of links with the counts of Sites by status (e.g., Public, Spam, etc.), similar to the post status links on the All Posts screen.

Network Sites screen showing site status views.

The status links can also be filtered with the new views_sites-network filterFilter Filters are one of the two types of Hooks https://codex.wordpress.org/Plugin_API/Hooks. They provide a way for functions to modify data of other functions. They are the counterpart to Actions. Unlike Actions, filters are meant to work in an isolated manner, and should never have side effects such as affecting global variables and output., introduced in TracTrac An open source project by Edgewall Software that serves as a bug tracker and project management tool for WordPress. ticketticket Created for both bug reports and feature development on the bug tracker. #37392.

For example, imagine there is a multisite where the main site acts as a directory of local restaurants and each separate site is for an individual restaurant, and restaurant owners can purchase a “subscription” that would allow them to display more information about their restaurant listing: a basic subscription would allow them to add photographs of their restaurant and an advanced subscription would additionally allow them to include their menu.

The subscription level could then be stored in the blogmeta table and “status” links can be added for the different subscription levels as follows:

add_filter( 'views_sites-network', 'myplugin_add_site_status_views' );
function myplugin_add_site_status_views( $view_links ) {
	$statuses = array(
		'free'      => _n_noop(
			'Free <span class="count">(%s)</span>',
			'Free <span class="count">(%s)</span>',
			'myplugin'
		),
		'basic'   => _n_noop(
			'Basic <span class="count">(%s)</span>',
			'Basic <span class="count">(%s)</span>',
			'myplugin'
		),
		'advanced'   => _n_noop(
			'Advanced <span class="count">(%s)</span>',
			'Advanced <span class="count">(%s)</span>',
			'myplugin'
		),
	);

	// get the count of sites with each of our custom statuses.
	$args = array(
		'meta_query' => array(
			array(
				'key'     => 'myplugin-status',
				'compare' => '=',
			),
		),
		'count' => true,
	);
	$counts = array();
	foreach ( array_keys( $statuses ) as $status ) {
		$args['meta_query'][0]['value'] = $status;
		$counts[ $status ] = get_sites( $args );
	}

	$requested_status = isset( $_GET['status'] ) ? wp_unslash( trim( $_GET['status'] ) ) : '';

	foreach ( $statuses as $status => $label_count ) {
		$current_link_attributes = $requested_status === $status ?
			' class="current" aria-current="page"' :
			'';
		if ( (int) $counts[ $status ] > 0 ) {
			$label = sprintf( translate_nooped_plural( $label_count, $counts[ $status ] ), number_format_i18n( $counts[ $status ] ) );

			$view_links[ $status ] = sprintf(
				'<a href="%1$s"%2$s>%3$s</a>',
				esc_url( add_query_arg( 'status', $status, 'sites.php' ) ),
				$current_link_attributes,
				$label
			);
		}
	}

	return $view_links;
}

When a user clicks on one of the custom status links, the rows in the list table can be limited to those sites with that specific custom Status using the existing ms_sites_list_table_query_args as follows:

add_filter( 'ms_sites_list_table_query_args', 'myplugin_sites_with_custom_status' );
function myplugin_sites_with_custom_status( $args ) {
	$status = ! empty( $_GET['status' ] ) ? wp_unslash( $_GET['status' ] ) : '';

	if ( empty( $status ) || ! in_array( $_GET['status'], array( 'free', 'basic', 'advanced' ) ) ) {
		return $args;
	}

	$meta_query = array(
		'key'   => 'myplugin-status',
		'value' => $status,
	);

	if ( isset( $args['meta_query'] ) ) {
		// add our meta query to the existing one(s).
		$args['meta_query'] = array(
			'relation' => 'AND',
			$meta_query,
			array( $args['meta_query'] ),
		);
	}
	else {
		// add our meta query.
		$args['meta_query'] = array(
			$meta_query,
		);
	}

	return $args;
}

Extra Tablenav

The posts displayed on the All Posts screen can be filtered by date and categoryCategory The 'category' taxonomy lets you group posts / content together that share a common bond. Categories are pre-defined and broad ranging.. Plugins can also add custom filter criteria with the restrict_manage_posts filter.

To continue with the above restaurant guide example, imagine the food served by each restaurant is also stored in the blogmeta table. We could then allow Network administrators to filter the Sites by the type of food by adding a dropdown of the various cuisines:

Network Sites screen that includes a dropdown added with the "restrict_manage_sites" action.

Dropdowns like this can now be added on the Network Sites screen with the new restrict_manage_sites action ( introduced in Trac ticket #45954), as follows:

add_action( 'restrict_manage_sites', 'myplugin_add_cuisines_dropdown' );
function myplugin_add_cuisines_dropdown( $which ) {
	if ( 'top' !== $which ) {
		return;
	}

	echo '<select name="cuisine">';
	printf( '<option value="">%s</option>', __( 'All cuisines', 'myplugin' ) );

	$cuisines = array(
		'French'  => __( 'French', 'myplugin' ),
		'Indian'  => __( 'Indian', 'myplugin' ),
		'Mexican' => __( 'Mexican', 'myplugin' ),
	);
	
	$requested_cuisine = isset( $_GET['cuisine'] ) ? wp_unslash( $_GET['cuisine'] ) : '';
	
	foreach ( $cuisines as $cuisine => $label ) {
		$selected = selected( $cuisine, $requested_cuisine, false );
		printf( '<option%s>%s</option>', $selected, $label );
	}

	echo '</select>';

	return;
}

When a user selects a food type and clicks the Filter button, the rows in the list table can be limited to just those Sites that serve that cuisine using the existing ms_sites_list_table_query_args filter, as follows:

add_filter( 'ms_sites_list_table_query_args', 'myplugin_sites_with_cuisine' );
function myplugin_sites_with_cuisine( $args ) {
	if ( empty( $_GET['cuisine' ] ) ) {
		return $args;
	}

	$meta_query = array(
		'key'   => 'myplugin-cuisine',
		'value' => wp_unslash( $_GET['cuisine' ] ),
	);

	if ( isset( $args['meta_query'] ) ) {
		// add our meta query to the existing one(s).
		$args['meta_query'] = array(
			'relation' => 'AND',
			$meta_query,
			array( $args['meta_query'] ),
		);
	}
	else {
		// add our meta query.
		$args['meta_query'] = array(
			$meta_query,
		);
	}

	return $args;
}

Site Display States

As with other list tables, each row in the Sites list table can now have display states. By default, all Site statuses (other than Public) of each Site are included as display states. Additionally, the main Site for the Network also has the “Main” display state.

Network Sites screen showing display states added with the "display_site_states" filter.

When a specific Site status view has been selected by the user, that status will not be among the display states (this is just like the All Posts screen).

Plugins can also modify the display states with the new display_site_states filter, introduced in Trac ticket #37684.

To further continue our restaurant guide example, we can add our custom statuses and the cuisine served at each restaurant as display states. This can be achieved as follows:

add_filter( 'display_site_states', 'site_display_states', 10, 2 );
function site_display_states( $display_states, $site ) {
	$status = get_site_meta( $site->blog_id, 'myplugin-status', true );
	$requested_status = isset( $_GET['status'] ) ? wp_unslash( trim( $_GET['status'] ) ) : '';

	if ( $status !== $requested_status ) {
		switch ( $status ) {
			case 'free':
				$display_states['free']     = __( 'Free', 'myplugin' );
				break;
			case 'basic':
				$display_states['basic']    = __( 'Basic', 'myplugin' );
				break;
			case 'advanced':
				$display_states['advanced'] = __( 'Advanced', 'myplugin' );
				break;
		}
	}

	$cuisine = get_site_meta( $site->blog_id, 'myplugin-cuisine', true );
	$requested_cuisine = isset( $_GET['cuisine'] ) ? wp_unslash( trim( $_GET['cuisine'] ) ) : '';

	if ( $cuisine !== $requested_cuisine ) {
		$display_states[ $cuisine ] = $cuisine;
	}

	return $display_states;
}

Misc changes

Return for short circuits for multisite classes.

Fixing a bugbug A bug is an error or unexpected result. Performance improvements, code optimization, and are considered enhancements, not defects. After feature freeze, only bugs are dealt with, with regressions (adverse changes from the previous version) being the highest priority. created in the [44983] original patchpatch A special text file that describes changes to code, by identifying the files and lines which are added, removed, and altered. It may also be referred to as a diff. A patch can be applied to a codebase for testing., introduced pre query filters in multisite classes. This bug made short circuit act differently from other short circuits and as it still continues to execute. Now after the filter networks_pre_query and sites_pre_query run, the code will exit straight away. This allows developers to completely hot-wire the network and site query, to load from another source, such as a different cache or Elastic search.

Improved performance for site and network lookups by ID

In earlier versions of WordPress when running the code get_site( 12345 ) was run and no ID with that site exists, the result is not being cached. That means every subsequent lookup will still cause a DB query to be fired, which is unnecessary. In [45910] non-existent sites data is stored as -1 instead of false to save further database lookups.

#5-3, #dev-notes, #multisite, #networks-sites

Expanded meta key comparison operators in 5.3

WordPress 5.1 introduced the compare_key parameter for WP_Meta_Query, allowing developers to perform LIKE queries against postmeta keys. (See #42409 and the related dev note.) WordPress 5.3 expands the options available to compare_key, so that developers have access to metaMeta Meta is a term that refers to the inside workings of a group. For us, this is the team that works on internal WordPress sites like WordCamp Central and Make WordPress.-key comparison operators similar to those available for meta values. See #43446 and [46188].

After this change, compare_key accepts the following operators: =, LIKE, !=, IN,NOT IN,NOT LIKE,RLIKE,REGEXP,NOT REGEXP,EXISTS, andNOT EXISTS. Usage notes:

  • For parity with value operators, we’ve added support for EXISTS and NOT EXISTS. In the case of compare_key, these map to = and !=, respectively.
  • MySQLMySQL MySQL is a relational database management system. A database is a structured collection of data where content, configuration and other options are stored. https://www.mysql.com/. regular expression comparison operators (RLIKE, REGEXP, NOT REGEXP) are case-insensitive by default. To perform case-sensitive regular expression matches, it’s necessary to cast to BINARY. To support this, WP_Meta_Query now accepts a type_key parameter; pass 'BINARY' to force case-sensitive comparisons. (This directly parallels the use of type when using regular expressions to match meta value.)
  • As is the case with other WP_Meta_Query-related parameters, the parameters discussed here are available to WP_Query using the meta_ prefix: meta_compare_key and meta_type_key.

#5-3, #dev-notes, #query

Use aria-label to ensure Posts and Comments navigation has proper context in WordPress 5.3

Many themes (including bundled themes) use previous/next navigation in single post and pagination links in the posts/comments archives.

The markup output is under the responsibility of coreCore Core is the set of software required to run WordPress. The Core Development Team builds WordPress. private function _navigation_markup, which prints out an unlabelled <nav> element:

<nav class="navigation post-navigation" role="navigation">

This <nav> element defines an ARIA landmark by default: landmarks help assistive technologyAssistive technology Assistive technology is an umbrella term that includes assistive, adaptive, and rehabilitative devices for people with disabilities and also includes the process used in selecting, locating, and using them. Assistive technology promotes greater independence by enabling people to perform tasks that they were formerly unable to accomplish, or had great difficulty accomplishing, by providing enhancements to, or changing methods of interacting with, the technology needed to accomplish such tasks. https://en.wikipedia.org/wiki/Assistive_technology users to perceive the page main sections and jump through them. However, when a landmark is used more than once in a page, it needs to be distinguished from the other ones to let users understand what the landmark is about.

For reference, see ARIA Landmarks Example on W3.org.

To distinguish each context WordPress 5.3 will programmatically add specific aria-label parameter for each navigation menuNavigation Menu A theme feature introduced with Version 3.0. WordPress includes an easy to use mechanism for giving various control options to get users to click from one place to another on a site.. That parameter is being added to navigation menus generated by the following functions:

  • _navigation_markup()
  • get_the_post_navigation()
  • get_the_posts_navigation()
  • get_the_posts_pagination()
  • get_the_comments_navigation()
  • get_the_comments_pagination()

The following functions are also impacted as they are used to echo the result of the functions listed above:

  • the_post_navigation()
  • the_posts_navigation()
  • the_posts_pagination()
  • the_comments_navigation()
  • the_comments_pagination()

All these functions now implement aria_label parameter which can be used to pass custom value for the related HTMLHTML HyperText Markup Language. The semantic scripting language primarily used for outputting content in web browsers. attribute.

For example:

the_post_navigation( array(
    'prev_text'          => __( 'previous: %title', 'text-domain' ),
    'next_text'          => __( 'next: %title', 'text-domain' ),
    'taxonomy'           => 'chapters',
    'aria_label'         => __( 'Chapters', 'text-domain' ),
) );

For reference, see the related TracTrac An open source project by Edgewall Software that serves as a bug tracker and project management tool for WordPress. ticketticket Created for both bug reports and feature development on the bug tracker.: #47123

#5-3, #accessibility, #dev-notes

Changes to wp_die() HTML output in WordPress 5.3

By default and before WordPress 5.3, the handler for wp_die() wraps error messages with a paragraph tagtag A directory in Subversion. WordPress uses tags to store a single snapshot of a version (3.6, 3.6.1, etc.), the common convention of tags in version control systems. (Not to be confused with post tags.).

For a number of wp_die() calls in WordPress, a plain text string is passed and the HTMLHTML HyperText Markup Language. The semantic scripting language primarily used for outputting content in web browsers. displayed is valid: 

wp_die( 'This is an error message.' );

Currently returns:

<p>This is an error message.</p>.

However, for a number of other wp_die() calls, the HTML displayed is invalidinvalid A resolution on the bug tracker (and generally common in software development, sometimes also notabug) that indicates the ticket is not a bug, is a support request, or is generally invalid. because paragraphs doesn’t allow every nesting possibility.

For example:

wp_die( '<h1>You need a higher level of permission.</h1><p>Sorry, you are not allowed to manage terms in this taxonomy.</p>' );

Currently returns:

<p><h1>You need a higher level of permission.</h1><p>Sorry, you are not allowed to manage terms in this taxonomy.</p></p>

With WordPress 5.3, error messages are wrapped in a <div> rather than a <p>, to better support string calls in wp_die(), without
outputting invalid HTML.

These changes also add .wp-die-message CSSCSS Cascading Style Sheets. class for styling.

For example:

wp_die( '<h1>You need a higher level of permission.</h1><p>Sorry, you are not allowed to manage terms in this taxonomy.</p>' );

Will now return:

&lt;div class="wp-die-message">
    &lt;h1>You need a higher level of permission.&lt;/h1>
    &lt;p>Sorry, you are not allowed to manage terms in this taxonomy.&lt;/p>
&lt;/div>

PluginPlugin A plugin is a piece of software containing a group of functions that can be added to a WordPress website. They can extend functionality or add new features to your WordPress websites. WordPress plugins are written in the PHP programming language and integrate seamlessly with WordPress. These can be free in the WordPress.org Plugin Directory https://wordpress.org/plugins/ or can be cost-based plugin from a third-party authors are encouraged to check their use of wp_die() and update their PHPPHP The web scripting language in which WordPress is primarily architected. WordPress requires PHP 7.4 or higher calls to the function or their CSS styles if needed.

For reference, see TracTrac An open source project by Edgewall Software that serves as a bug tracker and project management tool for WordPress. ticketticket Created for both bug reports and feature development on the bug tracker. #47580.

#5-3, #dev-notes

Miscellaneous Developer Focused Changes in 5.3

Oct. 14: Edited to include relevant ticketticket Created for both bug reports and feature development on the bug tracker. numbers for each External Library update.
Oct. 15: Corrected the jQueryColor updated from version and added a bullet point about the changes to the random_password filterFilter Filters are one of the two types of Hooks https://codex.wordpress.org/Plugin_API/Hooks. They provide a way for functions to modify data of other functions. They are the counterpart to Actions. Unlike Actions, filters are meant to work in an isolated manner, and should never have side effects such as affecting global variables and output..

Oct. 29: Added Lodash, ReactReact React is a JavaScript library that makes it easy to reason about, construct, and maintain stateless and stateful user interfaces. https://reactjs.org/., and ReactDOM to the list of updated external libraries.

In WordPress 5.3, a large handful of small developer-focused changes were made that deserve to be called out. Let’s take a look!

Passing Arrays to Supports Argument When Registering Post Types

When registering post type support for a feature using add_post_type_support(), it’s possible to pass “extra” arguments to provide more details for how that post type should support the feature.

<?php
add_post_type_support(
	'my_post_type',
	array(
		'custom_feature' => array(
			'setting-1' => 'value',
			'setting-2' => 'value',
		),
	)
);

However, passing multidimensional arrays with advanced configuration details to the supports argument in register_post_type() results in the extra arguments getting stripped before being added to the post type.

This has been fixed in WordPress 5.3 and multidimensional arrays can now be passed to supports in register_post_type().

Example

<?php
register_post_type(
	'my_post_type',
	array(
		...
		'supports' => array(
			'title',
			'editor',
			'custom_feature' => array(
				'setting-1' => 'value',
				'setting-2' => 'value',
			),
		),
		...
	)
);

For more information on this change, see #40413 on TracTrac An open source project by Edgewall Software that serves as a bug tracker and project management tool for WordPress..

HTML5 Supports Argument for Script and Style Tags

In HTML5, the type attribute is not required for the <script> and <style> tags. Including the attribute on these tags (type="text/javascript", for example) will trigger a validation warning in HTMLHTML HyperText Markup Language. The semantic scripting language primarily used for outputting content in web browsers. validation tools.

In WordPress 5.3, two new arguments are now supported for the html5 theme feature, script and style. When these arguments are passed, the type attribute will not be output for those tags.

Example

<?php
function mytheme_register_support() {
	add_theme_support( 'html5', array( 'script', 'style' ) );
}
add_action( 'after_setup_theme', 'mytheme_register_support' );

For more information on this change, see #42804 on Trac.

Recording Additional Information For Saved Queries.

When the SAVEQUERIES constant is set to true, an array of data for every query to the database is logged for debugging purposes. This data includes:

  • The query itself
  • The total time spent on the query
  • A comma separated list of the calling functions
  • The Unix timestamp of the time at the start of the query.

A new filter, log_query_custom_data, has been added to allow custom debugging information to be added to this array of data. A good example where this would be useful is a pluginPlugin A plugin is a piece of software containing a group of functions that can be added to a WordPress website. They can extend functionality or add new features to your WordPress websites. WordPress plugins are written in the PHP programming language and integrate seamlessly with WordPress. These can be free in the WordPress.org Plugin Directory https://wordpress.org/plugins/ or can be cost-based plugin from a third-party that runs a custom search implementation (such as Elasticsearch). “This query was served by Elasticsearch” could be added to the debug data to help trace where queries are being served.

Example

<?php
function myplugin_log_query_custom_data( $query_data, $query, $query_time, $query_callstack, $query_start ) {
	$query_data['myplugin'] = 'Custom debug information';
	
	return $query_data;
}
add_filter( 'log_query_custom_data', 'myplugin_log_query_custom_data', 10, 5 );

For more information, see #42151.

Unit-less CSSCSS Cascading Style Sheets. line-height Values

Line height should also be unit-less, unless necessary to be defined as a specific pixel value.

The WordPress CoreCore Core is the set of software required to run WordPress. The Core Development Team builds WordPress. CSS Coding Standards

This standard was not followed consistently in the WordPress Core CSS files. All 346 line-height style definitions in Core have been individually examined and adjusted to now adhere to this coding standard.

This change will not cause any issues with Core adminadmin (and super admin) CSS or custom styling, but sites with custom admin styling should be double checked just to be sure.

For more details, see #44643 on Trac, or any of the related sub-tickets (#46488, #46489, #46492, #46493, #46494, #46495, #46509, #46510, #46511, #46512, #46513, #46514, #46515, #46516, #46517, #46518, #46519, #46520, #46521, #46522, #46523, #46524, #46525, #46526, #46528, #46529, #46530, #46531).

Additional Developer Goodies

  • add_settings_error() now supports the warning and info message types in addition to the error and updated/success styles. error and updated types will also now output the .notice-error and .notice-success instead of the legacy .error and .updated classes (see #44941).
  • A typo in the Walker_Nav_Menu_Checklist class has been fixed for the hidden title attribute input field’s class. Previously, the class was .menu-item-attr_title. However, the other fields use a hyphen, which the admin JavaScriptJavaScript JavaScript or JS is an object-oriented computer programming language commonly used to create interactive effects within web browsers. WordPress makes extensive use of JS for a better user experience. While PHP is executed on the server, JS executes within a user’s browser. https://www.javascript.com/. also expects. For that reason, the class has been changed to .menu-item-attr-title. This field is used to auto-populate the Title Attribute input field for menu items when adding a menu item. Plugins and themes that extend or that have copied the Walker_Nav_Menu_Checklist class into their code base should also fix this typo (see #47838).
  • An index has been added to wp_options.autoload. While most sites will be completely unaffected by this, sites with a large number of rows in wp_options and a small number of autoload set will see a significant performance improvement (see #24044).
  • The Media Library type filter has been expanded to include document, spreadsheet, and archive filters (see #38195).
  • Autocomplete support has been added for PHPPHP The web scripting language in which WordPress is primarily architected. WordPress requires PHP 7.4 or higher mode in the CodeMirror code editor used when using the plugin and theme editors (see #47769).
  • Support for flex, grid, and column layout techniques have been added to the list of CSS attributes that KSES considers safe for inline CSS (see #37248).
  • The charset used when wp_die() is called is no longer hard coded as utf-8. Instead, utf-8 will be used as a default and a different charset argument can be passed in the third $args parameter for wp_die() (see #46666).
  • The sms protocol has been added to wp_allowed_protocols() (see #39415).
  • Support for a custom WP_PLUGIN_URL has been added to load_script_textdomain(). Plugins may not be on the same host/path as the rest of the content. This ensures translations are loaded correctly in this scenario (see #46336).
  • Three additional parameters ($length, $special_chars, and $extra_special_chars) are now passed to the random_password filter in wp_generate_password(). Previously, code using this filter had no knowledge of the requirements a generated password needed to meet. Now, custom password generators can better utilize the filter instead of overriding the entire pluggable function. (see #47092).

Build/Test Tools

  • A new job on TravisCI test builds has been added to scan for potential PHP compatibility issues (see #46152).
  • Composer scripts will now use the version of PHPCSPHP Code Sniffer PHP Code Sniffer, a popular tool for analyzing code quality. The WordPress Coding Standards rely on PHPCS./PHPCBF installed through Composer, removing the requirement to have them installed globally. The @php prefix has also been added to ensure each script runs on the PHP version that Composer used to install dependencies (see #47853).
  • Installing Grunt globally is no longer required to run build related scripts because Core now uses the local Grunt binary installed by NPM. For example, npm run build can now be used instead. (see #47380).

External Libraries

A number of external libraries and dependencies have been updated. Including Twemoji, which now includes the Transgender symbol and flag!

⚧️ 💖 🏳️‍⚧️

The following external libraries have been updated:

Props @earnjam for peer review.

#5-3, #dev-notes

Improvements in Media component accessibility in WordPress 5.3

Form controls are still unlabelled in WordPress media views. Some don’t have associated <label> element, <aria-label>attribute or some have an empty label.

Properly labeling form controls is essential for a basic level of accessibilityAccessibility Accessibility (commonly shortened to a11y) refers to the design of products, devices, services, or environments for people with disabilities. The concept of accessible design ensures both “direct access” (i.e. unassisted) and “indirect access” meaning compatibility with a person’s assistive technology (for example, computer screen readers). (https://en.wikipedia.org/wiki/Accessibility), as labels give form controls their accessible name. The name is then used by assistive technologies to inform users what the form control is about. Not to mention visible <label> elements are clickable and help users with motor impairments to set focus on the associated form control.

Also, the WordPress accessibility coding standards recommend explicitly associated labels (with for/id) attributes instead of implicitly (wrapping) labels.

WordPress 5.3 will now include some accessibility improvements of all the media views from controls:

  • Changes the media views form controls to have explicitly associated labels with for/id attributes
  • Adds a few missing labels / aria-labels
  • Improves a few existing labels / aria-labels
  • Improves semantics in a few places, by adding visually hidden headings, fieldset + legend elements, aria-describedby attributes
  • Improves the image custom size input fields and their labeling
  • Adds role=”status” to the “saved” indicator so that status messages are announced to assistive technologies
  • Swaps the columns source order in the image details template, to make visual and DOM order match
  • Swaps the “Replace” and “Back” buttons source order in the Replace Image view, to make visual and DOM order match
  • Gallery settings: move checkbox label to the right: checkboxes are supposed to have labels on the right
  • Merge similar strings, unified to “Drop files to upload” (removed “Drop files here”, and “Drop files anywhere to upload”)
  • Makes the “upload-ui” consistent across the media views
  • Hides the IE 11 “X” ::-ms-clear button in the Insert from URLURL A specific web address of a website or web page on the Internet, such as a website’s URL www.wordpress.org field, as it conflicts with the uploading spinner
  • Adds comments to all the media templates to clarify their usage
  • Slightly increases the vertical spacing between form fields in the media sidebarSidebar A sidebar in WordPress is referred to a widget-ready area used by WordPress themes to display information that is not a part of the main content. It is not always a vertical column on the side. It can be a horizontal rectangle below or above the content area, footer, header, or any where in the theme.
  • Removes some CSSCSS Cascading Style Sheets. selectors introduced as backwards compatibility for WordPress pre-4.4
  • Removes some CSS still targeting Internet Explorer 7 and 8
  • Fixes buttons group layout for Internet Explorer 11

The most important change to clarify is that the labeling changed from this (implicit labeling):

<label>
    My input
    <input type="text" />
</label>

to this (explicit labeling):

<label for="my-input">My input</label>
<input type="text" id="my-input" />

Simplified code sample


More details on these improvements can be found in TracTrac An open source project by Edgewall Software that serves as a bug tracker and project management tool for WordPress. ticketticket Created for both bug reports and feature development on the bug tracker. #47122.

This note was drafted by @justinahinon and proofread by @afercia.

#5-3, #accessibility, #dev-notes, #media

Updates to Image Processing in WordPress 5.3

WordPress 5.3 includes several enhancements to how images are used and post-processed after upload.

When an image is uploaded to WordPress, alternate smaller sizes are automatically created. Some of these “intermediate” sizes are defined by coreCore Core is the set of software required to run WordPress. The Core Development Team builds WordPress., and others by themes or plugins. These are used both for art direction uses, like alternate crops, and automatically by core for responsive images if they are the same aspect ratio.

Resizing images is very resource intensive. As average image sizes have increased over time, this has only increased the chances that requests may time out or run out of memory. WordPress 5.3 includes several enhancements to help more uploads succeed, and to aid users in recovery when they do not. These changes also enable WordPress to generate two new, higher resolution default sizes, to help user images look their best.

Saving of image metadata while creating intermediate sizes

Before 5.3, WordPress would first generate all intermediate sizes before saving proof of their existence in the database in metaMeta Meta is a term that refers to the inside workings of a group. For us, this is the team that works on internal WordPress sites like WordCamp Central and Make WordPress..

This meant that if an upload failed in the middle, there could be many sizes that had completed successfully stored, but this wouldn’t be reflected in the database. A user’s only recourse was to re-upload over and over again in the hope that their server was less busy and all of the sizes would be generated.

In 5.3, this problem is fixed through saving metadata for each size as it is created in the database. This means more database writes, but allows WordPress to use the sizes generated earlier, and to resume failed uploads.

To make this possible, a new method make_subsize() was introduced in the WP_Image_Editor_GD and WP_Image_Editor_Imagick classes. It returns the new sub-size image path and dimensions ready to be added to the image meta’s sizes array. See #40439.

Additional changes:

  • Introduces wp_get_missing_image_subsizes() and wp_update_image_subsizes() to generate image sub-sizes that are missing or were not created after the upload.
  • Adds a way to display errors that happened while creating sub-sizes.
  • Introduces wp_create_image_subsizes() intended for use after an image was uploaded. It saves/updates the image metadata immediately after each sub-size is created.

With that in place it became possible to attempt to finish post-processing of images after upload if the server runs out of resources while creating intermediate image sizes (the dreaded “HTTPHTTP HTTP is an acronym for Hyper Text Transfer Protocol. HTTP is the underlying protocol used by the World Wide Web and this protocol defines how messages are formatted and transmitted, and what actions Web servers and browsers should take in response to various commands. Error” message). See #47872.

“BIG image” enhancements

Until now it was possible to use the originally uploaded images on the front-end even when they are were not “web ready”. In WordPress 5.3 when a large image is uploaded it is stored in the uploads directory but is not used on the web site. A new scaled down image is created and used as the largest available size. This scaled down image is usually much more suitable for web use, the file size is up to ten times smaller than the original. See #47873.

Additional changes:

  • Introduces wp_get_original_image_path() that retrieves the path to the originally uploaded image in all cases.
  • Introduces big_image_size_threshold filterFilter Filters are one of the two types of Hooks https://codex.wordpress.org/Plugin_API/Hooks. They provide a way for functions to modify data of other functions. They are the counterpart to Actions. Unlike Actions, filters are meant to work in an isolated manner, and should never have side effects such as affecting global variables and output. to set the pixel value above which images will be scaled. The same value is used as max-width and max-height when scaling the original.

These enhancements also made it possible to automatically rotate uploaded photos according to the EXIF data, and to add two additional default image sizes to better support high-density displays. See #14459 and #43524.

Thanks @mikeschroder for helping to write this post.

#5-3, #dev-notes, #media, #upload

WordPress and PHP 7.4

PHPPHP The web scripting language in which WordPress is primarily architected. WordPress requires PHP 7.4 or higher 7.4 is in the final stages of its release cycle. As of the publish date of this post, version 7.4 RC3 has been released, and the final release of PHP 7.4.0 is scheduled for November 28, 2019.

As the expected changes in PHP 7.4 were made public earlier this year, contributors to WordPress CoreCore Core is the set of software required to run WordPress. The Core Development Team builds WordPress. worked to identify compatibility issues within the code base. Overall, the changes needed to declare full PHP 7.4 support were minor, and have all been made.

WordPress aims to fully support PHP 7.4 in the 5.3 release (currently scheduled for November 12, 2019).

Here is a breakdown of the changes in PHP 7.4 that pluginPlugin A plugin is a piece of software containing a group of functions that can be added to a WordPress website. They can extend functionality or add new features to your WordPress websites. WordPress plugins are written in the PHP programming language and integrate seamlessly with WordPress. These can be free in the WordPress.org Plugin Directory https://wordpress.org/plugins/ or can be cost-based plugin from a third-party and theme developers need to be aware of and should accommodate in their code.

Changes to Curly Brace Syntax

In the past, PHP has allowed the use of curly braces ({}) to access array elements and string offsets.

<?php
$array = [1, 2];
echo $array[1]; // prints 2
echo $array{1}; // also prints 2
 
$string = "foo";
echo $string[0]; // prints "f"
echo $string{0}; // also prints "f"

Using the curly brace syntax will now trigger a deprecated notice in PHP 7.4 with the plan to remove the feature entirely in PHP 8.0 (or another future release).

For more information about this change, see the accepted proposal on the official PHP RFC Wiki, or check out what changed in WordPress Core to fix these issues in #47751.

Specific Parameter Order Requirements For implode()

The implode() function accepts two parameters, $glue and $pieces. For historical reasons, implode() has accepted these parameters in any order, though it has been a recommendation that the documented order of implode( $glue, $pieces ) be used.

Starting in PHP 7.4, tolerance for passing the parameters in reverse order is deprecated and will be completely removed in PHP 8.0. Calling implode( $pieces, $glue ) in PHP 7.4 will trigger a deprecated notice.

Note: This also affects the join() function, which is an alias of implode() and accepts the same two parameters.

For more information about this change, see the accepted proposal on the official PHP RFC Wiki, or check out what changed in WordPress Core to fix these issues in #47746.

Accessing Array Offset on Non-Arrays/Objects

PHP has previously thrown a warning only when attempting to use an offset that is of an invalidinvalid A resolution on the bug tracker (and generally common in software development, sometimes also notabug) that indicates the ticket is not a bug, is a support request, or is generally invalid. type. However, starting with PHP 7.4, a warning will also be thrown when a container is of an invalid type.

While code which relies on the undocumented behavior of PHP returning null when attempting to array access a null/bool/int/float/resource will continue to work as expected, each and every instance of this will now throw a PHP E_WARNING.

This issue is most common when using array access on the outcome of functions with mixed return values, i.e. array|false. When the return values of these function are used, more type checking needs to be done before attempting to access the return value as if it were an array to prevent this warning.

For more information about this change, see the accepted proposal on the official PHP RFC Wiki, or check out what changed in WordPress Core to fix these issues in #47704.

Note: because this issue cannot be easily/reliably detected using static analysis tools, it is possible that there are more occurrences of this issue in Core. Please open a new ticket on Trac and tagtag A directory in Subversion. WordPress uses tags to store a single snapshot of a version (3.6, 3.6.1, etc.), the common convention of tags in version control systems. (Not to be confused with post tags.) it with the php74 keyword if additional issues of this type are discovered.

Concatenation & Plus/Minus Operator Precedence

In past versions of PHP, the operator precedence of the ., +, and - operators has been exactly the same. Because of this, operations are evaluated from left to right. However, because concatenated strings generally are not numbers, this often produces undesired behavior. It’s rare that the intended behavior is to add or subtract concatenated strings.

// Example:
echo "sum: " . $a + $b;
 
// Current behavior: evaluated left-to-right
echo ("sum: " . $a) + $b;
 
// Desired behavior: addition and subtraction have a higher precedence
echo "sum :" . ($a + $b);

In PHP 8.0, the . operator will have a lower precedence than + and -. This will ensure that additions and subtractions are always performed before concatenation occurs.

As an example, the expression '3' . '5' + 7 will now be equal to “312” instead of previously “42”.

Starting in PHP 7.4, a deprecation notice will be triggered for any unparenthesized expressions containing a . before a + or -. While this is a subtle change, every occurrence of this pattern will result in a change of behavior in PHP 8.

For more information about this change, see the accepted proposal on the official PHP RFC Wiki, or check out what changed in WordPress Core to fix this issue in #47441.

Deprecated: Magic Quotes Related Functions

The magic_quotes configuration was removed from PHP in version 5.4. The function implementations that check whether or not these settings have been enabled have returned false since then. Later, PHP 7.0 removed magic_quotes entirely.

As of PHP 7.4, get_magic_quotes_gpc() and get_magic_quotes_runtime() are now marked as deprecated and they are slated for removal in PHP 8.

For more information about this change, see the accepted proposal on the official PHP RFC Wiki, or check out what changed in WordPress Core to fix this issue in #47783.

Left-Associative Ternary Operators

In most other languages, the ternary operator is right-associative. However, in PHP, it is left-associative. This behavior is generally not useful and can be confusing for programmers who switch between different languages.

In PHP 7.4, nested ternaries without explicit parentheses will throw a deprecation warning In PHP 8.0, it will become a compile-time error instead.

<?php
1 ? 2 : 3 ? 4 : 5;   // deprecated
(1 ? 2 : 3) ? 4 : 5; // ok
1 ? 2 : (3 ? 4 : 5); // ok

There were no occurrences of this pattern in WordPress Core, but it’s important to check your plugins, themes, and custom code to ensure PHP 7.4 compatibility. For more information about this change, see the accepted proposal on the official PHP RFC Wiki.

Compatibility Tooling

To help detect potential compatibility issues with supported versions of PHP, the PHPCompatibility checker has been added to WordPress Core with a custom tailored ruleset that extends the PHPCompatibilityWP ruleset.

If you build or maintain plugins or themes, it is highly recommended that you add the PHPCompatibility checker to your toolkit to make detecting PHP version compatibility issues easier and consistent. Aside from the array offset issue, all other issues mentioned in this article can be automatically detected through the use of PHPCompatibility.

When working on WordPress Core, composer compat can be run to scan the Core code base for potential compatibility issues. Furthermore, every TravisCI build will now contain a “PHP Compatibility Check” job that will scan for potential compatibility issues. This job is currently allowed to fail while the results are analyzed and the ruleset is refined to eliminate false positives.

For more information, see #46152 on TracTrac An open source project by Edgewall Software that serves as a bug tracker and project management tool for WordPress..

External Libraries & Dependencies

WordPress Core contributorsCore Contributors Core contributors are those who have worked on a release of WordPress, by creating the functions or finding and patching bugs. These contributions are done through Trac. https://core.trac.wordpress.org. have collaborated with the maintainers of several external libraries and dependencies to ensure compatibility with PHP 7.4.

getID3

The getID3 library was updated from v1.9.14 to v1.9.18. This update removes some occurrences of the now deprecated curly brace syntax and some code related to magic quotes. For more details, check out these pull requests, #47783, or [46112].

PHPMailer

The PHPMailer library was updated from v5.2.22 to v5.2.27 in Core and patched to prevent deprecated notices related to magic quotes from being triggered. Magic quotes has been completely removed from PHPMailer 6.0 and higher. #41750 exists to upgrade PHPMailer to the latest and greatest early in the 5.4 release cycle. For more details, check out #40472 and #47783, or the relevant changesets ([46097] and [46378]).

Requests

The Requests library was updated to address occurrences of the now deprecated curly brace syntax and accessing array offsets on non-arrays. For more details on these updates, see PR-346 and PR-370 in the Requests repository, #47746, or the related changesets ([46258] and [46416]).

SimplePie

The SimplePie library was patched in Core to prevent deprecated notices related to passing parameters to implode() in the incorrect order from being triggered. This issue is fixed in the most recent release of version 1.5.3. Upgrading the entire library to the latest and greatest with increased test coverage is being explored and is expected early in the 5.4 release cycle (see #36669). For more details, check out #47746 or [46260].

Other Updates

A few other libraries that no longer have an externally maintained canonical source have also been updated.

Summary

As always, reading through the complete upgrade document is highly recommended.

Even as WordPress Core continues to expand its support for new versions of PHP, the current support for old versions will remain as is at PHP 5.6.20 and higher until usage numbers show that the impact on users will be minimal.

There is a separate initiative to decrease the usage numbers for older versions of PHP being guided by the Core PHP team through the servehappy initiative. If you wish to help with this effort, please join the #core-php room in the Making WordPress Core Slack instance.

WordPress continues to encourage all users to run the latest and greatest versions of PHP. This includes PHP 7.4 upon its official release.

A full list of tickets related to PHP 7.4 support can be found on Trac.

Props @jrf and @jorbin for peer reviewing.

#5-3, #dev-notes, #php-7-4

Filtering nested REST response _fields in WP 5.3

WordPress 4.9.8 introduced the ability to limit the fields included in the JSONJSON JSON, or JavaScript Object Notation, is a minimal, readable format for structuring data. It is used primarily to transmit data between a server and web application, as an alternative to XML. objects returned from the REST APIREST API The REST API is an acronym for the RESTful Application Program Interface (API) that uses HTTP requests to GET, PUT, POST and DELETE data. It is how the front end of an application (think “phone app” or “website”) can communicate with the data store (think “database” or “file system”) https://developer.wordpress.org/rest-api/., for example specifying

/wp/v2/posts?_fields=id,title,author

to return a list of posts with only id, title & author fields in situations where we don’t need all of the data contained in other fields like content or media (see #38131). Since 4.9.8 we’ve made further improvements to skip computing fields we did not explicitly request when _fields is present, saving time on the server in addition to slimming down the JSON response object.

In WordPress 5.3 we are adding the ability to filterFilter Filters are one of the two types of Hooks https://codex.wordpress.org/Plugin_API/Hooks. They provide a way for functions to modify data of other functions. They are the counterpart to Actions. Unlike Actions, filters are meant to work in an isolated manner, and should never have side effects such as affecting global variables and output. by nested fields. Previously we could only request top-level properties like content or meta, which would return the full content object (with raw and rendered properties when using an edit context) or the object containing all metaMeta Meta is a term that refers to the inside workings of a group. For us, this is the team that works on internal WordPress sites like WordCamp Central and Make WordPress. values. We can now specify a nested path such as content.raw and the REST API will skip computing the rendered content, a useful performance boost for applications like GutenbergGutenberg The Gutenberg project is the new Editor Interface for WordPress. The editor improves the process and experience of creating new content, making writing rich content much simpler. It uses ‘blocks’ to add richness rather than shortcodes, custom HTML etc. https://wordpress.org/gutenberg/ which only require that underlying raw post content.

Now that we can register complex array or object meta, we may similarly ask for only a few of many registered meta fields, or certain properties within a complex object, using a query such as this:

?_fields=meta.meta-key-1,meta.meta-key-2,meta.meta-key-3.nested-prop

(Note that this specific meta example depends on bugfix #48266, which will ship as part of RC1.)

Thank you @timothyblynjacobs, @dlh, @danielbachhuber, and @rmccue for assisting with the development of this useful feature!

#5-3, #dev-notes, #rest-api