<?php
namespace App\Repositories\Base;
use App\Repositories\User\UserInterface;
use App\Services\UploadService;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Http\UploadedFile;
use Storage;
class BaseRepository implements BaseInterface
{
/**
* @var Model
*/
protected Model $model;
protected string $uploadFolder;
/**
* BaseRepository constructor.
*
* @param Model $model
* @param string $folder
*/
public function __construct(Model $model, string $folder = '/')
{
$this->model = $model;
$this->uploadFolder = $folder;
}
public function defaultModel()
{
return $this->model;
}
/**
* @param array $columns
* @param array $relations
* @param array $where
* @return Collection
*/
public function all(array $columns = ['*'], array $relations = [], array $where = []): Collection
{
return $this->defaultModel()->with($relations)->where($where)->get($columns);
}
/**
* Get all trashed models.
*
* @return Collection
*/
public function allTrashed(): Collection
{
return $this->defaultModel()->onlyTrashed()->get();
}
/**
* Find model by id.
*
* @param int $modelId
* @param array $columns
* @param array $relations
* @param array $appends
* @return Model|null
*/
public function findById(int $modelId, array $columns = ['*'], array $relations = [], array $appends = []): ?Model
{
return $this->defaultModel()->select($columns)->with($relations)->findOrFail($modelId)->append($appends);
}
/**
* Find trashed model by id.
*
* @param int $modelId
* @return Model|null
*/
public function findTrashedById(int $modelId): ?Model
{
return $this->defaultModel()->withTrashed()->findOrFail($modelId);
}
/**
* Find only trashed model by id.
*
* @param int $modelId
* @return Model|null
*/
public function findOnlyTrashedById(int $modelId): ?Model
{
return $this->defaultModel()->onlyTrashed()->findOrFail($modelId);
}
/**
* Create a model.
*
* @param array $payload
* @return Model|null
*/
public function create(array $payload): ?Model
{
foreach ($payload as $column => $value) {
if ($value instanceof UploadedFile) {
$payload[$column] = UploadService::upload($value, $this->uploadFolder);
}
}
return $this->defaultModel()->create($payload);
// ->fresh()
}
/**
* Create a model.
*
* @param array $payload
* @return bool
*/
public function createBulk(array $payload): bool
{
foreach ($payload as $key => $arr) {
foreach ($arr as $column => $value) {
if ($value instanceof UploadedFile) {
$payload[$key][$column] = UploadService::upload($value, $this->uploadFolder);
}
}
$payload[$key]['created_at'] = now();
$payload[$key]['updated_at'] = now();
}
return $this->defaultModel()->insert($payload);
}
/**
* Update existing model.
*
* @param int $modelId
* @param array $payload
* @return Model|null
*/
public function update(int $modelId, array $payload): ?Model
{
$model = $this->findById($modelId);
foreach ($payload as $column => $value) {
if ($value instanceof UploadedFile) {
if ($model->getAttributes()[$column]) {
UploadService::delete($model->getAttributes()[$column]);
}
$payload[$column] = UploadService::upload($value, $this->uploadFolder);
}
}
$model->update($payload);
return $model;
}
/**
* Update existing model.
*
* @param array $uniqueColumns
* @param array $updatingColumn Names of the columns which will be updated
* @return Model
*/
public function updateOrCreate(array $uniqueColumns, array $updatingColumn): Model
{
foreach ($updatingColumn as $column => $value) {
if ($value instanceof UploadedFile) {
$updatingColumn[$column] = UploadService::upload($value, $this->uploadFolder);
}
}
return $this->defaultModel()->updateOrCreate($uniqueColumns, $updatingColumn);
}
/**
* Update existing model.
*
* @param array $payloads
* @param array $uniqueColumns
* @param array $updatingColumn Names of the columns which will be updated
* @return bool
*/
public function upsert(array $payloads, array $uniqueColumns, array $updatingColumn): bool
{
foreach ($payloads as $key => $payload) {
foreach ($payload as $column => $value) {
if ($value instanceof UploadedFile) {
$payloads[$key][$column] = UploadService::upload($value, $this->uploadFolder);
}
}
}
return $this->defaultModel()->upsert($payloads, $uniqueColumns, $updatingColumn);
}
/**
* Delete model by id.
*
* @param int $modelId
* @return bool
*/
public function deleteById(int $modelId): bool
{
return $this->findById($modelId)->delete();
}
/**
* Restore model by id.
*
* @param int $modelId
* @return void
*/
public function restoreById(int $modelId): void
{
$this->findOnlyTrashedById($modelId)->restore();
}
/**
* Permanently delete model by id.
*
* @param int $modelId
* @return bool
*/
public function permanentlyDeleteById(int $modelId): bool
{
return $this->findTrashedById($modelId)->forceDelete();
}
/**
* Returns the builder so that you can use your own conditions and functions.
*
* @return Model|Builder
*/
public function builder(): Model|Builder
{
return $this->defaultModel();
}
/**
* Returns the new model instance so that you can use your own conditions and functions.
*
* @return Model
*/
public function model(): Model
{
return new $this->model();
}
public function upsertProfile(array $payloads, array $uniqueColumns, array $updatingColumn): bool
{
$existingRecords = $this->defaultModel()->whereIn($uniqueColumns[0], array_column($payloads, $uniqueColumns[0]))->get();
foreach ($existingRecords as $key => $row) {
if ($row->image && $row->getRawOriginal('image')) {
if (Storage::disk('public')->exists($row->getRawOriginal('image'))) {
Storage::disk('public')->delete($row->getRawOriginal('image'));
}
}
}
foreach ($payloads as $key => $payload) {
foreach ($payload as $column => $value) {
if ($value instanceof UploadedFile) {
$payloads[$key][$column] = UploadService::upload($value, $this->uploadFolder);
}
}
}
return $this->defaultModel()->upsert($payloads, $uniqueColumns, $updatingColumn);
}
}