diff --git a/.distignore b/.distignore new file mode 100644 index 0000000..f049057 --- /dev/null +++ b/.distignore @@ -0,0 +1,22 @@ +# Directories +/.git/ +/.github/ +/bin/ +/node_modules/ +/tests/ +/vendor/ + +# Files +.distignore +.editorconfig +.gitattributes +.gitignore +.phpcs.xml.dist +.wp-env.json +.wp-env.override.json +CHANGELOG.md +composer.json +composer.lock +package.json +package-lock.json +phpunit.xml.dist diff --git a/.editorconfig b/.editorconfig index 8bd49bd..0524bfa 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,8 +1,9 @@ # This file is for unifying the coding style for different editors and IDEs -# editorconfig.org +# It is based on https://core.trac.wordpress.org/browser/trunk/.editorconfig +# See https://editorconfig.org for more information about the standard. # WordPress Coding Standards -# http://make.wordpress.org/core/handbook/coding-standards/ +# https://make.wordpress.org/core/handbook/coding-standards/ root = true diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000..3b8daef --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,3 @@ +# The following teams will get auto-tagged for a review. +# See https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners +* @Automattic/vip-plugins diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..d03f389 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,42 @@ +# Configuration for Dependabot version updates +# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file + +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" + day: "monday" + groups: + actions: + patterns: ["*"] + labels: + - "dependencies" + commit-message: + prefix: "Actions" + include: "scope" + open-pull-requests-limit: 5 + + - package-ecosystem: "composer" + directory: "/" + schedule: + interval: "weekly" + day: "tuesday" + groups: + dev-dependencies: + patterns: + - "automattic/*" + - "dealerdirect/*" + - "php-parallel-lint/*" + - "phpcompatibility/*" + - "phpunit/*" + - "squizlabs/*" + - "yoast/*" + labels: + - "dependencies" + commit-message: + prefix: "Composer" + include: "scope" + open-pull-requests-limit: 5 + versioning-strategy: increase-if-necessary diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 5fbcf66..659d5e5 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -15,7 +15,7 @@ jobs: contents: read steps: - name: Checkout - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 with: persist-credentials: false diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml new file mode 100644 index 0000000..25dd3f8 --- /dev/null +++ b/.github/workflows/integration.yml @@ -0,0 +1,79 @@ +name: Run PHPUnit + +on: + push: + branches: + - develop + - trunk + paths: + - '.github/workflows/integration.yml' + - '**.php' + - 'phpunit.xml.dist' + - 'composer.json' + pull_request: + paths: + - '.github/workflows/integration.yml' + - '**.php' + - 'phpunit.xml.dist' + - 'composer.json' + workflow_dispatch: + +permissions: + contents: read + +# Cancels all previous workflow runs for the same branch that have not yet completed. +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + test: + name: WP ${{ matrix.wordpress }} on PHP ${{ matrix.php }} + runs-on: ubuntu-latest + + env: + WP_ENV_CORE: WordPress/WordPress#${{ matrix.wordpress }} + + strategy: + matrix: + include: + # Check lowest supported WP version, with the lowest supported PHP. + - wordpress: '6.4' + php: '7.4' + # Check latest WP with the latest PHP. + - wordpress: 'master' + php: 'latest' + fail-fast: false + + steps: + - name: Checkout code + uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 + with: + persist-credentials: false + + - name: Install wordpress environment + run: npm install -g @wordpress/env + + - name: Setup PHP ${{ matrix.php }} + uses: shivammathur/setup-php@44454db4f0199b8b9685a5d763dc37cbf79108e1 # 2.36.0 + with: + php-version: ${{ matrix.php }} + tools: composer + + - name: Install Composer dependencies + uses: ramsey/composer-install@3cf229dc2919194e9e36783941438d17239e8520 # 3.1.1 + + - name: Setup problem matchers for PHP + run: echo "::add-matcher::${{ runner.tool_cache }}/php.json" + + - name: Setup problem matchers for PHPUnit + run: echo "::add-matcher::${{ runner.tool_cache }}/phpunit.json" + + - name: Setup wp-env + run: wp-env start + + - name: Run integration tests (single site) + run: composer test:integration + + - name: Run integration tests (multisite) + run: composer test:integration-ms diff --git a/.gitignore b/.gitignore index 442989f..dce6285 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,15 @@ +# Dependencies +/node_modules/ /vendor/ -.phpcs.xml -phpcs.xml -composer.lock + +# Composer +/composer.lock + +# Tests +/.phpunit.cache/ + +# Local config overrides +/.phpcs.xml +/phpcs.xml +/phpunit.xml +/.wp-env.override.json diff --git a/.phpcs.xml.dist b/.phpcs.xml.dist index eb8b25a..6993096 100644 --- a/.phpcs.xml.dist +++ b/.phpcs.xml.dist @@ -1,6 +1,6 @@ - Custom ruleset for wp-parsely plugin. + Custom ruleset for rewrite-rules-inspector plugin. @@ -39,7 +39,7 @@ - + diff --git a/.wp-env.json b/.wp-env.json new file mode 100644 index 0000000..bfe3821 --- /dev/null +++ b/.wp-env.json @@ -0,0 +1,20 @@ +{ + "plugins": [ + "." + ], + "phpVersion": "7.4", + "config": { + "WP_DEBUG": true, + "WP_DEBUG_LOG": true, + "SCRIPT_DEBUG": true + }, + "lifecycleScripts": { + "afterStart": "wp-env run cli wp plugin install query-monitor --activate" + }, + "env": { + "tests": { + "phpVersion": "8.4", + "core": "WordPress/WordPress#trunk" + } + } +} diff --git a/CHANGELOG.md b/CHANGELOG.md index d3f533f..3bdcdb0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,30 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [1.6.0] - 2026-01-06 + +Minimum WordPress version is now 6.4. + +### Changed + +- chore: bump minimum WordPress version to 6.4 by @GaryJones in https://github.com/Automattic/Rewrite-Rules-Inspector/pull/61 + +### Documentation + +- docs: add detailed explanation for "Flush Rules" functionality in README by @GaryJones in https://github.com/Automattic/Rewrite-Rules-Inspector/pull/59 + +### Maintenance + +- chore: add wp-env configuration for local development by @GaryJones in https://github.com/Automattic/Rewrite-Rules-Inspector/pull/60 +- chore: standardise .editorconfig file by @GaryJones in https://github.com/Automattic/Rewrite-Rules-Inspector/pull/62 +- chore: normalise composer.json by @GaryJones in https://github.com/Automattic/Rewrite-Rules-Inspector/pull/63 +- chore: standardise .gitignore and add .distignore by @GaryJones in https://github.com/Automattic/Rewrite-Rules-Inspector/pull/64 +- ci: add Dependabot, lint scripts, and test infrastructure by @GaryJones in https://github.com/Automattic/Rewrite-Rules-Inspector/pull/64 +- Composer(deps-dev): update rector/rector requirement from ^1.2 to ^2.2 by @dependabot in https://github.com/Automattic/Rewrite-Rules-Inspector/pull/66 +- Actions(deps): bump actions/checkout in the actions group by @dependabot in https://github.com/Automattic/Rewrite-Rules-Inspector/pull/65 +- chore: add CODEOWNERS file and migrate Dependabot reviewers by @GaryJones in https://github.com/Automattic/Rewrite-Rules-Inspector/pull/67 +- ci: add integration test workflow and consolidate test bootstrap by @GaryJones in https://github.com/Automattic/Rewrite-Rules-Inspector/pull/68 + ## [1.5.1] - 2025-10-14 ### Fixed @@ -81,6 +105,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Filter by different sources of rewrite rules. - An error message appears if rewrite rules are missing in the database. +[1.6.0]: https://github.com/Automattic/Rewrite-Rules-Inspector/compare/1.5.1...1.6.0 [1.5.1]: https://github.com/Automattic/Rewrite-Rules-Inspector/compare/1.5.0...1.5.1 [1.5.0]: https://github.com/Automattic/Rewrite-Rules-Inspector/compare/1.4.0...1.5.0 [1.4.0]: https://github.com/Automattic/Rewrite-Rules-Inspector/compare/1.3.1...1.4.0 diff --git a/README.md b/README.md index 1c41c13..3638103 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,12 @@ # Rewrite Rules Inspector -Stable tag: 1.5.1 -Requires at least: 5.9 -Tested up to: 6.8 +Stable tag: 1.6.0 +Requires at least: 6.4 +Tested up to: 6.9 Requires PHP: 7.4 License: GPLv2 or later Tags: rewrite rules, tools -Contributors: danielbachhuber, automattic, tmoorewp, GaryJ +Contributors: danielbachhuber, automattic, tmoorewp, garyj A simple admin tool for inspecting rewrite rules. @@ -38,6 +38,44 @@ Browse a table of all **permastructs** that WordPress is aware of, including: - **Structure** — the permalink structure pattern used to generate rules. - **Description** — a human-friendly summary of what the permastruct controls. +### Flush Rules + +The "Flush Rules" button allows you to regenerate your site's rewrite rules. Here's exactly what happens when you click it: + +#### What the Flush Rules Button Does + +When you click the "Flush Rules" button, the following sequence occurs: + +1. **Security Check**: The system verifies you have the proper permissions (`manage_options` capability) and validates the security nonce to prevent unauthorized access. + +2. **Cache Clearing**: WordPress deletes the cached rewrite rules from the options cache using `wp_cache_delete('rewrite_rules', 'options')`. + +3. **Rule Regeneration**: WordPress calls `flush_rewrite_rules(false)` to regenerate all rewrite rules based on: + - Current permalink structure settings + - Custom post types and taxonomies + - Any custom rewrite rules added by themes or plugins + +4. **Hook Execution**: The `rri_flush_rules` action hook is fired, allowing other plugins to perform additional cleanup or actions after the flush. + +5. **Success Feedback**: You're redirected back to the Rewrite Rules Inspector page with a success message confirming the rules have been flushed. + +#### When to Use Flush Rules + +Use the "Flush Rules" button when: + +- **Missing Rules**: You see rules marked as "missing" (red background) in the inspector +- **Custom URLs Not Working**: Your custom permalinks or post type URLs aren't working properly +- **After Plugin Changes**: You've activated/deactivated plugins that register custom rewrite rules +- **Permalink Structure Changes**: You've modified your site's permalink structure +- **Custom Post Type Issues**: New custom post types or taxonomies aren't generating proper URLs + +#### Important Notes + +- **Soft Flush**: This performs a "soft" flush (using `flush_rewrite_rules(false)`), which is safer than a hard flush as it doesn't force regeneration of all rules unnecessarily. +- **Permissions Required**: Only users with `manage_options` capability can flush rules. +- **No Data Loss**: Flushing rules doesn't delete any content or settings, it only regenerates the URL routing rules. +- **Immediate Effect**: Changes take effect immediately after flushing. + ## Installation ### Install the plugin from within WordPress diff --git a/composer.json b/composer.json index dee0417..cbf4402 100644 --- a/composer.json +++ b/composer.json @@ -1,19 +1,65 @@ { "name": "automattic/rewrite-rules-inspector", - "type": "wordpress-plugin", "description": "WordPress plugin to inspect your rewrite rules.", - "homepage": "https://wordpress.org/plugins/rewrite-rules-inspector/", "license": "GPL-2.0-or-later", + "type": "wordpress-plugin", + "authors": [ + { + "name": "Automattic", + "homepage": "https://automattic.com/" + } + ], + "homepage": "https://wordpress.org/plugins/rewrite-rules-inspector/", + "support": { + "issues": "https://github.com/Automattic/Rewrite-Rules-Inspector/issues", + "source": "https://github.com/Automattic/Rewrite-Rules-Inspector" + }, "require": { "php": ">=7.4", - "composer/installers": "^1 || ^2" + "composer/installers": "^1.0 || ^2.0" }, "require-dev": { - "rector/rector": "^1.2" + "automattic/vipwpcs": "^3.0", + "php-parallel-lint/php-parallel-lint": "^1.0", + "phpcompatibility/phpcompatibility-wp": "^2.1", + "phpunit/phpunit": "^9", + "rector/rector": "^2.2", + "yoast/wp-test-utils": "^1.2" + }, + "autoload-dev": { + "psr-4": { + "Automattic\\RewriteRulesInspector\\Tests\\": "tests/" + } }, "config": { "allow-plugins": { - "composer/installers": true - } + "composer/installers": true, + "dealerdirect/phpcodesniffer-composer-installer": true + }, + "sort-packages": true + }, + "scripts": { + "coverage": "@php ./vendor/bin/phpunit --coverage-html ./build/coverage-html", + "coverage-ci": "@php ./vendor/bin/phpunit", + "cs": "@php ./vendor/bin/phpcs -q", + "cs-fix": "@php ./vendor/bin/phpcbf -q", + "i18n": "@php wp i18n make-pot . ./languages/rewrite-rules-inspector.pot", + "lint": "@php ./vendor/php-parallel-lint/php-parallel-lint/parallel-lint . -e php --exclude vendor --exclude .git", + "lint-ci": "@php ./vendor/php-parallel-lint/php-parallel-lint/parallel-lint . -e php --exclude vendor --exclude .git --checkstyle", + "test:unit": "@php ./vendor/bin/phpunit --testsuite Unit", + "test:integration": "wp-env run tests-cli --env-cwd=wp-content/plugins/Rewrite-Rules-Inspector ./vendor/bin/phpunit --testsuite WP_Tests", + "test:integration-ms": "wp-env run tests-cli --env-cwd=wp-content/plugins/Rewrite-Rules-Inspector /bin/bash -c 'WP_MULTISITE=1 ./vendor/bin/phpunit --testsuite WP_Tests'" + }, + "scripts-descriptions": { + "coverage": "Run tests with code coverage reporting", + "coverage-ci": "Run tests with code coverage reporting and send results to stdout", + "cs": "Run PHP Code Sniffer", + "cs-fix": "Run PHP Code Sniffer and fix violations", + "i18n": "Generate a POT file for translation", + "lint": "Run PHP linting", + "lint-ci": "Run PHP linting and send results to stdout", + "test:unit": "Run unit tests", + "test:integration": "Run integration tests", + "test:integration-ms": "Run integration tests in multisite mode" } } diff --git a/languages/rewrite-rules-inspector.pot b/languages/rewrite-rules-inspector.pot index 4d41722..28d1320 100644 --- a/languages/rewrite-rules-inspector.pot +++ b/languages/rewrite-rules-inspector.pot @@ -1,15 +1,15 @@ -# Copyright (C) 2025 Automattic, Daniel Bachhuber +# Copyright (C) 2026 Automattic, Daniel Bachhuber # This file is distributed under the GPL-2.0-or-later. msgid "" msgstr "" -"Project-Id-Version: Rewrite Rules Inspector 1.5.1\n" +"Project-Id-Version: Rewrite Rules Inspector 1.6.0\n" "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/rewrite-rules-inspector\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"POT-Creation-Date: 2025-10-14T16:00:17+00:00\n" +"POT-Creation-Date: 2026-01-02T22:27:32+00:00\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "X-Generator: WP-CLI 2.12.0\n" "X-Domain: rewrite-rules-inspector\n" diff --git a/phpunit.xml.dist b/phpunit.xml.dist new file mode 100644 index 0000000..fa96020 --- /dev/null +++ b/phpunit.xml.dist @@ -0,0 +1,31 @@ + + + + + ./tests/Unit + + + ./tests/Integration + + + + + ./src + ./rewrite-rules-inspector.php + + + ./vendor + ./tests + + + diff --git a/rewrite-rules-inspector.php b/rewrite-rules-inspector.php index 46c5a60..616742c 100644 --- a/rewrite-rules-inspector.php +++ b/rewrite-rules-inspector.php @@ -11,18 +11,18 @@ * Plugin Name: Rewrite Rules Inspector * Plugin URI: https://wordpress.org/plugins/rewrite-rules-inspector/ * Description: Simple WordPress admin tool for inspecting your rewrite rules. - * Version: 1.5.1 + * Version: 1.6.0 + * Requires at least: 6.4 + * Requires PHP: 7.4 * Author: Automattic, Daniel Bachhuber * Author URI: https://automattic.com/ * Text Domain: rewrite-rules-inspector * License: GPL-2.0-or-later * License URI: http://www.gnu.org/licenses/gpl-2.0.txt * GitHub Plugin URI: https://github.com/Automattic/Rewrite-Rules-Inspector - * Requires PHP: 7.4 - * Requires WP: 5.9.0 */ -define( 'REWRITE_RULES_INSPECTOR_VERSION', '1.5.1' ); // Unused for now. +define( 'REWRITE_RULES_INSPECTOR_VERSION', '1.6.0' ); // Unused for now. define( 'REWRITE_RULES_INSPECTOR_FILE_PATH', plugin_basename( __FILE__ ) ); // Load the WP_List_Table class if it doesn't yet exist. diff --git a/tests/Integration/PluginTest.php b/tests/Integration/PluginTest.php new file mode 100644 index 0000000..94f00f7 --- /dev/null +++ b/tests/Integration/PluginTest.php @@ -0,0 +1,43 @@ +assertTrue( defined( 'REWRITE_RULES_INSPECTOR_VERSION' ) ); + } + + /** + * Test that the plugin file path constant is defined. + */ + public function test_plugin_file_path_constant_defined(): void { + $this->assertTrue( defined( 'REWRITE_RULES_INSPECTOR_FILE_PATH' ) ); + } + + /** + * Test that the global plugin instance exists. + */ + public function test_global_plugin_instance_exists(): void { + global $rewrite_rules_inspector; + $this->assertInstanceOf( \Automattic\RewriteRulesInspector\Plugin::class, $rewrite_rules_inspector ); + } + + /** + * Test that the admin menu is registered. + */ + public function test_admin_menu_registered(): void { + $this->assertGreaterThan( 0, has_action( 'admin_menu' ) ); + } +} diff --git a/tests/Integration/TestCase.php b/tests/Integration/TestCase.php new file mode 100644 index 0000000..f78d4d0 --- /dev/null +++ b/tests/Integration/TestCase.php @@ -0,0 +1,17 @@ +assertTrue( class_exists( \Automattic\RewriteRulesInspector\Core\RewriteRules::class ) ); + } +} diff --git a/tests/Unit/TestCase.php b/tests/Unit/TestCase.php new file mode 100644 index 0000000..305fd03 --- /dev/null +++ b/tests/Unit/TestCase.php @@ -0,0 +1,17 @@ +