Conversation
Adds a new Plesk provider that uses the REST API v2 CLI gateway to manage site aliases and subdomains automatically when domains are mapped or removed. Supports API key and Basic Auth, www alias handling, and AutoSSL. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
🔨 Build Complete - Ready for Testing!📦 Download Build Artifact (Recommended)Download the zip build, upload to WordPress and test:
🌐 Test in WordPress Playground (Very Experimental)Click the link below to instantly test this PR in your browser - no installation needed! Login credentials: |
|
Warning Rate limit exceeded
⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughAdded a new Plesk integration provider and a Plesk domain-mapping capability, registered them in the integration registry, and implemented Plesk API request handling plus lifecycle hooks for domain and subdomain create/delete. Also apply requested title after site duplication and adjust corresponding tests. Changes
Sequence Diagram(s)sequenceDiagram
participant Admin as WP Ultimo Admin
participant Core as WP Ultimo Core
participant Capability as Plesk Domain Mapping
participant Integration as Plesk Integration
participant API as Plesk API v2
Admin->>Core: Add domain to site
Core->>Capability: on_add_domain(domain, site_id)
Capability->>Integration: send_plesk_api_request("/api/v2/cli/site_alias/call", POST, --create)
Integration->>API: POST /api/v2/cli/site_alias/call with auth
API-->>Integration: 2xx / error
Integration-->>Capability: response/result
Capability-->>Core: complete
sequenceDiagram
participant Admin as WP Ultimo Admin
participant Core as WP Ultimo Core
participant Capability as Plesk Domain Mapping
participant Integration as Plesk Integration
participant API as Plesk API v2
Admin->>Core: Add subdomain to site
Core->>Capability: on_add_subdomain(subdomain, site_id)
Capability->>Integration: send_plesk_api_request("/api/v2/cli/subdomain/call", POST, --create)
Integration->>API: POST /api/v2/cli/subdomain/call with auth
API-->>Integration: 2xx / error
Integration-->>Capability: response/result
Capability-->>Core: complete
Estimated Code Review Effort🎯 4 (Complex) | ⏱️ ~45 minutes Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
🔨 Build Complete - Ready for Testing!📦 Download Build Artifact (Recommended)Download the zip build, upload to WordPress and test:
🌐 Test in WordPress Playground (Very Experimental)Click the link below to instantly test this PR in your browser - no installation needed! Login credentials: |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (2)
inc/integrations/providers/plesk/class-plesk-domain-mapping.php (1)
106-106: Mark intentionally unused hook parameters explicitly.
$site_idis unused in these handlers. Renaming to$_site_id(or adding a local suppression) will clarify intent and quiet PHPMD noise.Also applies to: 156-156, 198-198, 231-231
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@inc/integrations/providers/plesk/class-plesk-domain-mapping.php` at line 106, The hook handlers currently accept a $site_id parameter that is not used; rename the parameter to $_site_id in the affected methods (e.g., on_add_domain) so the intent is explicit and PHPMD won't flag it, or alternatively add a local suppression comment; update the function signatures where $site_id appears (the handlers at the noted locations) to use $_site_id and leave the bodies unchanged.inc/integrations/providers/plesk/class-plesk-integration.php (1)
183-200: Reduce raw payload logging by default.Line 186 and Line 200 log full request/response bodies. For hosting APIs, this can leak sensitive infrastructure details into persistent logs. Prefer status-level logs by default and gated/truncated payload logging only in debug mode.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@inc/integrations/providers/plesk/class-plesk-integration.php` around lines 183 - 200, The current logging in class-plesk-integration (around the wp_remote_request call) writes full request and response bodies via wu_log_add for $data and $response_body; change this to log only status-level info by default (e.g., method and $api_url and $response_code) and gate any full payload logging behind a debug flag (use WP_DEBUG or an internal $this->debug property) or truncate payloads before logging (e.g., first N chars + ellipsis). Update the wu_log_add calls that reference $data and $response_body so they only emit truncated or gated logs (keep the existing error log for WP_Error intact), and ensure you still use wp_json_encode for safe serialization when debug is enabled.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@inc/integrations/providers/plesk/class-plesk-domain-mapping.php`:
- Around line 170-183: The deletion of the "www" alias is unconditional and can
remove aliases this integration didn't create; wrap the existing deletion block
so it only runs when the same policy used for creation applies by checking
should_create_www_subdomain() before attempting to delete (in addition to the
existing ! str_starts_with($domain, 'www.') check). Update the code around the
log_response call that calls
$this->get_plesk()->send_plesk_api_request('/api/v2/cli/site_alias/call',
'POST', ...) so it is executed only when $this->should_create_www_subdomain()
returns true, mirroring the creation logic.
In `@inc/integrations/providers/plesk/class-plesk-integration.php`:
- Around line 41-46: The required credential list in the class constructor is
inconsistent with the runtime Basic Auth check: update the
set_required_constants call to include 'WU_PLESK_USERNAME' (and remove it from
set_optional_constants) so the class-level requirements match the runtime check
that expects both username and password; alternatively, if API-key-only auth is
intended keep 'WU_PLESK_USERNAME' optional but change the runtime credential
validation to accept API-key auth, ensuring the change is applied in the same
class (class-plesk-integration.php) where set_required_constants,
set_optional_constants and the runtime username/password validation are
implemented.
---
Nitpick comments:
In `@inc/integrations/providers/plesk/class-plesk-domain-mapping.php`:
- Line 106: The hook handlers currently accept a $site_id parameter that is not
used; rename the parameter to $_site_id in the affected methods (e.g.,
on_add_domain) so the intent is explicit and PHPMD won't flag it, or
alternatively add a local suppression comment; update the function signatures
where $site_id appears (the handlers at the noted locations) to use $_site_id
and leave the bodies unchanged.
In `@inc/integrations/providers/plesk/class-plesk-integration.php`:
- Around line 183-200: The current logging in class-plesk-integration (around
the wp_remote_request call) writes full request and response bodies via
wu_log_add for $data and $response_body; change this to log only status-level
info by default (e.g., method and $api_url and $response_code) and gate any full
payload logging behind a debug flag (use WP_DEBUG or an internal $this->debug
property) or truncate payloads before logging (e.g., first N chars + ellipsis).
Update the wu_log_add calls that reference $data and $response_body so they only
emit truncated or gated logs (keep the existing error log for WP_Error intact),
and ensure you still use wp_json_encode for safe serialization when debug is
enabled.
ℹ️ Review info
Configuration used: defaults
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
assets/img/hosts/plesk.svgis excluded by!**/*.svg
📒 Files selected for processing (3)
inc/integrations/class-integration-registry.phpinc/integrations/providers/plesk/class-plesk-domain-mapping.phpinc/integrations/providers/plesk/class-plesk-integration.php
| // Also try to remove www alias | ||
| if (! str_starts_with($domain, 'www.')) { | ||
| $www = 'www.' . $domain; | ||
|
|
||
| $this->log_response( | ||
| sprintf('Delete alias %s', $www), | ||
| $this->get_plesk()->send_plesk_api_request( | ||
| '/api/v2/cli/site_alias/call', | ||
| 'POST', | ||
| [ | ||
| 'params' => ['--delete', $www], | ||
| ] | ||
| ) | ||
| ); |
There was a problem hiding this comment.
www alias deletion should follow the same policy used for creation.
Line 129 gates www creation with should_create_www_subdomain(), but Line 171 deletes www.<domain> unconditionally. This can delete aliases not created by this integration.
🔧 Proposed fix
- // Also try to remove www alias
- if (! str_starts_with($domain, 'www.')) {
+ // Also remove www alias only when this integration policy would create it
+ if (
+ ! str_starts_with($domain, 'www.')
+ && \WP_Ultimo\Managers\Domain_Manager::get_instance()->should_create_www_subdomain($domain)
+ ) {
$www = 'www.' . $domain;
$this->log_response(
sprintf('Delete alias %s', $www),
$this->get_plesk()->send_plesk_api_request(🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@inc/integrations/providers/plesk/class-plesk-domain-mapping.php` around lines
170 - 183, The deletion of the "www" alias is unconditional and can remove
aliases this integration didn't create; wrap the existing deletion block so it
only runs when the same policy used for creation applies by checking
should_create_www_subdomain() before attempting to delete (in addition to the
existing ! str_starts_with($domain, 'www.') check). Update the code around the
log_response call that calls
$this->get_plesk()->send_plesk_api_request('/api/v2/cli/site_alias/call',
'POST', ...) so it is executed only when $this->should_create_www_subdomain()
returns true, mirroring the creation logic.
| ['WU_PLESK_API_KEY', 'WU_PLESK_PASSWORD'], | ||
| 'WU_PLESK_DOMAIN', | ||
| ] | ||
| ); | ||
| $this->set_optional_constants(['WU_PLESK_PORT', 'WU_PLESK_USERNAME']); | ||
| $this->set_supports(['autossl', 'no-instructions']); |
There was a problem hiding this comment.
Credential requirements are inconsistent with Basic Auth runtime checks.
Line 41 allows WU_PLESK_PASSWORD to satisfy setup without WU_PLESK_USERNAME, but Line 164 requires both username and password. That permits “configured” states that can only fail at runtime.
🔧 Proposed fix
public function __construct() {
parent::__construct('plesk', 'Plesk');
$this->set_description(__('Integrates with Plesk to add and remove domain aliases automatically when domains are mapped or removed.', 'ultimate-multisite'));
$this->set_logo(function_exists('wu_get_asset') ? wu_get_asset('plesk.svg', 'img/hosts') : '');
$this->set_tutorial_link('https://ultimatemultisite.com/docs/user-guide/host-integrations/plesk');
- $this->set_constants(
- [
- 'WU_PLESK_HOST',
- ['WU_PLESK_API_KEY', 'WU_PLESK_PASSWORD'],
- 'WU_PLESK_DOMAIN',
- ]
- );
- $this->set_optional_constants(['WU_PLESK_PORT', 'WU_PLESK_USERNAME']);
+ $this->set_constants(['WU_PLESK_HOST', 'WU_PLESK_DOMAIN']);
+ $this->set_optional_constants(['WU_PLESK_PORT', 'WU_PLESK_API_KEY', 'WU_PLESK_USERNAME', 'WU_PLESK_PASSWORD']);
$this->set_supports(['autossl', 'no-instructions']);
}
+
+public function is_setup(): bool {
+ if (! parent::is_setup()) {
+ return false;
+ }
+
+ $api_key = $this->get_credential('WU_PLESK_API_KEY');
+ $username = $this->get_credential('WU_PLESK_USERNAME');
+ $password = $this->get_credential('WU_PLESK_PASSWORD');
+
+ return ! empty($api_key) || (! empty($username) && ! empty($password));
+}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@inc/integrations/providers/plesk/class-plesk-integration.php` around lines 41
- 46, The required credential list in the class constructor is inconsistent with
the runtime Basic Auth check: update the set_required_constants call to include
'WU_PLESK_USERNAME' (and remove it from set_optional_constants) so the
class-level requirements match the runtime check that expects both username and
password; alternatively, if API-key-only auth is intended keep
'WU_PLESK_USERNAME' optional but change the runtime credential validation to
accept API-key auth, ensuring the change is applied in the same class
(class-plesk-integration.php) where set_required_constants,
set_optional_constants and the runtime username/password validation are
implemented.
🔨 Build Complete - Ready for Testing!📦 Download Build Artifact (Recommended)Download the zip build, upload to WordPress and test:
🌐 Test in WordPress Playground (Very Experimental)Click the link below to instantly test this PR in your browser - no installation needed! Login credentials: |
197be5a to
25c8655
Compare
🔨 Build Complete - Ready for Testing!📦 Download Build Artifact (Recommended)Download the zip build, upload to WordPress and test:
🌐 Test in WordPress Playground (Very Experimental)Click the link below to instantly test this PR in your browser - no installation needed! Login credentials: |
After MUCD_Data::copy_data copies the template's options table, the blogname option gets overwritten with the template's value. The existing save/restore mechanism can fail when the WordPress object cache returns stale values (particularly in test environments with transaction rollback). Explicitly set the blogname via update_blog_option after duplication completes so the requested title is always applied. Also use get_blog_option in the test assertion instead of the cached WP_Site property. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
25c8655 to
226f9e3
Compare
🔨 Build Complete - Ready for Testing!📦 Download Build Artifact (Recommended)Download the zip build, upload to WordPress and test:
🌐 Test in WordPress Playground (Very Experimental)Click the link below to instantly test this PR in your browser - no installation needed! Login credentials: |
Summary
site_alias/call) and subdomains (subdomain/call)X-API-Keyheader) and HTTP Basic AuthDomain_Manager::should_create_www_subdomain()Files
inc/integrations/providers/plesk/class-plesk-integration.php— Provider with credentials, connection test, and API request methodinc/integrations/providers/plesk/class-plesk-domain-mapping.php— Domain mapping capability (add/remove domain aliases and subdomains)assets/img/hosts/plesk.svg— Plesk logo for the integrations settings pageinc/integrations/class-integration-registry.php— Registration of Plesk provider and capabilityTest plan
🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Bug Fixes
Tests