Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion src/Models/Address.php
Original file line number Diff line number Diff line change
Expand Up @@ -246,18 +246,26 @@ public function getStreetNumberAttribute(): string
return '';
}

public function scopeFlag(Builder $query, string $flag): Builder
{
return $query->where('is_'.$flag, true);
}

/** @deprecated use scopeFlag('primary') instead */
public function scopePrimary(Builder $query): Builder
{
return $query->where('is_primary', true);
}

/** @deprecated use scopeFlag('billing') instead */
public function scopeBilling(Builder $query): Builder
{
return $query->where('is_billing', true);
}

/** @deprecated use scopeFlag('shipping') instead */
public function scopeShipping(Builder $query): Builder
{
return $query->where('is_shipping', true);
}
}
}
6 changes: 6 additions & 0 deletions src/Models/Contact.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Lecturize\Addresses\Models;

use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\MorphTo;
Expand Down Expand Up @@ -155,4 +156,9 @@ public function getFullNameRevAttribute(?bool $show_salutation = null): string

return trim(implode(', ', array_filter($names)));
}

public function scopeFlag(Builder $query, string $flag): Builder
{
return $query->where('is_'.$flag, true);
}
}
75 changes: 63 additions & 12 deletions src/Traits/HasAddresses.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,28 +57,79 @@ public function flushAddresses(): bool
return $this->addresses()->delete();
}

public function getAddress(string $flag = null, string $direction = 'desc', bool $strict = false): ?Address
{
if (! $this->hasAddresses()) {
return null; // short circuit if no addresses exist
}

$direction = strtoupper($direction) === 'ASC' ? 'ASC' : 'DESC';

if ($flag !== null) {
$address = $this->addresses()
->flag($flag, true)
->orderBy('is_' . $flag, $direction)
->first();

if ($address !== null) {
return $address;
}

if ($strict) {
return null;
}

/**
* use the array order of config lecturize.addresses.flags to build up
* a fallback solution for when no address with the given flag exists
*/
$fallback_order = config('lecturize.addresses.flags', []);

/**
* fallback order is an array of flags like: ['public', 'primary', 'billing', 'shipping']
* when calling getAddress('billing') and no address with the billing flag exists, the next earliest flag is used
* in this case, the flag 'primary' would be used
*/
$current_flag_index = array_search($flag, $fallback_order);
$try_flag = $fallback_order[$current_flag_index - 1] ?? null;

if ($try_flag !== null) {
$address = $this->getAddress($try_flag, $direction);

if ($address !== null) {
return $address;
}
}
}

/**
* should the default fallback logic fail, try to get the first or last address
*/
if (! $address && $direction === 'DESC') {
return $this->addresses()->first();
} elseif (! $address && $direction === 'ASC') {
return $this->addresses()->last();
}

return null;
}

/** @deprecated use getAddress('primary', $direction) instead */
public function getPrimaryAddress(string $direction = 'desc'): ?Address
{
return $this->addresses()
->primary()
->orderBy('is_primary', $direction)
->first();
return $this->getAddress('primary', $direction, true);
}

/** @deprecated use getAddress('billing', $direction) instead */
public function getBillingAddress(string $direction = 'desc'): ?Address
{
return $this->addresses()
->billing()
->orderBy('is_billing', $direction)
->first();
return $this->getAddress('billing', $direction, true);
}

/** @deprecated use getAddress('shipping', $direction) instead */
public function getShippingAddress(string $direction = 'desc'): ?Address
{
return $this->addresses()
->shipping()
->orderBy('is_shipping', $direction)
->first();
return $this->getAddress('shipping', $direction, true);
}

/** @throws FailedValidationException */
Expand Down
57 changes: 57 additions & 0 deletions src/Traits/HasContacts.php
Original file line number Diff line number Diff line change
Expand Up @@ -81,4 +81,61 @@ function validateContact(array $attributes): Validator

return validator($attributes, $rules);
}

public function getContact(string $flag, string $direction = 'desc', bool $strict = false): ?Contact
{
if (! $this->hasContacts()) {
return null; // short circuit if no contactes exist
}

$direction = strtoupper($direction) === 'ASC' ? 'ASC' : 'DESC';

if ($flag !== null) {
$contact = $this->contacts()
->flag($flag, true)
->orderBy('is_' . $flag, $direction)
->first();

if ($contact !== null) {
return $contact;
}

if ($strict) {
return null;
}

/**
* use the array order of config lecturize.contacts.flags to build up
* a fallback solution for when no contact with the given flag exists
*/
$fallback_order = config('lecturize.contacts.flags', []);

/**
* fallback order is an array of flags like: ['public', 'primary', 'billing', 'shipping']
* when calling getContact('billing') and no contact with the billing flag exists, the next earliest flag is used
* in this case, the flag 'primary' would be used
*/
$current_flag_index = array_search($flag, $fallback_order);
$try_flag = $fallback_order[$current_flag_index - 1] ?? null;

if ($try_flag !== null) {
$contact = $this->getContact($try_flag, $direction);

if ($contact !== null) {
return $contact;
}
}
}

/**
* should the default fallback logic fail, try to get the first or last contact
*/
if (! $contact && $direction === 'DESC') {
return $this->contacts()->first();
} elseif (! $contact && $direction === 'ASC') {
return $this->contacts()->last();
}

return null;
}
}