204 lines
7 KiB
PHP
204 lines
7 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\Back;
|
|
|
|
use App\Http\Requests\Back\ModelAccessRequest;
|
|
use App\Http\Requests\Back\ModelListRequest;
|
|
use App\Http\Requests\Back\RetrieveDataFromTokenRequest;
|
|
use App\Http\Requests\Back\UploadFileRequest;
|
|
use Illuminate\Support\Facades\Crypt;
|
|
use Illuminate\Support\Str;
|
|
use Uwil\LaravelCommon\Controllers\Controller;
|
|
use Uwil\LaravelCommon\Helpers\CollectionHelper;
|
|
use Uwil\LaravelCommon\Helpers\FileHelper;
|
|
|
|
class InputsController extends Controller
|
|
{
|
|
/**
|
|
* Get class from table name.
|
|
*
|
|
* @param string $tableName
|
|
* @return string|null
|
|
*/
|
|
private function getClassFromTableName(string $tableName): ?string
|
|
{
|
|
$class = '\\App\\Models\\' . Str::studly(Str::singular($tableName));
|
|
return class_exists($class) ? $class : null;
|
|
}
|
|
|
|
/**
|
|
* Get a paginate collection from specific model.
|
|
*
|
|
* @param \App\Http\Requests\Back\ModelListRequest $request
|
|
* @return \Illuminate\Http\JsonResponse
|
|
*/
|
|
public function modelList(ModelListRequest $request): \Illuminate\Http\JsonResponse
|
|
{
|
|
// Validated data from request.
|
|
$validated = $request->validated();
|
|
|
|
// Get the class of the target model and verify its existence.
|
|
$modelClass = $this->getClassFromTableName($validated['model']);
|
|
if (!$modelClass) {
|
|
return response()->json(['error' => 'Invalid model class'], 404);
|
|
}
|
|
|
|
// Determine the field to display.
|
|
$model = new $modelClass();
|
|
$isTranslatable = method_exists($model, 'getTranslations');
|
|
|
|
$locale = app()->getLocale();
|
|
|
|
$field = $validated['field'] ?? null;
|
|
if (!$field) {
|
|
$field = collect(['title', 'name', 'label'])
|
|
->first(fn($f) => in_array($f, $model->getFillable(), true))
|
|
?? $model->getKeyName();
|
|
}
|
|
|
|
$getValue = function ($item) use ($field, $locale, $isTranslatable) {
|
|
if ($isTranslatable) {
|
|
return $item->getTranslation($field, $locale, false);
|
|
}
|
|
|
|
return data_get($item, $field);
|
|
};
|
|
|
|
// Fetch all cached models once.
|
|
$allItems = $modelClass::getModelsCached()->filter(function ($item) use ($getValue) {
|
|
return filled($getValue($item));
|
|
});
|
|
|
|
// Apply search and exclude filters.
|
|
$items = $allItems
|
|
->when(!empty($validated['exclude']), function ($collection) use ($validated) {
|
|
return $collection->reject(fn($item) => $item->id == $validated['exclude']);
|
|
})
|
|
->when(!empty($validated['search']), function ($collection) use ($validated, $getValue) {
|
|
return $collection->filter(function ($item) use ($validated, $getValue) {
|
|
$value = $getValue($item);
|
|
return is_string($value)
|
|
&& Str::contains(Str::lower($value), Str::lower($validated['search']));
|
|
});
|
|
})
|
|
->sortBy(fn ($item) => $getValue($item))
|
|
->values();
|
|
|
|
// Paginate manually.
|
|
$itemsPaginate = CollectionHelper::paginateManually(
|
|
$items,
|
|
$validated['pageSize'],
|
|
$validated['page']
|
|
);
|
|
|
|
$selectedValue = null;
|
|
// Get selected model.
|
|
if (isset($validated['selectedIds'])) {
|
|
$selectedValue = $allItems->whereIn('id', $validated['selectedIds']);
|
|
}
|
|
return response()->json([
|
|
'items' => $itemsPaginate,
|
|
'field' => $field,
|
|
'model' => $selectedValue,
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Get access models.
|
|
*
|
|
* @param \App\Http\Requests\Back\ModelAccessRequest $request
|
|
* @return \Illuminate\Http\JsonResponse
|
|
*/
|
|
public function modelAccess(ModelAccessRequest $request): \Illuminate\Http\JsonResponse
|
|
{
|
|
$validated = $request->validated();
|
|
$modelClass = $this->getClassFromTableName($validated['modelName']);
|
|
if (!$modelClass) {
|
|
return response()->json(['error' => 'Invalid model class'], 404);
|
|
}
|
|
|
|
$url = (method_exists($modelClass, 'getAccessModel'))
|
|
? $modelClass::getAccessModel($validated['selectedEntry'])
|
|
: self::getAccessModel($validated['selectedEntry'], $validated['modelName']);
|
|
|
|
$token = Crypt::encryptString(json_encode([
|
|
'modelName' => $validated['modelName'],
|
|
'modelId' => $validated['selectedEntry'],
|
|
]));
|
|
|
|
|
|
return response()->json([
|
|
'url' => $url,
|
|
'token' => $token,
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Get the url to access a specific resource.
|
|
*
|
|
* @param integer $modelId Id of the target model.
|
|
* @param string $modelName Name of the target model.
|
|
* @return string|null
|
|
*/
|
|
private function getAccessModel(int $modelId, string $modelName): string|null
|
|
{
|
|
$targetModel = $this->getClassFromTableName($modelName)::getModelsCached()->firstWhere('id', $modelId);
|
|
if (!$targetModel) {
|
|
return null;
|
|
}
|
|
return parse_url(route("front.$modelName.show", $targetModel->slug), PHP_URL_PATH) ?? "/";
|
|
}
|
|
|
|
/**
|
|
* Retrieve some data from specific token.
|
|
*
|
|
* @param \App\Http\Requests\Back\RetrieveDataFromTokenRequest $request
|
|
* @return \Illuminate\Http\JsonResponse
|
|
*/
|
|
public function retrieveDataFromToken(RetrieveDataFromTokenRequest $request): \Illuminate\Http\JsonResponse
|
|
{
|
|
$validated = $request->validated();
|
|
$payload = json_decode(Crypt::decryptString($validated['token']), true);
|
|
|
|
$modelClass = $this->getClassFromTableName($payload['modelName']);
|
|
$modelId = null;
|
|
|
|
if ($modelClass && $modelClass::getModelsCached()->contains('id', $payload['modelId'])) {
|
|
$modelId = $payload['modelId'];
|
|
}
|
|
|
|
return response()->json([
|
|
'modelName' => $payload['modelName'],
|
|
'modelId' => $modelId,
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Upload a file sent in a request.
|
|
* Used for picture upload in CKEditor.
|
|
*
|
|
* @param \App\Http\Requests\Back\UploadFileRequest $request
|
|
* @return \Illuminate\Http\JsonResponse
|
|
*/
|
|
public function uploadFile(UploadFileRequest $request): \Illuminate\Http\JsonResponse
|
|
{
|
|
// Get the class of the target model and verify its existence.
|
|
$modelName = Str::singular($request->validated()['folder']);
|
|
$modelClass = "App\\Models\\$modelName";
|
|
if (!class_exists($modelClass)) {
|
|
return response()->json(['error' => 'Invalid model class'], 404);
|
|
}
|
|
|
|
// Get a new instance of the model.
|
|
$model = new $modelClass();
|
|
|
|
/** @var \Illuminate\Http\UploadedFile $image Get the file from the request data. */
|
|
$image = $request->file('upload');
|
|
|
|
// Store the uploaded file.
|
|
$path = FileHelper::storeFile($model, $image, true, private: false);
|
|
|
|
// Return the path of the file.
|
|
return response()->json(['url' => "/{$path}"]);
|
|
}
|
|
}
|