Skip to content

Commit 3fa66cc

Browse files
committed
Implement non-extraction calls
1 parent ebe5920 commit 3fa66cc

File tree

11 files changed

+358
-30
lines changed

11 files changed

+358
-30
lines changed

app/Enum/WebserviceEndpoint.php

Lines changed: 57 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,63 @@
22

33
namespace App\Enum;
44

5+
use App\RemoteSite\Responses\FinalizeUpdate;
6+
use App\RemoteSite\Responses\GetUpdate;
7+
use App\RemoteSite\Responses\HealthCheck;
8+
use App\RemoteSite\Responses\PrepareUpdate;
9+
510
enum WebserviceEndpoint: string
611
{
7-
case HEALTH_CHECK = "/api/index.php/v1/joomlaupdate/healthcheck";
8-
case FETCH_UPDATES = "/api/index.php/v1/joomlaupdate/fetchUpdate";
9-
case PREPARE_UPDATE = "/api/index.php/v1/joomlaupdate/prepareUpdate";
10-
case FINALIZE_UPDATE = "/api/index.php/v1/joomlaupdate/finalizeUpdate";
12+
case checkHealth = "/api/index.php/v1/joomlaupdate/healthcheck";
13+
case getUpdate = "/api/index.php/v1/joomlaupdate/getUpdate";
14+
case prepareUpdate = "/api/index.php/v1/joomlaupdate/prepareUpdate";
15+
case finalizeUpdate = "/api/index.php/v1/joomlaupdate/finalizeUpdate";
16+
17+
public function getMethod(): HttpMethod
18+
{
19+
switch ($this->name) {
20+
case self::checkHealth->name:
21+
case self::getUpdate->name:
22+
return HttpMethod::GET;
23+
24+
case self::prepareUpdate->name:
25+
case self::finalizeUpdate->name:
26+
return HttpMethod::POST;
27+
}
28+
29+
throw new \ValueError("No method defined");
30+
}
31+
32+
public function getResponseClass(): string
33+
{
34+
switch ($this->name) {
35+
case self::checkHealth->name:
36+
return HealthCheck::class;
37+
case self::getUpdate->name:
38+
return GetUpdate::class;
39+
case self::prepareUpdate->name:
40+
return PrepareUpdate::class;
41+
case self::finalizeUpdate->name:
42+
return FinalizeUpdate::class;
43+
}
44+
45+
throw new \ValueError("No method defined");
46+
}
47+
48+
public function getUrl(): string
49+
{
50+
return $this->value;
51+
}
52+
53+
public static function tryFromName(string $name): ?static
54+
{
55+
$reflection = new \ReflectionEnum(static::class);
56+
57+
if (!$reflection->hasCase($name)) {
58+
return null;
59+
}
60+
61+
/** @var static */
62+
return $reflection->getCase($name)->getValue();
63+
}
1164
}

app/Jobs/UpdateSite.php

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,15 @@
66

77
use App\Models\Site;
88
use App\RemoteSite\Connection;
9+
use App\RemoteSite\Responses\PrepareUpdate;
910
use Illuminate\Contracts\Queue\ShouldQueue;
1011
use Illuminate\Foundation\Queue\Queueable;
12+
use Illuminate\Support\Facades\Log;
1113

1214
class UpdateSite implements ShouldQueue
1315
{
16+
protected int $preUpdateCode;
17+
1418
use Queueable;
1519

1620
/**
@@ -30,5 +34,47 @@ public function handle(): void
3034

3135
// Test connection and get current version
3236
$healthResult = $connection->checkHealth();
37+
38+
// Check the version
39+
if (version_compare($healthResult->cms_version, $this->targetVersion, ">=")) {
40+
Log::info("Site is already up to date: " . $this->site->id);
41+
42+
return;
43+
}
44+
45+
// Store pre-update response code
46+
$this->preUpdateCode = $this->site->getFrontendStatus();
47+
48+
// Let site fetch available updates
49+
$updateResult = $connection->getUpdate();
50+
51+
// Check if update is found and return if not
52+
if (is_null($updateResult->availableUpdate)) {
53+
Log::info("No update available for site: " . $this->site->id);
54+
55+
return;
56+
}
57+
58+
// Check the version and return if it does not match
59+
if ($updateResult->availableUpdate !== $this->targetVersion) {
60+
Log::info("Update version mismatch for site: " . $this->site->id);
61+
62+
return;
63+
}
64+
65+
$prepareResult = $connection->prepareUpdate($this->targetVersion);
66+
67+
// Perform the actual extraction
68+
$this->performExtraction($prepareResult);
69+
70+
// Run the postupdate steps
71+
if (!$connection->finalizeUpdate()->success) {
72+
throw new \Exception("Update for site failed in postprocessing: " . $this->site->id);
73+
}
74+
}
75+
76+
protected function performExtraction(PrepareUpdate $prepareResult)
77+
{
78+
3379
}
3480
}

app/Models/Site.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@
55
namespace App\Models;
66

77
use App\RemoteSite\Connection;
8+
use GuzzleHttp\Client;
89
use Illuminate\Database\Eloquent\Model;
10+
use Illuminate\Support\Facades\App;
911

1012
class Site extends Model
1113
{
@@ -45,4 +47,12 @@ public function getConnectionAttribute(): Connection
4547
{
4648
return new Connection($this->url, $this->key);
4749
}
50+
51+
public function getFrontendStatus(): int
52+
{
53+
/** @var Client $httpClient */
54+
$httpClient = App::make(Client::class);
55+
56+
return $httpClient->get($this->url)->getStatusCode();
57+
}
4858
}

app/RemoteSite/Connection.php

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,35 +6,55 @@
66

77
use App\Enum\HttpMethod;
88
use App\Enum\WebserviceEndpoint;
9+
use App\RemoteSite\Responses\FinalizeUpdate as FinalizeUpdateResponse;
910
use App\RemoteSite\Responses\HealthCheck as HealthCheckResponse;
11+
use App\RemoteSite\Responses\GetUpdate as GetUpdateResponse;
12+
use App\RemoteSite\Responses\PrepareUpdate as PrepareUpdateResponse;
13+
use App\RemoteSite\Responses\ResponseInterface;
1014
use GuzzleHttp\Client;
1115
use GuzzleHttp\Exception\RequestException;
1216
use GuzzleHttp\Psr7\Request;
1317
use GuzzleHttp\Psr7\Response;
1418
use Illuminate\Support\Facades\App;
1519
use Psr\Http\Message\RequestInterface;
1620

21+
/**
22+
* @method HealthCheckResponse checkHealth()
23+
* @method GetUpdateResponse getUpdate()
24+
* @method PrepareUpdateResponse prepareUpdate(string $targetVersion)
25+
* @method FinalizeUpdateResponse finalizeUpdate()
26+
*/
1727
class Connection
1828
{
1929
public function __construct(protected readonly string $baseUrl, protected readonly string $key)
2030
{
2131
}
2232

23-
public function checkHealth(): HealthCheckResponse
33+
public function __call(string $method, array $arguments): ResponseInterface
2434
{
25-
$healthData = $this->performWebserviceRequest(
26-
HttpMethod::GET,
27-
WebserviceEndpoint::HEALTH_CHECK
35+
$endpoint = WebserviceEndpoint::tryFromName($method);
36+
37+
if (is_null($endpoint)) {
38+
throw new \BadMethodCallException();
39+
}
40+
41+
// Call
42+
$data = $this->performWebserviceRequest(
43+
$endpoint->getMethod(),
44+
$endpoint->getUrl(),
45+
...$arguments
2846
);
2947

30-
return HealthCheckResponse::from($healthData['data']['attributes']);
48+
$responseClass = $endpoint->getResponseClass();
49+
50+
return $responseClass::from($data);
3151
}
3252

3353
public function performExtractionRequest(array $requestData): array
3454
{
3555
$request = new Request(
3656
'POST',
37-
$this->baseUrl . 'extract.php'
57+
$this->baseUrl . '/extract.php'
3858
);
3959

4060
$data['password'] = $this->key;
@@ -55,12 +75,12 @@ public function performExtractionRequest(array $requestData): array
5575

5676
protected function performWebserviceRequest(
5777
HttpMethod $method,
58-
WebserviceEndpoint $endpoint,
78+
string $endpoint,
5979
array $requestData = []
6080
): array {
6181
$request = new Request(
6282
$method->name,
63-
$this->baseUrl . $endpoint->value,
83+
$this->baseUrl . $endpoint,
6484
[
6585
'X-JUpdate-Token' => $this->key
6686
]
@@ -85,7 +105,7 @@ protected function performWebserviceRequest(
85105
);
86106
}
87107

88-
return $responseData;
108+
return $responseData['data']['attributes'];
89109
}
90110

91111
protected function performHttpRequest(
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php
2+
3+
namespace App\RemoteSite\Responses;
4+
5+
use App\DTO\BaseDTO;
6+
7+
class FinalizeUpdate extends BaseDTO implements ResponseInterface
8+
{
9+
public function __construct(
10+
public bool $success
11+
) {
12+
}
13+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php
2+
3+
namespace App\RemoteSite\Responses;
4+
5+
use App\DTO\BaseDTO;
6+
7+
class GetUpdate extends BaseDTO implements ResponseInterface
8+
{
9+
public function __construct(
10+
public ?string $availableUpdate
11+
) {
12+
}
13+
}

app/RemoteSite/Responses/HealthCheck.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
use App\DTO\BaseDTO;
66

7-
class HealthCheck extends BaseDTO
7+
class HealthCheck extends BaseDTO implements ResponseInterface
88
{
99
public function __construct(
1010
public string $php_version,
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?php
2+
3+
namespace App\RemoteSite\Responses;
4+
5+
use App\DTO\BaseDTO;
6+
7+
class PrepareUpdate extends BaseDTO implements ResponseInterface
8+
{
9+
public function __construct(
10+
public string $password,
11+
public int $filesize
12+
) {
13+
}
14+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php
2+
3+
namespace App\RemoteSite\Responses;
4+
5+
interface ResponseInterface
6+
{
7+
public static function from(array $data): static;
8+
9+
public function toArray(): array;
10+
}

tests/Unit/ExampleTest.php

Lines changed: 0 additions & 16 deletions
This file was deleted.

0 commit comments

Comments
 (0)