initial commit
This commit is contained in:
78
src/app/Console/Commands/ResetPassword.php
Normal file
78
src/app/Console/Commands/ResetPassword.php
Normal file
@ -0,0 +1,78 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Models\User;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
|
||||
class ResetPassword extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'password:reset {--i|id= : The ID of the user} {--e|email= : The email address of the user} {--p|password}';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Reset the password for a given user';
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$id = $this->option('id');
|
||||
$email = $this->option('email');
|
||||
$password = $this->option('password');
|
||||
$column = null;
|
||||
$value = null;
|
||||
|
||||
if (! empty($id) && empty($email)) {
|
||||
$column = 'id';
|
||||
$value = $id;
|
||||
} elseif (empty($id) && ! empty($email)) {
|
||||
$column = 'email';
|
||||
$value = $email;
|
||||
} else {
|
||||
$column = strtolower($this->choice('What column would you like to search by?', ['ID', 'Email']));
|
||||
$value = $this->ask("Please provide an $column to search for");
|
||||
}
|
||||
|
||||
$user = User::where($column, $value)->first();
|
||||
if (! $user) {
|
||||
$this->error('Unable to find a user matching your input.');
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (empty($password)) {
|
||||
$password = $this->secret('What is the new password?');
|
||||
}
|
||||
try {
|
||||
$user->update(['password' => Hash::make($password)]);
|
||||
$this->info("User {$user->id} ({$user->email}) password update successful!");
|
||||
return 0;
|
||||
} catch (\Exception $e) {
|
||||
$this->error('Unable to set the password!');
|
||||
$this->line($e->getMessage());
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
28
src/app/Http/Middleware/CheckCustomSessionData.php
Normal file
28
src/app/Http/Middleware/CheckCustomSessionData.php
Normal file
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class CheckCustomSessionData
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle(Request $request, Closure $next)
|
||||
{
|
||||
if ((! session()->has('timezone_name') || empty(session('timezone_name'))) && $request->user()) {
|
||||
session()->put('timezone_name', $request->user()->timezone_name);
|
||||
}
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
}
|
59
src/app/Http/Middleware/HandleInertiaRequests.php
Normal file
59
src/app/Http/Middleware/HandleInertiaRequests.php
Normal file
@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Inertia\Middleware;
|
||||
|
||||
class HandleInertiaRequests extends Middleware
|
||||
{
|
||||
/**
|
||||
* The root template that's loaded on the first page visit.
|
||||
*
|
||||
* @see https://inertiajs.com/server-side-setup#root-template
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $rootView = 'app';
|
||||
|
||||
/**
|
||||
* Determines the current asset version.
|
||||
*
|
||||
* @see https://inertiajs.com/asset-versioning
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function version(Request $request)
|
||||
{
|
||||
return parent::version($request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines the props that are shared by default.
|
||||
*
|
||||
* @see https://inertiajs.com/shared-data
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function share(Request $request): array
|
||||
{
|
||||
$notifications = [];
|
||||
$unreadNotifications = false;
|
||||
if (! is_null($request->user())) {
|
||||
$notifications = $request->user()->notifications;
|
||||
if (count($request->user()->unreadNotifications) > 0) {
|
||||
$unreadNotifications = true;
|
||||
}
|
||||
}
|
||||
|
||||
return array_merge(parent::share($request), [
|
||||
'app_name' => config('app.name'),
|
||||
'notifications' => $notifications,
|
||||
'unreadNotifications' => $unreadNotifications,
|
||||
]);
|
||||
}
|
||||
}
|
160
src/app/Models/Address.php
Normal file
160
src/app/Models/Address.php
Normal file
@ -0,0 +1,160 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Traits\FormattedAddressTrait;
|
||||
use App\Models\Traits\HasUidTrait;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Prunable;
|
||||
use Illuminate\Database\Eloquent\Relations\MorphTo;
|
||||
|
||||
class Address extends Model
|
||||
{
|
||||
use FormattedAddressTrait;
|
||||
use HasFactory;
|
||||
use HasUidTrait;
|
||||
use Prunable;
|
||||
|
||||
/** @var string */
|
||||
protected $table = 'addresses';
|
||||
|
||||
/** @var string */
|
||||
protected $keyType = 'string';
|
||||
|
||||
/** @var bool */
|
||||
public $incrementing = false;
|
||||
|
||||
/** @var array */
|
||||
protected $fillable = [
|
||||
'addressable_type',
|
||||
'addressable_id',
|
||||
'team_id',
|
||||
'street',
|
||||
'unit',
|
||||
'city',
|
||||
'state',
|
||||
'postal_code',
|
||||
'country',
|
||||
];
|
||||
|
||||
/** @var array */
|
||||
protected $hidden = [];
|
||||
|
||||
/** @var array */
|
||||
protected $casts = [
|
||||
'is_primary' => 'boolean',
|
||||
];
|
||||
|
||||
/** @var array */
|
||||
protected $dates = [];
|
||||
|
||||
/** @var array */
|
||||
protected $appends = [];
|
||||
|
||||
/** @var array */
|
||||
protected $touches = [];
|
||||
|
||||
/** @var array */
|
||||
protected $dispatchesEvents = [];
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Class Constants
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
*/
|
||||
|
||||
//
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Custom/Private Methods
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get the prunable model query.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Builder
|
||||
*/
|
||||
public function prunable(): Builder
|
||||
{
|
||||
//return static::where('created_at', '<=', now()->subMonth());
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare the model for pruning.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function pruning(): void
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Accessors
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
*/
|
||||
|
||||
//
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Mutators
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
*/
|
||||
|
||||
//
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Scopes
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
*/
|
||||
|
||||
/**
|
||||
* Enforce that a given model belongs to a Team.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Builder $query
|
||||
* @param int|string $teamId
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Builder
|
||||
*/
|
||||
public function scopeOnTeam($query, $teamId): Builder
|
||||
{
|
||||
return $query->where('team_id', $teamId);
|
||||
}
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Relationships
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
*/
|
||||
|
||||
/**
|
||||
* Morphable relationship method.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\MorphTo
|
||||
*/
|
||||
public function addressable(): MorphTo
|
||||
{
|
||||
return $this->morphTo();
|
||||
}
|
||||
}
|
35
src/app/Models/Traits/FormattedAddressTrait.php
Normal file
35
src/app/Models/Traits/FormattedAddressTrait.php
Normal file
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models\Traits;
|
||||
|
||||
trait FormattedAddressTrait
|
||||
{
|
||||
/**
|
||||
* Combine the street and optionally a street suffix
|
||||
* e.g. Apt 1
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getAddressStreetAttribute(): string
|
||||
{
|
||||
$street = $this->street;
|
||||
if (! empty($this->unit)) {
|
||||
$street .= " {$this->unit}";
|
||||
}
|
||||
return $street;
|
||||
}
|
||||
|
||||
/**
|
||||
* Combine the city and state together as a single line
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getCityStateAttribute(): string
|
||||
{
|
||||
return "{$this->city}, {$this->state}";
|
||||
}
|
||||
}
|
171
src/app/Models/Traits/FormattedDateTrait.php
Normal file
171
src/app/Models/Traits/FormattedDateTrait.php
Normal file
@ -0,0 +1,171 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models\Traits;
|
||||
|
||||
use Carbon\Carbon;
|
||||
|
||||
trait FormattedDateTrait
|
||||
{
|
||||
/**
|
||||
* Return the created at datetime as mon D, year.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @param string $dateTimeString
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getCreatedAtDateShortAttribute(): string
|
||||
{
|
||||
return $this->created_at->format('M j, Y');
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the created at datetime as month day, year.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @param string $dateTimeString
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getCreatedAtDateFullAttribute(): string
|
||||
{
|
||||
return $this->created_at->format('F jS, Y');
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the created at datetime as month day, year hour:minute meridian.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @param string $dateTimeString
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getCreatedAtFullAttribute(): string
|
||||
{
|
||||
return $this->created_at->format('F jS, Y g:i a');
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the updated at datetime as mon day, year.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @param string $dateTimeString
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getUpdatedAtDateShortAttribute(): string
|
||||
{
|
||||
if (empty($this->updated_at)) {
|
||||
return '--';
|
||||
}
|
||||
return $this->updated_at->format('M j, Y');
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the updated at datetime as mon day, year.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @param string $dateTimeString
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getUpdatedAtDateFullAttribute(): string
|
||||
{
|
||||
if (empty($this->updated_at)) {
|
||||
return '--';
|
||||
}
|
||||
return $this->updated_at->format('F jS, Y');
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the updated at datetime as mon day, year hour:minute meridian.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @param string $dateTimeString
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getUpdatedAtFullAttribute(): string
|
||||
{
|
||||
if (empty($this->updated_at)) {
|
||||
return '--';
|
||||
}
|
||||
return $this->updated_at->format('F jS, Y g:i a');
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a datetime string as YYYY-MM-DD.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @param string $dateTimeString
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function dateStr(string $dateTimeString): string
|
||||
{
|
||||
return Carbon::parse($dateTimeString)->format('Y-m-d');
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a datetime string as mon d, year.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @param string $dateTimeString
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function dateShort(string $dateTimeString): string
|
||||
{
|
||||
return Carbon::parse($dateTimeString)->format('M j, Y');
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a datetime string as month day, year.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @param string $dateTimeString
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function dateFull(string $dateTimeString): string
|
||||
{
|
||||
return Carbon::parse($dateTimeString)->format('F jS, Y');
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a datetime string as HH:MM (military time)
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @param string $dateTimeString
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function timeShort(string $dateTimeString): string
|
||||
{
|
||||
return Carbon::parse($dateTimeString)->format('H:i');
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a datetime string as hour:minute meridian
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @param string $dateTimeString
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function timeFull(string $dateTimeString): string
|
||||
{
|
||||
return Carbon::parse($dateTimeString)->format('g:i a');
|
||||
}
|
||||
}
|
55
src/app/Models/Traits/FormattedPhoneTrait.php
Normal file
55
src/app/Models/Traits/FormattedPhoneTrait.php
Normal file
@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models\Traits;
|
||||
|
||||
trait FormattedPhoneTrait
|
||||
{
|
||||
/**
|
||||
* Format a phone number to be human readable.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getPhoneNumberAttribute(): string
|
||||
{
|
||||
$phoneLength = strlen($this->phone);
|
||||
$phoneNumber = preg_replace('//', '', $this->phone);
|
||||
|
||||
if ($phoneLength > 10) {
|
||||
$countryCode = substr($phoneNumber, 0, $phoneLength - 10);
|
||||
$areaCode = substr($phoneNumber, -10, 3);
|
||||
$nextThree = substr($phoneNumber, -7, 3);
|
||||
$lastFour = substr($phoneNumber, -4, 4);
|
||||
|
||||
$phoneNumber = "({$areaCode}) {$nextThree}-{$lastFour}";
|
||||
} elseif ($phoneLength == 10) {
|
||||
$areaCode = substr($phoneNumber, 0, 3);
|
||||
$nextThree = substr($phoneNumber, 3, 3);
|
||||
$lastFour = substr($phoneNumber, 6, 4);
|
||||
|
||||
$phoneNumber = "({$areaCode}) {$nextThree}-{$lastFour}";
|
||||
} elseif ($phoneLength == 7) {
|
||||
$nextThree = substr($phoneNumber, 0, 3);
|
||||
$lastFour = substr($phoneNumber, 3, 4);
|
||||
|
||||
$phoneNumber = "{$nextThree}-{$lastFour}";
|
||||
}
|
||||
|
||||
return $phoneNumber;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all non-numeric characters from the phone number.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @param string $value
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setPhoneNumberAttribute($value): void
|
||||
{
|
||||
$this->attributes['phone'] = preg_replace('/[^0-9]/', '', $value);
|
||||
}
|
||||
}
|
44
src/app/Models/Traits/HasUidTrait.php
Normal file
44
src/app/Models/Traits/HasUidTrait.php
Normal file
@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models\Traits;
|
||||
|
||||
trait HasUidTrait
|
||||
{
|
||||
/**
|
||||
* Ensure that when a model is saving, a unique ID
|
||||
* is set for the model.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function bootHasUidTrait(): void
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize logic.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function initializeHasUidTrait(): void
|
||||
{
|
||||
$this->id = $this->generateUid();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a cryptographically safe unique ID.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function generateUid(): string
|
||||
{
|
||||
$bytes = openssl_random_pseudo_bytes(env('APP_UID_BYTES', 8));
|
||||
return bin2hex($bytes);
|
||||
}
|
||||
}
|
182
src/app/Models/User.php
Normal file
182
src/app/Models/User.php
Normal file
@ -0,0 +1,182 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Traits\HasUidTrait;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Prunable;
|
||||
use Illuminate\Database\Eloquent\Relations\MorphOne;
|
||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||
use Illuminate\Notifications\Notifiable;
|
||||
use Laravel\Fortify\TwoFactorAuthenticatable;
|
||||
use Laravel\Jetstream\HasProfilePhoto;
|
||||
use Laravel\Jetstream\HasTeams;
|
||||
|
||||
class User extends Authenticatable
|
||||
{
|
||||
use HasApiTokens;
|
||||
use HasFactory;
|
||||
use HasProfilePhoto;
|
||||
use HasTeams;
|
||||
use HasUidTrait;
|
||||
use Notifiable;
|
||||
use Prunable;
|
||||
use TwoFactorAuthenticatable;
|
||||
|
||||
/** @var string */
|
||||
protected $table = 'users';
|
||||
|
||||
/** @var string */
|
||||
protected $keyType = 'string';
|
||||
|
||||
/** @var bool */
|
||||
public $incrementing = false;
|
||||
|
||||
/** @var array */
|
||||
protected $fillable = [
|
||||
'name',
|
||||
'surname',
|
||||
'timezone_name',
|
||||
'current_team_id',
|
||||
'profile_photo_path',
|
||||
'email',
|
||||
'password',
|
||||
];
|
||||
|
||||
/** @var array */
|
||||
protected $hidden = [
|
||||
'password',
|
||||
'remember_token',
|
||||
'two_factor_recovery_codes',
|
||||
'two_factor_secret',
|
||||
];
|
||||
|
||||
/** @var array */
|
||||
protected $casts = [
|
||||
'email_verified_at' => 'datetime',
|
||||
];
|
||||
|
||||
/** @var array */
|
||||
protected $dates = [];
|
||||
|
||||
/** @var array */
|
||||
protected $appends = [
|
||||
'full_name',
|
||||
'name_full',
|
||||
'profile_photo_url',
|
||||
];
|
||||
|
||||
/** @var array */
|
||||
protected $touches = [];
|
||||
|
||||
/** @var array */
|
||||
protected $dispatchesEvents = [];
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Class Constants
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
*/
|
||||
|
||||
//
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Custom/Private Methods
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get the prunable model query.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Builder
|
||||
*/
|
||||
public function prunable()//: Builder
|
||||
{
|
||||
//return static::where('created_at', '<=', now()->subMonth());
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare the model for pruning.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function pruning(): void
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Accessors
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
*/
|
||||
|
||||
/**
|
||||
* Return the surname then (first)name separated by a comma.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getFullNameAttribute(): string
|
||||
{
|
||||
return "{$this->surname}, {$this->name}";
|
||||
}
|
||||
|
||||
/**
|
||||
* Return both the (first)name and surname.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getNameFullAttribute(): string
|
||||
{
|
||||
return "{$this->name} {$this->surname}";
|
||||
}
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Mutators
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
*/
|
||||
|
||||
//
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Scopes
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
*/
|
||||
|
||||
//
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Relationships
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
*/
|
||||
|
||||
/**
|
||||
* Return the associated Address with a User.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\MorphOne
|
||||
*/
|
||||
public function addresses(): MorphOne
|
||||
{
|
||||
return $this->morphOne(Address::class, 'addressable');
|
||||
}
|
||||
}
|
30
src/app/Providers/AppServiceProvider.php
Normal file
30
src/app/Providers/AppServiceProvider.php
Normal file
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
|
||||
class AppServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* Register any application services.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Bootstrap any application services.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
// Disable lazy-loading when not in production to find N+1 problems
|
||||
Model::preventLazyLoading(! app()->isProduction());
|
||||
}
|
||||
}
|
84
src/app/Providers/JetstreamServiceProvider.php
Normal file
84
src/app/Providers/JetstreamServiceProvider.php
Normal file
@ -0,0 +1,84 @@
|
||||
<?php
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use App\Actions\Jetstream\AddTeamMember;
|
||||
use App\Actions\Jetstream\CreateTeam;
|
||||
use App\Actions\Jetstream\DeleteTeam;
|
||||
use App\Actions\Jetstream\DeleteUser;
|
||||
use App\Actions\Jetstream\InviteTeamMember;
|
||||
use App\Actions\Jetstream\RemoveTeamMember;
|
||||
use App\Actions\Jetstream\UpdateTeamName;
|
||||
use App\Models\User;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use Laravel\Fortify\Fortify;
|
||||
use Laravel\Jetstream\Jetstream;
|
||||
|
||||
class JetstreamServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* Register any application services.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Bootstrap any application services.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
$this->configurePermissions();
|
||||
|
||||
Jetstream::createTeamsUsing(CreateTeam::class);
|
||||
Jetstream::updateTeamNamesUsing(UpdateTeamName::class);
|
||||
Jetstream::addTeamMembersUsing(AddTeamMember::class);
|
||||
Jetstream::inviteTeamMembersUsing(InviteTeamMember::class);
|
||||
Jetstream::removeTeamMembersUsing(RemoveTeamMember::class);
|
||||
|
||||
Jetstream::deleteTeamsUsing(DeleteTeam::class);
|
||||
|
||||
Jetstream::deleteUsersUsing(DeleteUser::class);
|
||||
|
||||
// Allow a user to authenticate with either email or username fields
|
||||
Fortify::authenticateUsing(function (Request $request) {
|
||||
$user = User::where('email', $request->username)
|
||||
->orWhere('username', $request->username)
|
||||
->first();
|
||||
|
||||
if ($user && Hash::check($request->password, $user->password)) {
|
||||
return $user;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure the roles and permissions that are available within the application.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function configurePermissions()
|
||||
{
|
||||
Jetstream::defaultApiTokenPermissions(['read']);
|
||||
|
||||
Jetstream::role('admin', 'Administrator', [
|
||||
'create',
|
||||
'read',
|
||||
'update',
|
||||
'delete',
|
||||
])->description('Administrator users can perform any action.');
|
||||
|
||||
Jetstream::role('editor', 'Editor', [
|
||||
'read',
|
||||
'create',
|
||||
'update',
|
||||
])->description('Editor users have the ability to read, create, and update.');
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user