Skip to content

Commit 3f2b9ab

Browse files
committed
Remove illuminate/collections dependency and refactor to native PHP array functions
Add changelog and upgrade guide.
1 parent cc35fa4 commit 3f2b9ab

File tree

30 files changed

+198
-113
lines changed

30 files changed

+198
-113
lines changed

CHANGELOG.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,23 @@
11
# Changelog
22

3+
## 3.0.0-alpha.1 (18.03.2026)
4+
5+
### Breaking Changes
6+
* Minimum PHP version is now 8.2.
7+
* Removed dependency `illuminate/collections` - Replaced all `collect()` usages with native PHP array functions.
8+
* Method `delete()` now returns `?APIResponse` instead of `bool` across all models.
9+
* Changed various method signatures to use native PHP types and improved type hinting.
10+
11+
### Features
12+
* Improved support for Managed Certificates.
13+
* Improved support for Firewall label selectors.
14+
* Improved support for Primary IPs.
15+
* Improved support for Placement Groups.
16+
* Improved support for Load Balancers.
17+
18+
### Internal
19+
* General code cleanup and modernization.
20+
321
## 2.5.0 (12.10.2021)
422

523
* Upgrade to GitHub-native Dependabot by @dependabot-preview in https://github.com/LKDevelopment/hetzner-cloud-php-sdk/pull/73

README.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,11 @@ You can just run `phpunit`. The whole library is based on unit tests and sample
3333

3434
### Changelog
3535

36-
Please see [CHANGELOG](https://github.com/LKDevelopment/hetzner-cloud-php-sdk/releases) for more information what has changed recently.
36+
Please see [CHANGELOG](CHANGELOG.md) for more information what has changed recently.
37+
38+
### Upgrade Guide
39+
40+
Please see [Upgrade to v3.0](UPGRADE-3.0.md) for more information how to upgrade from v2.x.
3741

3842

3943
### Security

UPGRADE-3.0.md

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
# Upgrade Guide: v2.x to v3.0
2+
3+
This guide provides instructions for upgrading your application from `hetzner-cloud-php-sdk` version 2.x to 3.0.
4+
5+
## Breaking Changes
6+
7+
### PHP Version Requirement
8+
- **Requirement:** PHP 8.2 or higher is now required.
9+
- **Action:** Ensure your server or environment is running PHP 8.2+.
10+
11+
### Removal of `illuminate/collections`
12+
The dependency on `illuminate/collections` has been removed to reduce the library's footprint and avoid dependency conflicts. All internal usages of `collect()` have been replaced with native PHP array functions.
13+
14+
- **Impact:** If your application relied on the SDK returning Laravel Collections, this will no longer happen.
15+
- **Action:** Use native PHP array functions like `array_map()`, `array_filter()`, or wrap the returned arrays in a collection yourself if you still need them.
16+
17+
**Before (v2.x):**
18+
```php
19+
// Some internal methods or if you were using collect() on SDK results
20+
$names = collect($hetznerClient->servers()->all())->map(fn($s) => $s->name);
21+
```
22+
23+
**After (v3.0):**
24+
```php
25+
// Results are now always native arrays
26+
$servers = $hetznerClient->servers()->all();
27+
$names = array_map(fn($s) => $s->name, $servers);
28+
29+
// If you want to keep using Collections in your project:
30+
// composer require illuminate/collections
31+
$names = collect($hetznerClient->servers()->all())->map(fn($s) => $s->name);
32+
```
33+
34+
### `delete()` Method Return Type Change
35+
The `delete()` method on all resource models now returns an `APIResponse` object (or `null`) instead of a `boolean`. This provides more information about the API response, such as the `Action` created by the deletion.
36+
37+
- **Impact:** Any code checking for `if ($model->delete())` will still work as `APIResponse` is truthy, but it is better to update your logic if you were relying on the boolean result.
38+
39+
**Before (v2.x):**
40+
```php
41+
$success = $server->delete(); // returned bool
42+
if ($success) {
43+
// ...
44+
}
45+
```
46+
47+
**After (v3.0):**
48+
```php
49+
$response = $server->delete(); // returns ?APIResponse
50+
if ($response !== null) {
51+
$action = $response->action; // You can now access the action
52+
// ...
53+
}
54+
```
55+
56+
### Native Type Hints
57+
Many method signatures have been updated to include native PHP 8.1 type hints. This improves IDE support and static analysis.
58+
59+
- **Impact:** If you have extended SDK classes and overridden methods, you may need to update your method signatures to match the new type hints to avoid PHP fatal errors.
60+
61+
---
62+
63+
## New Features
64+
Version 3.0 also introduces several new features and improvements:
65+
- Support for **Primary IPs**.
66+
- Support for **Placement Groups**.
67+
- Support for **Firewalls** (including label selectors).
68+
- Improved support for **Load Balancers**.
69+
- Improved support for **Managed Certificates**.
70+
71+
## Summary for LLMs
72+
- Minimum PHP: `8.2`
73+
- Dependency removed: `illuminate/collections`
74+
- `delete()` returns: `?LKDev\HetznerCloud\APIResponse` (was `bool`)
75+
- All list methods return: `array`
76+
- Models use native type hints for parameters and return types.

composer.json

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,10 @@
88
"hetzner cloud",
99
"cloud php library"
1010
],
11-
"require": {
12-
"php": "^8.1",
11+
"require": {
12+
"php": "^8.2",
1313
"ext-json": "*",
14-
"guzzlehttp/guzzle": "^6.3|^7.0",
15-
"illuminate/collections": "^5.5|^v6.18|^7.0|^8.0|^9.0|^10.0|^11.0|^12.0|^13.0"
14+
"guzzlehttp/guzzle": "^6.3|^7.0"
1615
},
1716
"require-dev": {
1817
"phpunit/phpunit": "^7.0|^8.5.5|^9.0",

src/HetznerAPIClient.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ class HetznerAPIClient
3232
/**
3333
* Version of the API Client.
3434
*/
35-
const VERSION = '3.0.0-alpha.1';
35+
const VERSION = '3.0.0';
3636

3737
const MAX_ENTITIES_PER_PAGE = 50;
3838

src/Models/Actions/Actions.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,9 @@ public function getByName(string $name)
8080
*/
8181
public function setAdditionalData($input)
8282
{
83-
$this->actions = collect($input)->map(function ($action, $key) {
83+
$this->actions = array_map(function ($action) {
8484
return Action::parse($action);
85-
})->toArray();
85+
}, $input);
8686

8787
return $this;
8888
}

src/Models/Certificates/Certificates.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,9 +122,9 @@ public function list(?RequestOpts $requestOpts = null): ?APIResponse
122122
*/
123123
public function setAdditionalData($input)
124124
{
125-
$this->certificates = collect($input)->map(function ($certificate, $key) {
125+
$this->certificates = array_map(function ($certificate) {
126126
return Certificate::parse($certificate);
127-
})->toArray();
127+
}, $input);
128128

129129
return $this;
130130
}

src/Models/Datacenters/Datacenters.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,9 +120,9 @@ public function getByName(string $name): ?Datacenter
120120
*/
121121
public function setAdditionalData($input)
122122
{
123-
$this->datacenters = collect($input)->map(function ($datacenter, $key) {
123+
$this->datacenters = array_map(function ($datacenter) {
124124
return Datacenter::parse($datacenter);
125-
})->toArray();
125+
}, $input);
126126

127127
return $this;
128128
}

src/Models/Firewalls/Firewall.php

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -147,18 +147,18 @@ public function setRules(array $rules): ?ApiResponse
147147
{
148148
$response = $this->httpClient->post('firewalls/'.$this->id.'/actions/set_rules', [
149149
'json' => [
150-
'rules' => collect($rules)->map(function ($r) {
150+
'rules' => array_map(function ($r) {
151151
return $r->toRequestSchema();
152-
}),
152+
}, $rules),
153153
],
154154
]);
155155
if (! HetznerAPIClient::hasError($response)) {
156156
$payload = json_decode((string) $response->getBody());
157157

158158
return APIResponse::create([
159-
'actions' => collect($payload->actions)->map(function ($action) {
159+
'actions' => array_map(function ($action) {
160160
return Action::parse($action);
161-
})->toArray(),
161+
}, $payload->actions),
162162
], $response->getHeaders());
163163
}
164164

@@ -198,18 +198,18 @@ public function applyToResources(array $resources): ?APIResponse
198198
{
199199
$response = $this->httpClient->post('firewalls/'.$this->id.'/actions/apply_to_resources', [
200200
'json' => [
201-
'apply_to' => collect($resources)->map(function ($r) {
201+
'apply_to' => array_map(function ($r) {
202202
return $r->toRequestSchema();
203-
}),
203+
}, $resources),
204204
],
205205
]);
206206
if (! HetznerAPIClient::hasError($response)) {
207207
$payload = json_decode((string) $response->getBody());
208208

209209
return APIResponse::create([
210-
'actions' => collect($payload->actions)->map(function ($action) {
210+
'actions' => array_map(function ($action) {
211211
return Action::parse($action);
212-
})->toArray(),
212+
}, $payload->actions),
213213
], $response->getHeaders());
214214
}
215215

@@ -230,18 +230,18 @@ public function removeFromResources(array $resources): ?APIResponse
230230
{
231231
$response = $this->httpClient->post('firewalls/'.$this->id.'/actions/remove_from_resources', [
232232
'json' => [
233-
'remove_from' => collect($resources)->map(function ($r) {
233+
'remove_from' => array_map(function ($r) {
234234
return $r->toRequestSchema();
235-
}),
235+
}, $resources),
236236
],
237237
]);
238238
if (! HetznerAPIClient::hasError($response)) {
239239
$payload = json_decode((string) $response->getBody());
240240

241241
return APIResponse::create([
242-
'actions' => collect($payload->actions)->map(function ($action) {
242+
'actions' => array_map(function ($action) {
243243
return Action::parse($action);
244-
})->toArray(),
244+
}, $payload->actions),
245245
], $response->getHeaders());
246246
}
247247

src/Models/Firewalls/Firewalls.php

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -134,9 +134,9 @@ public static function parse($input)
134134
*/
135135
public function setAdditionalData($input)
136136
{
137-
$this->firewalls = collect($input)->map(function ($firewall, $key) {
137+
$this->firewalls = array_map(function ($firewall) {
138138
return Firewall::parse($firewall);
139-
})->toArray();
139+
}, $input);
140140

141141
return $this;
142142
}
@@ -163,15 +163,15 @@ public function create(
163163
'name' => $name,
164164
];
165165
if (! empty($rules)) {
166-
$parameters['rules'] = collect($rules)->map(function ($r) {
166+
$parameters['rules'] = array_map(function ($r) {
167167
return $r->toRequestSchema();
168-
});
168+
}, $rules);
169169
}
170170

171171
if (! empty($applyTo)) {
172-
$parameters['apply_to'] = collect($applyTo)->map(function ($r) {
172+
$parameters['apply_to'] = array_map(function ($r) {
173173
return $r->toRequestSchema();
174-
});
174+
}, $applyTo);
175175
}
176176
if (! empty($labels)) {
177177
$parameters['labels'] = $labels;
@@ -184,9 +184,9 @@ public function create(
184184

185185
return APIResponse::create([
186186
'firewall' => Firewall::parse($payload->{$this->_getKeys()['one']}),
187-
'actions' => collect($payload->actions)->map(function ($action) {
187+
'actions' => array_map(function ($action) {
188188
return Action::parse($action);
189-
})->toArray(),
189+
}, $payload->actions),
190190
], $response->getHeaders());
191191
}
192192

0 commit comments

Comments
 (0)