Create a% base% base that will serve as a contract for all other Repository classes in your program, example :
<?php namespace App\Repositories\Base;
interface IRepositoryBase
{
public function create(array $data);
public function edit(array $data, $id);
public function find($id);
public function all();
public function delete($id);
}
With this interface
create your abstract base class with the basic commands of a interface
:
<?php namespace App\Repositories\Base;
use Illuminate\Database\Eloquent\Model;
abstract class RepositoryBase implements IRepositoryBase
{
protected $model;
public function __construct($model)
{
if (($model instanceof Model) === false)
throw new \Exception("Model is invalid");
$this->model = $model;
}
public function create(array $array)
{
return $this->model->create($array);
}
public function edit(array $array, $id)
{
$m = $this->find($id);
if ($m)
{
$m->fill($array);
if ($m->save()) return $m;
}
return null;
}
public function find($id)
{
return $this->model->find($id);
}
public function delete($id)
{
$m = $this->find($id);
if ($m) return $m->delete();
return false;
}
public function all()
{
return $this->model->all();
}
}
This code will be used by all its entity classes, ie for each entity ( CRUD
) it will have an abstract base class and a concrete one for its instance, examples :
User
Model User
<?php namespace App\Models;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
use Notifiable;
protected $table = "users";
protected $fillable = ['name', 'email', 'password'];
protected $hidden = ['password', 'remember_token'];
}
Abstract base class:
<?php namespace App\Repositories\Base;
use App\Models\User;
abstract class RepositoryUserBase extends RepositoryBase implements IRepositoryBase
{
public function __construct(User $model)
{
parent::__construct($model);
}
}
Concrete class:
<?php namespace App\Repositories;
use App\Repositories\Base\RepositoryUserBase;
class RepositoryUser extends RepositoryUserBase
{
}
Notice
Model Notice
<?php namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Notice extends Model
{
protected $table = "notices";
protected $primaryKey = "id";
protected $fillable = ['title'];
}
Abstract base class:
<?php namespace App\Repositories\Base;
use App\Models\Notice;
abstract class RepositoryNoticeBase extends RepositoryBase implements IRepositoryBase
{
public function __construct(Notice $model)
{
parent::__construct($model);
}
}
Concrete class:
<?php namespace App\Repositories;
use App\Repositories\Base\RepositoryNoticeBase;
class RepositoryNotice extends RepositoryNoticeBase
{
}
Note that the constructor of the Illuminate\Database\Eloquent\Model
and RepositoryNoticeBase
classes being passed to its class corresponds, respectively, RepositoryUserBase
and Notice
, and all code made in the base is equal to its spelling and standardization, internally belongs to its User
configuration that is set in the constructor of each base class and belongs to its given table, so for each new Repository created that is changed from one to the other and also the class names that must follow the same logic that the two of them followed. This guarantees the non-repetition of coding that is in your question, of course, also this model can be further improved, this would be an initial default.
In order to set% dependency injection and Dependency Injection open the file in the Model
folder and set it as follows in the Container
method:
<?php namespace App\Providers;
use App\Repositories\Base\RepositoryNoticeBase;
use App\Repositories\Base\RepositoryUserBase;
use App\Repositories\RepositoryNotice;
use App\Repositories\RepositoryUser;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
public function boot()
{
}
public function register()
{
//
app()->singleton(RepositoryNoticeBase::class, RepositoryNotice::class);
app()->singleton(RepositoryUserBase::class, RepositoryUser::class);
}
}
Why do that?
For injection to work in the constructors or methods of the app\Providers\AppServiceProvider.php
class of your application, eg
<?php namespace App\Http\Controllers;
use App\Repositories\Base\RepositoryNoticeBase;
use App\Repositories\Base\RepositoryUserBase;
use Illuminate\Http\Request;
class TestController extends Controller
{
private $notice;
private $user;
private $request;
public function __construct(
RepositoryNoticeBase $notice,
RepositoryUserBase $user,
Request $request)
{
$this->notice = $notice;
$this->user = $user;
$this->request = $request;
}
public function index()
{
return $this->user->all();
}
}
If you do not want to do this part, just put the Concrete class directly in the constructors or methods instead of the base classes, example :
<?php namespace App\Http\Controllers;
use App\Repositories\Base\RepositoryNoticeBase;
use App\Repositories\Base\RepositoryUserBase;
use Illuminate\Http\Request;
class TestController extends Controller
{
private $notice;
private $user;
private $request;
public function __construct(
RepositoryNotice $notice,
RepositoryUser $user,
Request $request)
{
$this->notice = $notice;
$this->user = $user;
$this->request = $request;
}
public function index()
{
return $this->user->all();
}
}
that will have the same effect.