fndmiranda / simple-address
在多个API中通过邮编搜索地址,并可选择在搜索结果中使用谷歌地图获取地理编码。
Requires
- php: >=7.0.0
- illuminate/support: ~5.0|^7.0
This package is auto-updated.
Last update: 2024-09-15 00:44:43 UTC
README
本文也可以在巴西葡萄牙语中阅读。
Laravel的简单地址
此包简化了在API中通过邮编搜索地址以及在数据库中管理地址的过程,您还可以创建自己的适配器用于API查询。
安装
composer require fndmiranda/simple-address
使用
使用Artisan命令vendor:publish
发布包配置文件
php artisan vendor:publish --tag=simple-address-config
发布的配置文件address.php
将被放置在您的config
目录中。
搜索API
可用的API列表位于您的config/address.php
文件中的apis
部分,您可以按照以下方式删除或添加新的适配器
'apis' => [ Fndmiranda\SimpleAddress\Adapters\ViaCepAdapter::class, Fndmiranda\SimpleAddress\Adapters\PostmonAdapter::class, Fndmiranda\SimpleAddress\Adapters\WidenetAdapter::class, ],
如果您将config/address.php
中的force_priority
更改为true
,则搜索顺序将始终符合apis
适配器列表,默认情况下此值为false
,以便顺序是随机的。
使用Address
外观的search
方法,包将遍历API,直到找到请求的邮编,如下所示
$address = Address::search(38017170);
地理编码
您可以使用search
方法返回的数据,通过外观Address
的geocoding
方法获取地址的latitude
和longitude
,如下所示
$address = Address::search(38017170); $geocode = Address::geocoding($address);
注意,要使用geocoding
功能,您需要提供谷歌地图API的key
,在您的.env
文件中添加ADDRESS_GOOGLE_MAPS_KEY
条目,如下所示
ADDRESS_GOOGLE_MAPS_KEY=YourMapsKey
数据库
此包附带一个完整的数据库结构,用于存储搜索到的地址。
注意,将创建一个多态性表,该表应该使用与您在表中使用的类型相同的列创建,您可以在config/address.php
文件中将column_type
设置为column_type
,选项有integer
、bigInteger
和uuid
,然后使用migrate
Artisan命令创建表
php artisan migrate
迁移自定义
如果您不打算使用SimpleAddress默认迁移,您应该在AppServiceProvider
的register
方法中调用Address::ignoreMigrations
方法。您可以使用vendor:publish
Artisan命令导出默认迁移
php artisan vendor:publish --tag=simple-address-migrations
如果您不想在数据库中管理地址,只想查询API,请将config/address.php
文件中的manager_address
更改为false
。
保存到数据库
供应商模型与地址多态性集成的示例。
<?php namespace App\Supplier; use Fndmiranda\SimpleAddress\Entities\Address; use Illuminate\Database\Eloquent\Model; use Fndmiranda\SimpleAddress\Pivot\AddressPivot; class Supplier extends Model { /** * The attributes that are mass assignable. * * @var array */ protected $fillable = [ 'name', 'email', 'document', 'is_active', ]; /** * Get all of the addresses for the supplier. */ public function addresses() { return $this->morphToMany(Address::class, 'addressable', 'address_addressables') ->withPivot(['number', 'complement', 'lat', 'lng', 'type']) ->using(AddressPivot::class) ->withTimestamps(); } }
然后您可以使用以下示例使用外观Address
的search
和geocoding
方法将地址保存到供应商中
// Find a supplier $supplier = \App\Supplier::find(1); // Search a address by postcode $address = Address::search(38017170); // Get geocode of address $geocode = Address::geocoding($address); // Save an address to the supplier $attributes = array_merge(['number' => 16, 'complement' => 'House'], $geocode); $supplier->addresses()->save($address, $attributes); // Or without geocode $supplier->addresses()->save($address, ['number' => 16, 'complement' => 'House']); // To update a supplier address $supplier->addresses()->first()->pivot->update(['number' => 25, 'complement' => 'Store 10']);
或者在您的控制器中
<?php namespace App\Http\Controllers; use Illuminate\Http\Response; use App\Supplier; use App\Http\Resources\SupplierResource; use App\Repositories\SupplierRepository; use Fndmiranda\SimpleAddress\Facades\Address; use Fndmiranda\SimpleAddress\Repositories\AddressRepository; class SupplierController extends Controller { /** * The supplier repository instance. * * @var SupplierRepository */ protected $supplierRepository; /** * The address repository instance. * * @var AddressRepository */ protected $addressRepository; /** * Create a new controller instance. * * @return void */ public function __construct(SupplierRepository $supplierRepository, AddressRepository $addressRepository) { $this->supplierRepository = $supplierRepository; $this->addressRepository = $addressRepository; } /** * Store a newly created resource in storage. * * @param SupplierRequest $request * @return Response */ public function store(SupplierRequest $request) { $attributes = $request->all(); $entity = $this->addressRepository->create($attributes); if (!empty($attributes['address'])) { if (!empty(config('address.google_maps_key'))) { $address = $this->addressRepository->find($attributes['address']['address_id']); $geocode = Address::geocoding($address, $attributes['address']); if (!empty($geocode)) { array_merge($attributes['address'], $geocode); } } $entity->addresses()->sync([$attributes['address']['address_id'] => $attributes['address']]); } $data = SupplierResource::make($entity); return response()->json(['data' => $data], Response::HTTP_CREATED); } /** * Update the specified resource in storage. * * @param SupplierRequest $request * @param string $id * @return AccountResource */ public function update(SupplierRequest $request, $id) { $attributes = $request->all(); $entity = $this->supplierRepository->find($id); if (!empty($attributes['address'])) { if (!empty(config('address.google_maps_key'))) { $address = $this->addressRepository->find($attributes['address']['address_id']); $geocode = Address::geocoding($address, $attributes['address']); if (!empty($geocode)) { array_merge($attributes['address'], $geocode); } } $entity->addresses()->sync([$attributes['address']['address_id'] => $attributes['address']]); } $entity->update($attributes); return SupplierResource::make($entity); } }
请求体示例
{ "name": "Name of supplier", "email": "email@domain.com", "document": "11111111111", "is_active": true, "address": { "address_id": "0fdecea5-9f99-47ea-87a9-3dc191839008", "number": 16, "complement": "House" } }
创建您自己的自定义适配器
您可以为不在列表中的API创建自己的自定义适配器来查询,您可以使用simple-address:make
Artisan命令生成适配器
php artisan simple-address:make YourApiAdapter
此命令将在app/SimpleAddress/Adapters/YourApiAdapter.php
处生成适配器。
该文件将包含空的search
和prepare
方法,因此您可以按照以下示例的文件结构进行适配
<?php namespace App\SimpleAddress\Adapters; use Fndmiranda\SimpleAddress\Contracts\AdapterContract; class YourApiAdapter implements AdapterContract { /** * Search external address by postcode. * * @param $postcode * @return array|bool * @throws \GuzzleHttp\Exception\GuzzleException */ public function search($postcode) { $client = new \GuzzleHttp\Client(); $request = new \GuzzleHttp\Psr7\Request('GET', 'https://api.postmon.com.br/v1/cep/'.$postcode.'?format=json'); $response = $client->send($request); if ($response->getStatusCode() != 200) { return false; } $data = json_decode((string) $response->getBody(), true); return $this->prepare($data); } /** * Prepare address data. * * @param $data * @return array */ public function prepare($data) { return [ 'postcode' => $data['cep'], 'address' => $data['logradouro'], 'neighborhood' => $data['bairro'], 'city' => $data['cidade'], 'state' => $data['estado'], ]; } }
按照以下方式将您的适配器添加到config/address.php
文件中的apis
列表中
'apis' => [ Fndmiranda\SimpleAddress\Adapters\ViaCepAdapter::class, Fndmiranda\SimpleAddress\Adapters\PostmonAdapter::class, Fndmiranda\SimpleAddress\Adapters\WidenetAdapter::class, App\SimpleAddress\Adapters\YourApiAdapter::class, // Your custom Api adapter ],
如果您创建了一个新的API适配器,我将非常感激您通过添加适配器并将其映射到包的config/address.php
文件中的apis
列表来发起一个pull request。
搜索方法
搜索方法将请求发送到端点以查询邮政编码,并使用 prepare
方法将获取的数据转换为标准数组,然后返回这些数组或如果找不到 postcode
或 API 不响应,则返回 false
以自动查询下一个 API adapter
。
prepare 方法
prepare
方法将 API 返回的数据转换为具有 postcode
、address
、neighborhood
、city
和 state
键的标准 array
。
安全
如果您发现任何与安全相关的问题,请通过电子邮件 fndmiranda@gmail.com 联系,而不是使用问题跟踪器。
许可证
MIT 许可证 (MIT)。有关更多信息,请参阅 许可证文件。