Move all Eloquent models from the app/ root directory to app/Models/
for consistency with modern Laravel conventions. The project already had
54 models in App\Models; this migrates the remaining 52 legacy models.
Changes:
- Move 52 model files from app/ to app/Models/
- Update namespace declarations in each model
- Update all ~1000 import references across the codebase
- Add Relation::morphMap() in AppServiceProvider for backward
compatibility with existing polymorphic database records
- Add missing HasSnowflakePrimary imports for models that relied
on same-namespace resolution
Adds explicit return type declarations to 498 controller methods
across 88 files. Types inferred from return statements:
- JsonResponse for response()->json() returns
- RedirectResponse for redirect()/back() returns
- View (contract) for view() returns
- Response for response() returns
- void for methods with no return value
- array for array returns
- string/int/bool for scalar returns
Also fixes 3 methods with incorrect bare returns:
- AvatarController::deleteAvatar - bare return → json response
- ImportPostController::checkPermissions - bare return → true
- RemoteAuthController::accountToId - bare return → empty array
Convert all 273 short facade alias imports (e.g. 'use Cache;') to their
fully-qualified class names (e.g. 'use Illuminate\Support\Facades\Cache;')
across 193 files.
This resolves 643 PHPStan 'class.notFound' errors caused by the static
analyzer being unable to resolve global aliases, and aligns with modern
Laravel conventions. It also unblocks removing the aliases array from
config/app.php in a future change.
All 107 tests pass.
str_random() is a deprecated helper from laravel/helpers that was
missed in the initial helpers removal. Replace all 18 call sites
with the modern Str::random() equivalent.
Fixes#6643
The POST /api/v1/accounts/{id}/remove_from_followers endpoint was missing
the token existence check (! $request->user()->token()). While the
tokenCan('follow') scope check was already present, the missing token
guard meant unauthenticated token-less requests could potentially bypass
the scope enforcement.
Added the standard guard pattern consistent with accountFollowById and
accountUnfollowById endpoints.
Also adds tests verifying:
- Read-only tokens are denied (403)
- Follow-scoped tokens succeed (200)
- Unauthenticated requests are denied (403)
Fixes#6695
When no pagination params are provided, the default min_id was set to 1
and the query used 'id > 1', which excluded the very first follower row
(id=1) on fresh instances.
Changed default min_id from 1 to 0 and switched the direction check from
truthy evaluation to !== null, so the query becomes 'id > 0' which
correctly includes all records.
PHP 5.5.9 adds the new static `class` property which provides the fully qualified class name. This is preferred over using strings for class names since the `class` property references are checked by PHP.
`GET /api/v1/timelines/home?max_id=` (empty value) fails validation
because `min_id`/`max_id` use the `sometimes|integer` rule. The global
`ConvertEmptyStringsToNull` middleware turns `?max_id=` into `null`, and
since the field is present, `sometimes` does not skip it while `null`
fails the `integer` rule — returning HTTP 422.
Every other timeline/listing endpoint in this controller (timelinePublic,
accountStatusesById, etc.) uses `nullable|integer` for these params, so
`timelineHome` was the lone outlier. Mastodon-API clients such as Pixelfed
for iOS send `max_id=` on first page load and could not paginate the home
timeline.
Switch `min_id`/`max_id` to `nullable|integer` to match the rest of the
controller.
Fixes#6610
Co-Authored-By: Claude <noreply@anthropic.com>