baks-dev/users-profile-user
Модуль профилей пользователя для PHP 8.4+: установка через Composer, установка ресурсов (baks:assets:install), обновление схемы БД через Doctrine migrations, тестирование PHPUnit (group=users-profile-user).
Install the Package
composer require baks-dev/users-profile-user
Ensure your composer.json specifies PHP 8.4+ and Laravel 10+ constraints.
Publish Configuration and Assets
php artisan vendor:publish --provider="BaksDev\UsersProfileUser\UsersProfileUserServiceProvider"
php artisan baks:assets:install
Verify the config/users-profile-user.php and asset files (CSS/JS) are published to config/ and public/ respectively.
Run Migrations
php artisan doctrine:migrations:diff
php artisan doctrine:migrations:migrate
Review the generated migration for conflicts with existing users table or custom profile schemas.
Test the Profile System
/profile (or the configured route) after logging in.GET request to /api/profile (if API routes are included).php artisan test --group=users-profile-user
First Customization Extend the default profile fields by publishing the config and modifying:
// config/users-profile-user.php
'fields' => [
'name' => 'string|max:255',
'bio' => 'string|nullable',
'location' => 'string|nullable',
// Add custom fields (e.g., 'portfolio_url')
],
Profile model (e.g., BaksDev\UsersProfileUser\Models\Profile) linked to the users table via user_id. Use Eloquent for operations:
use BaksDev\UsersProfileUser\Models\Profile;
// Get current user's profile
$profile = Profile::where('user_id', auth()->id())->firstOrFail();
// Update profile
$profile->update([
'bio' => 'Updated bio',
'location' => 'New York',
]);
use Illuminate\Support\Facades\Validator;
$validator = Validator::make($request->all(), [
'bio' => 'string|max:500',
'location' => 'string|nullable',
], [
'bio.max' => 'Bio must be less than 500 characters.',
]);
baks:assets:install command likely sets up storage paths. Use Laravel’s Store facade or custom logic:
use Illuminate\Support\Facades\Storage;
$path = $request->file('avatar')->store('profile_avatars', 'public');
$profile->update(['avatar_path' => $path]);
$avatarUrl = Storage::url($profile->avatar_path);
ProfileUpdated. Listen in EventServiceProvider:
protected $listen = [
\BaksDev\UsersProfileUser\Events\ProfileUpdated::class => [
\App\Listeners\SendProfileUpdateNotification::class,
],
];
/api/profile. Test with:
php artisan route:list | grep profile
Example API request:
curl -X GET http://your-app.test/api/profile \
-H "Authorization: Bearer {token}"
namespace App\Http\Controllers;
use BaksDev\UsersProfileUser\Http\Controllers\ProfileController as BaseProfileController;
class ProfileController extends BaseProfileController {
public function update(Request $request) {
// Custom logic before/after update
return parent::update($request);
}
}
<!-- resources/views/profile.blade.php -->
@include('users-profile-user::profile.form')
<img src="{{ $profile->avatarUrl() }}" alt="Profile Avatar">
@foreach(config('users-profile-user.fields') as $field => $rules)
<div>
<label for="{{ $field }}">{{ ucfirst($field) }}</label>
<input type="text" name="{{ $field }}" id="{{ $field }}">
</div>
@endforeach
public function test_profile_update_validation()
{
$profile = Profile::factory()->create();
$response = $this->put("/profile/{$profile->id}", [
'bio' => str_repeat('x', 600), // Exceed max length
]);
$response->assertSessionHasErrors('bio');
}
public function test_profile_api_endpoint()
{
$response = $this->actingAs(User::factory()->create())
->get('/api/profile');
$response->assertStatus(200);
}
Extend User Model:
If the package uses a separate Profile model, eager-load it in your User model:
// app/Models/User.php
public function profile()
{
return $this->hasOne(\BaksDev\UsersProfileUser\Models\Profile::class);
}
Access via:
auth()->user()->profile->bio;
Auth Middleware: Protect profile routes with Laravel’s built-in middleware:
Route::middleware(['auth'])->group(function () {
Route::get('/profile', [ProfileController::class, 'show']);
});
Route::middleware('auth:sanctum')->group(function () {
Route::apiResource('profile', \BaksDev\UsersProfileUser\Http\Controllers\ProfileController::class);
});
use Spatie\MediaLibrary\HasMedia;
use Spatie\MediaLibrary\InteractsWithMedia;
class Profile extends \BaksDev\UsersProfileUser\Models\Profile implements HasMedia
{
use InteractsWithMedia;
}
php artisan nova:resource ProfileResource --model=BaksDev\UsersProfileUser\Models\Profile
Customize fields in ProfileResource.php:
public function fields(Request $request)
{
return [
ID::make()->sortable(),
Text::make('Bio')->onlyOnDetail(),
// Add custom fields
];
}
$profile->update([
'bio' => $request->bio,
]);
UpdateProfileNotification::dispatch($profile)->delay(now()->addSeconds(10));
use Laravel\Scout\Searchable;
class Profile extends \BaksDev\UsersProfileUser\Models\Profile
{
use Searchable;
public function toSearchableArray()
{
return [
'bio' => $this->bio,
'location' => $this->location,
];
}
}
profiles table or extend the users table in ways conflicting with your existing schema.doctrine:migrations:diff first to preview changes.user_profiles vs. profiles).// In your migration
Schema::table('user_profiles', function (Blueprint $table) {
$table->string
How can I help you explore Laravel packages today?