Skip to content

Commit d0ff7d1

Browse files
committed
Added migration guide
1 parent 9626e8f commit d0ff7d1

5 files changed

Lines changed: 273 additions & 48 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@ cache
44
vendor
55
.php-cs-fixer.cache
66
.phpunit.result.cache
7+
test.php

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ All notable changes to this project will be documented in this file.
44
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
55
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
66

7-
## [4.0.0] - 2025-12
7+
## [4.0.0] - 2026-06-28
88
### Added
99
- Full HTTP observability tools: structured logging with token masking, per-status log levels, and custom logger support.
1010
- Reliability features: retry strategies (exponential and fixed), circuit breaker, and a combined reliability plugin.

UPGRADE-4.0.md

Lines changed: 270 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,270 @@
1+
# Upgrading from 3.x to 4.0.0
2+
3+
## Requirements
4+
5+
- PHP **8.2** or higher (raised from 8.1)
6+
- `surfoo/oauth2-geocaching` **^3.0** (new required package — see Authentication section)
7+
8+
Update your dependencies:
9+
10+
```bash
11+
composer require surfoo/geocaching-php-sdk:^4.0 surfoo/oauth2-geocaching:^3.0
12+
```
13+
14+
---
15+
16+
## Breaking Changes
17+
18+
### PHP 8.1 dropped
19+
20+
PHP 8.1 is no longer supported. Update your runtime to PHP 8.2+.
21+
22+
### `GeocachingSdkInterface` removed
23+
24+
The `GeocachingSdkInterface` interface has been removed. `GeocachingSdk` is no longer `final` either. If you were type-hinting against the interface, switch to the concrete class or your own interface.
25+
26+
**Before:**
27+
```php
28+
use Geocaching\GeocachingSdkInterface;
29+
30+
function doSomething(GeocachingSdkInterface $sdk): void { ... }
31+
```
32+
33+
**After:**
34+
```php
35+
use Geocaching\GeocachingSdk;
36+
37+
function doSomething(GeocachingSdk $sdk): void { ... }
38+
```
39+
40+
### `ClientBuilder::getHttpClient()` return type changed
41+
42+
The return type of `ClientBuilder::getHttpClient()` changed from `ClientInterface` (PSR-18) to `HttpMethodsClientInterface` (HTTPlug), which is a superset. This is only a breaking change if you stored the result in a typed variable or type-hinted against `ClientInterface`.
43+
44+
**Before:**
45+
```php
46+
use Psr\Http\Client\ClientInterface;
47+
48+
$client = $options->getClientBuilder()->getHttpClient(); // ClientInterface
49+
```
50+
51+
**After:**
52+
```php
53+
use Http\Client\Common\HttpMethodsClientInterface;
54+
55+
$client = $options->getClientBuilder()->getHttpClient(); // HttpMethodsClientInterface
56+
```
57+
58+
### `Options` and `ClientBuilder` are no longer `final`
59+
60+
Both classes were `final` in 3.x. In 4.0 this restriction is removed, so extension is now possible.
61+
62+
### `setGeocacheUserWaypoint()` signature changed
63+
64+
The `$referenceCode` first parameter has been removed.
65+
66+
**Before:**
67+
```php
68+
$sdk->setGeocacheUserWaypoint($referenceCode, $body, $headers);
69+
```
70+
71+
**After:**
72+
```php
73+
$sdk->setGeocacheUserWaypoint($body, $headers);
74+
```
75+
76+
### `updateUserWaypoint()` parameter renamed
77+
78+
The third parameter was `array $query` (misleading); it is now `array $waypoint` to reflect its actual purpose. The call signature is unchanged but semantics are clearer.
79+
80+
### `updateGeocacheNote()` parameter renamed
81+
82+
The parameter `array $note` is now `array $notes` (plural). No functional change.
83+
84+
### `getHQPromotions()` now accepts a `$query` parameter
85+
86+
**Before:**
87+
```php
88+
$sdk->getHQPromotions($headers);
89+
```
90+
91+
**After:**
92+
```php
93+
$sdk->getHQPromotions($query, $headers);
94+
// or keep passing only headers (first arg defaults to [])
95+
$sdk->getHQPromotions([], $headers);
96+
```
97+
98+
### `getGeocachesGeotour()` renamed to `getGeotourGeocaches()`
99+
100+
**Before:**
101+
```php
102+
$sdk->getGeocachesGeotour($referenceCode, $query, $headers);
103+
```
104+
105+
**After:**
106+
```php
107+
$sdk->getGeotourGeocaches($referenceCode, $query, $headers);
108+
```
109+
110+
### `getStartLocationAdventure()` removed
111+
112+
This endpoint was removed from the Geocaching API and is no longer available.
113+
114+
---
115+
116+
## New Features
117+
118+
The sections below describe what 4.0 adds. Nothing else you already use has been removed.
119+
120+
### Automatic token refresh
121+
122+
Pass a `TokenStorageInterface` and a `reference_code` (the user's Geocaching reference code, e.g. `'PR12345'`) to `Options` to enable automatic access-token refresh on `401` responses. The SDK will refresh, store the new token, and retry the request transparently.
123+
124+
```php
125+
use Geocaching\Options;
126+
use Geocaching\Enum\Environment;
127+
use League\OAuth2\Client\Provider\Geocaching as OAuthProvider;
128+
129+
$provider = new OAuthProvider([
130+
'clientId' => 'your-client-id',
131+
'clientSecret' => 'your-client-secret',
132+
'redirectUri' => 'https://example.com/callback',
133+
'environment' => 'production',
134+
]);
135+
136+
$options = new Options([
137+
'environment' => Environment::PRODUCTION,
138+
'access_token' => $storedAccessToken,
139+
'token_storage' => new MyTokenStorage(), // implements TokenStorageInterface
140+
'reference_code' => 'PR12345',
141+
]);
142+
```
143+
144+
`TokenStorageInterface` and `TokenSet` come from `surfoo/oauth2-geocaching ^3.0`. See that package's `UPGRADE-3.0.md` for implementation details.
145+
146+
When `token_storage` and `reference_code` are omitted, the SDK behaves exactly as in 3.x with a static bearer token.
147+
148+
### HTTP request/response logging
149+
150+
```php
151+
use Psr\Log\LogLevel;
152+
153+
$options->enableHttpLogging(
154+
'php://stdout', // destination: file path, php://stdout, php://stderr
155+
LogLevel::INFO, // minimum log level
156+
false, // log request/response bodies
157+
true, // mask bearer tokens in logs
158+
1000 // max body length before truncation
159+
);
160+
```
161+
162+
Each request gets a unique correlation ID so requests and responses can be matched. Sensitive tokens are masked automatically. HTTP 4xx/5xx responses are logged at `WARNING`/`ERROR` level regardless of the configured level.
163+
164+
### Reliability plugins
165+
166+
#### Retry
167+
168+
```php
169+
use Geocaching\Reliability\ExponentialBackoffStrategy;
170+
use Geocaching\Reliability\FixedDelayStrategy;
171+
172+
// Exponential back-off: 100ms, 200ms, 400ms, …
173+
$options->enableRetry(
174+
maxRetries: 3,
175+
strategy: new ExponentialBackoffStrategy(initialDelayMs: 100)
176+
);
177+
178+
// Fixed delay
179+
$options->enableRetry(
180+
maxRetries: 3,
181+
strategy: new FixedDelayStrategy(delayMs: 500)
182+
);
183+
```
184+
185+
#### Circuit breaker
186+
187+
```php
188+
$options->enableCircuitBreaker(
189+
failureThreshold: 5, // open after this many consecutive failures
190+
resetTimeout: 60 // seconds before attempting to close again
191+
);
192+
```
193+
194+
#### Combined reliability plugin
195+
196+
`ReliabilityPlugin` bundles retry and circuit breaker together:
197+
198+
```php
199+
$options->enableReliability(
200+
maxRetries: 3,
201+
strategy: new ExponentialBackoffStrategy(100),
202+
failureThreshold: 5,
203+
resetTimeout: 60
204+
);
205+
```
206+
207+
### New enum: `Attribute`
208+
209+
`Geocaching\Enum\Attribute` covers all 65 geocache attributes (dogs, wheelchair accessible, night cache, etc.) with `id()` returning the Groundspeak attribute ID.
210+
211+
```php
212+
use Geocaching\Enum\Attribute;
213+
214+
$attr = Attribute::WHEELCHAIR_ACCESSIBLE;
215+
$attr->value; // 'Wheelchair accessible'
216+
$attr->id(); // 24
217+
```
218+
219+
### `EnumTrait` on all enums
220+
221+
All enums now use `EnumTrait`, which adds three helpers:
222+
223+
```php
224+
// Look up an enum by its integer ID
225+
$type = GeocacheType::fromId(2); // GeocacheType::TRADITIONAL
226+
227+
// Get all human-readable values
228+
GeocacheType::getList(); // ['Traditional Cache', 'Multi-cache', ...]
229+
230+
// Get all IDs
231+
GeocacheType::getListId(); // [2, 3, ...]
232+
```
233+
234+
### New method: `getDifficultyTerrainStatistics()`
235+
236+
Returns aggregated D/T statistics from the Geocaching API:
237+
238+
```php
239+
$response = $sdk->getDifficultyTerrainStatistics();
240+
```
241+
242+
### New method: `deleteImageFromLogdraft()`
243+
244+
```php
245+
$sdk->deleteImageFromLogdraft($referenceCode, $guid, $headers);
246+
```
247+
248+
### `ClientBuilderInterface`
249+
250+
A new `ClientBuilderInterface` is available if you need to swap or mock the client builder in your own code:
251+
252+
```php
253+
use Geocaching\ClientBuilderInterface;
254+
```
255+
256+
---
257+
258+
## New exception: `CircuitBreakerOpenException`
259+
260+
Thrown by `CircuitBreakerPlugin` when the circuit is open and the request is rejected immediately. Catch it to short-circuit your own retry logic:
261+
262+
```php
263+
use Geocaching\Exception\CircuitBreakerOpenException;
264+
265+
try {
266+
$response = $sdk->getGeocache('GC12345');
267+
} catch (CircuitBreakerOpenException $e) {
268+
// API is unavailable; serve from cache or return a degraded response
269+
}
270+
```

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
"psr/http-client": "^1.0",
3131
"psr/http-client-implementation": "*",
3232
"psr/http-factory": "^1.0",
33-
"surfoo/oauth2-geocaching": "dev-feat-v3"
33+
"surfoo/oauth2-geocaching": "^3.0"
3434
},
3535
"require-dev": {
3636
"friendsofphp/php-cs-fixer": "^3.0",

test.php

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

0 commit comments

Comments
 (0)