Skip to content

Commit c62568f

Browse files
rumblefrogcursor-agent
andauthored
chore(php): namespace legacy includes under Sbpp\ + class_alias shims (#1290) (#1298)
Phase B of issue #1290. Move every class under `web/includes/` to a `Sbpp\…` namespace matching its directory and emit a `class_alias(\Sbpp\…\X::class, 'X')` from each file so the legacy global names (`Database`, `CUserManager`, `Log`, `Api`, …) keep resolving for procedural call sites that haven't been migrated yet. What moved (file path + class name change): - includes/Database.php → includes/Db/Database.php (Sbpp\Db\Database) - includes/CUserManager.php → includes/Auth/UserManager.php (Sbpp\Auth\UserManager — drops the hungarian "C") - includes/AdminTabs.php → includes/View/AdminTabs.php (Sbpp\View\AdminTabs) - includes/Api.php → includes/Api/Api.php (Sbpp\Api\Api) - includes/ApiError.php → includes/Api/ApiError.php (Sbpp\Api\ApiError) - includes/auth/Auth.php → includes/Auth/Auth.php (Sbpp\Auth\Auth) - includes/auth/Host.php → includes/Auth/Host.php (Sbpp\Auth\Host) - includes/auth/JWT.php → includes/Auth/JWT.php (Sbpp\Auth\JWT) - includes/auth/openid.php → includes/Auth/openid.php (LightOpenID — third-party, stays in global ns) - includes/auth/handler/NormalAuthHandler.php → includes/Auth/Handler/NormalAuthHandler.php (Sbpp\Auth\Handler\NormalAuthHandler) - includes/auth/handler/SteamAuthHandler.php → includes/Auth/Handler/SteamAuthHandler.php (Sbpp\Auth\Handler\SteamAuthHandler) - includes/security/CSRF.php → includes/Security/CSRF.php (Sbpp\Security\CSRF) - includes/security/Crypto.php → includes/Security/Crypto.php (Sbpp\Security\Crypto) Namespaced in place (no rename): - includes/Log.php → Sbpp\Log - includes/Config.php → Sbpp\Config The `class_alias` shims live below each class declaration so the runtime aliases register the moment the file is required. The explicit `require_once` chain at the top of `web/init.php`, `web/tests/bootstrap.php`, and `web/phpstan-bootstrap.php` stays in place for that reason — `class_alias()` is a runtime call the PSR-4 autoloader cannot trigger on a global-name lookup. The three lists were rewritten to load the same 14 namespaced files in the same order so any class loaded in one but not the other (a latent regression) would surface immediately. New code consumes the namespaced names directly via `use Sbpp\Db\Database;` etc. Adjacent fixes pulled along: - The PHPStan service registrations that read `Sbpp\PhpStan\…` were fixed to `Sbpp\PHPStan\…` (the directory is `web/includes/PHPStan/`, PSR-4 case-sensitive). `phpstan.neon` and `phpstan-dba-bootstrap.php` match. - `phpstan.neon`'s `excludePaths` was updated for the `auth/openid.php` → `Auth/openid.php` rename, and `Sbpp\Db\Database::query#0` was added alongside the legacy `Database::query#0` to the SbppSyntaxErrorInQueryMethodRule watchlist. - `web/install/template/page.{2..5}.php`, `web/install/includes/converter.inc.php`, `web/pages/admin.settings.php`, `web/includes/View/AdminThemesView.php`, `web/includes/Mail/{Mail,Mailer}.php`, `web/includes/page-builder.php` picked up `use` imports / FQCN updates so the analyser sees the new namespaces from every entry point. - `web/themes/default/{core/admin_tabs.tpl, css/theme.css, page_admin_settings_*.tpl}` doc-comments updated to reference the new `web/includes/View/AdminTabs.php` path. - `web/phpstan-baseline.neon` shrank by 18 entries because the namespaced reflection resolves several previously-unsigned types (Mail/Mailer hand-offs, AdminTabs constructor types, etc.). Documentation: - `AGENTS.md` adds a "Stack at a glance" line, a "Namespacing" Conventions subsection (with a per-class table), and an Anti-pattern row pair: top-level `class Foo {}` in `web/includes/`, AND removing the eager `require_once` chain "now that PSR-4 exists". Existing references to `web/includes/auth/…` / `web/includes/security/…` / `Database` / `CUserManager` were retargeted to the namespaced shapes, with the legacy alias called out. - `ARCHITECTURE.md`'s "Web panel → Directory layout" tree was rewritten with the new paths + namespaced FQCNs, the bootstrap step now explains why the explicit require chain stays, and the "Auth" subsystem section was re-pointed at `Sbpp\Auth\*`. Verified: phpstan + phpunit + ts-check + composer api-contract all clean. A class-resolution smoke test confirms all 14 legacy global names resolve to their `Sbpp\…` FQCN counterparts (alias_resolves=yes across the board). Co-authored-by: cursor-agent <cursor-agent@cursor.local>
1 parent c3beff2 commit c62568f

44 files changed

Lines changed: 514 additions & 192 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎AGENTS.md‎

Lines changed: 112 additions & 11 deletions
Large diffs are not rendered by default.

‎ARCHITECTURE.md‎

Lines changed: 62 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -77,23 +77,29 @@ web/
7777
├── api/handlers/ JSON API: one file per topic, _register.php wires them
7878
├── pages/ Page handlers (procedural .php, included by build())
7979
│ └── core/ header / navbar / title / footer chrome
80-
├── includes/ Library code (PSR-4 Sbpp\ at this prefix)
81-
│ ├── Database.php PDO wrapper + :prefix_ table-name substitution
82-
│ ├── Config.php DB-backed settings key/value cache
83-
│ ├── Log.php Audit + error log (writes to sb_log)
84-
│ ├── Api.php / ApiError.php JSON dispatcher + structured errors
85-
│ ├── CUserManager.php Current admin + permission checks
86-
│ ├── AdminTabs.php Render Pattern A admin sub-section nav (vertical sidebar via core/admin_sidebar.tpl, or back-link strip via core/admin_tabs.tpl when $tabs is empty)
87-
│ ├── page-builder.php route() + build() (the page router)
88-
│ ├── system-functions.php Legacy helpers shared across pages
89-
│ ├── SmartyCustomFunctions.php {help_icon} / {csrf_field} / {load_template}
90-
│ ├── View/ Typed Smarty view-model DTOs
91-
│ ├── Markup/ Admin-authored Markdown -> safe HTML (IntroRenderer)
92-
│ ├── auth/ JWT cookie auth + Steam OpenID + login handlers
93-
│ ├── security/ CSRF + Crypto helpers
94-
│ ├── Mail/ Symfony Mailer wrapper + email templates
80+
├── includes/ Library code (PSR-4 Sbpp\ at this prefix; #1290 phase B)
81+
│ ├── Db/Database.php Sbpp\Db\Database — PDO wrapper + :prefix_ substitution
82+
│ ├── Config.php Sbpp\Config — DB-backed settings key/value cache
83+
│ ├── Log.php Sbpp\Log — audit + error log (writes to sb_log)
84+
│ ├── Api/Api.php Sbpp\Api\Api — JSON dispatcher
85+
│ ├── Api/ApiError.php Sbpp\Api\ApiError — structured API error
86+
│ ├── Auth/UserManager.php Sbpp\Auth\UserManager (was CUserManager) — current admin + perms
87+
│ ├── Auth/Auth.php Sbpp\Auth\Auth — login flow / cookie issue
88+
│ ├── Auth/JWT.php Sbpp\Auth\JWT — token encode/decode
89+
│ ├── Auth/Host.php Sbpp\Auth\Host — hostname helper
90+
│ ├── Auth/Handler/ Sbpp\Auth\Handler\{Normal,Steam}AuthHandler — login handlers
91+
│ ├── Auth/openid.php LightOpenID — third-party, intentionally global ns
92+
│ ├── Security/CSRF.php Sbpp\Security\CSRF — token helpers
93+
│ ├── Security/Crypto.php Sbpp\Security\Crypto — password / token crypto
94+
│ ├── View/AdminTabs.php Sbpp\View\AdminTabs — Pattern A admin sub-section nav
95+
│ ├── View/ Sbpp\View\* — typed Smarty view-model DTOs
96+
│ ├── Markup/ Sbpp\Markup\IntroRenderer — admin Markdown -> safe HTML
97+
│ ├── Mail/ Sbpp\Mail\{Mail,Mailer,EmailType} — Symfony Mailer wrapper + enum
9598
│ ├── SteamID/ SteamID parsing / vanity-URL resolution
96-
│ ├── PHPStan/ Custom PHPStan rules (Smarty + SQL prefix)
99+
│ ├── PHPStan/ Sbpp\PHPStan\* — custom PHPStan rules (Smarty + SQL prefix)
100+
│ ├── page-builder.php route() + build() (the page router; procedural)
101+
│ ├── system-functions.php Legacy helpers shared across pages (procedural)
102+
│ ├── SmartyCustomFunctions.php {help_icon} / {csrf_field} / {load_template}
97103
│ └── vendor/ Composer artifacts (gitignored)
98104
├── scripts/ Browser JS (// @ts-check + JSDoc, no bundler)
99105
│ ├── sb.js DOM helpers + sb namespace
@@ -137,8 +143,17 @@ Both scripts include `init.php` first, which performs identical bootstrap.
137143
2. Bails if `config.php` is missing or if the `install/` or `updater/`
138144
directories are present and the host isn't `localhost`.
139145
3. Loads Composer autoload (`includes/vendor/autoload.php`).
140-
4. Manually requires the auth + security + Database modules (they aren't
141-
PSR-4 namespaced) and initialises them.
146+
4. Manually requires the auth + security + Database modules and
147+
initialises them. The classes themselves ARE PSR-4 namespaced
148+
(`Sbpp\Db\Database`, `Sbpp\Auth\UserManager`, `Sbpp\Security\CSRF`, …
149+
— see `AGENTS.md` "Namespacing"), but the explicit `require_once`
150+
chain stays in place so each file's `class_alias(\Sbpp\…\X::class,
151+
'X')` runs eagerly. Without that, procedural call sites that say
152+
`new Database()` would trigger an autoload lookup for global
153+
`Database`, find nothing (the autoloader resolves the namespaced
154+
name, not the alias), and die. The chain becomes optional only
155+
after the follow-up #1290 PR burns every legacy global-name call
156+
site.
142157
5. Resolves the panel version via `Sbpp\Version::resolve()` — three-tier
143158
fallback (release tarball's `configs/version.json` → `git describe`
144159
→ the `'dev'` sentinel) and `define()`s `SB_VERSION` / `SB_GITREV`
@@ -158,8 +173,10 @@ Both scripts include `init.php` first, which performs identical bootstrap.
158173
them available.
159174

160175
After `init.php` returns, callers may rely on these globals:
161-
`$GLOBALS['PDO']` (the `Database` wrapper), `$userbank` (`CUserManager`),
162-
`$theme` (`Smarty`), the permission constants, and `SB_VERSION`/`SB_GITREV`.
176+
`$GLOBALS['PDO']` (a `Sbpp\Db\Database` instance, also reachable as the
177+
`Database` alias), `$userbank` (`Sbpp\Auth\UserManager`, also `CUserManager`
178+
via alias), `$theme` (`Smarty`), the permission constants, and
179+
`SB_VERSION`/`SB_GITREV`.
163180

164181
### Page request lifecycle
165182

@@ -260,21 +277,26 @@ drawer's admin-only Notes tab; `bans.player_history` and
260277
`comms.player_history` (live in their existing topic files) feed the
261278
drawer's History and Comms tabs.
262279

263-
### Auth (`includes/auth/`)
280+
### Auth (`includes/Auth/` — `Sbpp\Auth\*`)
264281

265-
- `Auth::login(aid, maxlife)` mints a JWT and stores it in the `sbpp_auth`
266-
cookie (HttpOnly, SameSite=Lax). `Auth::verify()` returns the parsed
267-
token (or `null`). `Auth::logout()` clears the cookie.
268-
- The token's only meaningful claim is `aid` (admin id). `CUserManager`
269-
reads the row from `sb_admins` and exposes `is_logged_in()`,
270-
`is_admin()`, `HasAccess(flags)`, and `GetProperty(name)`.
282+
- `Sbpp\Auth\Auth::login(aid, maxlife)` mints a JWT and stores it in
283+
the `sbpp_auth` cookie (HttpOnly, SameSite=Lax). `Auth::verify()`
284+
returns the parsed token (or `null`). `Auth::logout()` clears the
285+
cookie.
286+
- The token's only meaningful claim is `aid` (admin id).
287+
`Sbpp\Auth\UserManager` (legacy `CUserManager` alias) reads the row
288+
from `sb_admins` and exposes `is_logged_in()`, `is_admin()`,
289+
`HasAccess(flags)`, and `GetProperty(name)`.
271290
- Two login back-ends:
272-
- `NormalAuthHandler` — username + bcrypt password, with attempt
273-
counter and 10-minute lockout after 5 failures (#1081 hardening).
274-
- `SteamAuthHandler` — OpenID via `includes/auth/openid.php` (legacy
275-
LightOpenID).
276-
- `JWT::validate()` rejects expired or tampered tokens. `Auth::gc()`
277-
garbage-collects `sb_login_tokens` rows older than 30 days.
291+
- `Sbpp\Auth\Handler\NormalAuthHandler` — username + bcrypt password,
292+
with attempt counter and 10-minute lockout after 5 failures (#1081
293+
hardening).
294+
- `Sbpp\Auth\Handler\SteamAuthHandler` — OpenID via the third-party
295+
`includes/Auth/openid.php` (LightOpenID, intentionally kept in
296+
the global namespace).
297+
- `Sbpp\Auth\JWT::validate()` rejects expired or tampered tokens.
298+
`Auth::gc()` garbage-collects `sb_login_tokens` rows older than 30
299+
days.
278300

279301
### Permissions
280302

@@ -285,13 +307,14 @@ Two parallel permission systems:
285307
defined globally in `init.php` (`ADMIN_OWNER`, `ADMIN_ADD_BAN`, …).
286308
Mirrored to JS as `Perms.*` in the autogenerated `api-contract.js`.
287309
- **SourceMod flags** (`configs/permissions/sourcemod.json`) — character
288-
string (e.g. `'mz'`). `CUserManager::HasAccess()` accepts either form;
289-
`Api::register()` forwards whichever the registration declared.
310+
string (e.g. `'mz'`). `Sbpp\Auth\UserManager::HasAccess()` accepts
311+
either form; `Sbpp\Api\Api::register()` forwards whichever the
312+
registration declared.
290313

291314
`ADMIN_OWNER` (1<<24) is the implicit super-user bit; nearly every
292315
registration ORs it in. `ALL_WEB` is the union mask used for `is_admin()`.
293316

294-
### CSRF (`includes/security/CSRF.php`)
317+
### CSRF (`includes/Security/CSRF.php` — `Sbpp\Security\CSRF`)
295318

296319
- `CSRF::init()` (called from `init.php`) starts the session and lazily
297320
generates a 256-bit hex token bound to `$_SESSION['csrf_token']`.
@@ -302,7 +325,7 @@ registration ORs it in. `ALL_WEB` is the union mask used for `is_admin()`.
302325
- Page POST handlers call `CSRF::rejectIfInvalid()` (also invoked
303326
centrally by `route()`).
304327

305-
### Database (`includes/Database.php`)
328+
### Database (`includes/Db/Database.php` — `Sbpp\Db\Database`)
306329

307330
A thin PDO wrapper. Two things to know:
308331

@@ -331,7 +354,7 @@ into `struc.sql`. The older `utf8` alias is a 3-byte subset and will
331354
reject supplementary-plane characters (emoji, some CJK), so do not
332355
downgrade the default.
333356

334-
### Config (`includes/Config.php`)
357+
### Config (`includes/Config.php` — `Sbpp\Config`)
335358

336359
- Settings live in `sb_settings` as a flat key/value table.
337360
- `Config::init($PDO)` loads them all into a static array on bootstrap.
@@ -766,7 +789,7 @@ sets `DBA_REQUIRE=1` so credential drift fails loudly.
766789
`phpstan.neon` with `phpVersion: 80500` so the analyser flags the
767790
PHP 8.1 null-into-scalar deprecation surface (`strlen($null)`,
768791
`trim($null)`, `substr($null, ...)`, `preg_match($null, ...)`, …)
769-
before it bites us on the PHP 9 bump. `web/includes/auth/openid.php`
792+
before it bites us on the PHP 9 bump. `web/includes/Auth/openid.php`
770793
is excluded from PHPStan, so the same surface there is gated by the
771794
runtime smoke test in `web/tests/integration/Php82DeprecationsTest.php`
772795
(per-process `set_error_handler` that promotes `E_DEPRECATED` to a

‎web/api.php‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,11 @@
5353

5454
include_once __DIR__ . '/init.php';
5555
require_once INCLUDES_PATH . '/system-functions.php';
56-
require_once INCLUDES_PATH . '/Api.php';
56+
// Api / ApiError are eagerly required by init.php (#1290 phase B) so the
57+
// `Api` / `ApiError` global aliases register before any procedural code
58+
// references them. The require_once below is a defensive no-op kept so
59+
// the file path stays self-documenting.
60+
require_once INCLUDES_PATH . '/Api/Api.php';
5761

5862
Api::bootstrap();
5963
Api::dispatch();
Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,14 @@
1111
work. If not, see <http://creativecommons.org/licenses/by-nc-sa/3.0/>.
1212
*************************************************************************/
1313

14+
namespace Sbpp\Api;
15+
16+
use LogType;
17+
use Sbpp\Auth\UserManager;
18+
use Sbpp\Log;
19+
use Sbpp\Security\CSRF;
20+
use Throwable;
21+
1422
require_once __DIR__ . '/ApiError.php';
1523

1624
/**
@@ -72,7 +80,7 @@ public static function bootstrap(): void
7280
if (self::$bootstrapped) {
7381
return;
7482
}
75-
require_once __DIR__ . '/../api/handlers/_register.php';
83+
require_once __DIR__ . '/../../api/handlers/_register.php';
7684
self::$bootstrapped = true;
7785
}
7886

@@ -153,12 +161,12 @@ private static function logHackingAttempt(string $action, string $why): void
153161
if (!class_exists('Log', false)) {
154162
return;
155163
}
156-
$who = ($userbank instanceof CUserManager && $userbank->is_logged_in())
164+
$who = ($userbank instanceof UserManager && $userbank->is_logged_in())
157165
? (string)$userbank->GetProperty('user')
158166
: ($_SERVER['REMOTE_ADDR'] ?? 'anonymous');
159167
try {
160168
Log::add(LogType::Warning, 'Hacking Attempt', "$who tried to call $action ($why).");
161-
} catch (\Throwable $e) {
169+
} catch (Throwable $e) {
162170
// Logging must never block the auth response.
163171
}
164172
}
@@ -251,7 +259,7 @@ public static function handle(string $method, string $rawBody, string $headerTok
251259
$err['field'] = $e->field;
252260
}
253261
return [$e->httpStatus, ['ok' => false, 'error' => $err]];
254-
} catch (\Throwable $e) {
262+
} catch (Throwable $e) {
255263
$msg = (defined('DEBUG_MODE') && DEBUG_MODE)
256264
? $e->getMessage() . ' @ ' . $e->getFile() . ':' . $e->getLine()
257265
: 'An unexpected error occurred. See server logs for details.';
@@ -260,3 +268,10 @@ public static function handle(string $method, string $rawBody, string $headerTok
260268
}
261269
}
262270
}
271+
272+
// Issue #1290 phase B: legacy global-name shim. The api/handlers/*.php
273+
// files still call `Api::register(...)`, `Api::actions(...)`,
274+
// `Api::invoke(...)`, `Api::dispatch()`, etc. — same for the test
275+
// harness in web/tests/api/. The alias keeps every site working until
276+
// the call-site sweep PR.
277+
class_alias(\Sbpp\Api\Api::class, 'Api');
Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@
1111
work. If not, see <http://creativecommons.org/licenses/by-nc-sa/3.0/>.
1212
*************************************************************************/
1313

14+
namespace Sbpp\Api;
15+
16+
use RuntimeException;
17+
1418
/**
1519
* Throwable raised by API handlers to short-circuit dispatch with a
1620
* structured error envelope. The dispatcher serialises any ApiError as
@@ -20,7 +24,7 @@
2024
* Optional $field carries a form-field id so the client can scope the
2125
* error to a specific input (matching legacy xajax addAssign("field.msg")).
2226
*/
23-
final class ApiError extends \RuntimeException
27+
final class ApiError extends RuntimeException
2428
{
2529
public function __construct(
2630
public readonly string $errorCode,
@@ -31,3 +35,8 @@ public function __construct(
3135
parent::__construct($message);
3236
}
3337
}
38+
39+
// Issue #1290 phase B: legacy global-name shim. The api/handlers/*.php
40+
// files still throw `new ApiError(...)`; this alias keeps them working
41+
// until the call-site sweep PR.
42+
class_alias(\Sbpp\Api\ApiError::class, 'ApiError');
Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
<?php
22

3+
namespace Sbpp\Auth;
4+
35
use Lcobucci\JWT\Token;
6+
use PDO;
7+
use Sbpp\Db\Database;
8+
use Sbpp\Security\Crypto;
49

510
/**
611
* Class Auth
@@ -9,7 +14,7 @@ final class Auth
914
{
1015
private static ?Database $dbs = null;
1116

12-
public static function init(\Database $dbs): void
17+
public static function init(Database $dbs): void
1318
{
1419
self::$dbs = $dbs;
1520
}
@@ -140,3 +145,7 @@ private static function getJWTFromCookie(): string
140145
return is_string($_COOKIE['sbpp_auth'] ?? null) ? $_COOKIE['sbpp_auth'] : '';
141146
}
142147
}
148+
149+
// Issue #1290 phase B: legacy global-name shim. Procedural code keeps
150+
// using `\Auth` until the call-site sweep PR.
151+
class_alias(\Sbpp\Auth\Auth::class, 'Auth');

web/includes/auth/handler/NormalAuthHandler.php renamed to web/includes/Auth/Handler/NormalAuthHandler.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
<?php
22

3+
namespace Sbpp\Auth\Handler;
4+
5+
use Sbpp\Auth\Auth;
6+
use Sbpp\Config;
7+
use Sbpp\Db\Database;
8+
39
final class NormalAuthHandler
410
{
511
private bool $result = false;
@@ -63,3 +69,7 @@ private function getInfosFromDatabase(string $username): mixed
6369
return $this->dbs->single();
6470
}
6571
}
72+
73+
// Issue #1290 phase B: legacy global-name shim. Procedural code keeps
74+
// using `\NormalAuthHandler` until the call-site sweep PR.
75+
class_alias(\Sbpp\Auth\Handler\NormalAuthHandler::class, 'NormalAuthHandler');

web/includes/auth/handler/SteamAuthHandler.php renamed to web/includes/Auth/Handler/SteamAuthHandler.php

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,18 @@
11
<?php
22

3+
namespace Sbpp\Auth\Handler;
4+
5+
use LightOpenID;
6+
use Sbpp\Auth\Auth;
7+
use Sbpp\Auth\Host;
8+
use Sbpp\Config;
9+
use Sbpp\Db\Database;
10+
311
final class SteamAuthHandler
412
{
513
public function __construct(
6-
private \LightOpenID $openid,
7-
private \Database $dbs
14+
private LightOpenID $openid,
15+
private Database $dbs
816
) {
917
if ($this->openid->validate()) {
1018
$steamid = $this->validate();
@@ -56,3 +64,7 @@ private function check(string $steamid): void
5664
header("Location: ".Host::complete()."/index.php?p=login&m=steam_failed");
5765
}
5866
}
67+
68+
// Issue #1290 phase B: legacy global-name shim. Procedural code keeps
69+
// using `\SteamAuthHandler` until the call-site sweep PR.
70+
class_alias(\Sbpp\Auth\Handler\SteamAuthHandler::class, 'SteamAuthHandler');
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
<?php
22

3+
namespace Sbpp\Auth;
4+
35
/**
46
* Class Host
57
*/
@@ -56,3 +58,7 @@ public static function complete(bool $withoutRequest = false): string
5658
return self::protocol().self::domain() . ($withoutRequest ? '' : "/$request");
5759
}
5860
}
61+
62+
// Issue #1290 phase B: legacy global-name shim. Procedural code keeps
63+
// using `\Host` until the call-site sweep PR.
64+
class_alias(\Sbpp\Auth\Host::class, 'Host');
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
<?php
22

3+
namespace Sbpp\Auth;
4+
5+
use DateTimeImmutable;
36
use Lcobucci\JWT\Builder;
47
use Lcobucci\JWT\Configuration;
58
use Lcobucci\JWT\Signer\Hmac\Sha256;
@@ -56,3 +59,7 @@ private static function getConfig(): Configuration
5659
return Configuration::forSymmetricSigner(new Sha256(), InMemory::base64Encoded(SB_SECRET_KEY));
5760
}
5861
}
62+
63+
// Issue #1290 phase B: legacy global-name shim. Procedural code keeps
64+
// using `\JWT` until the call-site sweep PR.
65+
class_alias(\Sbpp\Auth\JWT::class, 'JWT');

0 commit comments

Comments
 (0)