baks-dev/users-address
Laravel/PHP модуль для управления пользовательскими адресами: установка через Composer, установка ассетов, миграции Doctrine для схемы БД и набор PHPUnit-тестов. Поддерживает PHP 8.4+ и распространяется по MIT-лицензии.
Install the Package
composer require baks-dev/users-address
Ensure your composer.json supports PHP 8.4+ and Laravel 10.x.
Publish Assets and Config Run the Artisan command to install migrations, views, and configurations:
php artisan baks:assets:install
This generates:
database/migrations/).config/users-address.php).resources/views/vendor/users-address/).Run Migrations Generate and apply the schema changes:
php artisan doctrine:migrations:diff
php artisan doctrine:migrations:migrate
Verify the users_addresses table and related entities exist.
First Use Case: Create a User with an Address
Use the package’s Address entity to attach addresses to users:
use Baks\UsersAddress\Models\Address;
use Baks\UsersAddress\Models\User; // Assuming extended User model
$user = User::find(1);
$user->addresses()->create([
'type' => 'home', // e.g., 'home', 'work', 'billing'
'street' => '123 Main St',
'city' => 'Springfield',
'postal_code' => '12345',
'country' => 'US',
]);
Save the user to persist the address.
// Define in User model (Doctrine)
/**
* @ORM\OneToMany(targetEntity="Baks\UsersAddress\Models\Address", mappedBy="user")
*/
private Collection $addresses;
$user->setDefaultAddress($address);
$defaultAddress = $user->getDefaultAddress();
$validator = \Baks\UsersAddress\Validators\AddressValidator::validate($data);
if ($validator->fails()) {
// Handle errors
}
// Configure in config/users-address.php
'geocoding' => [
'provider' => 'google',
'api_key' => env('GOOGLE_MAPS_API_KEY'),
];
// Trigger geocoding
$address->geocode();
$address = $user->addresses()->create($validatedData);
$address->update(['street' => 'New Address']);
$address->delete(); // Soft delete if configured
type field (e.g., home, work) to categorize addresses.
$billingAddress = $user->addresses()->where('type', 'billing')->first();
// Set default address
$user->addresses()->where('type', 'home')->update(['is_default' => false]);
$newDefault = $user->addresses()->where('type', 'work')->first();
$newDefault->setAsDefault();
routes/web.php:
Route::apiResource('user-addresses', \Baks\UsersAddress\Http\Controllers\AddressController::class);
// Example: Middleware to validate address on checkout
public function handle(Request $request, Closure $next) {
$address = $request->user()->getDefaultAddress();
if (!$address || !$address->isValid()) {
abort(422, 'Invalid address for checkout.');
}
return $next($request);
}
Doctrine vs. Eloquent:
// Example: Eloquent-compatible Address model
class EloquentAddress extends \Illuminate\Database\Eloquent\Model {
protected $fillable = ['user_id', 'type', 'street', 'city', ...];
public function user() {
return $this->belongsTo(User::class);
}
}
EntityManager to bridge models:
$em = app(\Doctrine\ORM\EntityManagerInterface::class);
$address = $em->find(Address::class, $id);
Event-Driven Extensions:
use Baks\UsersAddress\Events\AddressCreated;
AddressCreated::listen(function ($event) {
\Log::info("New address created for user {$event->user->id}");
// Send welcome email or trigger geocoding
});
Testing:
php artisan test --group=users-address
public function test_user_can_add_address() {
$user = User::factory()->create();
$this->actingAs($user);
$response = $this->post('/user-addresses', [
'type' => 'home',
'street' => '123 Test St',
// ...
]);
$response->assertCreated();
}
Localization:
config/users-address.php:
'validation' => [
'messages' => [
'street.required' => 'The street field is required.',
'country.in' => 'The selected country is invalid.',
],
],
Geocoding Providers:
namespace App\Services;
use Baks\UsersAddress\Contracts\GeocodingService;
class CustomGeocodingService implements GeocodingService {
public function geocode($address) {
// Integrate with your API
return ['lat' => 12.34, 'lng' => 56.78];
}
}
$this->app->bind(GeocodingService::class, CustomGeocodingService::class);
Doctrine ORM Dependency:
Migration Conflicts:
addresses table or related migrations, conflicts may arise.doctrine:migrations:diff) before applying.--down migrations to roll back if needed:
php artisan doctrine:migrations:execute --down
Geocoding API Dependencies:
$geocodedData = cache()->remember("geocode_{$address->hash}", now()->addHours(1), function () {
return $address->geocode();
});
Address Validation Overrides:
// Override in a service provider
$validator = new \Baks\UsersAddress\Validators\AddressValidator();
$validator->setRules([
'country' => 'required|in:US,CA,JP,IN', // Custom list
'postal_code' => 'required|regex:/^[A-Z0-9]{5}$/', // US-specific
]);
Performance with Large Address Books:
How can I help you explore Laravel packages today?