3 Commits

Author SHA1 Message Date
Jean-Marc Strauven
98b8ff236b Merge pull request #23 from Grazulex/feat/laravel-13-upgrade
feat!: upgrade to Laravel 13 compatibility
2026-03-30 18:03:04 +02:00
Jean-Marc Strauven
53913c1596 fix(ci): set platform PHP to 8.3 for CI compatibility
The platform PHP was set to 8.4.5 which caused Symfony to resolve
to v8.0 requiring PHP 8.4+, breaking the PHP 8.3 CI job.
2026-03-30 18:02:08 +02:00
Jean-Marc Strauven
f2dcd0059a feat!: upgrade to Laravel 13 compatibility
- Update laravel/framework to ^13.0, tinker to ^3.0, query-builder to ^7.0
- Migrate User model to #[Fillable] and #[Hidden] attributes (Laravel 13 pattern)
- Add LARAVEL_130 ruleset to Rector configuration
- Add PHP 8.4 to CI test matrix
- Update README badges and description for Laravel 13

BREAKING CHANGE: requires Laravel 13.x, drops Laravel 12 support
2026-03-30 17:59:00 +02:00
6 changed files with 524 additions and 510 deletions

View File

@@ -12,6 +12,10 @@ jobs:
ci: ci:
runs-on: ubuntu-latest runs-on: ubuntu-latest
strategy:
matrix:
php-version: ['8.3', '8.4']
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v4 uses: actions/checkout@v4
@@ -19,7 +23,7 @@ jobs:
- name: Setup PHP - name: Setup PHP
uses: shivammathur/setup-php@v2 uses: shivammathur/setup-php@v2
with: with:
php-version: 8.3 php-version: ${{ matrix.php-version }}
tools: composer:v2 tools: composer:v2
coverage: xdebug coverage: xdebug

View File

@@ -1,9 +1,9 @@
# Laravel API Kit # Laravel API Kit
A production-ready, API-only Laravel 12 starter kit following the 2024-2025 REST API ecosystem best practices. No frontend dependencies - purely headless API for mobile apps, SPAs, or microservices. A production-ready, API-only Laravel 13 starter kit following the 2025-2026 REST API ecosystem best practices. No frontend dependencies - purely headless API for mobile apps, SPAs, or microservices.
[![PHP Version](https://img.shields.io/badge/PHP-8.3%2B-blue)](https://php.net) [![PHP Version](https://img.shields.io/badge/PHP-8.3%2B-blue)](https://php.net)
[![Laravel Version](https://img.shields.io/badge/Laravel-12.x-red)](https://laravel.com) [![Laravel Version](https://img.shields.io/badge/Laravel-13.x-red)](https://laravel.com)
[![License](https://img.shields.io/badge/License-MIT-green)](LICENSE) [![License](https://img.shields.io/badge/License-MIT-green)](LICENSE)
## Features ## Features

View File

@@ -6,6 +6,8 @@ namespace App\Models;
use Database\Factories\UserFactory; use Database\Factories\UserFactory;
use Illuminate\Contracts\Auth\MustVerifyEmail; use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Attributes\Fillable;
use Illuminate\Database\Eloquent\Attributes\Hidden;
use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable; use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable; use Illuminate\Notifications\Notifiable;
@@ -21,6 +23,15 @@ use Laravel\Sanctum\HasApiTokens;
* @property Carbon|null $created_at * @property Carbon|null $created_at
* @property Carbon|null $updated_at * @property Carbon|null $updated_at
*/ */
#[Fillable([
'name',
'email',
'password',
])]
#[Hidden([
'password',
'remember_token',
])]
final class User extends Authenticatable implements MustVerifyEmail final class User extends Authenticatable implements MustVerifyEmail
{ {
use HasApiTokens; use HasApiTokens;
@@ -30,27 +41,6 @@ final class User extends Authenticatable implements MustVerifyEmail
use Notifiable; use Notifiable;
/**
* The attributes that are mass assignable.
*
* @var list<string>
*/
protected $fillable = [
'name',
'email',
'password',
];
/**
* The attributes that should be hidden for serialization.
*
* @var list<string>
*/
protected $hidden = [
'password',
'remember_token',
];
/** /**
* Get the attributes that should be cast. * Get the attributes that should be cast.
* *

View File

@@ -7,13 +7,13 @@
"license": "MIT", "license": "MIT",
"require": { "require": {
"php": "^8.3", "php": "^8.3",
"dedoc/scramble": "^0.12", "dedoc/scramble": "^0.12|^0.13",
"grazulex/laravel-apiroute": "^2.0", "grazulex/laravel-apiroute": "^2.0",
"laravel/framework": "^12.0", "laravel/framework": "^13.0",
"laravel/sanctum": "^4.0", "laravel/sanctum": "^4.0",
"laravel/tinker": "^2.10.1", "laravel/tinker": "^3.0",
"spatie/laravel-data": "^4.0", "spatie/laravel-data": "^4.0",
"spatie/laravel-query-builder": "^6.0" "spatie/laravel-query-builder": "^7.0"
}, },
"require-dev": { "require-dev": {
"driftingly/rector-laravel": "^2.0", "driftingly/rector-laravel": "^2.0",
@@ -94,7 +94,7 @@
"php-http/discovery": true "php-http/discovery": true
}, },
"platform": { "platform": {
"php": "8.3.30" "php": "8.3.0"
} }
}, },
"minimum-stability": "stable", "minimum-stability": "stable",

981
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -21,6 +21,7 @@ return RectorConfig::configure()
LaravelSetList::LARAVEL_FACTORIES, LaravelSetList::LARAVEL_FACTORIES,
LaravelSetList::LARAVEL_IF_HELPERS, LaravelSetList::LARAVEL_IF_HELPERS,
LaravelSetList::LARAVEL_LEGACY_FACTORIES_TO_CLASSES, LaravelSetList::LARAVEL_LEGACY_FACTORIES_TO_CLASSES,
LaravelSetList::LARAVEL_130,
]) ])
->withImportNames( ->withImportNames(
removeUnusedImports: true, removeUnusedImports: true,