diff --git a/.eslintrc.js b/.eslintrc.js index 86eba448b8..45d5312467 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -9,6 +9,10 @@ const config = { ...( wpConfig?.rules || {} ), 'jsdoc/valid-types': 'off', }, + env: { + browser: true, + }, + ignorePatterns: [ '/vendor', '/node_modules' ], }; module.exports = config; diff --git a/.github/workflows/php-test-standalone-plugins.yml b/.github/workflows/php-test-standalone-plugins.yml index 3065f9f39a..410ae38028 100644 --- a/.github/workflows/php-test-standalone-plugins.yml +++ b/.github/workflows/php-test-standalone-plugins.yml @@ -42,9 +42,25 @@ jobs: name: PHP Integration Tests for Standalone Plugins runs-on: ubuntu-latest timeout-minutes: 20 + strategy: + fail-fast: false + matrix: + php: [ '8.2', '8.1', '8.0', '7.4', '7.3', '7.2', '7.1', '7.0' ] + wp: [ 'latest' ] + include: + - php: '7.4' + wp: '6.3' + - php: '8.3' + wp: 'trunk' + env: + WP_ENV_PHP_VERSION: ${{ matrix.php }} + WP_ENV_CORE: ${{ matrix.wp == 'trunk' && 'WordPress/WordPress' || format( 'https://wordpress.org/wordpress-{0}.zip', matrix.wp ) }} steps: - uses: styfle/cancel-workflow-action@0.11.0 - uses: actions/checkout@v3 + - uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php }} - name: Setup Node.js (.nvmrc) uses: actions/setup-node@v3 with: @@ -52,6 +68,12 @@ jobs: cache: npm - name: npm install run: npm ci + - name: General debug information + run: | + npm --version + node --version + composer --version + php -v - name: Building standalone plugins run: npm run build-plugins - name: Running single site standalone plugin integration tests diff --git a/.github/workflows/php-test.yml b/.github/workflows/php-test.yml index 4c249687b0..5fe4fc6c90 100644 --- a/.github/workflows/php-test.yml +++ b/.github/workflows/php-test.yml @@ -39,9 +39,22 @@ on: jobs: php-test: - name: PHP + name: "PHP ${{ matrix.php }} / WP ${{ matrix.wp }}" runs-on: ubuntu-latest timeout-minutes: 20 + strategy: + fail-fast: false + matrix: + php: ['8.2', '8.1', '8.0', '7.4', '7.3', '7.2', '7.1', '7.0'] + wp: [ 'latest' ] + include: + - php: '7.4' + wp: '6.3' + - php: '8.3' + wp: 'trunk' + env: + WP_ENV_PHP_VERSION: ${{ matrix.php }} + WP_ENV_CORE: ${{ matrix.wp == 'trunk' && 'WordPress/WordPress' || format( 'https://wordpress.org/wordpress-{0}.zip', matrix.wp ) }} steps: - uses: styfle/cancel-workflow-action@0.11.0 - uses: actions/checkout@v3 @@ -54,6 +67,11 @@ jobs: run: npm ci - name: Install WordPress run: npm run wp-env start + # Note that `composer update` is required instead of `composer install` + # for the sake of PHP versions older than 8.1, which is the version of + # PHP that the composer.lock was created for. + - name: Composer update + run: npm run wp-env run tests-cli -- --env-cwd="wp-content/plugins/$(basename $(pwd))" composer update --no-interaction - name: Running single site unit tests run: npm run test-php - name: Running multisite unit tests diff --git a/.github/workflows/props-bot.yml b/.github/workflows/props-bot.yml new file mode 100644 index 0000000000..806ca19583 --- /dev/null +++ b/.github/workflows/props-bot.yml @@ -0,0 +1,88 @@ +name: Props Bot + +on: + # This event runs anytime a PR is (re)opened, updated, marked ready for review, or labeled. + # GitHub does not allow filtering the `labeled` event by a specific label. + # However, the logic below will short-circuit the workflow when the `props-bot` label is not the one being added. + # Note: The pull_request_target event is used instead of pull_request because this workflow needs permission to comment + # on the pull request. Because this event grants extra permissions to `GITHUB_TOKEN`, any code changes within the PR + # should be considered untrusted. See https://securitylab.github.com/research/github-actions-preventing-pwn-requests/. + pull_request_target: + types: + - opened + - synchronize + - reopened + - labeled + - ready_for_review + # This event runs anytime a comment is added or deleted. + # You cannot filter this event for PR comments only. + # However, the logic below does short-circuit the workflow for issues. + issue_comment: + type: + - created + # This event will run everytime a new PR review is initially submitted. + pull_request_review: + types: + - submitted + # This event runs anytime a PR review comment is created or deleted. + pull_request_review_comment: + types: + - created + +# Cancels all previous workflow runs for pull requests that have not completed. +concurrency: + # The concurrency group contains the workflow name and the branch name for pull requests + # or the commit hash for any other events. + group: ${{ github.workflow }}-${{ contains( fromJSON( '["pull_request_target", "pull_request_review", "pull_request_review_comment"]' ), github.event_name ) && github.head_ref || github.sha }} + cancel-in-progress: true + +# Disable permissions for all available scopes by default. +# Any needed permissions should be configured at the job level. +permissions: {} + +jobs: + # Compiles a list of props for a pull request. + # + # Performs the following steps: + # - Collects a list of contributor props and leaves a comment. + # - Removes the props-bot label, if necessary. + props-bot: + name: Generate a list of props + runs-on: ubuntu-latest + permissions: + # The action needs permission `write` permission for PRs in order to add a comment. + pull-requests: write + contents: read + timeout-minutes: 20 + # The job will run when pull requests are open, ready for review and: + # + # - A comment is added to the pull request. + # - A review is created or commented on. + # - The pull request is opened, synchronized, marked ready for review, or reopened. + # - The `props-bot` label is added to the pull request. + if: | + ( + github.event_name == 'issue_comment' && github.event.issue.pull_request || + contains( fromJSON( '["pull_request_review", "pull_request_review_comment"]' ), github.event_name ) || + github.event_name == 'pull_request_target' && github.event.action != 'labeled' || + 'props-bot' == github.event.label.name + ) && + ( ! github.event.pull_request.draft && github.event.pull_request.state == 'open' || ! github.event.issue.draft && github.event.issue.state == 'open' ) + + steps: + - name: Gather a list of contributors + uses: WordPress/props-bot-action@trunk + + - name: Remove the props-bot label + uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1 + if: ${{ github.event.action == 'labeled' && 'props-bot' == github.event.label.name }} + with: + retries: 2 + retry-exempt-status-codes: 418 + script: | + github.rest.issues.removeLabel({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: '${{ github.event.number }}', + name: 'props-bot' + }); diff --git a/.gitignore b/.gitignore index 1889d02de2..02b6696654 100644 --- a/.gitignore +++ b/.gitignore @@ -23,6 +23,8 @@ nbproject/ build .wp-env.override.json +build-cs/vendor/ +build-cs/composer.lock ############ ## Vendor diff --git a/.wp-env.json b/.wp-env.json index 9af20e97ab..673c3bd542 100644 --- a/.wp-env.json +++ b/.wp-env.json @@ -5,8 +5,7 @@ "tests": { "config": { "FS_METHOD": "direct" - }, - "phpVersion": "7.4" + } } } } diff --git a/admin/js/perflab-module-migration-notice.js b/admin/js/perflab-module-migration-notice.js index 12844e801f..bdebc98f26 100644 --- a/admin/js/perflab-module-migration-notice.js +++ b/admin/js/perflab-module-migration-notice.js @@ -1,3 +1,6 @@ +/* eslint camelcase: "off", no-alert: "off" */ +/* global perflab_module_migration_notice:false */ + ( function ( document ) { document.addEventListener( 'DOMContentLoaded', function () { document.addEventListener( 'click', function ( event ) { @@ -26,7 +29,10 @@ .then( function ( response ) { if ( ! response.ok ) { throw new Error( - wp.i18n.__( 'Network response was not ok.', 'performance-lab' ) + wp.i18n.__( + 'Network response was not ok.', + 'performance-lab' + ) ); } return response.json(); diff --git a/admin/js/perflab-plugin-management.js b/admin/js/perflab-plugin-management.js index f36626204a..45200150e8 100644 --- a/admin/js/perflab-plugin-management.js +++ b/admin/js/perflab-plugin-management.js @@ -1,16 +1,25 @@ +/* eslint no-var: "off", camelcase: "off" */ +/* global jQuery:false */ + ( function ( $, document ) { - $( document ).ajaxComplete( function( event, xhr, settings ) { + $( document ).ajaxComplete( function ( event, xhr, settings ) { // Check if this is the 'install-plugin' request. - if ( settings.data && typeof settings.data === 'string' && settings.data.includes( 'action=install-plugin' ) ) { + if ( + settings.data && + typeof settings.data === 'string' && + settings.data.includes( 'action=install-plugin' ) + ) { var params = new URLSearchParams( settings.data ); - var slug = params.get('slug'); + var slug = params.get( 'slug' ); // Check if 'slug' was found and output the value. if ( ! slug ) { return; } - var target_element = $( '.wpp-standalone-plugins a[data-slug="' + slug + '"]' ); + var target_element = $( + '.wpp-standalone-plugins a[data-slug="' + slug + '"]' + ); if ( ! target_element ) { return; } @@ -20,12 +29,14 @@ * so we set a 1.5 timeout here to ensure our changes get updated after * the core changes have taken place. */ - setTimeout( function() { + setTimeout( function () { var plugin_url = target_element.attr( 'href' ); if ( ! plugin_url ) { return; } - var nonce = target_element.attr( 'data-plugin-activation-nonce' ); + var nonce = target_element.attr( + 'data-plugin-activation-nonce' + ); var plugin_slug = target_element.attr( 'data-slug' ); var url = new URL( plugin_url ); url.searchParams.set( 'action', 'perflab_activate_plugin' ); diff --git a/admin/load.php b/admin/load.php index 2e04628959..d29937498c 100644 --- a/admin/load.php +++ b/admin/load.php @@ -413,8 +413,7 @@ function perflab_admin_pointer( $hook_suffix ) { $active_modules_with_inactive_plugins = perflab_get_active_module_data_with_inactive_standalone_plugins(); if ( ! empty( $active_modules_with_inactive_plugins ) - && current_user_can( 'install_plugins' ) - && current_user_can( 'activate_plugins' ) + && ( current_user_can( 'install_plugins' ) || current_user_can( 'activate_plugins' ) ) && ! in_array( 'perflab-module-migration-pointer', $dismissed, true ) ) { // Enqueue the pointer logic and return early. @@ -557,7 +556,7 @@ function perflab_dismiss_wp_pointer_wrapper() { /** * Callback function to handle admin scripts. * - * @since n.e.x.t + * @since 2.8.0 */ function perflab_enqueue_modules_page_scripts() { wp_enqueue_script( 'updates' ); @@ -580,7 +579,7 @@ function perflab_enqueue_modules_page_scripts() { wp_enqueue_script( 'perflab-plugin-management', plugin_dir_url( __FILE__ ) . 'js/perflab-plugin-management.js', - array(), + array( 'jquery' ), '1.0.0', array( 'in_footer' => true, @@ -617,7 +616,7 @@ function perflab_enqueue_modules_page_scripts() { /** * Callback function hooked to admin_action_perflab_activate_plugin to handle plugin activation. * - * @since n.e.x.t + * @since 2.8.0 */ function perflab_activate_plugin() { // Do not proceed if plugin query arg is not present. @@ -666,7 +665,7 @@ function perflab_activate_plugin() { /** * Callback function hooked to admin_action_perflab_deactivate_plugin to handle plugin deactivation. * - * @since n.e.x.t + * @since 2.8.0 */ function perflab_deactivate_plugin() { // Do not proceed if plugin query arg is not present. @@ -707,7 +706,7 @@ function perflab_deactivate_plugin() { /** * Handles the standalone plugin install and activation via AJAX. * - * @since n.e.x.t + * @since 2.8.0 */ function perflab_install_activate_standalone_plugins_callback() { if ( ! wp_verify_nonce( $_REQUEST['nonce'], 'perflab-install-activate-plugins' ) ) { @@ -787,7 +786,7 @@ function perflab_install_activate_standalone_plugins_callback() { /** * Callback function hooked to admin_notices to render admin notices on the plugin's screen. * - * @since n.e.x.t + * @since 2.8.0 */ function perflab_plugin_admin_notices() { if ( isset( $_GET['activate'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended @@ -812,6 +811,19 @@ function perflab_plugin_admin_notices() { $available_module_names = wp_list_pluck( $active_modules_with_inactive_plugins, 'name' ); $modules_count = count( $available_module_names ); + $has_cap = current_user_can( 'install_plugins' ) && current_user_can( 'activate_plugins' ); + if ( $has_cap ) { + if ( 1 === $modules_count ) { + $additional_message = __( 'Please click the following button to install and activate the relevant plugin in favor of the module.', 'performance-lab' ); + } else { + $additional_message = __( 'Please click the following button to install and activate the relevant plugins in favor of the modules.', 'performance-lab' ); + } + } elseif ( 1 === $modules_count ) { + $additional_message = __( 'Please install and activate the relevant plugin in favor of the module.', 'performance-lab' ); + } else { + $additional_message = __( 'Please install and activate the relevant plugins in favor of the modules.', 'performance-lab' ); + } + if ( 1 === $modules_count ) { $message = '

'; $message .= sprintf( @@ -820,13 +832,17 @@ function perflab_plugin_admin_notices() { esc_attr( $available_module_names[0] ) ); $message .= ' '; - $message .= esc_html__( 'Please click the following button to install and activate the relevant plugin in favor of the module. This will not impact any of the underlying functionality.', 'performance-lab' ); + $message .= esc_html( $additional_message ); + $message .= ' '; + $message .= esc_html__( 'This will not impact any of the underlying functionality.', 'performance-lab' ); $message .= '

'; } else { $message = '

'; $message .= esc_html__( 'Your site is using modules which will be removed in the future in favor of their equivalent standalone plugins.', 'performance-lab' ); $message .= ' '; - $message .= esc_html__( 'Please click the following button to install and activate the relevant plugins in favor of the modules. This will not impact any of the underlying functionality.', 'performance-lab' ); + $message .= esc_html( $additional_message ); + $message .= ' '; + $message .= esc_html__( 'This will not impact any of the underlying functionality.', 'performance-lab' ); $message .= '

'; $message .= '' . esc_html__( 'Available standalone plugins:', 'performance-lab' ) . ''; $message .= '
    '; @@ -835,16 +851,17 @@ function perflab_plugin_admin_notices() { } $message .= '
'; } - ?>
+

+
@@ -888,6 +905,10 @@ function perflab_print_modules_page_style() { animation: rotation 2s infinite linear; margin-left: 5px; } + .plugin-action-buttons a[id^="deactivate-"] { + color: #b32d2e; + text-decoration: underline; + } %s', - add_query_arg( - array( - '_wpnonce' => wp_create_nonce( 'perflab_deactivate_plugin_' . $status['file'] ), - 'action' => 'perflab_deactivate_plugin', - 'plugin' => $status['file'], - ), - network_admin_url( 'plugins.php' ) + '%s', + esc_url( + add_query_arg( + array( + '_wpnonce' => wp_create_nonce( 'perflab_deactivate_plugin_' . $status['file'] ), + 'action' => 'perflab_deactivate_plugin', + 'plugin' => $status['file'], + ), + network_admin_url( 'plugins.php' ) + ) ), esc_attr( $plugin_data['slug'] ), /* translators: %s: Plugin name. */ @@ -288,23 +288,29 @@ function perflab_render_plugin_card( array $plugin_data ) { echo '

' . esc_html_e( 'This plugin does not work with your versions of WordPress and PHP.', 'default' ) . '

'; if ( current_user_can( 'update_core' ) && current_user_can( 'update_php' ) ) { echo wp_kses_post( - /* translators: 1: URL to WordPress Updates screen, 2: URL to Update PHP page. */ - ' ' . __( 'Please update WordPress, and then learn more about updating PHP.', 'default' ), - esc_url( self_admin_url( 'update-core.php' ) ), - esc_url( wp_get_update_php_url() ) + sprintf( + /* translators: 1: URL to WordPress Updates screen, 2: URL to Update PHP page. */ + ' ' . __( 'Please update WordPress, and then learn more about updating PHP.', 'default' ), + esc_url( self_admin_url( 'update-core.php' ) ), + esc_url( wp_get_update_php_url() ) + ) ); wp_update_php_annotation( '

', '

' ); } elseif ( current_user_can( 'update_core' ) ) { echo wp_kses_post( - /* translators: %s: URL to WordPress Updates screen. */ - ' ' . __( 'Please update WordPress.', 'default' ), - esc_url( self_admin_url( 'update-core.php' ) ) + sprintf( + /* translators: %s: URL to WordPress Updates screen. */ + ' ' . __( 'Please update WordPress.', 'default' ), + esc_url( self_admin_url( 'update-core.php' ) ) + ) ); } elseif ( current_user_can( 'update_php' ) ) { echo wp_kses_post( - /* translators: %s: URL to Update PHP page. */ - ' ' . __( 'Learn more about updating PHP.', 'default' ), - esc_url( wp_get_update_php_url() ) + sprintf( + /* translators: %s: URL to Update PHP page. */ + ' ' . __( 'Learn more about updating PHP.', 'default' ), + esc_url( wp_get_update_php_url() ) + ) ); wp_update_php_annotation( '

', '

' ); } @@ -312,18 +318,22 @@ function perflab_render_plugin_card( array $plugin_data ) { esc_html_e( 'This plugin does not work with your version of WordPress.', 'default' ); if ( current_user_can( 'update_core' ) ) { echo wp_kses_post( - /* translators: %s: URL to WordPress Updates screen. */ - ' ' . __( 'Please update WordPress.', 'default' ), - esc_url( self_admin_url( 'update-core.php' ) ) + sprintf( + /* translators: %s: URL to WordPress Updates screen. */ + ' ' . __( 'Please update WordPress.', 'default' ), + esc_url( self_admin_url( 'update-core.php' ) ) + ) ); } } elseif ( ! $compatible_php ) { esc_html_e( 'This plugin does not work with your version of PHP.', 'default' ); if ( current_user_can( 'update_php' ) ) { echo wp_kses_post( - /* translators: %s: URL to Update PHP page. */ - ' ' . __( 'Learn more about updating PHP.', 'default' ), - esc_url( wp_get_update_php_url() ) + sprintf( + /* translators: %s: URL to Update PHP page. */ + ' ' . __( 'Learn more about updating PHP.', 'default' ), + esc_url( wp_get_update_php_url() ) + ) ); wp_update_php_annotation( '

', '

' ); } @@ -378,7 +388,7 @@ function perflab_render_plugin_card( array $plugin_data ) {
= 1000000 ) { - $active_installs_millions = floor( $plugin_data['active_installs'] / 1000000 ); + $active_installs_millions = (int) floor( $plugin_data['active_installs'] / 1000000 ); $active_installs_text = sprintf( /* translators: %s: Number of millions. */ _nx( '%s+ Million', '%s+ Million', $active_installs_millions, 'Active plugin installations', 'default' ), diff --git a/bin/plugin/commands/test-plugins.js b/bin/plugin/commands/test-plugins.js index 08a7b85a6b..1394698a2c 100644 --- a/bin/plugin/commands/test-plugins.js +++ b/bin/plugin/commands/test-plugins.js @@ -316,6 +316,18 @@ function doRunUnitTests( settings ) { ) ); + execSync( + `composer install --working-dir=${ settings.builtPluginsDir }${ plugin } --no-interaction`, + ( err, output ) => { + if ( err ) { + log( formats.error( `${ err }` ) ); + process.exit( 1 ); + } + // log the output received from the command + log( output ); + } + ); + // Define multi site flag based on single vs multi sitetype arg. const isMultiSite = 'multi' === settings.siteType; let command = ''; @@ -325,8 +337,8 @@ function doRunUnitTests( settings ) { 'wp-env', [ 'run', - 'phpunit', - `'WP_MULTISITE=1 phpunit -c /var/www/html/wp-content/plugins/${ plugin }/multisite.xml --verbose --testdox'`, + 'tests-cli', + `--env-cwd=/var/www/html/wp-content/plugins/${ plugin } vendor/bin/phpunit -c multisite.xml --verbose --testdox`, ], { shell: true, encoding: 'utf8' } ); @@ -335,8 +347,8 @@ function doRunUnitTests( settings ) { 'wp-env', [ 'run', - 'phpunit', - `'phpunit -c /var/www/html/wp-content/plugins/${ plugin }/phpunit.xml --verbose --testdox'`, + 'tests-cli', + `--env-cwd=/var/www/html/wp-content/plugins/${ plugin } vendor/bin/phpunit -c phpunit.xml --verbose --testdox`, ], { shell: true, encoding: 'utf8' } ); @@ -345,6 +357,9 @@ function doRunUnitTests( settings ) { log( command.stdout.replace( '\n', '' ) ); if ( 1 === command.status ) { + // Log error. + log( formats.error( command.stderr.replace( '\n', '' ) ) ); + log( formats.error( `One or more tests failed for plugin ${ plugin }` diff --git a/build-cs/composer.json b/build-cs/composer.json new file mode 100644 index 0000000000..d75d3943f6 --- /dev/null +++ b/build-cs/composer.json @@ -0,0 +1,20 @@ +{ + "require-dev": { + "dealerdirect/phpcodesniffer-composer-installer": "^0.7", + "phpcompatibility/php-compatibility": "^9.3", + "phpstan/extension-installer": "^1.3.0", + "phpstan/phpstan": "^1.10", + "phpstan/phpstan-deprecation-rules": "^1.1", + "phpstan/phpstan-phpunit": "^1.3", + "slevomat/coding-standard": "^8.0", + "squizlabs/php_codesniffer": "^3.5", + "szepeviktor/phpstan-wordpress": "^1.3.0", + "wp-coding-standards/wpcs": "^3.0.0" + }, + "config": { + "allow-plugins": { + "dealerdirect/phpcodesniffer-composer-installer": true, + "phpstan/extension-installer": true + } + } +} diff --git a/composer.json b/composer.json index 8ddca6af09..acb638d468 100644 --- a/composer.json +++ b/composer.json @@ -12,35 +12,27 @@ "issues": "https://github.com/WordPress/performance/issues" }, "require-dev": { - "dealerdirect/phpcodesniffer-composer-installer": "^0.7", - "phpcompatibility/php-compatibility": "^9.3", - "phpstan/extension-installer": "^1.3.0", - "phpstan/phpstan": "^1.10", - "squizlabs/php_codesniffer": "^3.5", - "szepeviktor/phpstan-wordpress": "^1.3.0", - "wp-coding-standards/wpcs": "^3.0.0", "wp-phpunit/wp-phpunit": "^5.8", - "yoast/phpunit-polyfills": "^1.0", - "phpstan/phpstan-phpunit": "^1.3", - "phpstan/phpstan-deprecation-rules": "^1.1", - "slevomat/coding-standard": "^8.0" + "yoast/phpunit-polyfills": "^1.0" }, "require": { "composer/installers": "~1.0", "php": ">=7|^8" }, "scripts": { - "phpstan": "phpstan analyze --ansi --memory-limit=2048M", - "format": "phpcbf --standard=phpcs.xml.dist --report-summary --report-source", - "lint": "phpcs --standard=phpcs.xml.dist", + "post-install-cmd": "if php -r 'exit( version_compare( phpversion(), \"8.1\", \">=\" ) ? 0 : 1 );'; then composer --working-dir=build-cs install --no-interaction; else echo 'Skipping composer install for build-cs since not on PHP 8.1+. You are running: '; php -v; fi", + "post-update-cmd": "if php -r 'exit( version_compare( phpversion(), \"8.1\", \">=\" ) ? 0 : 1 );'; then composer --working-dir=build-cs update --no-interaction; else echo 'Skipping composer update for build-cs since not on PHP 8.1+. You are running: '; php -v; fi", + "phpstan": "build-cs/vendor/bin/phpstan analyse --memory-limit=2048M -c phpstan.neon.dist", + "format": "build-cs/vendor/bin/phpcbf --standard=phpcs.xml.dist --report-summary --report-source", + "lint": "build-cs/vendor/bin/phpcs --standard=phpcs.xml.dist", "test": "phpunit -c phpunit.xml.dist --verbose", - "test-multisite": "WP_MULTISITE=1 phpunit -c tests/multisite.xml --verbose" + "test-multisite": "phpunit -c tests/multisite.xml --verbose" }, "config": { "allow-plugins": { - "dealerdirect/phpcodesniffer-composer-installer": true, "composer/installers": true, - "phpstan/extension-installer": true + "phpstan/extension-installer": true, + "dealerdirect/phpcodesniffer-composer-installer": true } }, "autoload-dev": { diff --git a/composer.lock b/composer.lock index 59e7347f06..b6c27e7892 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "8afb8511538e46c6875a017b72ad8711", + "content-hash": "bd9b816ae7c15eb36b10d97e807a6ce2", "packages": [ { "name": "composer/installers", @@ -159,81 +159,6 @@ } ], "packages-dev": [ - { - "name": "dealerdirect/phpcodesniffer-composer-installer", - "version": "v0.7.2", - "source": { - "type": "git", - "url": "https://github.com/Dealerdirect/phpcodesniffer-composer-installer.git", - "reference": "1c968e542d8843d7cd71de3c5c9c3ff3ad71a1db" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Dealerdirect/phpcodesniffer-composer-installer/zipball/1c968e542d8843d7cd71de3c5c9c3ff3ad71a1db", - "reference": "1c968e542d8843d7cd71de3c5c9c3ff3ad71a1db", - "shasum": "" - }, - "require": { - "composer-plugin-api": "^1.0 || ^2.0", - "php": ">=5.3", - "squizlabs/php_codesniffer": "^2.0 || ^3.1.0 || ^4.0" - }, - "require-dev": { - "composer/composer": "*", - "php-parallel-lint/php-parallel-lint": "^1.3.1", - "phpcompatibility/php-compatibility": "^9.0" - }, - "type": "composer-plugin", - "extra": { - "class": "Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\Plugin" - }, - "autoload": { - "psr-4": { - "Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Franck Nijhof", - "email": "franck.nijhof@dealerdirect.com", - "homepage": "http://www.frenck.nl", - "role": "Developer / IT Manager" - }, - { - "name": "Contributors", - "homepage": "https://github.com/Dealerdirect/phpcodesniffer-composer-installer/graphs/contributors" - } - ], - "description": "PHP_CodeSniffer Standards Composer Installer Plugin", - "homepage": "http://www.dealerdirect.com", - "keywords": [ - "PHPCodeSniffer", - "PHP_CodeSniffer", - "code quality", - "codesniffer", - "composer", - "installer", - "phpcbf", - "phpcs", - "plugin", - "qa", - "quality", - "standard", - "standards", - "style guide", - "stylecheck", - "tests" - ], - "support": { - "issues": "https://github.com/dealerdirect/phpcodesniffer-composer-installer/issues", - "source": "https://github.com/dealerdirect/phpcodesniffer-composer-installer" - }, - "time": "2022-02-04T12:51:07+00:00" - }, { "name": "doctrine/instantiator", "version": "2.0.0", @@ -365,25 +290,27 @@ }, { "name": "nikic/php-parser", - "version": "v4.17.1", + "version": "v5.0.0", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d" + "reference": "4a21235f7e56e713259a6f76bf4b5ea08502b9dc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d", - "reference": "a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/4a21235f7e56e713259a6f76bf4b5ea08502b9dc", + "reference": "4a21235f7e56e713259a6f76bf4b5ea08502b9dc", "shasum": "" }, "require": { + "ext-ctype": "*", + "ext-json": "*", "ext-tokenizer": "*", - "php": ">=7.0" + "php": ">=7.4" }, "require-dev": { "ircmaxell/php-yacc": "^0.0.7", - "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0" + "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0" }, "bin": [ "bin/php-parse" @@ -391,7 +318,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.9-dev" + "dev-master": "5.0-dev" } }, "autoload": { @@ -415,9 +342,9 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v4.17.1" + "source": "https://github.com/nikic/PHP-Parser/tree/v5.0.0" }, - "time": "2023-08-13T19:53:39+00:00" + "time": "2024-01-07T17:17:35+00:00" }, { "name": "phar-io/manifest", @@ -530,520 +457,25 @@ }, "time": "2022-02-21T01:04:05+00:00" }, - { - "name": "php-stubs/wordpress-stubs", - "version": "v6.3.0", - "source": { - "type": "git", - "url": "https://github.com/php-stubs/wordpress-stubs.git", - "reference": "adda7609e71d5f4dc7b87c74f8ec9e3437d2e92c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-stubs/wordpress-stubs/zipball/adda7609e71d5f4dc7b87c74f8ec9e3437d2e92c", - "reference": "adda7609e71d5f4dc7b87c74f8ec9e3437d2e92c", - "shasum": "" - }, - "require-dev": { - "nikic/php-parser": "^4.13", - "php": "^7.4 || ~8.0.0", - "php-stubs/generator": "^0.8.3", - "phpdocumentor/reflection-docblock": "^5.3", - "phpstan/phpstan": "^1.10.12", - "phpunit/phpunit": "^9.5" - }, - "suggest": { - "paragonie/sodium_compat": "Pure PHP implementation of libsodium", - "szepeviktor/phpstan-wordpress": "WordPress extensions for PHPStan" - }, - "type": "library", - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "WordPress function and class declaration stubs for static analysis.", - "homepage": "https://github.com/php-stubs/wordpress-stubs", - "keywords": [ - "PHPStan", - "static analysis", - "wordpress" - ], - "support": { - "issues": "https://github.com/php-stubs/wordpress-stubs/issues", - "source": "https://github.com/php-stubs/wordpress-stubs/tree/v6.3.0" - }, - "time": "2023-08-10T16:34:11+00:00" - }, - { - "name": "phpcompatibility/php-compatibility", - "version": "9.3.5", - "source": { - "type": "git", - "url": "https://github.com/PHPCompatibility/PHPCompatibility.git", - "reference": "9fb324479acf6f39452e0655d2429cc0d3914243" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/PHPCompatibility/PHPCompatibility/zipball/9fb324479acf6f39452e0655d2429cc0d3914243", - "reference": "9fb324479acf6f39452e0655d2429cc0d3914243", - "shasum": "" - }, - "require": { - "php": ">=5.3", - "squizlabs/php_codesniffer": "^2.3 || ^3.0.2" - }, - "conflict": { - "squizlabs/php_codesniffer": "2.6.2" - }, - "require-dev": { - "phpunit/phpunit": "~4.5 || ^5.0 || ^6.0 || ^7.0" - }, - "suggest": { - "dealerdirect/phpcodesniffer-composer-installer": "^0.5 || This Composer plugin will sort out the PHPCS 'installed_paths' automatically.", - "roave/security-advisories": "dev-master || Helps prevent installing dependencies with known security issues." - }, - "type": "phpcodesniffer-standard", - "notification-url": "https://packagist.org/downloads/", - "license": [ - "LGPL-3.0-or-later" - ], - "authors": [ - { - "name": "Wim Godden", - "homepage": "https://github.com/wimg", - "role": "lead" - }, - { - "name": "Juliette Reinders Folmer", - "homepage": "https://github.com/jrfnl", - "role": "lead" - }, - { - "name": "Contributors", - "homepage": "https://github.com/PHPCompatibility/PHPCompatibility/graphs/contributors" - } - ], - "description": "A set of sniffs for PHP_CodeSniffer that checks for PHP cross-version compatibility.", - "homepage": "http://techblog.wimgodden.be/tag/codesniffer/", - "keywords": [ - "compatibility", - "phpcs", - "standards" - ], - "support": { - "issues": "https://github.com/PHPCompatibility/PHPCompatibility/issues", - "source": "https://github.com/PHPCompatibility/PHPCompatibility" - }, - "time": "2019-12-27T09:44:58+00:00" - }, - { - "name": "phpcsstandards/phpcsextra", - "version": "1.1.2", - "source": { - "type": "git", - "url": "https://github.com/PHPCSStandards/PHPCSExtra.git", - "reference": "746c3190ba8eb2f212087c947ba75f4f5b9a58d5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/PHPCSStandards/PHPCSExtra/zipball/746c3190ba8eb2f212087c947ba75f4f5b9a58d5", - "reference": "746c3190ba8eb2f212087c947ba75f4f5b9a58d5", - "shasum": "" - }, - "require": { - "php": ">=5.4", - "phpcsstandards/phpcsutils": "^1.0.8", - "squizlabs/php_codesniffer": "^3.7.1" - }, - "require-dev": { - "php-parallel-lint/php-console-highlighter": "^1.0", - "php-parallel-lint/php-parallel-lint": "^1.3.2", - "phpcsstandards/phpcsdevcs": "^1.1.6", - "phpcsstandards/phpcsdevtools": "^1.2.1", - "phpunit/phpunit": "^4.5 || ^5.0 || ^6.0 || ^7.0" - }, - "type": "phpcodesniffer-standard", - "extra": { - "branch-alias": { - "dev-stable": "1.x-dev", - "dev-develop": "1.x-dev" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "LGPL-3.0-or-later" - ], - "authors": [ - { - "name": "Juliette Reinders Folmer", - "homepage": "https://github.com/jrfnl", - "role": "lead" - }, - { - "name": "Contributors", - "homepage": "https://github.com/PHPCSStandards/PHPCSExtra/graphs/contributors" - } - ], - "description": "A collection of sniffs and standards for use with PHP_CodeSniffer.", - "keywords": [ - "PHP_CodeSniffer", - "phpcbf", - "phpcodesniffer-standard", - "phpcs", - "standards", - "static analysis" - ], - "support": { - "issues": "https://github.com/PHPCSStandards/PHPCSExtra/issues", - "source": "https://github.com/PHPCSStandards/PHPCSExtra" - }, - "time": "2023-09-20T22:06:18+00:00" - }, - { - "name": "phpcsstandards/phpcsutils", - "version": "1.0.8", - "source": { - "type": "git", - "url": "https://github.com/PHPCSStandards/PHPCSUtils.git", - "reference": "69465cab9d12454e5e7767b9041af0cd8cd13be7" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/PHPCSStandards/PHPCSUtils/zipball/69465cab9d12454e5e7767b9041af0cd8cd13be7", - "reference": "69465cab9d12454e5e7767b9041af0cd8cd13be7", - "shasum": "" - }, - "require": { - "dealerdirect/phpcodesniffer-composer-installer": "^0.4.1 || ^0.5 || ^0.6.2 || ^0.7 || ^1.0", - "php": ">=5.4", - "squizlabs/php_codesniffer": "^3.7.1 || 4.0.x-dev@dev" - }, - "require-dev": { - "ext-filter": "*", - "php-parallel-lint/php-console-highlighter": "^1.0", - "php-parallel-lint/php-parallel-lint": "^1.3.2", - "phpcsstandards/phpcsdevcs": "^1.1.6", - "yoast/phpunit-polyfills": "^1.0.5 || ^2.0.0" - }, - "type": "phpcodesniffer-standard", - "extra": { - "branch-alias": { - "dev-stable": "1.x-dev", - "dev-develop": "1.x-dev" - } - }, - "autoload": { - "classmap": [ - "PHPCSUtils/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "LGPL-3.0-or-later" - ], - "authors": [ - { - "name": "Juliette Reinders Folmer", - "homepage": "https://github.com/jrfnl", - "role": "lead" - }, - { - "name": "Contributors", - "homepage": "https://github.com/PHPCSStandards/PHPCSUtils/graphs/contributors" - } - ], - "description": "A suite of utility functions for use with PHP_CodeSniffer", - "homepage": "https://phpcsutils.com/", - "keywords": [ - "PHP_CodeSniffer", - "phpcbf", - "phpcodesniffer-standard", - "phpcs", - "phpcs3", - "standards", - "static analysis", - "tokens", - "utility" - ], - "support": { - "docs": "https://phpcsutils.com/", - "issues": "https://github.com/PHPCSStandards/PHPCSUtils/issues", - "source": "https://github.com/PHPCSStandards/PHPCSUtils" - }, - "time": "2023-07-16T21:39:41+00:00" - }, - { - "name": "phpstan/extension-installer", - "version": "1.3.1", - "source": { - "type": "git", - "url": "https://github.com/phpstan/extension-installer.git", - "reference": "f45734bfb9984c6c56c4486b71230355f066a58a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpstan/extension-installer/zipball/f45734bfb9984c6c56c4486b71230355f066a58a", - "reference": "f45734bfb9984c6c56c4486b71230355f066a58a", - "shasum": "" - }, - "require": { - "composer-plugin-api": "^2.0", - "php": "^7.2 || ^8.0", - "phpstan/phpstan": "^1.9.0" - }, - "require-dev": { - "composer/composer": "^2.0", - "php-parallel-lint/php-parallel-lint": "^1.2.0", - "phpstan/phpstan-strict-rules": "^0.11 || ^0.12 || ^1.0" - }, - "type": "composer-plugin", - "extra": { - "class": "PHPStan\\ExtensionInstaller\\Plugin" - }, - "autoload": { - "psr-4": { - "PHPStan\\ExtensionInstaller\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "Composer plugin for automatic installation of PHPStan extensions", - "support": { - "issues": "https://github.com/phpstan/extension-installer/issues", - "source": "https://github.com/phpstan/extension-installer/tree/1.3.1" - }, - "time": "2023-05-24T08:59:17+00:00" - }, - { - "name": "phpstan/phpdoc-parser", - "version": "1.24.2", - "source": { - "type": "git", - "url": "https://github.com/phpstan/phpdoc-parser.git", - "reference": "bcad8d995980440892759db0c32acae7c8e79442" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/bcad8d995980440892759db0c32acae7c8e79442", - "reference": "bcad8d995980440892759db0c32acae7c8e79442", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0" - }, - "require-dev": { - "doctrine/annotations": "^2.0", - "nikic/php-parser": "^4.15", - "php-parallel-lint/php-parallel-lint": "^1.2", - "phpstan/extension-installer": "^1.0", - "phpstan/phpstan": "^1.5", - "phpstan/phpstan-phpunit": "^1.1", - "phpstan/phpstan-strict-rules": "^1.0", - "phpunit/phpunit": "^9.5", - "symfony/process": "^5.2" - }, - "type": "library", - "autoload": { - "psr-4": { - "PHPStan\\PhpDocParser\\": [ - "src/" - ] - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "PHPDoc parser with support for nullable, intersection and generic types", - "support": { - "issues": "https://github.com/phpstan/phpdoc-parser/issues", - "source": "https://github.com/phpstan/phpdoc-parser/tree/1.24.2" - }, - "time": "2023-09-26T12:28:12+00:00" - }, - { - "name": "phpstan/phpstan", - "version": "1.10.38", - "source": { - "type": "git", - "url": "https://github.com/phpstan/phpstan.git", - "reference": "5302bb402c57f00fb3c2c015bac86e0827e4b691" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/5302bb402c57f00fb3c2c015bac86e0827e4b691", - "reference": "5302bb402c57f00fb3c2c015bac86e0827e4b691", - "shasum": "" - }, - "require": { - "php": "^7.2|^8.0" - }, - "conflict": { - "phpstan/phpstan-shim": "*" - }, - "bin": [ - "phpstan", - "phpstan.phar" - ], - "type": "library", - "autoload": { - "files": [ - "bootstrap.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "PHPStan - PHP Static Analysis Tool", - "keywords": [ - "dev", - "static analysis" - ], - "support": { - "docs": "https://phpstan.org/user-guide/getting-started", - "forum": "https://github.com/phpstan/phpstan/discussions", - "issues": "https://github.com/phpstan/phpstan/issues", - "security": "https://github.com/phpstan/phpstan/security/policy", - "source": "https://github.com/phpstan/phpstan-src" - }, - "funding": [ - { - "url": "https://github.com/ondrejmirtes", - "type": "github" - }, - { - "url": "https://github.com/phpstan", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/phpstan/phpstan", - "type": "tidelift" - } - ], - "time": "2023-10-06T14:19:14+00:00" - }, - { - "name": "phpstan/phpstan-deprecation-rules", - "version": "1.1.4", - "source": { - "type": "git", - "url": "https://github.com/phpstan/phpstan-deprecation-rules.git", - "reference": "089d8a8258ed0aeefdc7b68b6c3d25572ebfdbaa" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan-deprecation-rules/zipball/089d8a8258ed0aeefdc7b68b6c3d25572ebfdbaa", - "reference": "089d8a8258ed0aeefdc7b68b6c3d25572ebfdbaa", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0", - "phpstan/phpstan": "^1.10.3" - }, - "require-dev": { - "php-parallel-lint/php-parallel-lint": "^1.2", - "phpstan/phpstan-php-parser": "^1.1", - "phpstan/phpstan-phpunit": "^1.0", - "phpunit/phpunit": "^9.5" - }, - "type": "phpstan-extension", - "extra": { - "phpstan": { - "includes": [ - "rules.neon" - ] - } - }, - "autoload": { - "psr-4": { - "PHPStan\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "PHPStan rules for detecting usage of deprecated classes, methods, properties, constants and traits.", - "support": { - "issues": "https://github.com/phpstan/phpstan-deprecation-rules/issues", - "source": "https://github.com/phpstan/phpstan-deprecation-rules/tree/1.1.4" - }, - "time": "2023-08-05T09:02:04+00:00" - }, - { - "name": "phpstan/phpstan-phpunit", - "version": "1.3.15", - "source": { - "type": "git", - "url": "https://github.com/phpstan/phpstan-phpunit.git", - "reference": "70ecacc64fe8090d8d2a33db5a51fe8e88acd93a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan-phpunit/zipball/70ecacc64fe8090d8d2a33db5a51fe8e88acd93a", - "reference": "70ecacc64fe8090d8d2a33db5a51fe8e88acd93a", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0", - "phpstan/phpstan": "^1.10" - }, - "conflict": { - "phpunit/phpunit": "<7.0" - }, - "require-dev": { - "nikic/php-parser": "^4.13.0", - "php-parallel-lint/php-parallel-lint": "^1.2", - "phpstan/phpstan-strict-rules": "^1.5.1", - "phpunit/phpunit": "^9.5" - }, - "type": "phpstan-extension", - "extra": { - "phpstan": { - "includes": [ - "extension.neon", - "rules.neon" - ] - } - }, - "autoload": { - "psr-4": { - "PHPStan\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "PHPUnit extensions and rules for PHPStan", - "support": { - "issues": "https://github.com/phpstan/phpstan-phpunit/issues", - "source": "https://github.com/phpstan/phpstan-phpunit/tree/1.3.15" - }, - "time": "2023-10-09T18:58:39+00:00" - }, { "name": "phpunit/php-code-coverage", - "version": "9.2.29", + "version": "9.2.30", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "6a3a87ac2bbe33b25042753df8195ba4aa534c76" + "reference": "ca2bd87d2f9215904682a9cb9bb37dda98e76089" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/6a3a87ac2bbe33b25042753df8195ba4aa534c76", - "reference": "6a3a87ac2bbe33b25042753df8195ba4aa534c76", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/ca2bd87d2f9215904682a9cb9bb37dda98e76089", + "reference": "ca2bd87d2f9215904682a9cb9bb37dda98e76089", "shasum": "" }, "require": { "ext-dom": "*", "ext-libxml": "*", "ext-xmlwriter": "*", - "nikic/php-parser": "^4.15", + "nikic/php-parser": "^4.18 || ^5.0", "php": ">=7.3", "phpunit/php-file-iterator": "^3.0.3", "phpunit/php-text-template": "^2.0.2", @@ -1093,7 +525,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.29" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.30" }, "funding": [ { @@ -1101,7 +533,7 @@ "type": "github" } ], - "time": "2023-09-19T04:57:46+00:00" + "time": "2023-12-22T06:47:57+00:00" }, { "name": "phpunit/php-file-iterator", @@ -1346,16 +778,16 @@ }, { "name": "phpunit/phpunit", - "version": "9.6.13", + "version": "9.6.16", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "f3d767f7f9e191eab4189abe41ab37797e30b1be" + "reference": "3767b2c56ce02d01e3491046f33466a1ae60a37f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/f3d767f7f9e191eab4189abe41ab37797e30b1be", - "reference": "f3d767f7f9e191eab4189abe41ab37797e30b1be", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/3767b2c56ce02d01e3491046f33466a1ae60a37f", + "reference": "3767b2c56ce02d01e3491046f33466a1ae60a37f", "shasum": "" }, "require": { @@ -1429,7 +861,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.13" + "source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.16" }, "funding": [ { @@ -1445,7 +877,7 @@ "type": "tidelift" } ], - "time": "2023-09-19T05:39:22+00:00" + "time": "2024-01-19T07:03:14+00:00" }, { "name": "sebastian/cli-parser", @@ -1690,20 +1122,20 @@ }, { "name": "sebastian/complexity", - "version": "2.0.2", + "version": "2.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/complexity.git", - "reference": "739b35e53379900cc9ac327b2147867b8b6efd88" + "reference": "25f207c40d62b8b7aa32f5ab026c53561964053a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/739b35e53379900cc9ac327b2147867b8b6efd88", - "reference": "739b35e53379900cc9ac327b2147867b8b6efd88", + "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/25f207c40d62b8b7aa32f5ab026c53561964053a", + "reference": "25f207c40d62b8b7aa32f5ab026c53561964053a", "shasum": "" }, "require": { - "nikic/php-parser": "^4.7", + "nikic/php-parser": "^4.18 || ^5.0", "php": ">=7.3" }, "require-dev": { @@ -1735,7 +1167,7 @@ "homepage": "https://github.com/sebastianbergmann/complexity", "support": { "issues": "https://github.com/sebastianbergmann/complexity/issues", - "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.2" + "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.3" }, "funding": [ { @@ -1743,7 +1175,7 @@ "type": "github" } ], - "time": "2020-10-26T15:52:27+00:00" + "time": "2023-12-22T06:19:30+00:00" }, { "name": "sebastian/diff", @@ -2017,20 +1449,20 @@ }, { "name": "sebastian/lines-of-code", - "version": "1.0.3", + "version": "1.0.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/lines-of-code.git", - "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc" + "reference": "e1e4a170560925c26d424b6a03aed157e7dcc5c5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/c1c2e997aa3146983ed888ad08b15470a2e22ecc", - "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/e1e4a170560925c26d424b6a03aed157e7dcc5c5", + "reference": "e1e4a170560925c26d424b6a03aed157e7dcc5c5", "shasum": "" }, "require": { - "nikic/php-parser": "^4.6", + "nikic/php-parser": "^4.18 || ^5.0", "php": ">=7.3" }, "require-dev": { @@ -2062,7 +1494,7 @@ "homepage": "https://github.com/sebastianbergmann/lines-of-code", "support": { "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", - "source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.3" + "source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.4" }, "funding": [ { @@ -2070,7 +1502,7 @@ "type": "github" } ], - "time": "2020-11-28T06:42:11+00:00" + "time": "2023-12-22T06:20:34+00:00" }, { "name": "sebastian/object-enumerator", @@ -2411,278 +1843,18 @@ ], "time": "2020-09-28T06:39:44+00:00" }, - { - "name": "slevomat/coding-standard", - "version": "8.14.1", - "source": { - "type": "git", - "url": "https://github.com/slevomat/coding-standard.git", - "reference": "fea1fd6f137cc84f9cba0ae30d549615dbc6a926" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/slevomat/coding-standard/zipball/fea1fd6f137cc84f9cba0ae30d549615dbc6a926", - "reference": "fea1fd6f137cc84f9cba0ae30d549615dbc6a926", - "shasum": "" - }, - "require": { - "dealerdirect/phpcodesniffer-composer-installer": "^0.6.2 || ^0.7 || ^1.0", - "php": "^7.2 || ^8.0", - "phpstan/phpdoc-parser": "^1.23.1", - "squizlabs/php_codesniffer": "^3.7.1" - }, - "require-dev": { - "phing/phing": "2.17.4", - "php-parallel-lint/php-parallel-lint": "1.3.2", - "phpstan/phpstan": "1.10.37", - "phpstan/phpstan-deprecation-rules": "1.1.4", - "phpstan/phpstan-phpunit": "1.3.14", - "phpstan/phpstan-strict-rules": "1.5.1", - "phpunit/phpunit": "8.5.21|9.6.8|10.3.5" - }, - "type": "phpcodesniffer-standard", - "extra": { - "branch-alias": { - "dev-master": "8.x-dev" - } - }, - "autoload": { - "psr-4": { - "SlevomatCodingStandard\\": "SlevomatCodingStandard/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "Slevomat Coding Standard for PHP_CodeSniffer complements Consistence Coding Standard by providing sniffs with additional checks.", - "keywords": [ - "dev", - "phpcs" - ], - "support": { - "issues": "https://github.com/slevomat/coding-standard/issues", - "source": "https://github.com/slevomat/coding-standard/tree/8.14.1" - }, - "funding": [ - { - "url": "https://github.com/kukulich", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/slevomat/coding-standard", - "type": "tidelift" - } - ], - "time": "2023-10-08T07:28:08+00:00" - }, - { - "name": "squizlabs/php_codesniffer", - "version": "3.7.2", - "source": { - "type": "git", - "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", - "reference": "ed8e00df0a83aa96acf703f8c2979ff33341f879" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/ed8e00df0a83aa96acf703f8c2979ff33341f879", - "reference": "ed8e00df0a83aa96acf703f8c2979ff33341f879", - "shasum": "" - }, - "require": { - "ext-simplexml": "*", - "ext-tokenizer": "*", - "ext-xmlwriter": "*", - "php": ">=5.4.0" - }, - "require-dev": { - "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0" - }, - "bin": [ - "bin/phpcs", - "bin/phpcbf" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.x-dev" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Greg Sherwood", - "role": "lead" - } - ], - "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", - "homepage": "https://github.com/squizlabs/PHP_CodeSniffer", - "keywords": [ - "phpcs", - "standards", - "static analysis" - ], - "support": { - "issues": "https://github.com/squizlabs/PHP_CodeSniffer/issues", - "source": "https://github.com/squizlabs/PHP_CodeSniffer", - "wiki": "https://github.com/squizlabs/PHP_CodeSniffer/wiki" - }, - "time": "2023-02-22T23:07:41+00:00" - }, - { - "name": "symfony/polyfill-php73", - "version": "v1.28.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php73.git", - "reference": "fe2f306d1d9d346a7fee353d0d5012e401e984b5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/fe2f306d1d9d346a7fee353d0d5012e401e984b5", - "reference": "fe2f306d1d9d346a7fee353d0d5012e401e984b5", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.28-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Php73\\": "" - }, - "classmap": [ - "Resources/stubs" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting some PHP 7.3+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-php73/tree/v1.28.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2023-01-26T09:26:14+00:00" - }, - { - "name": "szepeviktor/phpstan-wordpress", - "version": "v1.3.0", - "source": { - "type": "git", - "url": "https://github.com/szepeviktor/phpstan-wordpress.git", - "reference": "5b5cc77ed51fdaf64efe3f00b5aae4b709d2cfa9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/szepeviktor/phpstan-wordpress/zipball/5b5cc77ed51fdaf64efe3f00b5aae4b709d2cfa9", - "reference": "5b5cc77ed51fdaf64efe3f00b5aae4b709d2cfa9", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0", - "php-stubs/wordpress-stubs": "^4.7 || ^5.0 || ^6.0", - "phpstan/phpstan": "^1.10.0", - "symfony/polyfill-php73": "^1.12.0" - }, - "require-dev": { - "composer/composer": "^2.1.14", - "dealerdirect/phpcodesniffer-composer-installer": "^1.0", - "php-parallel-lint/php-parallel-lint": "^1.1", - "phpstan/phpstan-strict-rules": "^1.2", - "phpunit/phpunit": "^8.0 || ^9.0", - "szepeviktor/phpcs-psr-12-neutron-hybrid-ruleset": "^0.8" - }, - "type": "phpstan-extension", - "extra": { - "phpstan": { - "includes": [ - "extension.neon" - ] - } - }, - "autoload": { - "psr-4": { - "SzepeViktor\\PHPStan\\WordPress\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "WordPress extensions for PHPStan", - "keywords": [ - "PHPStan", - "code analyse", - "code analysis", - "static analysis", - "wordpress" - ], - "support": { - "issues": "https://github.com/szepeviktor/phpstan-wordpress/issues", - "source": "https://github.com/szepeviktor/phpstan-wordpress/tree/v1.3.0" - }, - "time": "2023-04-23T06:15:06+00:00" - }, { "name": "theseer/tokenizer", - "version": "1.2.1", + "version": "1.2.2", "source": { "type": "git", "url": "https://github.com/theseer/tokenizer.git", - "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e" + "reference": "b2ad5003ca10d4ee50a12da31de12a5774ba6b96" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/theseer/tokenizer/zipball/34a41e998c2183e22995f158c581e7b5e755ab9e", - "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/b2ad5003ca10d4ee50a12da31de12a5774ba6b96", + "reference": "b2ad5003ca10d4ee50a12da31de12a5774ba6b96", "shasum": "" }, "require": { @@ -2711,7 +1883,7 @@ "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", "support": { "issues": "https://github.com/theseer/tokenizer/issues", - "source": "https://github.com/theseer/tokenizer/tree/1.2.1" + "source": "https://github.com/theseer/tokenizer/tree/1.2.2" }, "funding": [ { @@ -2719,77 +1891,11 @@ "type": "github" } ], - "time": "2021-07-28T10:34:58+00:00" - }, - { - "name": "wp-coding-standards/wpcs", - "version": "3.0.1", - "source": { - "type": "git", - "url": "https://github.com/WordPress/WordPress-Coding-Standards.git", - "reference": "b4caf9689f1a0e4a4c632679a44e638c1c67aff1" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/WordPress/WordPress-Coding-Standards/zipball/b4caf9689f1a0e4a4c632679a44e638c1c67aff1", - "reference": "b4caf9689f1a0e4a4c632679a44e638c1c67aff1", - "shasum": "" - }, - "require": { - "ext-filter": "*", - "ext-libxml": "*", - "ext-tokenizer": "*", - "ext-xmlreader": "*", - "php": ">=5.4", - "phpcsstandards/phpcsextra": "^1.1.0", - "phpcsstandards/phpcsutils": "^1.0.8", - "squizlabs/php_codesniffer": "^3.7.2" - }, - "require-dev": { - "php-parallel-lint/php-console-highlighter": "^1.0.0", - "php-parallel-lint/php-parallel-lint": "^1.3.2", - "phpcompatibility/php-compatibility": "^9.0", - "phpcsstandards/phpcsdevtools": "^1.2.0", - "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0" - }, - "suggest": { - "ext-iconv": "For improved results", - "ext-mbstring": "For improved results" - }, - "type": "phpcodesniffer-standard", - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Contributors", - "homepage": "https://github.com/WordPress/WordPress-Coding-Standards/graphs/contributors" - } - ], - "description": "PHP_CodeSniffer rules (sniffs) to enforce WordPress coding conventions", - "keywords": [ - "phpcs", - "standards", - "static analysis", - "wordpress" - ], - "support": { - "issues": "https://github.com/WordPress/WordPress-Coding-Standards/issues", - "source": "https://github.com/WordPress/WordPress-Coding-Standards", - "wiki": "https://github.com/WordPress/WordPress-Coding-Standards/wiki" - }, - "funding": [ - { - "url": "https://opencollective.com/thewpcc/contribute/wp-php-63406", - "type": "custom" - } - ], - "time": "2023-09-14T07:06:09+00:00" + "time": "2023-11-20T00:12:19+00:00" }, { "name": "wp-phpunit/wp-phpunit", - "version": "5.9.7", + "version": "5.9.8", "source": { "type": "git", "url": "https://github.com/wp-phpunit/wp-phpunit.git", diff --git a/load.php b/load.php index 2f71b5d99a..23f8503463 100644 --- a/load.php +++ b/load.php @@ -5,7 +5,7 @@ * Description: Performance plugin from the WordPress Performance Team, which is a collection of standalone performance modules. * Requires at least: 6.3 * Requires PHP: 7.0 - * Version: 2.7.0 + * Version: 2.8.0 * Author: WordPress Performance Team * Author URI: https://make.wordpress.org/performance/ * License: GPLv2 or later @@ -19,7 +19,7 @@ exit; // Exit if accessed directly. } -define( 'PERFLAB_VERSION', '2.7.0' ); +define( 'PERFLAB_VERSION', '2.8.0' ); define( 'PERFLAB_MAIN_FILE', __FILE__ ); define( 'PERFLAB_PLUGIN_DIR_PATH', plugin_dir_path( PERFLAB_MAIN_FILE ) ); define( 'PERFLAB_MODULES_SETTING', 'perflab_modules_settings' ); @@ -207,14 +207,23 @@ function perflab_is_valid_module( $module ) { * This attribute is then used in {@see perflab_render_generator()}. * * @since 1.1.0 + * @since n.e.x.t The generator tag now includes the active standalone plugin slugs. */ function perflab_get_generator_content() { $active_and_valid_modules = array_filter( perflab_get_active_modules(), 'perflab_is_valid_module' ); + $active_plugins = array(); + foreach ( perflab_get_standalone_plugin_version_constants( 'plugins' ) as $plugin_slug => $constant_name ) { + if ( defined( $constant_name ) && ! str_starts_with( constant( $constant_name ), 'Performance Lab ' ) ) { + $active_plugins[] = $plugin_slug; + } + } + return sprintf( - 'Performance Lab %1$s; modules: %2$s', + 'Performance Lab %1$s; modules: %2$s; plugins: %3$s', PERFLAB_VERSION, - implode( ', ', $active_and_valid_modules ) + implode( ', ', $active_and_valid_modules ), + implode( ', ', $active_plugins ) ); } @@ -236,7 +245,7 @@ function perflab_render_generator() { * Checks whether the given module can be loaded in the current environment. * * @since 1.3.0 - * @since n.e.x.t The function may now alternatively return a WP_Error. + * @since 2.8.0 The function may now alternatively return a WP_Error. * * @param string $module Slug of the module. * @return bool|WP_Error True if the module can be loaded, or false or a WP_Error with more concrete information otherwise. @@ -276,7 +285,7 @@ function perflab_can_load_module( $module ) { * @return bool Whether the module has already been loaded by a separate plugin. */ function perflab_is_standalone_plugin_loaded( $module ) { - $standalone_plugins_constants = perflab_get_standalone_plugins_constants(); + $standalone_plugins_constants = perflab_get_standalone_plugin_version_constants( 'modules' ); if ( isset( $standalone_plugins_constants[ $module ] ) && defined( $standalone_plugins_constants[ $module ] ) && @@ -288,16 +297,48 @@ function perflab_is_standalone_plugin_loaded( $module ) { } /** - * Gets the standalone plugin constants used for each module / plugin. + * Gets the standalone plugin constants used for each module with a standalone plugin. * * @since 2.2.0 + * @deprecated 2.9.0 * * @return array Map of module path to version constant used. */ function perflab_get_standalone_plugins_constants() { + _deprecated_function( __FUNCTION__, 'Performance Lab 2.9.0', "perflab_get_standalone_plugin_version_constants( 'modules' )" ); + return perflab_get_standalone_plugin_version_constants( 'modules' ); +} + +/** + * Gets the standalone plugin constants used for each available standalone plugin, or module with a standalone plugin. + * + * @since n.e.x.t + * + * @param string $source Optional. Either 'plugins' or 'modules'. Default 'plugins'. + * @return array Map of plugin slug / module path and the version constant used. + */ +function perflab_get_standalone_plugin_version_constants( $source = 'plugins' ) { + if ( 'modules' === $source ) { + /* + * This list includes all modules which are also available as standalone plugins, + * as `$module_dir => $version_constant` pairs. + */ + return array( + 'images/dominant-color-images' => 'DOMINANT_COLOR_IMAGES_VERSION', + 'images/webp-uploads' => 'WEBP_UPLOADS_VERSION', + ); + } + + /* + * This list includes all standalone plugins that are part of the Performance Lab project, + * as `$plugin_slug => $version_constant` pairs. + */ return array( - 'images/dominant-color-images' => 'DOMINANT_COLOR_IMAGES_VERSION', - 'images/webp-uploads' => 'WEBP_UPLOADS_VERSION', + 'webp-uploads' => 'WEBP_UPLOADS_VERSION', + 'dominant-color-images' => 'DOMINANT_COLOR_IMAGES_VERSION', + 'performant-translations' => 'PERFORMANT_TRANSLATIONS_VERSION', + 'auto-sizes' => 'IMAGE_AUTO_SIZES_VERSION', + 'speculation-rules' => 'SPECULATION_RULES_VERSION', ); } @@ -535,7 +576,7 @@ function perflab_run_module_activation_deactivation( $old_value, $value ) { /** * Reverts the module migration pointer dismissal for the given user. * - * @since n.e.x.t + * @since 2.8.0 * * @param WP_User $user The WP_User object. */ diff --git a/modules/database/audit-autoloaded-options/can-load.php b/modules/database/audit-autoloaded-options/can-load.php index 230f62cbe5..274a266348 100644 --- a/modules/database/audit-autoloaded-options/can-load.php +++ b/modules/database/audit-autoloaded-options/can-load.php @@ -2,7 +2,7 @@ /** * Can load function to determine if Site Health module is supported or not. * - * @since n.e.x.t + * @since 2.8.0 * @package performance-lab */ diff --git a/modules/images/webp-support/can-load.php b/modules/images/webp-support/can-load.php index 230f62cbe5..274a266348 100644 --- a/modules/images/webp-support/can-load.php +++ b/modules/images/webp-support/can-load.php @@ -2,7 +2,7 @@ /** * Can load function to determine if Site Health module is supported or not. * - * @since n.e.x.t + * @since 2.8.0 * @package performance-lab */ diff --git a/modules/images/webp-uploads/fallback.js b/modules/images/webp-uploads/fallback.js index 9adc3ad1cb..d1b900411c 100644 --- a/modules/images/webp-uploads/fallback.js +++ b/modules/images/webp-uploads/fallback.js @@ -1,31 +1,41 @@ +/* eslint no-var: "off", camelcase: "off" */ + window.wpPerfLab = window.wpPerfLab || {}; -( function( document ) { - window.wpPerfLab.webpUploadsFallbackWebpImages = function( media ) { - for ( var i = 0; i < media.length; i++ ) { +( function ( document ) { + window.wpPerfLab.webpUploadsFallbackWebpImages = function ( media ) { + for ( let i = 0; i < media.length; i++ ) { try { - var image = media[ i ], + var image = media[ i ], media_details = image.media_details, media_sources = media_details.sources, - sizes = media_details.sizes, - sizes_keys = Object.keys( sizes ); + sizes = media_details.sizes, + sizes_keys = Object.keys( sizes ); // If the full image has no JPEG version available, no sub-size will have JPEG available either. - if ( sizes.full && ! sizes.full.sources['image/jpeg'] ) { + if ( sizes.full && ! sizes.full.sources[ 'image/jpeg' ] ) { continue; } - var images = document.querySelectorAll( 'img.wp-image-' + image.id ); - - for ( var j = 0; j < images.length; j++ ) { + var images = document.querySelectorAll( + 'img.wp-image-' + image.id + ); + for ( let j = 0; j < images.length; j++ ) { var src = images[ j ].src; // If there are sources but no sizes, then attempt to replace src through sources. In that case, there is nothing more to replace. if ( media_sources && ! sizes_keys.length ) { // Only modify src if available and the relevant sources are set. - if ( src && media_sources['image/webp'] && media_sources['image/jpeg'] ) { - src = src.replace( media_sources['image/webp'].file, media_sources['image/jpeg'].file ); + if ( + src && + media_sources[ 'image/webp' ] && + media_sources[ 'image/jpeg' ] + ) { + src = src.replace( + media_sources[ 'image/webp' ].file, + media_sources[ 'image/jpeg' ].file + ); images[ j ].setAttribute( 'src', src ); } continue; @@ -33,15 +43,24 @@ window.wpPerfLab = window.wpPerfLab || {}; var srcset = images[ j ].getAttribute( 'srcset' ); - for ( var k = 0; k < sizes_keys.length; k++ ) { - var media_sizes_sources = sizes[ sizes_keys[ k ] ].sources; - if ( ! media_sizes_sources || ! media_sizes_sources['image/webp'] || ! media_sizes_sources['image/jpeg'] ) { + for ( let k = 0; k < sizes_keys.length; k++ ) { + var media_sizes_sources = + sizes[ sizes_keys[ k ] ].sources; + if ( + ! media_sizes_sources || + ! media_sizes_sources[ 'image/webp' ] || + ! media_sizes_sources[ 'image/jpeg' ] + ) { continue; } // Check to see if the image src has any size set, then update it. - if ( media_sizes_sources['image/webp'].source_url === src ) { - src = media_sizes_sources['image/jpeg'].source_url; + if ( + media_sizes_sources[ 'image/webp' ].source_url === + src + ) { + src = + media_sizes_sources[ 'image/jpeg' ].source_url; // If there is no srcset and the src has been replaced, there is nothing more to replace. if ( ! srcset ) { @@ -50,7 +69,10 @@ window.wpPerfLab = window.wpPerfLab || {}; } if ( srcset ) { - srcset = srcset.replace( media_sizes_sources['image/webp'].source_url, media_sizes_sources['image/jpeg'].source_url ); + srcset = srcset.replace( + media_sizes_sources[ 'image/webp' ].source_url, + media_sizes_sources[ 'image/jpeg' ].source_url + ); } } @@ -62,40 +84,52 @@ window.wpPerfLab = window.wpPerfLab || {}; images[ j ].setAttribute( 'src', src ); } } - } catch ( e ) { - } + } catch ( e ) {} } }; - var restApi = document.getElementById( 'webpUploadsFallbackWebpImages' ).getAttribute( 'data-rest-api' ); + var restApi = document + .getElementById( 'webpUploadsFallbackWebpImages' ) + .getAttribute( 'data-rest-api' ); - var loadMediaDetails = function( nodes ) { + var loadMediaDetails = function ( nodes ) { var ids = []; - for ( var i = 0; i < nodes.length; i++ ) { + for ( let i = 0; i < nodes.length; i++ ) { var node = nodes[ i ]; var srcset = node.getAttribute( 'srcset' ) || ''; if ( - node.nodeName !== "IMG" || - ( ! node.src.match( /\.webp$/i ) && ! srcset.match( /\.webp\s+/ ) ) + node.nodeName !== 'IMG' || + ( ! node.src.match( /\.webp$/i ) && + ! srcset.match( /\.webp\s+/ ) ) ) { continue; } var attachment = node.className.match( /wp-image-(\d+)/i ); - if ( attachment && attachment[1] && ids.indexOf( attachment[1] ) === -1 ) { - ids.push( attachment[1] ); + if ( + attachment && + attachment[ 1 ] && + ids.indexOf( attachment[ 1 ] ) === -1 + ) { + ids.push( attachment[ 1 ] ); } } - for ( var page = 0, pages = Math.ceil( ids.length / 100 ); page < pages; page++ ) { + for ( + let page = 0, pages = Math.ceil( ids.length / 100 ); + page < pages; + page++ + ) { var pageIds = []; - for ( var i = 0; i < 100 && i + page * 100 < ids.length; i++ ) { + for ( let i = 0; i < 100 && i + page * 100 < ids.length; i++ ) { pageIds.push( ids[ i + page * 100 ] ); } var jsonp = document.createElement( 'script' ); - var restPath = 'wp/v2/media/?_fields=id,media_details&_jsonp=wpPerfLab.webpUploadsFallbackWebpImages&per_page=100&include=' + pageIds.join( ',' ); + var restPath = + 'wp/v2/media/?_fields=id,media_details&_jsonp=wpPerfLab.webpUploadsFallbackWebpImages&per_page=100&include=' + + pageIds.join( ',' ); if ( -1 !== restApi.indexOf( '?' ) ) { restPath = restPath.replace( '?', '&' ); } @@ -109,8 +143,8 @@ window.wpPerfLab = window.wpPerfLab || {}; loadMediaDetails( document.querySelectorAll( 'img' ) ); // Start the mutation observer to update images added dynamically. - var observer = new MutationObserver( function( mutationList ) { - for ( var i = 0; i < mutationList.length; i++ ) { + var observer = new MutationObserver( function ( mutationList ) { + for ( let i = 0; i < mutationList.length; i++ ) { loadMediaDetails( mutationList[ i ].addedNodes ); } } ); @@ -119,6 +153,5 @@ window.wpPerfLab = window.wpPerfLab || {}; subtree: true, childList: true, } ); - } catch ( e ) { - } + } catch ( e ) {} } )( document ); diff --git a/modules/js-and-css/audit-enqueued-assets/can-load.php b/modules/js-and-css/audit-enqueued-assets/can-load.php index 230f62cbe5..274a266348 100644 --- a/modules/js-and-css/audit-enqueued-assets/can-load.php +++ b/modules/js-and-css/audit-enqueued-assets/can-load.php @@ -2,7 +2,7 @@ /** * Can load function to determine if Site Health module is supported or not. * - * @since n.e.x.t + * @since 2.8.0 * @package performance-lab */ diff --git a/package-lock.json b/package-lock.json index a0cebf590a..54ca2008e4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,7 +8,7 @@ "license": "GPL-2.0-or-later", "devDependencies": { "@octokit/rest": "^19.0.5", - "@wordpress/env": "^5.7.0", + "@wordpress/env": "^8.13.0", "@wordpress/scripts": "^26.19.0", "chalk": "^4.1.2", "commander": "^9.4.1", @@ -4917,9 +4917,9 @@ } }, "node_modules/@wordpress/env": { - "version": "5.16.0", - "resolved": "https://registry.npmjs.org/@wordpress/env/-/env-5.16.0.tgz", - "integrity": "sha512-zx6UO8PuJBrQ34cfeedK1HlGHLFaj7oWzTo9tTt+noB79Ttqc4+a0lYwDqBLLJhlHU+cWgcyOP2lB6TboXH0xA==", + "version": "8.13.0", + "resolved": "https://registry.npmjs.org/@wordpress/env/-/env-8.13.0.tgz", + "integrity": "sha512-rtrrBO22DnbLsdBlsGqlMQrjz1dZfbwGnxyKev+gFd1rSfmLs+1F8L89RHOx9vsGPixl5uRwoU/qgYo7Hf1NVQ==", "dev": true, "dependencies": { "chalk": "^4.0.0", @@ -23946,9 +23946,9 @@ } }, "@wordpress/env": { - "version": "5.16.0", - "resolved": "https://registry.npmjs.org/@wordpress/env/-/env-5.16.0.tgz", - "integrity": "sha512-zx6UO8PuJBrQ34cfeedK1HlGHLFaj7oWzTo9tTt+noB79Ttqc4+a0lYwDqBLLJhlHU+cWgcyOP2lB6TboXH0xA==", + "version": "8.13.0", + "resolved": "https://registry.npmjs.org/@wordpress/env/-/env-8.13.0.tgz", + "integrity": "sha512-rtrrBO22DnbLsdBlsGqlMQrjz1dZfbwGnxyKev+gFd1rSfmLs+1F8L89RHOx9vsGPixl5uRwoU/qgYo7Hf1NVQ==", "dev": true, "requires": { "chalk": "^4.0.0", diff --git a/package.json b/package.json index 8228b736af..bc3287b7e9 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ }, "devDependencies": { "@octokit/rest": "^19.0.5", - "@wordpress/env": "^5.7.0", + "@wordpress/env": "^8.13.0", "@wordpress/scripts": "^26.19.0", "chalk": "^4.1.2", "commander": "^9.4.1", @@ -27,16 +27,13 @@ "test-plugins": "./bin/plugin/cli.js test-plugins", "test-plugins-multisite": "./bin/plugin/cli.js test-plugins --sitetype=multi", "enabled-modules": "./bin/plugin/cli.js enabled-modules", - "format-js": "wp-scripts format ./bin", - "lint-js": "wp-scripts lint-js ./bin", - "format-php": "wp-env run composer run-script format", - "phpstan": "wp-env run composer run-script phpstan", - "prelint-php": "wp-env run composer 'install --no-interaction'", - "lint-php": "wp-env run composer run-script lint", - "pretest-php": "wp-env run composer 'install --no-interaction'", - "test-php": "wp-env run phpunit 'phpunit -c /var/www/html/wp-content/plugins/$(basename $(pwd))/phpunit.xml.dist --verbose'", - "pretest-php-multisite": "wp-env run composer 'install --no-interaction'", - "test-php-multisite": "wp-env run phpunit 'WP_MULTISITE=1 phpunit -c /var/www/html/wp-content/plugins/$(basename $(pwd))/tests/multisite.xml --verbose'", + "format-js": "wp-scripts format", + "lint-js": "wp-scripts lint-js", + "format-php": "composer format", + "phpstan": "composer phpstan", + "lint-php": "composer lint", + "test-php": "wp-env run tests-cli --env-cwd=/var/www/html/wp-content/plugins/$(basename $(pwd)) composer test", + "test-php-multisite": "wp-env run tests-cli --env-cwd=/var/www/html/wp-content/plugins/$(basename $(pwd)) composer test-multisite", "wp-env": "wp-env", "prepare": "husky install" }, @@ -44,6 +41,9 @@ "*.php": [ "composer run-script lint", "composer run-script phpstan" + ], + "*.js": [ + "npm run lint-js" ] } } diff --git a/phpstan.neon.dist b/phpstan.neon.dist index a25d2d4cf4..2b6e1848a2 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -1,5 +1,5 @@ includes: - - phar://phpstan.phar/conf/bleedingEdge.neon + - build-cs/vendor/phpstan/phpstan/conf/bleedingEdge.neon parameters: level: 0 paths: diff --git a/plugin-tests/.wp-env.json b/plugin-tests/.wp-env.json index 9af20e97ab..673c3bd542 100644 --- a/plugin-tests/.wp-env.json +++ b/plugin-tests/.wp-env.json @@ -5,8 +5,7 @@ "tests": { "config": { "FS_METHOD": "direct" - }, - "phpVersion": "7.4" + } } } } diff --git a/plugin-tests/multisite.xml b/plugin-tests/multisite.xml index 0971a444be..59f52e39a6 100644 --- a/plugin-tests/multisite.xml +++ b/plugin-tests/multisite.xml @@ -14,4 +14,9 @@ ./tests + + + ms-excluded + + diff --git a/plugin-tests/phpunit.xml b/plugin-tests/phpunit.xml index 044c1447d2..d94c4a3d95 100644 --- a/plugin-tests/phpunit.xml +++ b/plugin-tests/phpunit.xml @@ -11,4 +11,9 @@ ./tests + + + ms-required + + diff --git a/readme.txt b/readme.txt index cd9defdadf..25833cd4bb 100644 --- a/readme.txt +++ b/readme.txt @@ -4,7 +4,7 @@ Contributors: wordpressdotorg Requires at least: 6.3 Tested up to: 6.4 Requires PHP: 7.0 -Stable tag: 2.7.0 +Stable tag: 2.8.0 License: GPLv2 or later License URI: https://www.gnu.org/licenses/gpl-2.0.html Tags: performance, images, javascript, site health, measurement, object caching @@ -79,6 +79,24 @@ By default, the WebP Uploads module will only generate WebP versions of the imag == Changelog == += 2.8.0 = + +**Features** + +* Infrastructure: Introduce UI for managing Performance Lab standalone plugins. ([864](https://github.com/WordPress/performance/pull/864)) + +**Enhancements** + +* Infrastructure: Add support for plugin live preview in the plugin directory. ([890](https://github.com/WordPress/performance/pull/890)) +* Infrastructure: Allow module `can-load.php` callbacks to return a `WP_Error` with more information. ([891](https://github.com/WordPress/performance/pull/891)) +* Infrastructure: Implement admin pointer to indicate to the user they need to migrate modules to their standalone plugins. ([910](https://github.com/WordPress/performance/pull/910)) +* Infrastructure: Implement migration logic and UI from Performance Lab modules to their standalone plugins. ([899](https://github.com/WordPress/performance/pull/899)) +* Infrastructure: Reset admin pointer dismissal for module migration when the user activates a module. ([915](https://github.com/WordPress/performance/pull/915)) + +**Bug Fixes** + +* Infrastructure: Fix construction of translation strings in admin/plugins.php. ([925](https://github.com/WordPress/performance/pull/925)) + = 2.7.0 = **Enhancements** diff --git a/server-timing/class-perflab-server-timing.php b/server-timing/class-perflab-server-timing.php index 66f376ab2b..bf9fae647e 100644 --- a/server-timing/class-perflab-server-timing.php +++ b/server-timing/class-perflab-server-timing.php @@ -258,6 +258,10 @@ private function format_metric_header_value( Perflab_Server_Timing_Metric $metri if ( is_float( $value ) ) { $value = round( $value, 2 ); } - return sprintf( 'wp-%1$s;dur=%2$s', $metric->get_slug(), $value ); + + // See https://github.com/WordPress/performance/issues/955. + $name = preg_replace( '/[^!#$%&\'*+\-.^_`|~0-9a-zA-Z]/', '-', $metric->get_slug() ); + + return sprintf( 'wp-%1$s;dur=%2$s', $name, $value ); } } diff --git a/tests/admin/load-tests.php b/tests/admin/load-tests.php index c7746f9bf9..83e4555d8e 100644 --- a/tests/admin/load-tests.php +++ b/tests/admin/load-tests.php @@ -91,7 +91,7 @@ public function test_perflab_add_modules_page() { remove_all_filters( 'plugin_action_links_' . plugin_basename( PERFLAB_MAIN_FILE ) ); // Does not register the page if the perflab_active_modules filter is used. - add_filter( 'perflab_active_modules', '__return_null' ); + add_filter( 'perflab_active_modules', '__return_array' ); $hook_suffix = perflab_add_modules_page(); $this->assertFalse( $hook_suffix ); $this->assertFalse( isset( $_wp_submenu_nopriv['options-general.php'][ PERFLAB_MODULES_SCREEN ] ) ); diff --git a/tests/load-tests.php b/tests/load-tests.php index 19c8a9a88f..d2be1eec03 100644 --- a/tests/load-tests.php +++ b/tests/load-tests.php @@ -163,7 +163,7 @@ static function () use ( $active_modules ) { } ); $active_modules = array_filter( perflab_get_active_modules(), 'perflab_is_valid_module' ); - $expected = 'Performance Lab ' . PERFLAB_VERSION . '; modules: ' . implode( ', ', $active_modules ); + $expected = 'Performance Lab ' . PERFLAB_VERSION . '; modules: ' . implode( ', ', $active_modules ) . '; plugins: '; $content = perflab_get_generator_content(); $this->assertSame( $expected, $content ); } @@ -171,7 +171,7 @@ static function () use ( $active_modules ) { public function test_perflab_render_generator() { // Assert generator tag is rendered. Content does not matter, so just use no modules active. add_filter( 'perflab_active_modules', '__return_empty_array' ); - $expected = '' . "\n"; + $expected = '' . "\n"; $output = get_echo( 'perflab_render_generator' ); $this->assertSame( $expected, $output ); diff --git a/tests/modules/images/dominant-color-images/dominant-color-image-editor-gd-test.php b/tests/modules/images/dominant-color-images/dominant-color-image-editor-gd-test.php index 5d4188bc62..3ce2a52f79 100644 --- a/tests/modules/images/dominant-color-images/dominant-color-image-editor-gd-test.php +++ b/tests/modules/images/dominant-color-images/dominant-color-image-editor-gd-test.php @@ -9,17 +9,6 @@ use PerformanceLab\Tests\TestCase\DominantColorTestCase; class Dominant_Color_Image_Editor_GD_Test extends DominantColorTestCase { - public function set_up() { - parent::set_up(); // TODO: Change the autogenerated stub. - - add_filter( - 'wp_image_editors', - static function () { - return array( 'Dominant_Color_Image_Editor_GD' ); - }, - 100 - ); - } /** * Test if the function returns the correct color. @@ -29,12 +18,21 @@ static function () { * @covers Dominant_Color_Image_Editor_GD::get_dominant_color */ public function test_get_dominant_color( $image_path, $expected_color, $expected_transparency ) { + if ( ! extension_loaded( 'gd' ) || ! function_exists( 'gd_info' ) ) { + $this->markTestSkipped( 'The GD PHP extension is not loaded.' ); + } + + $mime_type = wp_check_filetype( $image_path )['type']; + if ( ! wp_image_editor_supports( array( 'mime_type' => $mime_type ) ) ) { + $this->markTestSkipped( "Mime type $mime_type is not supported." ); + } $attachment_id = self::factory()->attachment->create_upload_object( $image_path ); wp_maybe_generate_attachment_metadata( get_post( $attachment_id ) ); $dominant_color_data = dominant_color_get_dominant_color_data( $attachment_id ); + $this->assertNotWPError( $dominant_color_data ); $this->assertContains( $dominant_color_data['dominant_color'], $expected_color ); $this->assertSame( $dominant_color_data['has_transparency'], $expected_transparency ); } @@ -48,7 +46,10 @@ public function test_get_dominant_color( $image_path, $expected_color, $expected * * @covers Dominant_Color_Image_Editor_GD::get_dominant_color */ - public function test_get_dominant_color_invalid( $image_path, $expected_color, $expected_transparency ) { + public function test_get_dominant_color_invalid( $image_path ) { + if ( ! extension_loaded( 'gd' ) || ! function_exists( 'gd_info' ) ) { + $this->markTestSkipped( 'The GD PHP extension is not loaded.' ); + } $attachment_id = self::factory()->attachment->create_upload_object( $image_path ); wp_maybe_generate_attachment_metadata( get_post( $attachment_id ) ); @@ -67,6 +68,9 @@ public function test_get_dominant_color_invalid( $image_path, $expected_color, $ * @covers Dominant_Color_Image_Editor_GD::get_dominant_color */ public function test_get_dominant_color_none_images( $image_path ) { + if ( ! extension_loaded( 'gd' ) || ! function_exists( 'gd_info' ) ) { + $this->markTestSkipped( 'The GD PHP extension is not loaded.' ); + } $attachment_id = self::factory()->attachment->create_upload_object( $image_path ); wp_maybe_generate_attachment_metadata( get_post( $attachment_id ) ); diff --git a/tests/modules/images/dominant-color-images/dominant-color-image-editor-imageick-test.php b/tests/modules/images/dominant-color-images/dominant-color-image-editor-imagick-test.php similarity index 65% rename from tests/modules/images/dominant-color-images/dominant-color-image-editor-imageick-test.php rename to tests/modules/images/dominant-color-images/dominant-color-image-editor-imagick-test.php index b4ceecb51a..ee4ae74303 100644 --- a/tests/modules/images/dominant-color-images/dominant-color-image-editor-imageick-test.php +++ b/tests/modules/images/dominant-color-images/dominant-color-image-editor-imagick-test.php @@ -10,18 +10,7 @@ use PerformanceLab\Tests\TestCase\DominantColorTestCase; -class Dominant_Color_Image_Editor_Imageick_Test extends DominantColorTestCase { - public function set_up() { - parent::set_up(); // TODO: Change the autogenerated stub. - - add_filter( - 'wp_image_editors', - static function () { - return array( 'Dominant_Color_Image_Editor_Imagick' ); - }, - 100 - ); - } +class Dominant_Color_Image_Editor_Imagick_Test extends DominantColorTestCase { /** * Test if the function returns the correct color. @@ -31,12 +20,21 @@ static function () { * @covers Dominant_Color_Image_Editor_GD::get_dominant_color */ public function test_get_dominant_color( $image_path, $expected_color, $expected_transparency ) { + if ( ! extension_loaded( 'imagick' ) || ! class_exists( 'Imagick', false ) ) { + $this->markTestSkipped( 'The Imagick PHP extension is not loaded.' ); + } + + $mime_type = wp_check_filetype( $image_path )['type']; + if ( ! wp_image_editor_supports( array( 'mime_type' => $mime_type ) ) ) { + $this->markTestSkipped( "Mime type $mime_type is not supported." ); + } $attachment_id = self::factory()->attachment->create_upload_object( $image_path ); wp_maybe_generate_attachment_metadata( get_post( $attachment_id ) ); $dominant_color_data = dominant_color_get_dominant_color_data( $attachment_id ); + $this->assertNotWPError( $dominant_color_data ); $this->assertContains( $dominant_color_data['dominant_color'], $expected_color ); $this->assertSame( $dominant_color_data['has_transparency'], $expected_transparency ); } @@ -50,15 +48,18 @@ public function test_get_dominant_color( $image_path, $expected_color, $expected * * @covers Dominant_Color_Image_Editor_GD::get_dominant_color */ - public function test_get_dominant_color_invalid( $image_path, $expected_color, $expected_transparency ) { + public function test_get_dominant_color_invalid( $image_path ) { + if ( ! extension_loaded( 'imagick' ) || ! class_exists( 'Imagick', false ) ) { + $this->markTestSkipped( 'The Imagick PHP extension is not loaded.' ); + } $attachment_id = self::factory()->attachment->create_upload_object( $image_path ); wp_maybe_generate_attachment_metadata( get_post( $attachment_id ) ); $dominant_color_data = dominant_color_get_dominant_color_data( $attachment_id ); - $this->assertContains( $dominant_color_data['dominant_color'], $expected_color ); - $this->assertSame( $dominant_color_data['has_transparency'], $expected_transparency ); + $this->assertWPError( $dominant_color_data ); + $this->assertStringContainsString( 'image_no_editor', $dominant_color_data->get_error_code() ); } /** @@ -69,6 +70,9 @@ public function test_get_dominant_color_invalid( $image_path, $expected_color, $ * @covers Dominant_Color_Image_Editor_GD::get_dominant_color */ public function test_get_dominant_color_none_images( $image_path ) { + if ( ! extension_loaded( 'imagick' ) || ! class_exists( 'Imagick', false ) ) { + $this->markTestSkipped( 'The Imagick PHP extension is not loaded.' ); + } $attachment_id = self::factory()->attachment->create_upload_object( $image_path ); wp_maybe_generate_attachment_metadata( get_post( $attachment_id ) ); diff --git a/tests/modules/images/dominant-color-images/dominant-color-test.php b/tests/modules/images/dominant-color-images/dominant-color-test.php index 02ebf80dc1..4ae090ccec 100644 --- a/tests/modules/images/dominant-color-images/dominant-color-test.php +++ b/tests/modules/images/dominant-color-images/dominant-color-test.php @@ -17,6 +17,11 @@ class Dominant_Color_Test extends DominantColorTestCase { * @covers ::dominant_color_metadata */ public function test_dominant_color_metadata( $image_path, $expected_color, $expected_transparency ) { + $mime_type = wp_check_filetype( $image_path )['type']; + if ( ! wp_image_editor_supports( array( 'mime_type' => $mime_type ) ) ) { + $this->markTestSkipped( "Mime type $mime_type is not supported." ); + } + // Non existing attachment. $dominant_color_metadata = dominant_color_metadata( array(), 1 ); $this->assertEmpty( $dominant_color_metadata ); @@ -38,6 +43,11 @@ public function test_dominant_color_metadata( $image_path, $expected_color, $exp * @covers ::dominant_color_get_dominant_color */ public function test_dominant_color_get_dominant_color( $image_path, $expected_color, $expected_transparency ) { + $mime_type = wp_check_filetype( $image_path )['type']; + if ( ! wp_image_editor_supports( array( 'mime_type' => $mime_type ) ) ) { + $this->markTestSkipped( "Mime type $mime_type is not supported." ); + } + // Creating attachment. $attachment_id = self::factory()->attachment->create_upload_object( $image_path ); $this->assertContains( dominant_color_get_dominant_color( $attachment_id ), $expected_color ); @@ -51,6 +61,11 @@ public function test_dominant_color_get_dominant_color( $image_path, $expected_c * @covers ::dominant_color_metadata */ public function test_has_transparency_metadata( $image_path, $expected_color, $expected_transparency ) { + $mime_type = wp_check_filetype( $image_path )['type']; + if ( ! wp_image_editor_supports( array( 'mime_type' => $mime_type ) ) ) { + $this->markTestSkipped( "Mime type $mime_type is not supported." ); + } + // Non-existing attachment. $transparency_metadata = dominant_color_metadata( array(), 1 ); $this->assertEmpty( $transparency_metadata ); @@ -70,6 +85,11 @@ public function test_has_transparency_metadata( $image_path, $expected_color, $e * @covers ::dominant_color_get_dominant_color */ public function test_dominant_color_has_transparency( $image_path, $expected_color, $expected_transparency ) { + $mime_type = wp_check_filetype( $image_path )['type']; + if ( ! wp_image_editor_supports( array( 'mime_type' => $mime_type ) ) ) { + $this->markTestSkipped( "Mime type $mime_type is not supported." ); + } + // Creating attachment. $attachment_id = self::factory()->attachment->create_upload_object( $image_path ); $this->assertSame( $expected_transparency, dominant_color_has_transparency( $attachment_id ) ); @@ -83,6 +103,11 @@ public function test_dominant_color_has_transparency( $image_path, $expected_col * @covers ::dominant_color_img_tag_add_dominant_color */ public function test_tag_add_adjust_to_image_attributes( $image_path, $expected_color, $expected_transparency ) { + $mime_type = wp_check_filetype( $image_path )['type']; + if ( ! wp_image_editor_supports( array( 'mime_type' => $mime_type ) ) ) { + $this->markTestSkipped( "Mime type $mime_type is not supported." ); + } + $attachment_id = self::factory()->attachment->create_upload_object( $image_path ); wp_maybe_generate_attachment_metadata( get_post( $attachment_id ) ); diff --git a/tests/modules/images/webp-uploads/helper-tests.php b/tests/modules/images/webp-uploads/helper-tests.php index 9fa6fbbd67..7197a4c9b5 100644 --- a/tests/modules/images/webp-uploads/helper-tests.php +++ b/tests/modules/images/webp-uploads/helper-tests.php @@ -79,6 +79,10 @@ public function data_provider_invalid_arguments_for_webp_uploads_generate_additi * @test */ public function it_should_create_an_image_with_the_default_suffix_in_the_same_location_when_no_destination_is_specified() { + if ( ! wp_image_editor_supports( array( 'mime_type' => 'image/webp' ) ) ) { + $this->markTestSkipped( 'Mime type image/webp is not supported.' ); + } + // Create JPEG and WebP so that both versions are generated. $this->opt_in_to_jpeg_and_webp(); @@ -94,6 +98,7 @@ public function it_should_create_an_image_with_the_default_suffix_in_the_same_lo $directory = trailingslashit( pathinfo( $file, PATHINFO_DIRNAME ) ); $name = pathinfo( $file, PATHINFO_FILENAME ); + $this->assertNotWPError( $result ); $this->assertIsArray( $result ); $this->assertArrayHasKey( 'filesize', $result ); $this->assertArrayHasKey( 'file', $result ); @@ -107,6 +112,10 @@ public function it_should_create_an_image_with_the_default_suffix_in_the_same_lo * @test */ public function it_should_create_a_file_in_the_specified_location_with_the_specified_name() { + if ( ! wp_image_editor_supports( array( 'mime_type' => 'image/webp' ) ) ) { + $this->markTestSkipped( 'Mime type image/webp is not supported.' ); + } + $attachment_id = self::factory()->attachment->create_upload_object( TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/car.jpeg' ); $size_data = array( 'width' => 300, @@ -116,6 +125,7 @@ public function it_should_create_a_file_in_the_specified_location_with_the_speci $result = webp_uploads_generate_additional_image_source( $attachment_id, 'medium', $size_data, 'image/webp', '/tmp/image.jpg' ); + $this->assertNotWPError( $result ); $this->assertIsArray( $result ); $this->assertArrayHasKey( 'filesize', $result ); $this->assertArrayHasKey( 'file', $result ); @@ -175,8 +185,12 @@ static function ( $metadata ) { * @test */ public function it_should_prevent_to_create_an_image_size_when_attached_file_does_not_exists() { + if ( ! wp_image_editor_supports( array( 'mime_type' => 'image/webp' ) ) ) { + $this->markTestSkipped( 'Mime type image/webp is not supported.' ); + } + $attachment_id = self::factory()->attachment->create_upload_object( - TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/leafs.jpg' + TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/leaves.jpg' ); $file = get_attached_file( $attachment_id ); $original_file = wp_get_original_image_path( $attachment_id ); @@ -200,7 +214,7 @@ public function it_should_prevent_to_create_an_image_size_when_attached_file_doe */ public function it_should_prevent_to_create_a_subsize_if_the_image_editor_does_not_exists() { $attachment_id = self::factory()->attachment->create_upload_object( - TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/leafs.jpg' + TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/leaves.jpg' ); // Make sure no editor is available. @@ -217,9 +231,9 @@ public function it_should_prevent_to_create_a_subsize_if_the_image_editor_does_n */ public function it_should_prevent_to_upload_a_mime_that_is_not_supported_by_wordpress() { $attachment_id = self::factory()->attachment->create_upload_object( - TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/leafs.jpg' + TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/leaves.jpg' ); - $result = webp_uploads_generate_image_size( $attachment_id, 'medium', 'image/avif' ); + $result = webp_uploads_generate_image_size( $attachment_id, 'medium', 'image/vnd.zbrush.pcx' ); $this->assertWPError( $result ); $this->assertSame( 'image_mime_type_invalid', $result->get_error_code() ); } @@ -232,7 +246,7 @@ public function it_should_prevent_to_upload_a_mime_that_is_not_supported_by_word public function it_should_prevent_to_process_an_image_when_the_editor_does_not_support_the_format() { // Make sure no editor is available. $attachment_id = self::factory()->attachment->create_upload_object( - TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/leafs.jpg' + TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/leaves.jpg' ); add_filter( @@ -364,6 +378,7 @@ public function it_should_return_empty_array_when_filter_returns_empty_array() { * @test */ public function it_should_return_default_transforms_when_filter_returns_non_array_type() { + /** @phpstan-ignore-next-line */ add_filter( 'webp_uploads_upload_image_mime_transforms', '__return_null' ); $default_transforms = array( @@ -542,6 +557,10 @@ private function mock_empty_action( $action ) { * @test */ public function it_should_add_original_image_extension_to_the_webp_file_name_to_ensure_it_is_unique( $jpeg_image, $jpg_image ) { + if ( ! wp_image_editor_supports( array( 'mime_type' => 'image/webp' ) ) ) { + $this->markTestSkipped( 'Mime type image/webp is not supported.' ); + } + $jpeg_image_attachment_id = self::factory()->attachment->create_upload_object( $jpeg_image ); $jpg_image_attachment_id = self::factory()->attachment->create_upload_object( $jpg_image ); diff --git a/tests/modules/images/webp-uploads/image-edit-tests.php b/tests/modules/images/webp-uploads/image-edit-tests.php index 80b1ec5cdb..7e6b82c5eb 100644 --- a/tests/modules/images/webp-uploads/image-edit-tests.php +++ b/tests/modules/images/webp-uploads/image-edit-tests.php @@ -22,7 +22,7 @@ public function set_up() { * @test */ public function it_should_backup_the_sources_structure_alongside_the_full_size() { - $attachment_id = self::factory()->attachment->create_upload_object( TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/leafs.jpg' ); + $attachment_id = self::factory()->attachment->create_upload_object( TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/leaves.jpg' ); $metadata = wp_get_attachment_metadata( $attachment_id ); $this->assertEmpty( get_post_meta( $attachment_id, '_wp_attachment_backup_sizes', true ) ); @@ -64,7 +64,11 @@ public function it_should_backup_the_sources_structure_alongside_the_full_size() * @test */ public function it_should_restore_the_sources_array_from_the_backup_when_an_image_is_edited() { - $attachment_id = self::factory()->attachment->create_upload_object( TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/leafs.jpg' ); + if ( ! wp_image_editor_supports( array( 'mime_type' => 'image/webp' ) ) ) { + $this->markTestSkipped( 'Mime type image/webp is not supported.' ); + } + + $attachment_id = self::factory()->attachment->create_upload_object( TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/leaves.jpg' ); $metadata = wp_get_attachment_metadata( $attachment_id ); $editor = new WP_Image_Edit( $attachment_id ); @@ -118,7 +122,7 @@ public function it_should_prevent_to_back_up_the_sources_when_the_sources_attrib // Disable the generation of the sources attributes. add_filter( 'webp_uploads_upload_image_mime_transforms', '__return_empty_array' ); - $attachment_id = self::factory()->attachment->create_upload_object( TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/leafs.jpg' ); + $attachment_id = self::factory()->attachment->create_upload_object( TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/leaves.jpg' ); $metadata = wp_get_attachment_metadata( $attachment_id ); $this->assertArrayNotHasKey( 'sources', $metadata ); @@ -151,7 +155,7 @@ public function it_should_prevent_to_backup_the_full_size_image_if_only_the_thum // Create JPEG and WebP. $this->opt_in_to_jpeg_and_webp(); - $attachment_id = self::factory()->attachment->create_upload_object( TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/leafs.jpg' ); + $attachment_id = self::factory()->attachment->create_upload_object( TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/leaves.jpg' ); $metadata = wp_get_attachment_metadata( $attachment_id ); $this->assertArrayHasKey( 'sources', $metadata ); @@ -203,7 +207,7 @@ public function it_should_backup_the_image_when_all_images_except_the_thumbnail_ $this->markTestSkipped( 'Editing image thumbnails separately is disabled' ); } - $attachment_id = self::factory()->attachment->create_upload_object( TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/leafs.jpg' ); + $attachment_id = self::factory()->attachment->create_upload_object( TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/leaves.jpg' ); $metadata = wp_get_attachment_metadata( $attachment_id ); $editor = new WP_Image_Edit( $attachment_id ); @@ -248,7 +252,7 @@ public function it_should_use_the_attached_image_when_updating_subsequent_images $this->markTestSkipped( 'Editing image thumbnails separately is disabled' ); } - // The leafs image is 1080 pixels wide with this filter we ensure a -scaled version is created for this test. + // The leaves image is 1080 pixels wide with this filter we ensure a -scaled version is created for this test. add_filter( 'big_image_size_threshold', static function () { @@ -258,7 +262,7 @@ static function () { ); $attachment_id = self::factory()->attachment->create_upload_object( - TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/leafs.jpg' + TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/leaves.jpg' ); $this->assertNotSame( wp_get_original_image_path( $attachment_id ), get_attached_file( $attachment_id ) ); @@ -302,7 +306,11 @@ static function () { * @test */ public function it_should_validate_source_attribute_update_when_webp_edited() { - $attachment_id = self::factory()->attachment->create_upload_object( TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/leafs.jpg' ); + if ( ! webp_uploads_image_edit_thumbnails_separately() ) { + $this->markTestSkipped( 'Editing image thumbnails separately is disabled' ); + } + + $attachment_id = self::factory()->attachment->create_upload_object( TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/leaves.jpg' ); $editor = new WP_Image_Edit( $attachment_id ); $editor->crop( 1000, 200, 0, 0 )->save(); @@ -331,7 +339,7 @@ public function it_should_validate_source_attribute_update_when_webp_edited() { * @test */ public function it_should_not_return_a_target_if_no_backup_image_exists() { - $attachment_id = self::factory()->attachment->create_upload_object( TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/leafs.jpg' ); + $attachment_id = self::factory()->attachment->create_upload_object( TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/leaves.jpg' ); $this->assertNull( webp_uploads_get_next_full_size_key_from_backup( $attachment_id ) ); } @@ -344,7 +352,7 @@ public function it_should_return_the_full_orig_target_key_when_only_one_edit_ima // Remove the filter to prevent the usage of the next target. remove_filter( 'wp_update_attachment_metadata', 'webp_uploads_update_attachment_metadata' ); - $attachment_id = self::factory()->attachment->create_upload_object( TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/leafs.jpg' ); + $attachment_id = self::factory()->attachment->create_upload_object( TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/leaves.jpg' ); $editor = new WP_Image_Edit( $attachment_id ); $editor->rotate_right()->save(); @@ -358,7 +366,7 @@ public function it_should_return_the_full_orig_target_key_when_only_one_edit_ima * @test */ public function it_should_return_null_when_looking_for_a_target_that_is_already_used() { - $attachment_id = self::factory()->attachment->create_upload_object( TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/leafs.jpg' ); + $attachment_id = self::factory()->attachment->create_upload_object( TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/leaves.jpg' ); $editor = new WP_Image_Edit( $attachment_id ); $editor->rotate_right()->save(); @@ -375,7 +383,7 @@ public function it_should_use_the_next_available_hash_for_the_full_size_image_on // Create JPEG and WebP. $this->opt_in_to_jpeg_and_webp(); - $attachment_id = self::factory()->attachment->create_upload_object( TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/leafs.jpg' ); + $attachment_id = self::factory()->attachment->create_upload_object( TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/leaves.jpg' ); $editor = new WP_Image_Edit( $attachment_id ); $editor->rotate_right()->save(); @@ -397,12 +405,12 @@ public function it_should_save_populate_the_backup_sources_with_the_next_target( // Remove the filter to prevent the usage of the next target. remove_filter( 'wp_update_attachment_metadata', 'webp_uploads_update_attachment_metadata' ); - $attachment_id = self::factory()->attachment->create_upload_object( TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/leafs.jpg' ); + $attachment_id = self::factory()->attachment->create_upload_object( TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/leaves.jpg' ); $editor = new WP_Image_Edit( $attachment_id ); $editor->rotate_right()->save(); $this->assertTrue( $editor->success() ); - $sources = array( 'image/webp' => 'leafs.webp' ); + $sources = array( 'image/webp' => 'leaves.webp' ); webp_uploads_backup_full_image_sources( $attachment_id, $sources ); $this->assertSame( array( 'full-orig' => $sources ), get_post_meta( $attachment_id, '_wp_attachment_backup_sources', true ) ); @@ -417,7 +425,7 @@ public function it_should_store_the_metadata_on_the_next_available_hash() { // Create JPEG and WebP. $this->opt_in_to_jpeg_and_webp(); - $attachment_id = self::factory()->attachment->create_upload_object( TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/leafs.jpg' ); + $attachment_id = self::factory()->attachment->create_upload_object( TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/leaves.jpg' ); $editor = new WP_Image_Edit( $attachment_id ); $editor->rotate_right()->save(); @@ -428,7 +436,7 @@ public function it_should_store_the_metadata_on_the_next_available_hash() { $editor->rotate_right()->save(); $this->assertTrue( $editor->success() ); - $sources = array( 'image/webp' => 'leafs.webp' ); + $sources = array( 'image/webp' => 'leaves.webp' ); webp_uploads_backup_full_image_sources( $attachment_id, $sources ); $backup_sources = get_post_meta( $attachment_id, '_wp_attachment_backup_sources', true ); @@ -449,7 +457,7 @@ public function it_should_prevent_to_store_an_empty_set_of_sources() { // Remove the filter to prevent the usage of the next target. remove_filter( 'wp_update_attachment_metadata', 'webp_uploads_update_attachment_metadata' ); - $attachment_id = self::factory()->attachment->create_upload_object( TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/leafs.jpg' ); + $attachment_id = self::factory()->attachment->create_upload_object( TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/leaves.jpg' ); $editor = new WP_Image_Edit( $attachment_id ); $editor->rotate_right()->save(); @@ -465,7 +473,11 @@ public function it_should_prevent_to_store_an_empty_set_of_sources() { * @test */ public function it_should_store_the_next_image_hash_on_the_backup_sources() { - $attachment_id = self::factory()->attachment->create_upload_object( TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/leafs.jpg' ); + if ( ! wp_image_editor_supports( array( 'mime_type' => 'image/webp' ) ) ) { + $this->markTestSkipped( 'Mime type image/webp is not supported.' ); + } + + $attachment_id = self::factory()->attachment->create_upload_object( TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/leaves.jpg' ); $editor = new WP_Image_Edit( $attachment_id ); // Edit the image. $editor->rotate_right()->save(); @@ -494,7 +506,7 @@ public function it_should_create_backup_of_full_size_images_with_the_same_hash_k // Create JPEG and WebP. $this->opt_in_to_jpeg_and_webp(); - $attachment_id = self::factory()->attachment->create_upload_object( TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/leafs.jpg' ); + $attachment_id = self::factory()->attachment->create_upload_object( TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/leaves.jpg' ); $editor = new WP_Image_Edit( $attachment_id ); $editor->rotate_right()->save(); diff --git a/tests/modules/images/webp-uploads/load-tests.php b/tests/modules/images/webp-uploads/load-tests.php index cf8ce7e566..f2413eba50 100644 --- a/tests/modules/images/webp-uploads/load-tests.php +++ b/tests/modules/images/webp-uploads/load-tests.php @@ -21,6 +21,10 @@ public function set_up() { parent::set_up(); add_filter( 'webp_uploads_discard_larger_generated_images', '__return_false' ); + + if ( ! wp_image_editor_supports( array( 'mime_type' => 'image/webp' ) ) ) { + $this->markTestSkipped( 'Mime type image/webp is not supported.' ); + } } public function tear_down() { @@ -40,7 +44,7 @@ static function ( $filename ) { * @test */ public function it_should_not_create_the_original_mime_type_for_jpeg_images() { - $attachment_id = self::factory()->attachment->create_upload_object( TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/leafs.jpg' ); + $attachment_id = self::factory()->attachment->create_upload_object( TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/leaves.jpg' ); // There should be a WebP source, but no JPEG source for the full image. $this->assertImageHasSource( $attachment_id, 'image/webp' ); @@ -103,7 +107,7 @@ public function it_should_create_the_original_mime_type_as_well_with_all_the_ava public function it_should_create_jpeg_and_webp_for_jpeg_images_if_opted_in() { $this->opt_in_to_jpeg_and_webp(); - $attachment_id = self::factory()->attachment->create_upload_object( TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/leafs.jpg' ); + $attachment_id = self::factory()->attachment->create_upload_object( TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/leaves.jpg' ); // There should be JPEG and WebP sources for the full image. $this->assertImageHasSource( $attachment_id, 'image/jpeg' ); @@ -134,7 +138,7 @@ public function it_should_create_jpeg_and_webp_for_jpeg_images_if_opted_in() { public function it_should_create_jpeg_and_webp_for_jpeg_images_if_generate_webp_and_jpeg_set() { update_option( 'perflab_generate_webp_and_jpeg', true ); - $attachment_id = self::factory()->attachment->create_upload_object( TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/leafs.jpg' ); + $attachment_id = self::factory()->attachment->create_upload_object( TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/leaves.jpg' ); // There should be JPEG and WebP sources for the full image. $this->assertImageHasSource( $attachment_id, 'image/jpeg' ); @@ -166,7 +170,7 @@ public function it_should_not_create_the_sources_property_if_no_transform_is_pro add_filter( 'webp_uploads_upload_image_mime_transforms', '__return_empty_array' ); $attachment_id = self::factory()->attachment->create_upload_object( - TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/leafs.jpg' + TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/leaves.jpg' ); $metadata = wp_get_attachment_metadata( $attachment_id ); @@ -192,7 +196,7 @@ static function () { ); $attachment_id = self::factory()->attachment->create_upload_object( - TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/leafs.jpg' + TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/leaves.jpg' ); $this->assertImageHasSource( $attachment_id, 'image/jpeg' ); @@ -238,7 +242,7 @@ static function () { */ public function it_should_create_a_webp_version_with_all_the_required_properties() { $attachment_id = self::factory()->attachment->create_upload_object( - TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/leafs.jpg' + TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/leaves.jpg' ); $metadata = wp_get_attachment_metadata( $attachment_id ); @@ -268,7 +272,7 @@ public function it_should_create_the_full_size_images_when_no_size_is_available( add_filter( 'intermediate_image_sizes', '__return_empty_array' ); add_filter( 'fallback_intermediate_image_sizes', '__return_empty_array' ); - $attachment_id = self::factory()->attachment->create_upload_object( TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/leafs.jpg' ); + $attachment_id = self::factory()->attachment->create_upload_object( TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/leaves.jpg' ); $metadata = wp_get_attachment_metadata( $attachment_id ); $this->assertEmpty( $metadata['sizes'] ); @@ -286,7 +290,7 @@ public function it_should_remove_scaled_suffix_from_the_generated_filename() { // Create JPEG and WebP to check for scaled suffix. $this->opt_in_to_jpeg_and_webp(); - // The leafs image is 1080 pixels wide with this filter we ensure a -scaled version is created. + // The leaves image is 1080 pixels wide with this filter we ensure a -scaled version is created. add_filter( 'big_image_size_threshold', static function () { @@ -295,7 +299,7 @@ static function () { ); $attachment_id = self::factory()->attachment->create_upload_object( - TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/leafs.jpg' + TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/leaves.jpg' ); $metadata = wp_get_attachment_metadata( $attachment_id ); $this->assertStringEndsWith( '-scaled.jpg', get_attached_file( $attachment_id ) ); @@ -311,7 +315,7 @@ static function () { */ public function it_should_remove_the_generated_webp_images_when_the_attachment_is_deleted() { $attachment_id = self::factory()->attachment->create_upload_object( - TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/leafs.jpg' + TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/leaves.jpg' ); $file = get_attached_file( $attachment_id, true ); @@ -346,7 +350,7 @@ public function it_should_remove_the_generated_webp_images_when_the_attachment_i */ public function it_should_remove_the_attached_webp_version_if_the_attachment_is_force_deleted() { $attachment_id = self::factory()->attachment->create_upload_object( - TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/leafs.jpg' + TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/leaves.jpg' ); $file = get_attached_file( $attachment_id, true ); @@ -375,7 +379,7 @@ public function it_should_remove_full_size_images_when_no_size_image_exists() { add_filter( 'intermediate_image_sizes', '__return_empty_array' ); add_filter( 'fallback_intermediate_image_sizes', '__return_empty_array' ); - $attachment_id = self::factory()->attachment->create_upload_object( TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/leafs.jpg' ); + $attachment_id = self::factory()->attachment->create_upload_object( TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/leaves.jpg' ); $file = get_attached_file( $attachment_id, true ); $dirname = pathinfo( $file, PATHINFO_DIRNAME ); @@ -398,7 +402,7 @@ public function it_should_remove_full_size_images_when_no_size_image_exists() { */ public function it_should_remove_the_backup_sizes_and_sources_if_the_attachment_is_deleted_after_edit() { $attachment_id = self::factory()->attachment->create_upload_object( - TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/leafs.jpg' + TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/leaves.jpg' ); $file = get_attached_file( $attachment_id, true ); @@ -492,7 +496,7 @@ public function it_should_prevent_replacing_a_webp_image() { */ public function it_should_prevent_replacing_a_jpg_image_if_the_image_does_not_have_the_target_class_name() { $attachment_id = self::factory()->attachment->create_upload_object( - TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/leafs.jpg' + TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/leaves.jpg' ); // Run critical hooks to satisfy webp_uploads_in_frontend_body() conditions. @@ -557,7 +561,7 @@ static function ( $mime_types ) { } public function provider_replace_images_with_different_extensions() { - yield 'An image with a .jpg extension' => array( TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/leafs.jpg' ); + yield 'An image with a .jpg extension' => array( TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/leaves.jpg' ); yield 'An image with a .jpeg extension' => array( TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/car.jpeg' ); } @@ -571,7 +575,7 @@ public function it_should_replace_all_the_images_including_the_full_size_image() $this->opt_in_to_jpeg_and_webp(); $attachment_id = self::factory()->attachment->create_upload_object( - TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/leafs.jpg' + TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/leaves.jpg' ); $tag = wp_get_attachment_image( $attachment_id, 'full', false, array( 'class' => "wp-image-{$attachment_id}" ) ); @@ -646,6 +650,7 @@ static function () { continue; } + $this->assertIsString( $size['sources']['image/webp']['file'] ); $this->assertStringContainsString( $size['width'], $size['sources']['image/webp']['file'] ); $this->assertStringContainsString( $size['height'], $size['sources']['image/webp']['file'] ); $this->assertStringContainsString( @@ -694,7 +699,7 @@ static function () { $this->assertTrue( wp_image_editor_supports( array( 'mime_type' => 'image/webp' ) ) ); - $attachment_id = self::factory()->attachment->create_upload_object( TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/leafs.jpg' ); + $attachment_id = self::factory()->attachment->create_upload_object( TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/leaves.jpg' ); $metadata = wp_get_attachment_metadata( $attachment_id ); $this->assertArrayHasKey( 'sources', $metadata ); @@ -796,7 +801,7 @@ public function it_should_create_webp_for_full_size_which_is_smaller_in_webp_for add_filter( 'wp_editor_set_quality', array( $this, 'force_webp_image_quality_86' ), PHP_INT_MAX, 2 ); // Look for an image that contains only full size mime type images. - $attachment_id = self::factory()->attachment->create_upload_object( TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/leafs.jpg' ); + $attachment_id = self::factory()->attachment->create_upload_object( TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/leaves.jpg' ); $tag = wp_get_attachment_image( $attachment_id, 'full', false, array( 'class' => "wp-image-{$attachment_id}" ) ); $metadata = wp_get_attachment_metadata( $attachment_id ); $file = get_attached_file( $attachment_id, true ); @@ -855,7 +860,7 @@ public function it_should_add_fallback_script_if_content_has_updated_images() { remove_all_actions( 'wp_footer' ); $attachment_id = self::factory()->attachment->create_upload_object( - TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/leafs.jpg' + TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/leaves.jpg' ); // Run critical hooks to satisfy webp_uploads_in_frontend_body() conditions. @@ -956,7 +961,7 @@ public function it_should_set_quality_with_image_conversion() { $editor->save( $file, 'image/webp' ); $this->assertSame( 82, $editor->get_quality(), 'Output image format is WebP. Quality setting for it should be 82 universally.' ); - $editor = wp_get_image_editor( TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/leafs.jpg' ); + $editor = wp_get_image_editor( TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/leaves.jpg' ); // Quality setting for the source image. For JPG the fallback default of 82 is used. $this->assertSame( 82, $editor->get_quality(), 'Default quality setting for JPG is 82.' ); diff --git a/tests/modules/images/webp-uploads/rest-api-tests.php b/tests/modules/images/webp-uploads/rest-api-tests.php index 2dc5145d7c..93a23ee3fb 100644 --- a/tests/modules/images/webp-uploads/rest-api-tests.php +++ b/tests/modules/images/webp-uploads/rest-api-tests.php @@ -30,7 +30,7 @@ static function ( $transforms ) { } ); - $file_location = TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/leafs.jpg'; + $file_location = TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/leaves.jpg'; $attachment_id = self::factory()->attachment->create_upload_object( $file_location ); $metadata = wp_get_attachment_metadata( $attachment_id ); @@ -77,7 +77,7 @@ static function ( $transforms ) { * @test */ public function it_should_check_media_details_in_rest_response() { - $file_location = TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/leafs.jpg'; + $file_location = TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/leaves.jpg'; $attachment_id = self::factory()->attachment->create_upload_object( $file_location ); $request = new WP_REST_Request(); diff --git a/tests/modules/js-and-css/audit-enqueued-assets/audit-enqueued-assets-test.php b/tests/modules/js-and-css/audit-enqueued-assets/audit-enqueued-assets-test.php index c4a640b923..cd71fd1ed0 100644 --- a/tests/modules/js-and-css/audit-enqueued-assets/audit-enqueued-assets-test.php +++ b/tests/modules/js-and-css/audit-enqueued-assets/audit-enqueued-assets-test.php @@ -241,7 +241,23 @@ public function test_perflab_aea_clean_aea_audit_action() { $_REQUEST['_wpnonce'] = wp_create_nonce( 'clean_aea_audit' ); $_GET['action'] = 'clean_aea_audit'; $this->current_user_can_view_site_health_checks_cap(); + $redirected_url = null; + add_filter( + 'wp_redirect', + static function ( $url ) use ( &$redirected_url ) { + $redirected_url = $url; + return false; + } + ); + $_REQUEST['_wp_http_referer'] = add_query_arg( + array( + '_wpnonce' => 'foo', + 'action' => 'bar', + ), + home_url( '/' ) + ); perflab_aea_clean_aea_audit_action(); + $this->assertSame( home_url( '/' ), $redirected_url ); $this->assertFalse( get_transient( 'aea_enqueued_front_page_scripts' ) ); $this->assertFalse( get_transient( 'aea_enqueued_front_page_styles' ) ); } diff --git a/tests/multisite.xml b/tests/multisite.xml index 271b488b6c..17ec47b055 100644 --- a/tests/multisite.xml +++ b/tests/multisite.xml @@ -6,6 +6,9 @@ convertNoticesToExceptions="true" convertWarningsToExceptions="true" > + + + ./ diff --git a/tests/server-timing/perflab-server-timing-tests.php b/tests/server-timing/perflab-server-timing-tests.php index 33d7ca28be..1e5fc5a028 100644 --- a/tests/server-timing/perflab-server-timing-tests.php +++ b/tests/server-timing/perflab-server-timing-tests.php @@ -10,6 +10,9 @@ */ class Perflab_Server_Timing_Tests extends WP_UnitTestCase { + /** + * @var Perflab_Server_Timing + */ private $server_timing; private static $admin_id; @@ -119,6 +122,19 @@ public function test_has_registered_metric() { $this->assertTrue( $this->server_timing->has_registered_metric( 'metric-to-check-for' ), 'Metric should be available after registration' ); } + public function test_register_metric_replaces_slashes() { + $this->server_timing->register_metric( + 'foo/bar/baz', + array( + 'measure_callback' => static function ( $metric ) { + $metric->set_value( 123 ); + }, + 'access_cap' => 'exist', + ) + ); + $this->assertSame( 'wp-foo-bar-baz;dur=123', $this->server_timing->get_header() ); + } + /** * @dataProvider data_get_header */ diff --git a/tests/testdata/modules/images/dominant-color-images/video-play.svg b/tests/testdata/modules/images/dominant-color-images/video-play.svg deleted file mode 100644 index b5ea206dde..0000000000 --- a/tests/testdata/modules/images/dominant-color-images/video-play.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/tests/testdata/modules/images/leafs.jpg b/tests/testdata/modules/images/leaves.jpg similarity index 100% rename from tests/testdata/modules/images/leafs.jpg rename to tests/testdata/modules/images/leaves.jpg diff --git a/tests/utils/TestCase/DominantColorTestCase.php b/tests/utils/TestCase/DominantColorTestCase.php index cb3dbb916a..0012976dd9 100644 --- a/tests/utils/TestCase/DominantColorTestCase.php +++ b/tests/utils/TestCase/DominantColorTestCase.php @@ -14,7 +14,7 @@ public function provider_get_dominant_color() { return array( 'animated_gif' => array( 'image_path' => TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/dominant-color-images/animated.gif', - 'expected_color' => array( '874e4e', 'df7f7f' ), + 'expected_color' => array( '874e4e', '864e4e', 'df7f7f' ), 'expected_transparency' => true, ), 'red_jpg' => array( @@ -97,7 +97,7 @@ public function provider_get_dominant_color() { ), 'balloons_webp' => array( 'image_path' => TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/balloons.webp', - 'expected_color' => array( 'c1bbb9', 'c3bdbd' ), + 'expected_color' => array( 'c1bbb9', 'c0bbb9', 'c0bab8', 'c3bdbd', 'bfbab8' ), 'expected_transparency' => false, ), ); @@ -111,14 +111,10 @@ public function provider_get_dominant_color() { public function provider_get_dominant_color_invalid_images() { return array( 'tiff' => array( - 'image_path' => TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/dominant-color-images/test-image.tiff', - 'expected_color' => array( 'dfdfdf' ), - 'expected_transparency' => true, + 'image_path' => TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/dominant-color-images/test-image.tiff', ), 'bmp' => array( - 'image_path' => TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/dominant-color-images/test-image.bmp', - 'expected_color' => array( 'dfdfdf' ), - 'expected_transparency' => true, + 'image_path' => TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/dominant-color-images/test-image.bmp', ), ); } @@ -130,9 +126,6 @@ public function provider_get_dominant_color_invalid_images() { */ public function provider_get_dominant_color_none_images() { return array( - 'svg' => array( - 'files_path' => TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/dominant-color-images/video-play.svg', - ), 'pdf' => array( 'files_path' => TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/dominant-color-images/wordpress-gsoc-flyer.pdf', ),