Skip to content

Commit 6fe00b4

Browse files
committed
docs: add contribution guide for the compatibility layer
The new section in CONTRIBUTING.md outlines the two primary methods for contributing to the plugin's compatibility layer: - Reporting issues for manual fixes via the Site Health tool. - Implementing automated code fixes using Compatibility and Fix classes. This provides clear guidance for developers looking to help improve plugin compatibility on the Pantheon platform.
1 parent ee643d8 commit 6fe00b4

1 file changed

Lines changed: 86 additions & 1 deletion

File tree

CONTRIBUTING.md

Lines changed: 86 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,89 @@ When you are ready for a new `pantheon-mu-plugin` release, before cutting a new
1313

1414
1. Update the version number in `pantheon.php` in the plugin header and the `PANTHEON_MU_PLUGIN_VERSION` constant.
1515
1. If there were any new files that were added to the plugin that should be excluded from the WordPress upstream, add them to the `.gitattributes` file with `export-ignore` and be sure to add them to the `$files_to_delete` array in [`update-tool/src/Update/Filters/CopyMuPlugin.php`](https://github.com/pantheon-systems/update-tool/blob/master/src/Update/Filters/CopyMuPlugin.php).
16-
1. Use the GitHub UI to create a new release. The tag should be the version number only (not prefixed with `v`, e.g. `1.2.1`). Use the GitHub tools to autocomplete the title and body of the release with the changelog. The release should be created from the `main` branch.
16+
1. Use the GitHub UI to create a new release. The tag should be the version number only (not prefixed with `v`, e.g. `1.2.1`). Use the GitHub tools to autocomplete the title and body of the release with the changelog. The release should be created from the `main` branch.
17+
18+
## Contributing to the Compatibility Layer
19+
20+
There are two main ways to contribute to the compatibility layer: reporting an issue with a plugin or adding an automated fix.
21+
22+
### Type 1: Reporting an Incompatibility (No Code Fix)
23+
24+
Use this method when a plugin is incompatible and requires manual user action, or when there is no programmatic fix. These notices appear in the WordPress Site Health tool.
25+
26+
1. **Choose the correct category in `inc/site-health.php`:**
27+
* **`get_compatibility_manual_fixes()`**: For plugins that require specific manual configuration. The user will be told a "Manual Fix Required".
28+
* **`get_compatibility_review_fixes()`**: For plugins that are partially or fully incompatible. The user will see statuses like "Incompatible" or "Partial Compatibility".
29+
30+
2. **Add the plugin to the appropriate function's `$plugins` array.**
31+
32+
*Example (Adding a "Manual Fix Required" notice):*
33+
```php
34+
// In get_compatibility_manual_fixes() in inc/site-health.php
35+
$plugins = [
36+
// ... existing plugins
37+
'my-other-plugin' => [
38+
'plugin_status' => esc_html__( 'Manual Fix Required', 'pantheon' ),
39+
'plugin_slug' => 'my-other-plugin/my-other-plugin.php',
40+
'plugin_message' => wp_kses_post( 'This plugin requires manual configuration. See <a href="...">docs</a>.' ),
41+
],
42+
];
43+
```
44+
45+
### Type 2: Adding an Automated Fix (Code Fix)
46+
47+
Use this method when you can fix an incompatibility with code. This involves creating a **Compatibility Class** and, optionally, a **Fix Class**.
48+
49+
#### Understanding the Classes
50+
51+
* **Compatibility Class (The "When"):** This class is the trigger. It tells the system *when* to run a fix for a specific plugin. It extends `Pantheon\Compatibility\Base` and is stored in `inc/compatibility/`. Its primary job is to define the conditions for the fix (e.g., run on every page load, only on activation).
52+
53+
* **Fix Class (The "What"):** This class contains the *actual code* that solves the problem (e.g., defines a constant, adds a filter). It is stored in `inc/compatibility/fixes/`. **Using a separate Fix Class is optional but highly recommended for clarity and reusability.** For very simple, one-line fixes, you can place the logic directly in the Compatibility Class. For anything more complex, or for logic that could be reused (like `DefineConstantFix`), a Fix Class is the best practice.
54+
55+
#### How to Implement an Automated Fix
56+
57+
1. **Create the Compatibility Class (Required):**
58+
* Create a new file in `inc/compatibility/` named `class-{plugin-name}.php`.
59+
* The class must extend `Pantheon\Compatibility\Base`.
60+
* You must implement the `apply_fix()` and `remove_fix()` methods, even if their bodies are empty.
61+
* Set a property like `$run_fix_everytime = true;` to control when the fix runs.
62+
63+
2. **Implement the Fix Logic (Choose One):**
64+
65+
* **Option A (Simple Fix, No Fix Class):** Place your logic directly inside the `apply_fix` method of your new Compatibility Class.
66+
67+
*Example:*
68+
```php
69+
// in inc/compatibility/class-simplefixplugin.php
70+
public function apply_fix() {
71+
if ( ! defined( 'SIMPLE_FIX' ) ) {
72+
define( 'SIMPLE_FIX', true );
73+
}
74+
}
75+
```
76+
77+
* **Option B (Recommended, Using a Fix Class):**
78+
* Create a new file in `inc/compatibility/fixes/` named `class-{plugin-name}fix.php`.
79+
* Create a static `apply()` method in this class containing your fix logic.
80+
* Call this static method from your Compatibility Class's `apply_fix()` method.
81+
82+
*Example:*
83+
```php
84+
// in inc/compatibility/fixes/class-complexfix.php
85+
class ComplexFix {
86+
public static function apply() {
87+
// ... complex logic here ...
88+
}
89+
}
90+
91+
// in inc/compatibility/class-complexplugin.php
92+
public function apply_fix() {
93+
\Pantheon\Compatibility\Fixes\ComplexFix::apply();
94+
}
95+
```
96+
97+
3. **Register the Compatibility Class:**
98+
* In `inc/compatibility/class-compatibilityfactory.php`, add your new **Compatibility Class** and the target plugin's slug to the `$targets` array in the `setup_targets()` method.
99+
100+
4. **Add a Test:**
101+
* In `tests/phpunit/test-compatibility-layer.php`, add a test to ensure your component is instantiated correctly.

0 commit comments

Comments
 (0)