fixed common api endpoints

This commit is contained in:
Denis Duliçi 2020-12-26 16:13:34 +03:00
parent 8dbe178a70
commit 2e09989cf5
13 changed files with 267 additions and 113 deletions

View File

@ -0,0 +1,28 @@
<?php
namespace App\Events\Auth;
use App\Abstracts\Event;
class ApiPermissionsAssigning extends Event
{
public $permission;
public $table;
public $type;
/**
* Create a new event instance.
*
* @param $permission
* @param $table
* @param $type
*/
public function __construct($permission, $table, $type)
{
$this->permission = $permission;
$this->table = $table;
$this->type = $type;
}
}

View File

@ -15,18 +15,6 @@ class Contacts extends ApiController
{ {
use Uploads; use Uploads;
/**
* Instantiate a new controller instance.
*/
public function __construct()
{
// Add CRUD permission check
$this->middleware('permission:create-sales-customers')->only('create', 'store', 'duplicate', 'import');
$this->middleware('permission:read-sales-customers')->only('index', 'show', 'edit', 'export');
$this->middleware('permission:update-sales-customers')->only('update', 'enable', 'disable');
$this->middleware('permission:delete-sales-customers')->only('destroy');
}
/** /**
* Display a listing of the resource. * Display a listing of the resource.
* *

View File

@ -0,0 +1,54 @@
<?php
namespace App\Listeners\Auth;
use App\Events\Auth\ApiPermissionsAssigning as Event;
class SetPermissionControllerForCommonApiEndpoints
{
/**
* Handle the event.
*
* @param Event $event
* @return void
*/
public function handle(Event $event)
{
if (!in_array($event->table, ['contacts', 'documents', 'transactions'])) {
return;
}
if ($event->table == 'contacts') {
switch ($event->type) {
case 'customer':
$event->permission->controller = 'sales-customers';
break;
case 'vendor':
$event->permission->controller = 'purchases-vendors';
break;
}
}
if ($event->table == 'documents') {
switch ($event->type) {
case 'invoice':
$event->permission->controller = 'sales-invoices';
break;
case 'bill':
$event->permission->controller = 'purchases-bills';
break;
}
}
if ($event->table == 'transactions') {
switch ($event->type) {
case 'income':
$event->permission->controller = 'sales-revenues';
break;
case 'expense':
$event->permission->controller = 'purchases-payments';
break;
}
}
}
}

View File

@ -4,6 +4,7 @@ namespace App\Models\Banking;
use App\Abstracts\Model; use App\Abstracts\Model;
use App\Models\Setting\Category; use App\Models\Setting\Category;
use App\Scopes\Transaction as Scope;
use App\Traits\Currencies; use App\Traits\Currencies;
use App\Traits\DateTime; use App\Traits\DateTime;
use App\Traits\Media; use App\Traits\Media;
@ -52,6 +53,18 @@ class Transaction extends Model
*/ */
public $cloneable_relations = ['recurring']; public $cloneable_relations = ['recurring'];
/**
* The "booting" method of the model.
*
* @return void
*/
protected static function boot()
{
parent::boot();
static::addGlobalScope(new Scope);
}
public function account() public function account()
{ {
return $this->belongsTo('App\Models\Banking\Account')->withDefault(['name' => trans('general.na')]); return $this->belongsTo('App\Models\Banking\Account')->withDefault(['name' => trans('general.na')]);

View File

@ -4,11 +4,12 @@ namespace App\Models\Common;
use App\Abstracts\Model; use App\Abstracts\Model;
use App\Models\Document\Document; use App\Models\Document\Document;
use Bkwld\Cloner\Cloneable; use App\Scopes\Contact as Scope;
use App\Traits\Contacts; use App\Traits\Contacts;
use App\Traits\Currencies; use App\Traits\Currencies;
use App\Traits\Media; use App\Traits\Media;
use App\Traits\Transactions; use App\Traits\Transactions;
use Bkwld\Cloner\Cloneable;
use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Notifications\Notifiable; use Illuminate\Notifications\Notifiable;
@ -41,6 +42,18 @@ class Contact extends Model
*/ */
public $sortable = ['name', 'email', 'phone', 'enabled']; public $sortable = ['name', 'email', 'phone', 'enabled'];
/**
* The "booting" method of the model.
*
* @return void
*/
protected static function boot()
{
parent::boot();
static::addGlobalScope(new Scope);
}
public function documents() public function documents()
{ {
return $this->hasMany('App\Models\Document\Document'); return $this->hasMany('App\Models\Document\Document');

View File

@ -3,8 +3,8 @@
namespace App\Models\Document; namespace App\Models\Document;
use App\Abstracts\Model; use App\Abstracts\Model;
use App\Scopes\Document as Scope;
use App\Models\Setting\Tax; use App\Models\Setting\Tax;
use App\Scopes\Document as Scope;
use App\Traits\Currencies; use App\Traits\Currencies;
use App\Traits\DateTime; use App\Traits\DateTime;
use App\Traits\Documents; use App\Traits\Documents;
@ -15,9 +15,6 @@ use Database\Factories\Document as DocumentFactory;
use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Factories\Factory; use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\MorphOne;
class Document extends Model class Document extends Model
{ {

View File

@ -36,6 +36,9 @@ class Event extends Provider
'App\Events\Auth\LandingPageShowing' => [ 'App\Events\Auth\LandingPageShowing' => [
'App\Listeners\Auth\AddLandingPages', 'App\Listeners\Auth\AddLandingPages',
], ],
'App\Events\Auth\ApiPermissionsAssigning' => [
'App\Listeners\Auth\SetPermissionControllerForCommonApiEndpoints',
],
'App\Events\Document\DocumentCreated' => [ 'App\Events\Document\DocumentCreated' => [
'App\Listeners\Document\CreateDocumentCreatedHistory', 'App\Listeners\Document\CreateDocumentCreatedHistory',
'App\Listeners\Document\IncreaseNextDocumentNumber', 'App\Listeners\Document\IncreaseNextDocumentNumber',

View File

@ -2,12 +2,15 @@
namespace App\Scopes; namespace App\Scopes;
use App\Traits\Scopes;
use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Scope; use Illuminate\Database\Eloquent\Scope;
class Company implements Scope class Company implements Scope
{ {
use Scopes;
/** /**
* Apply the scope to a given Eloquent query builder. * Apply the scope to a given Eloquent query builder.
* *
@ -34,43 +37,11 @@ class Company implements Scope
} }
// Skip if already exists // Skip if already exists
if ($this->exists($builder, 'company_id')) { if ($this->scopeExists($builder, 'company_id')) {
return; return;
} }
// Apply company scope // Apply company scope
$builder->where($table . '.company_id', '=', session('company_id')); $builder->where($table . '.company_id', '=', session('company_id'));
} }
/**
* Check if scope exists.
*
* @param \Illuminate\Database\Eloquent\Builder $builder
* @param $column
* @return boolean
*/
protected function exists($builder, $column)
{
$query = $builder->getQuery();
foreach ((array) $query->wheres as $key => $where) {
if (empty($where) || empty($where['column'])) {
continue;
}
if (strstr($where['column'], '.')) {
$whr = explode('.', $where['column']);
$where['column'] = $whr[1];
}
if ($where['column'] != $column) {
continue;
}
return true;
}
return false;
}
} }

25
app/Scopes/Contact.php Normal file
View File

@ -0,0 +1,25 @@
<?php
namespace App\Scopes;
use App\Traits\Scopes;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Scope;
class Contact implements Scope
{
use Scopes;
/**
* Apply the scope to a given Eloquent query builder.
*
* @param \Illuminate\Database\Eloquent\Builder $builder
* @param \Illuminate\Database\Eloquent\Model $model
* @return void
*/
public function apply(Builder $builder, Model $model)
{
$this->applyTypeScope($builder, $model);
}
}

View File

@ -2,13 +2,15 @@
namespace App\Scopes; namespace App\Scopes;
use App\Traits\Scopes;
use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Scope; use Illuminate\Database\Eloquent\Scope;
use Illuminate\Support\Str;
class Document implements Scope class Document implements Scope
{ {
use Scopes;
/** /**
* Apply the scope to a given Eloquent query builder. * Apply the scope to a given Eloquent query builder.
* *
@ -18,46 +20,6 @@ class Document implements Scope
*/ */
public function apply(Builder $builder, Model $model) public function apply(Builder $builder, Model $model)
{ {
// Skip if already exists $this->applyTypeScope($builder, $model);
if ($this->exists($builder, 'type')) {
return;
}
$type = Str::singular(request()->segment(2, ''));
// Apply document scope
$builder->where($model->getTable() . '.type', '=', $type);
}
/**
* Check if scope exists.
*
* @param \Illuminate\Database\Eloquent\Builder $builder
* @param $column
* @return boolean
*/
protected function exists($builder, $column)
{
$query = $builder->getQuery();
foreach ((array) $query->wheres as $key => $where) {
if (empty($where) || empty($where['column'])) {
continue;
}
if (strstr($where['column'], '.')) {
$whr = explode('.', $where['column']);
$where['column'] = $whr[1];
}
if ($where['column'] != $column) {
continue;
}
return true;
}
return false;
} }
} }

View File

@ -0,0 +1,25 @@
<?php
namespace App\Scopes;
use App\Traits\Scopes;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Scope;
class Transaction implements Scope
{
use Scopes;
/**
* Apply the scope to a given Eloquent query builder.
*
* @param \Illuminate\Database\Eloquent\Builder $builder
* @param \Illuminate\Database\Eloquent\Model $model
* @return void
*/
public function apply(Builder $builder, Model $model)
{
$this->applyTypeScope($builder, $model);
}
}

View File

@ -2,6 +2,7 @@
namespace App\Traits; namespace App\Traits;
use App\Events\Auth\ApiPermissionsAssigning;
use App\Models\Auth\Permission; use App\Models\Auth\Permission;
use App\Models\Auth\Role; use App\Models\Auth\Role;
use App\Utilities\Reports; use App\Utilities\Reports;
@ -401,6 +402,17 @@ trait Permissions
return; return;
} }
$table = request()->is('api/*') ? request()->segment(2) : '';
// Fire event to find the proper controller for common API endpoints
if (in_array($table, ['contacts', 'documents', 'transactions'])) {
$p = new \stdClass();
$p->controller = '';
event(new ApiPermissionsAssigning($p, $table, request()->get('type')));
$controller = $p->controller;
} else {
$route = app(Route::class); $route = app(Route::class);
// Get the controller array // Get the controller array
@ -430,6 +442,7 @@ trait Permissions
if (in_array($controller, $skip)) { if (in_array($controller, $skip)) {
return; return;
} }
}
// App\Http\Controllers\FooBar -->> foo-bar // App\Http\Controllers\FooBar -->> foo-bar
// App\Http\Controllers\FooBar\Main -->> foo-bar-main // App\Http\Controllers\FooBar\Main -->> foo-bar-main

62
app/Traits/Scopes.php Normal file
View File

@ -0,0 +1,62 @@
<?php
namespace App\Traits;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Str;
trait Scopes
{
/**
* Apply the scope to a given Eloquent query builder.
*
* @param \Illuminate\Database\Eloquent\Builder $builder
* @param \Illuminate\Database\Eloquent\Model $model
* @return void
*/
public function applyTypeScope(Builder $builder, Model $model)
{
// Skip if already exists
if ($this->scopeExists($builder, 'type')) {
return;
}
$type = request()->get('type') ?: Str::singular(request()->segment(2, ''));
// Apply type scope
$builder->where($model->getTable() . '.type', '=', $type);
}
/**
* Check if scope exists.
*
* @param \Illuminate\Database\Eloquent\Builder $builder
* @param $column
* @return boolean
*/
public function scopeExists($builder, $column)
{
$query = $builder->getQuery();
foreach ((array) $query->wheres as $key => $where) {
if (empty($where) || empty($where['column'])) {
continue;
}
if (strstr($where['column'], '.')) {
$whr = explode('.', $where['column']);
$where['column'] = $whr[1];
}
if ($where['column'] != $column) {
continue;
}
return true;
}
return false;
}
}