From 49c054709d2adc9f673e3d0d662c50870bb5be6e Mon Sep 17 00:00:00 2001 From: George Fehr Date: Wed, 21 Jan 2026 15:32:26 -0500 Subject: [PATCH 1/3] Add functions from changes related to SpinupWP subdomains --- README.md | 79 ++++++++++++++++++++- src/Endpoints/Endpoint.php | 5 ++ src/Endpoints/Site.php | 70 +++++++++++++++++++ src/Resources/Site.php | 50 +++++++++++++ tests/Endpoints/SiteTest.php | 131 +++++++++++++++++++++++++++++++++++ 5 files changed, 333 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 21383fc..ca91065 100644 --- a/README.md +++ b/README.md @@ -83,7 +83,7 @@ $sites = $spinupwp->sites->list(); // Return a single site $site = $spinupwp->sites->get($siteId); -// Create and return a new site +// Create and return a new site $site = $spinupwp->sites->create($serverId, []); // Delete a site @@ -100,6 +100,51 @@ $eventId = $spinupwp->sites->purgeObjectCache($siteId); // Reset a site's file permissions $eventId = $spinupwp->sites->correctFilePermissions($siteId); + +// Enable HTTPS +$eventId = $spinupwp->sites->enableHttps($siteId, ['type' => 'webroot']); + +// Update HTTPS settings +$eventId = $spinupwp->sites->updateHttps($siteId, [ + 'type' => 'custom', + 'certificate' => '-----BEGIN CERTIFICATE-----...', + 'private_key' => '-----BEGIN PRIVATE KEY-----...', +]); + +// Disable HTTPS +$eventId = $spinupwp->sites->disableHttps($siteId); + +// Update PHP version +$eventId = $spinupwp->sites->updatePhpSettings($siteId, ['php_version' => '8.3']); + +// Enable the SpinupWP subdomain +$eventId = $spinupwp->sites->enableSpinupwpSubdomain($siteId); + +// Disable the SpinupWP subdomain +$eventId = $spinupwp->sites->disableSpinupwpSubdomain($siteId); + +// List additional domains +$domains = $spinupwp->sites->listDomains($siteId); + +// Add an additional domain +$domain = $spinupwp->sites->addDomain($siteId, [ + 'domain' => 'www.turnipjuice.media', + 'redirect' => [ + 'enabled' => true, + ], +]); + +// Update an additional domain +$domain = $spinupwp->sites->updateDomain($siteId, $domainId, [ + 'redirect' => [ + 'enabled' => true, + 'type' => 301, + 'destination' => 'turnipjuice.media', + ], +]); + +// Delete an additional domain +$eventId = $spinupwp->sites->deleteDomain($siteId, $domainId); ``` On a `Site` instance you may also call: ```php @@ -117,7 +162,37 @@ $site->purgeObjectCache(); // Reset a site's file permissions $site->correctFilePermissions(); -```` + +// Enable HTTPS +$site->enableHttps(['type' => 'webroot']); + +// Update HTTPS settings +$site->updateHttps(['type' => 'custom', 'certificate' => '...', 'private_key' => '...']); + +// Disable HTTPS +$site->disableHttps(); + +// Update PHP version +$site->updatePhpSettings(['php_version' => '8.3']); + +// Enable the SpinupWP subdomain +$site->enableSpinupwpSubdomain(); + +// Disable the SpinupWP subdomain +$site->disableSpinupwpSubdomain(); + +// List additional domains +$site->listDomains(); + +// Add an additional domain +$site->addDomain(['domain' => 'www.turnipjuice.media']); + +// Update an additional domain +$site->updateDomain($domainId, ['redirect' => ['enabled' => true]]); + +// Delete an additional domain +$site->deleteDomain($domainId); +``` ### Events ```php diff --git a/src/Endpoints/Endpoint.php b/src/Endpoints/Endpoint.php index eedcbd2..7f3325b 100644 --- a/src/Endpoints/Endpoint.php +++ b/src/Endpoints/Endpoint.php @@ -83,6 +83,11 @@ public function postRequest(string $uri, array $payload = []): array return $this->request('POST', $uri, $payload); } + public function putRequest(string $uri, array $payload = []): array + { + return $this->request('PUT', $uri, $payload); + } + public function deleteRequest(string $uri, array $payload = []): array { return $this->request('DELETE', $uri, $payload); diff --git a/src/Endpoints/Site.php b/src/Endpoints/Site.php index da4b531..781bcaf 100644 --- a/src/Endpoints/Site.php +++ b/src/Endpoints/Site.php @@ -92,4 +92,74 @@ public function correctFilePermissions(int $id): int return $request['event_id']; } + + public function enableHttps(int $id, array $data): int + { + $request = $this->postRequest("sites/{$id}/https", $data); + + return $request['event_id']; + } + + public function updateHttps(int $id, array $data): int + { + $request = $this->putRequest("sites/{$id}/https", $data); + + return $request['event_id']; + } + + public function disableHttps(int $id): int + { + $request = $this->deleteRequest("sites/{$id}/https"); + + return $request['event_id']; + } + + public function updatePhpSettings(int $id, array $data): int + { + $request = $this->putRequest("sites/{$id}/php", $data); + + return $request['event_id']; + } + + public function enableSpinupwpSubdomain(int $id): int + { + $request = $this->postRequest("sites/{$id}/spinupwp-subdomain"); + + return $request['event_id']; + } + + public function disableSpinupwpSubdomain(int $id): int + { + $request = $this->deleteRequest("sites/{$id}/spinupwp-subdomain"); + + return $request['event_id']; + } + + public function listDomains(int $id): array + { + $domains = $this->getRequest("sites/{$id}/domains"); + + return $domains['data']; + } + + public function addDomain(int $id, array $data): array + { + $domain = $this->postRequest("sites/{$id}/domains", $data); + + return $domain; + } + + public function updateDomain(int $siteId, int $domainId, array $data): array + { + $domain = $this->putRequest("sites/{$siteId}/domains/{$domainId}", $data); + + return $domain; + } + + public function deleteDomain(int $siteId, int $domainId): int + { + $request = $this->deleteRequest("sites/{$siteId}/domains/{$domainId}"); + + return $request['event_id']; + } } diff --git a/src/Resources/Site.php b/src/Resources/Site.php index e4a66f5..a608479 100644 --- a/src/Resources/Site.php +++ b/src/Resources/Site.php @@ -32,4 +32,54 @@ public function correctFilePermissions(): int { return $this->spinupwp->sites->correctFilePermissions($this->id); } + + public function enableHttps(array $data): int + { + return $this->spinupwp->sites->enableHttps($this->id, $data); + } + + public function updateHttps(array $data): int + { + return $this->spinupwp->sites->updateHttps($this->id, $data); + } + + public function disableHttps(): int + { + return $this->spinupwp->sites->disableHttps($this->id); + } + + public function updatePhpSettings(array $data): int + { + return $this->spinupwp->sites->updatePhpSettings($this->id, $data); + } + + public function enableSpinupwpSubdomain(): int + { + return $this->spinupwp->sites->enableSpinupwpSubdomain($this->id); + } + + public function disableSpinupwpSubdomain(): int + { + return $this->spinupwp->sites->disableSpinupwpSubdomain($this->id); + } + + public function listDomains(): array + { + return $this->spinupwp->sites->listDomains($this->id); + } + + public function addDomain(array $data): array + { + return $this->spinupwp->sites->addDomain($this->id, $data); + } + + public function updateDomain(int $domainId, array $data): array + { + return $this->spinupwp->sites->updateDomain($this->id, $domainId, $data); + } + + public function deleteDomain(int $domainId): int + { + return $this->spinupwp->sites->deleteDomain($this->id, $domainId); + } } diff --git a/tests/Endpoints/SiteTest.php b/tests/Endpoints/SiteTest.php index b600916..14319ac 100644 --- a/tests/Endpoints/SiteTest.php +++ b/tests/Endpoints/SiteTest.php @@ -184,4 +184,135 @@ public function test_handling_429_errors(): void (new Site($this->spinupwp))->get(1); } + + public function test_enable_https_request(): void + { + $this->client->shouldReceive('request')->once()->with('POST', 'sites/1/https', [ + 'form_params' => [ + 'type' => 'webroot', + ], + ])->andReturn( + new Response(200, [], '{"event_id": 100}') + ); + + $this->assertEquals(100, $this->siteEndpoint->enableHttps(1, ['type' => 'webroot'])); + } + + public function test_update_https_request(): void + { + $this->client->shouldReceive('request')->once()->with('PUT', 'sites/1/https', [ + 'form_params' => [ + 'type' => 'custom', + 'certificate' => '-----BEGIN CERTIFICATE-----', + 'private_key' => '-----BEGIN PRIVATE KEY-----', + ], + ])->andReturn( + new Response(200, [], '{"event_id": 100}') + ); + + $this->assertEquals(100, $this->siteEndpoint->updateHttps(1, [ + 'type' => 'custom', + 'certificate' => '-----BEGIN CERTIFICATE-----', + 'private_key' => '-----BEGIN PRIVATE KEY-----', + ])); + } + + public function test_disable_https_request(): void + { + $this->client->shouldReceive('request')->once()->with('DELETE', 'sites/1/https', [])->andReturn( + new Response(200, [], '{"event_id": 100}') + ); + + $this->assertEquals(100, $this->siteEndpoint->disableHttps(1)); + } + + public function test_update_php_version_request(): void + { + $this->client->shouldReceive('request')->once()->with('PUT', 'sites/1/php', [ + 'form_params' => [ + 'php_version' => '8.3', + ], + ])->andReturn( + new Response(200, [], '{"event_id": 100}') + ); + + $this->assertEquals(100, $this->siteEndpoint->updatePhpSettings(1, ['php_version' => '8.3'])); + } + + public function test_enable_spinupwp_subdomain_request(): void + { + $this->client->shouldReceive('request')->once()->with('POST', 'sites/1/spinupwp-subdomain', [])->andReturn( + new Response(200, [], '{"event_id": 100}') + ); + + $this->assertEquals(100, $this->siteEndpoint->enableSpinupwpSubdomain(1)); + } + + public function test_disable_spinupwp_subdomain_request(): void + { + $this->client->shouldReceive('request')->once()->with('DELETE', 'sites/1/spinupwp-subdomain', [])->andReturn( + new Response(200, [], '{"event_id": 100}') + ); + + $this->assertEquals(100, $this->siteEndpoint->disableSpinupwpSubdomain(1)); + } + + public function test_list_domains_request(): void + { + $this->client->shouldReceive('request')->once()->with('GET', 'sites/1/domains', [])->andReturn( + new Response(200, [], '{"data": [{"id": 1, "domain": "www.hellfish.media"}]}') + ); + + $domains = $this->siteEndpoint->listDomains(1); + $this->assertCount(1, $domains); + $this->assertEquals('www.hellfish.media', $domains[0]['domain']); + } + + public function test_add_domain_request(): void + { + $this->client->shouldReceive('request')->once()->with('POST', 'sites/1/domains', [ + 'form_params' => [ + 'domain' => 'www.hellfish.media', + ], + ])->andReturn( + new Response(200, [], '{"event_id": 100, "data": {"id": 1, "domain": "www.hellfish.media"}}') + ); + + $result = $this->siteEndpoint->addDomain(1, ['domain' => 'www.hellfish.media']); + $this->assertEquals(100, $result['event_id']); + $this->assertEquals('www.hellfish.media', $result['data']['domain']); + } + + public function test_update_domain_request(): void + { + $this->client->shouldReceive('request')->once()->with('PUT', 'sites/1/domains/2', [ + 'form_params' => [ + 'redirect' => [ + 'enabled' => true, + 'type' => 301, + 'destination' => 'hellfish.media', + ], + ], + ])->andReturn( + new Response(200, [], '{"event_id": 100, "data": {"id": 2, "domain": "www.hellfish.media"}}') + ); + + $result = $this->siteEndpoint->updateDomain(1, 2, [ + 'redirect' => [ + 'enabled' => true, + 'type' => 301, + 'destination' => 'hellfish.media', + ], + ]); + $this->assertEquals(100, $result['event_id']); + } + + public function test_delete_domain_request(): void + { + $this->client->shouldReceive('request')->once()->with('DELETE', 'sites/1/domains/2', [])->andReturn( + new Response(200, [], '{"event_id": 100}') + ); + + $this->assertEquals(100, $this->siteEndpoint->deleteDomain(1, 2)); + } } From 765a338be68271106b181aa5ad9741b3586b515a Mon Sep 17 00:00:00 2001 From: George Fehr Date: Wed, 21 Jan 2026 16:19:18 -0500 Subject: [PATCH 2/3] Add bad request exception --- src/Endpoints/Endpoint.php | 7 +++++++ src/Exceptions/BadRequestException.php | 13 +++++++++++++ 2 files changed, 20 insertions(+) create mode 100644 src/Exceptions/BadRequestException.php diff --git a/src/Endpoints/Endpoint.php b/src/Endpoints/Endpoint.php index 7f3325b..bf3225a 100644 --- a/src/Endpoints/Endpoint.php +++ b/src/Endpoints/Endpoint.php @@ -4,6 +4,7 @@ use Exception; use Psr\Http\Message\ResponseInterface; +use SpinupWp\Exceptions\BadRequestException; use SpinupWp\Exceptions\AccessDeniedException; use SpinupWp\Exceptions\NotFoundException; use SpinupWp\Exceptions\RateLimitException; @@ -44,6 +45,12 @@ protected function request(string $verb, string $uri, array $payload = []): arra protected function handleRequestError(ResponseInterface $response): void { + if ($response->getStatusCode() === 400) { + $responseBody = (string) $response->getBody(); + + throw new BadRequestException(json_decode($responseBody, true, 512, JSON_THROW_ON_ERROR)); + } + if ($response->getStatusCode() === 401) { throw new UnauthorizedException(); } diff --git a/src/Exceptions/BadRequestException.php b/src/Exceptions/BadRequestException.php new file mode 100644 index 0000000..f091ef2 --- /dev/null +++ b/src/Exceptions/BadRequestException.php @@ -0,0 +1,13 @@ + Date: Wed, 21 Jan 2026 21:20:04 +0000 Subject: [PATCH 3/3] Apply php-cs-fixer changes --- src/Endpoints/Endpoint.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Endpoints/Endpoint.php b/src/Endpoints/Endpoint.php index bf3225a..e688ae2 100644 --- a/src/Endpoints/Endpoint.php +++ b/src/Endpoints/Endpoint.php @@ -4,8 +4,8 @@ use Exception; use Psr\Http\Message\ResponseInterface; -use SpinupWp\Exceptions\BadRequestException; use SpinupWp\Exceptions\AccessDeniedException; +use SpinupWp\Exceptions\BadRequestException; use SpinupWp\Exceptions\NotFoundException; use SpinupWp\Exceptions\RateLimitException; use SpinupWp\Exceptions\TimeoutException;