This commit is contained in:
2024-09-01 18:54:23 +05:00
parent 76d18365a5
commit 061f09eca1
1597 changed files with 109451 additions and 1 deletions

View File

@@ -0,0 +1,306 @@
<?php
namespace Laravel\Nova\Http\Requests;
use Closure;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Arr;
use Laravel\Nova\Actions\ActionModelCollection;
use Laravel\Nova\Fields\ActionFields;
use Laravel\Nova\Fields\FieldCollection;
use Laravel\Nova\Support\Fluent;
/**
* @property-read string|null $resources
* @property-read string|null $pivotAction
*/
class ActionRequest extends NovaRequest
{
use QueriesResources;
/**
* Get the action instance specified by the request.
*
* @return \Laravel\Nova\Actions\Action|\Laravel\Nova\Actions\DestructiveAction
*/
public function action()
{
return once(function () {
$hasResources = ! empty($this->resources);
return $this->availableActions()
->filter(function ($action) use ($hasResources) {
return $hasResources ? true : $action->isStandalone();
})->first(function ($action) {
return $action->uriKey() == $this->query('action');
}) ?: abort($this->actionExists() ? 403 : 404);
});
}
/**
* Get the all actions for the request.
*
* @return \Illuminate\Support\Collection
*/
protected function resolveActions()
{
return $this->isPivotAction()
? $this->newResource()->resolvePivotActions($this)
: $this->newResource()->resolveActions($this);
}
/**
* Get the possible actions for the request.
*
* @return \Illuminate\Support\Collection
*/
protected function availableActions()
{
return $this->resolveActions()->filter->authorizedToSee($this)->values();
}
/**
* Determine if the specified action exists at all.
*
* @return bool
*/
protected function actionExists()
{
return $this->resolveActions()->contains(function ($action) {
return $action->uriKey() == $this->query('action');
});
}
/**
* Determine if the action being executed is a pivot action.
*
* @return bool
*/
public function isPivotAction()
{
return $this->pivotAction === 'true';
}
/**
* Get the selected models for the action in chunks.
*
* @param int $count
* @param \Closure(\Laravel\Nova\Actions\ActionModelCollection):mixed $callback
* @return mixed
*/
public function chunks($count, Closure $callback)
{
$output = [];
$this->toSelectedResourceQuery()
->cursor()
->chunk($count)
->each(function ($chunk) use ($callback, &$output) {
$output[] = $callback($this->mapChunk($chunk));
});
return $output;
}
/**
* Get the query for the models that were selected by the user.
*
* @return \Illuminate\Database\Eloquent\Builder
*/
public function toSelectedResourceQuery()
{
if ($this->allResourcesSelected()) {
return $this->toQuery();
}
$query = $this->viaRelationship()
? $this->modelsViaRelationship()
: $this->toQueryWithoutScopes()->whereKey(Arr::wrap($this->resources));
return $query->tap(function ($query) {
$query->latest($this->model()->getQualifiedKeyName());
});
}
/**
* Transform the request into a query without scope.
*
* @return \Illuminate\Database\Eloquent\Builder
*/
public function toQueryWithoutScopes()
{
return tap($this->newQueryWithoutScopes(), function ($query) {
$resource = $this->resource();
$query->with($resource::$with);
if (! $this->allResourcesSelected() && $this->selectedResourceIds()->count() === 1) {
$resource::detailQuery($this, $query);
} else {
$resource::indexQuery($this, $query);
}
});
}
/**
* Get the query for the related models that were selected by the user.
*
* @return \Illuminate\Database\Eloquent\Builder
*/
protected function modelsViaRelationship()
{
$relation = tap($this->findParentResource(), function ($resource) {
abort_unless($resource->hasRelatableField($this, $this->viaRelationship), 404);
})->model()->{$this->viaRelationship}()->withoutGlobalScopes();
if (isset($this->pivots) && ! empty($this->pivots)) {
/** @var class-string<\Illuminate\Database\Eloquent\Relations\Pivot> $pivotClass */
$pivotClass = $relation->getPivotClass();
$relation->wherePivotIn((new $pivotClass())->getKeyName(), Arr::wrap($this->pivots));
}
return $relation->whereIn($this->model()->getQualifiedKeyName(), Arr::wrap($this->resources));
}
/**
* Map the chunk of models into an appropriate state.
*
* @param \Illuminate\Support\LazyCollection|\Illuminate\Database\Eloquent\Collection $chunk
* @return \Laravel\Nova\Actions\ActionModelCollection
*/
protected function mapChunk($chunk)
{
return ActionModelCollection::make(
$this->isPivotAction()
? $chunk->map->{$this->pivotRelation()->getPivotAccessor()}
: $chunk
);
}
/**
* Validate the given fields.
*
* @return void
*
* @throws \Illuminate\Validation\ValidationException
*/
public function validateFields()
{
$this->action()->validateFields($this);
}
/**
* Resolve the fields for database storage using the request.
*
* @return array
*/
public function resolveFieldsForStorage()
{
return collect($this->resolveFields()->getAttributes())->map(function ($attribute) {
return $attribute instanceof UploadedFile ? $attribute->hashName() : $attribute;
})->all();
}
/**
* Resolve the fields using the request.
*
* @return \Laravel\Nova\Fields\ActionFields
*/
public function resolveFields()
{
return once(function () {
$fields = new Fluent;
$results = FieldCollection::make($this->action()->fields($this))
->authorized($this)
->applyDependsOn($this)
->withoutReadonly($this)
->withoutUnfillable()
->mapWithKeys(function ($field) use ($fields) {
return [$field->attribute => $field->fillForAction($this, $fields)];
});
return new ActionFields(collect($fields->getAttributes()), $results->filter(function ($field) {
return is_callable($field);
}));
});
}
/**
* Get the key of model that lists the action on its dashboard.
*
* When running pivot actions, this is the key of the owning model.
*
* @param \Illuminate\Database\Eloquent\Model $model
* @return int
*/
public function actionableKey($model)
{
return $this->isPivotAction()
? $model->{$this->pivotRelation()->getForeignPivotKeyName()}
: $model->getKey();
}
/**
* Get the model instance that lists the action on its dashboard.
*
* When running pivot actions, this is the owning model.
*
* @return \Illuminate\Database\Eloquent\Model
*/
public function actionableModel()
{
return $this->isPivotAction()
? $this->newViaResource()->model()
: $this->model();
}
/**
* Get the key of model that is the target of the action.
*
* When running pivot actions, this is the key of the target model.
*
* @param \Illuminate\Database\Eloquent\Model $model
* @return int
*/
public function targetKey($model)
{
return $this->isPivotAction()
? $model->{$this->pivotRelation()->getRelatedPivotKeyName()}
: $model->getKey();
}
/**
* Get an instance of the target model of the action.
*
* @return \Illuminate\Database\Eloquent\Model
*/
public function targetModel()
{
return $this->isPivotAction() ? $this->pivotRelation()->newPivot() : $this->model();
}
/**
* Get the many-to-many relationship for a pivot action.
*
* @return \Illuminate\Database\Eloquent\Relations\MorphToMany|\Illuminate\Database\Eloquent\Relations\BelongsToMany|null
*/
public function pivotRelation()
{
if ($this->isPivotAction()) {
return tap($this->newViaResource(), function ($resource) {
abort_unless($resource->hasRelatableField($this, $this->viaRelationship), 404);
})->model()->{$this->viaRelationship}();
}
}
/**
* Determine if this request is an action request.
*
* @return bool
*/
public function isActionRequest()
{
return true;
}
}

View File

@@ -0,0 +1,22 @@
<?php
namespace Laravel\Nova\Http\Requests;
class CardRequest extends NovaRequest
{
/**
* Get all of the possible metrics for the request.
*
* @return \Illuminate\Support\Collection
*/
public function availableCards()
{
$resource = $this->newResource();
if ($this->resourceId) {
return $this->newResource()->availableCardsForDetail($this);
}
return $this->newResource()->availableCards($this);
}
}

View File

@@ -0,0 +1,31 @@
<?php
namespace Laravel\Nova\Http\Requests;
trait CountsResources
{
/**
* Build a new count query for the given query.
*
* @param \Illuminate\Database\Eloquent\Builder $query
* @return \Illuminate\Database\Query\Builder
*/
public function buildCountQuery($query)
{
$baseQuery = $query->toBase();
if (empty($baseQuery->groups)) {
return $baseQuery;
}
$subQuery = $baseQuery->cloneWithout(
$baseQuery->unions ? ['orders', 'limit', 'offset'] : ['columns', 'orders', 'limit', 'offset']
)->cloneWithoutBindings(
$baseQuery->unions ? ['order'] : ['select', 'order']
)->selectRaw('1 as exists_temp');
return $query->getConnection()
->query()
->fromSub($subQuery, 'count_temp');
}
}

View File

@@ -0,0 +1,16 @@
<?php
namespace Laravel\Nova\Http\Requests;
class CreateResourceRequest extends NovaRequest
{
/**
* Determine if this request is a create or attach request.
*
* @return bool
*/
public function isCreateOrAttachRequest()
{
return true;
}
}

View File

@@ -0,0 +1,34 @@
<?php
namespace Laravel\Nova\Http\Requests;
use Laravel\Nova\Metrics\Metric;
use Laravel\Nova\Nova;
/**
* @property-read string $metric
*/
class DashboardMetricRequest extends NovaRequest
{
/**
* Get the metric instance for the given request.
*
* @return \Laravel\Nova\Metrics\Metric
*/
public function metric()
{
return $this->availableMetrics()->first(function ($metric) {
return $this->metric === $metric->uriKey();
}) ?: abort(404);
}
/**
* Get all of the possible metrics for the request.
*
* @return \Illuminate\Support\Collection
*/
public function availableMetrics()
{
return Nova::allAvailableDashboardCards($this)->whereInstanceOf(Metric::class);
}
}

View File

@@ -0,0 +1,19 @@
<?php
namespace Laravel\Nova\Http\Requests;
use Laravel\Nova\Nova;
class DashboardRequest extends NovaRequest
{
/**
* Get all of the possible cards for the request.
*
* @param string $dashboard
* @return \Illuminate\Support\Collection
*/
public function availableCards($dashboard)
{
return Nova::availableDashboardCardsForDashboard($dashboard, $this);
}
}

View File

@@ -0,0 +1,31 @@
<?php
namespace Laravel\Nova\Http\Requests;
use Laravel\Nova\Filters\FilterDecoder;
/**
* @property-read string $filters
*/
trait DecodesFilters
{
/**
* Get the filters for the request.
*
* @return \Illuminate\Support\Collection
*/
public function filters()
{
return (new FilterDecoder($this->filters, $this->availableFilters()))->filters();
}
/**
* Get all of the possibly available filters for the request.
*
* @return \Illuminate\Support\Collection
*/
protected function availableFilters()
{
return $this->newResource()->availableFilters($this);
}
}

View File

@@ -0,0 +1,37 @@
<?php
namespace Laravel\Nova\Http\Requests;
use Closure;
use Illuminate\Support\Collection;
class DeleteLensResourceRequest extends LensResourceDeletionRequest
{
/**
* Get the selected models for the action in chunks.
*
* @param int $count
* @param \Closure(\Illuminate\Support\Collection):void $callback
* @return mixed
*/
public function chunks($count, Closure $callback)
{
return $this->chunkWithAuthorization($count, $callback, function ($models) {
return $this->deletableModels($models);
});
}
/**
* Get the models that may be deleted.
*
* @param \Illuminate\Support\Collection $models
* @return \Illuminate\Support\Collection
*/
protected function deletableModels(Collection $models)
{
return $models->mapInto($this->resource())
->filter
->authorizedToDelete($this)
->map->model();
}
}

View File

@@ -0,0 +1,50 @@
<?php
namespace Laravel\Nova\Http\Requests;
use Closure;
use Illuminate\Support\Collection;
/**
* @property-read string|array<int, mixed> $resources
*/
class DeleteResourceRequest extends DeletionRequest
{
/**
* Get the selected models for the action in chunks.
*
* @param int $count
* @param \Closure(\Illuminate\Support\Collection):void $callback
* @return mixed
*/
public function chunks($count, Closure $callback)
{
return $this->chunkWithAuthorization($count, $callback, function ($models) {
return $this->deletableModels($models);
});
}
/**
* Get the models that may be deleted.
*
* @param \Illuminate\Support\Collection $models
* @return \Illuminate\Support\Collection
*/
protected function deletableModels(Collection $models)
{
return $models->mapInto($this->resource())
->filter
->authorizedToDelete($this)
->map->model();
}
/**
* Determine if the request is for a single resource only.
*
* @return bool
*/
public function isForSingleResource()
{
return $this->resources !== 'all' && count($this->resources) == 1;
}
}

View File

@@ -0,0 +1,52 @@
<?php
namespace Laravel\Nova\Http\Requests;
use Closure;
/**
* @property-read string|array<int, mixed> $resources
*/
class DeletionRequest extends NovaRequest
{
use QueriesResources;
/**
* Get the selected models for the action in chunks.
*
* @param int $count
* @param \Closure(\Illuminate\Support\Collection):void $callback
* @param \Closure(\Illuminate\Support\Collection):\Illuminate\Support\Collection $authCallback
* @return mixed
*/
protected function chunkWithAuthorization($count, Closure $callback, Closure $authCallback)
{
$model = $this->model();
$this->toSelectedResourceQuery()->when(! $this->allResourcesSelected(), function ($query) {
$query->whereKey($this->resources);
})->tap(function ($query) {
$query->getQuery()->orders = [];
})->chunkById($count, function ($models) use ($callback, $authCallback) {
$models = $authCallback($models);
if ($models->isNotEmpty()) {
$callback($models);
}
}, $model->getQualifiedKeyName(), $model->getKeyName());
}
/**
* Get the query for the models that were selected by the user.
*
* @return \Illuminate\Database\Eloquent\Builder
*/
protected function toSelectedResourceQuery()
{
if ($this->allResourcesSelected()) {
return $this->toQuery();
}
return $this->newQueryWithoutScopes();
}
}

View File

@@ -0,0 +1,46 @@
<?php
namespace Laravel\Nova\Http\Requests;
use Closure;
use Illuminate\Support\Collection;
class DetachResourceRequest extends DeletionRequest
{
/**
* Get the selected models for the action in chunks.
*
* @param int $count
* @param \Closure(\Illuminate\Support\Collection):void $callback
* @return mixed
*/
public function chunks($count, Closure $callback)
{
$parentResource = $this->findParentResourceOrFail();
$model = $this->model();
$this->toSelectedResourceQuery()->when(! $this->allResourcesSelected(), function ($query) {
$query->whereKey($this->resources);
})->chunkById($count, function ($models) use ($callback, $parentResource) {
$models = $this->detachableModels($models, $parentResource);
if ($models->isNotEmpty()) {
$callback($models);
}
}, $model->getQualifiedKeyName(), $model->getKeyName());
}
/**
* Get the models that may be detached.
*
* @param \Illuminate\Support\Collection $models
* @param \Laravel\Nova\Resource $parentResource
* @return \Illuminate\Support\Collection
*/
protected function detachableModels(Collection $models, $parentResource)
{
return $models->filter(function ($model) use ($parentResource) {
return $parentResource->authorizedToDetach($this, $model, $this->viaRelationship);
});
}
}

View File

@@ -0,0 +1,37 @@
<?php
namespace Laravel\Nova\Http\Requests;
use Closure;
use Illuminate\Support\Collection;
class ForceDeleteLensResourceRequest extends LensResourceDeletionRequest
{
/**
* Get the selected models for the action in chunks.
*
* @param int $count
* @param \Closure(\Illuminate\Support\Collection):void $callback
* @return mixed
*/
public function chunks($count, Closure $callback)
{
return $this->chunkWithAuthorization($count, $callback, function ($models) {
return $this->deletableModels($models);
});
}
/**
* Get the models that may be deleted.
*
* @param \Illuminate\Support\Collection $models
* @return \Illuminate\Support\Collection
*/
protected function deletableModels(Collection $models)
{
return $models->mapInto($this->resource())
->filter
->authorizedToForceDelete($this)
->map->model();
}
}

View File

@@ -0,0 +1,47 @@
<?php
namespace Laravel\Nova\Http\Requests;
use Closure;
use Illuminate\Support\Collection;
class ForceDeleteResourceRequest extends DeletionRequest
{
/**
* Get the selected models for the action in chunks.
*
* @param int $count
* @param \Closure(\Illuminate\Support\Collection):void $callback
* @return mixed
*/
public function chunks($count, Closure $callback)
{
return $this->chunkWithAuthorization($count, $callback, function ($models) {
return $this->deletableModels($models);
});
}
/**
* Get the models that may be deleted.
*
* @param \Illuminate\Support\Collection $models
* @return \Illuminate\Support\Collection
*/
protected function deletableModels(Collection $models)
{
return $models->mapInto($this->resource())
->filter
->authorizedToForceDelete($this)
->map->model();
}
/**
* Determine if the request is for a single resource only.
*
* @return bool
*/
public function isForSingleResource()
{
return $this->resources !== 'all' && count($this->resources) == 1;
}
}

View File

@@ -0,0 +1,8 @@
<?php
namespace Laravel\Nova\Http\Requests;
class GlobalSearchRequest extends NovaRequest
{
//
}

View File

@@ -0,0 +1,63 @@
<?php
namespace Laravel\Nova\Http\Requests;
use Laravel\Nova\Query\Search;
/**
* @property-read string|null $lens
*/
trait InteractsWithLenses
{
/**
* Get the lens instance for the given request.
*
* @return \Laravel\Nova\Lenses\Lens
*/
public function lens()
{
return $this->availableLenses()->first(function ($lens) {
return $this->lens === $lens->uriKey();
}) ?: abort($this->lensExists() ? 403 : 404);
}
/**
* Get all of the possible lenses for the request.
*
* @return \Illuminate\Support\Collection
*/
public function availableLenses()
{
return transform($this->newResource(), function ($resource) {
abort_unless($resource::authorizedToViewAny($this), 403);
return $resource->availableLenses($this);
});
}
/**
* Transform the request into a search query.
*
* @return \Illuminate\Database\Eloquent\Builder
*/
public function newSearchQuery()
{
$lens = $this->lens();
return $lens::searchable() && ! empty($this->search)
? (new Search($this->newQuery(), $this->search))->handle($this->resource(), $lens->searchableColumns())
: $this->newQuery();
}
/**
* Determine if the specified action exists at all.
*
* @return bool
*/
protected function lensExists()
{
return $this->newResource()->resolveLenses($this)->contains(function ($lens) {
return $this->lens === $lens->uriKey();
});
}
}

View File

@@ -0,0 +1,230 @@
<?php
namespace Laravel\Nova\Http\Requests;
use Laravel\Nova\Nova;
use Laravel\Nova\Resource;
trait InteractsWithRelatedResources
{
/**
* Find the parent resource model instance for the request.
*
* @param string|int|null $resourceId
* @return \Laravel\Nova\Resource
*/
public function findParentResource($resourceId = null)
{
$resource = $this->viaResource();
return new $resource($this->findParentModel($resourceId));
}
/**
* Find the parent resource model instance for the request.
*
* @param string|int|null $resourceId
* @return \Laravel\Nova\Resource<\Illuminate\Database\Eloquent\Model>
*
* @throws \Illuminate\Database\Eloquent\ModelNotFoundException
*/
public function findParentResourceOrFail($resourceId = null)
{
$resource = $this->viaResource();
return new $resource($this->findParentModelOrFail($resourceId));
}
/**
* Find the parent resource model instance for the request.
*
* @param string|int|null $resourceId
* @return \Illuminate\Database\Eloquent\Model|null
*/
public function findParentModel($resourceId = null)
{
if (! $this->viaRelationship()) {
return null;
}
return rescue(function () use ($resourceId) {
return $this->findParentModelOrFail($resourceId);
}, Nova::modelInstanceForKey($this->viaResource), false);
}
/**
* Find the parent resource model instance for the request or abort.
*
* @param string|int|null $resourceId
* @return \Illuminate\Database\Eloquent\Model
*
* @throws \Illuminate\Database\Eloquent\ModelNotFoundException
*/
public function findParentModelOrFail($resourceId = null)
{
$query = Nova::modelInstanceForKey($this->viaResource)->newQueryWithoutScopes();
if (! is_null($resourceId)) {
return $query->whereKey($resourceId)->firstOrFail();
}
return once(function () use ($query) {
return $query->findOrFail($this->viaResourceId);
});
}
/**
* Find the related resource instance for the request.
*
* @param string|int|null $resourceId
* @return \Laravel\Nova\Resource
*/
public function findRelatedResource($resourceId = null)
{
$resource = $this->relatedResource();
return new $resource($this->findRelatedModel($resourceId));
}
/**
* Find the related resource instance for the request or abort.
*
* @param string|int|null $resourceId
* @return \Laravel\Nova\Resource<\Illuminate\Database\Eloquent\Model>
*
* @throws \Illuminate\Database\Eloquent\ModelNotFoundException
*/
public function findRelatedResourceOrFail($resourceId = null)
{
$resource = $this->relatedResource();
return new $resource($this->findRelatedModelOrFail($resourceId));
}
/**
* Find the related resource model instance for the request.
*
* @param string|int|null $resourceId
* @return \Illuminate\Database\Eloquent\Model
*/
public function findRelatedModel($resourceId = null)
{
return rescue(function () use ($resourceId) {
return $this->findRelatedModelOrFail($resourceId);
}, Nova::modelInstanceForKey($this->relatedResource), false);
}
/**
* Find the parent resource model instance for the request or abort.
*
* @param string|int|null $resourceId
* @return \Illuminate\Database\Eloquent\Model
*
* @throws \Illuminate\Database\Eloquent\ModelNotFoundException
*/
public function findRelatedModelOrFail($resourceId = null)
{
$query = Nova::modelInstanceForKey($this->relatedResource)->newQueryWithoutScopes();
if (! is_null($resourceId)) {
return $query->whereKey($resourceId)->firstOrFail();
}
return once(function () use ($query) {
return $query->findOrFail($this->input($this->relatedResource));
});
}
/**
* Get the displayable pivot model name for a "via relationship" request.
*
* @return string
*/
public function pivotName()
{
if (! $this->viaRelationship()) {
return Resource::DEFAULT_PIVOT_NAME;
}
$resource = Nova::resourceInstanceForKey($this->viaResource);
if ($name = $resource->pivotNameForField($this, $this->viaRelationship)) {
return $name;
}
$parentResource = $this->findParentResource();
$parent = $parentResource->model();
return ($parent && $parentResource->hasRelatableField($this, $this->viaRelationship))
? class_basename($parent->{$this->viaRelationship}()->getPivotClass())
: Resource::DEFAULT_PIVOT_NAME;
}
/**
* Get the class name of the "related" resource being requested.
*
* @return class-string<\Laravel\Nova\Resource>
*/
public function relatedResource()
{
return Nova::resourceForKey($this->relatedResource);
}
/**
* Get a new instance of the "related" resource being requested.
*
* @return \Laravel\Nova\Resource<\Illuminate\Database\Eloquent\Model>
*/
public function newRelatedResource()
{
$resource = $this->relatedResource();
return new $resource($resource::newModel());
}
/**
* Get the class name of the "via" resource being requested.
*
* @return class-string<\Laravel\Nova\Resource>
*/
public function viaResource()
{
return Nova::resourceForKey($this->viaResource);
}
/**
* Get a new instance of the "via" resource being requested.
*
* @return \Laravel\Nova\Resource<\Illuminate\Database\Eloquent\Model>
*/
public function newViaResource()
{
$resource = $this->viaResource();
return new $resource($resource::newModel());
}
/**
* Determine if the request is via a relationship.
*
* @return bool
*/
public function viaRelationship()
{
return filled($this->viaResource) && filled($this->viaResourceId) && $this->viaRelationship;
}
/**
* Determine if this request is via a many-to-many relationship.
*
* @return bool
*/
public function viaManyToMany()
{
return in_array(
$this->relationshipType,
['belongsToMany', 'morphToMany']
);
}
}

View File

@@ -0,0 +1,187 @@
<?php
namespace Laravel\Nova\Http\Requests;
use Laravel\Nova\Contracts\QueryBuilder;
use Laravel\Nova\Nova;
trait InteractsWithResources
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
//
];
}
/**
* Determine if the requested resource is soft deleting.
*
* @return bool
*/
public function resourceSoftDeletes()
{
$resource = $this->resource();
return $resource::softDeletes();
}
/**
* Get the class name of the resource being requested.
*
* @return class-string<\Laravel\Nova\Resource>
*
* @throws \Symfony\Component\HttpKernel\Exception\NotFoundHttpException
*/
public function resource()
{
return tap(once(function () {
return Nova::resourceForKey($this->route('resource'));
}), function ($resource) {
abort_if(is_null($resource), 404);
});
}
/**
* Get a new instance of the resource being requested.
*
* @return \Laravel\Nova\Resource<\Illuminate\Database\Eloquent\Model>
*/
public function newResource()
{
$resource = $this->resource();
return new $resource($this->model());
}
/**
* Find the resource instance for the request or abort.
*
* @param string|int|null $resourceId
* @return \Laravel\Nova\Resource<\Illuminate\Database\Eloquent\Model>
*
* @throws \Illuminate\Database\Eloquent\ModelNotFoundException
*/
public function findResourceOrFail($resourceId = null)
{
return $this->newResourceWith($this->findModelOrFail($resourceId));
}
/**
* Find the resource instance for the request.
*
* @param string|int|null $resourceId
* @return \Laravel\Nova\Resource
*/
public function findResource($resourceId = null)
{
return $this->newResourceWith($this->findModel($resourceId));
}
/**
* Find the model instance for the request or throw an exception.
*
* @param string|int|null $resourceId
* @return \Illuminate\Database\Eloquent\Model
*
* @throws \Illuminate\Database\Eloquent\ModelNotFoundException
*/
public function findModelOrFail($resourceId = null)
{
if (! is_null($resourceId)) {
return $this->findModelQuery($resourceId)->firstOrFail();
}
return once(function () {
return $this->findModelQuery()->firstOrFail();
});
}
/**
* Find the model instance for the request.
*
* @param string|int|null $resourceId
* @return \Illuminate\Database\Eloquent\Model|null
*/
public function findModel($resourceId = null)
{
return rescue(function () use ($resourceId) {
return $this->findModelOrFail($resourceId);
}, $this->model(), false);
}
/**
* Get the query to find the model instance for the request.
*
* @param mixed|null $resourceId
* @return \Illuminate\Database\Eloquent\Builder
*/
public function findModelQuery($resourceId = null)
{
return app()->make(QueryBuilder::class, [$this->resource()])
->whereKey(
$this->newQueryWithoutScopes(),
$resourceId ?? $this->resourceId
)->toBase();
}
/**
* Get a new instance of the resource being requested.
*
* @param \Illuminate\Database\Eloquent\Model $model
* @return \Laravel\Nova\Resource<\Illuminate\Database\Eloquent\Model>
*/
public function newResourceWith($model)
{
$resource = $this->resource();
return new $resource($model);
}
/**
* Get a new query builder for the underlying model.
*
* @return \Illuminate\Database\Eloquent\Builder
*/
public function newQuery()
{
return $this->model()->newQuery();
}
/**
* Get a new, scopeless query builder for the underlying model.
*
* @return \Illuminate\Database\Eloquent\Builder
*/
public function newQueryWithoutScopes()
{
return $this->model()->newQueryWithoutScopes();
}
/**
* Get a new instance of the underlying model.
*
* @return \Illuminate\Database\Eloquent\Model
*/
public function model()
{
$resource = $this->resource();
return $resource::newModel();
}
}

View File

@@ -0,0 +1,67 @@
<?php
namespace Laravel\Nova\Http\Requests;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Arr;
/**
* @property-read int|null $resourceId
* @property-read array|string|null $resources
*/
trait InteractsWithResourcesSelection
{
/**
* Determine if currently all resources is selected.
*
* @return bool
*/
public function allResourcesSelected()
{
return $this->resources === 'all';
}
/**
* Get selected resource IDs.
*
* @return \Illuminate\Support\Collection<int, string|int>|null
*/
public function selectedResourceIds()
{
if ($this->allResourcesSelected()) {
return null;
}
$resourceIds = array_filter(! empty($this->resources) ? Arr::wrap($this->resources) : [$this->resourceId]);
if (count($resourceIds) < 1) {
return collect(
$this->resource instanceof Model ? [$this->resource->getKey()] : []
);
}
return collect($resourceIds);
}
/**
* Get selected resources.
*
* @return \Illuminate\Database\Eloquent\Collection|\Illuminate\Support\Collection|null
*/
public function selectedResources()
{
if ($this->allResourcesSelected()) {
return null;
}
$resourceIds = array_filter(! empty($this->resources) ? Arr::wrap($this->resources) : [$this->resourceId]);
if (count($resourceIds) < 1) {
return $this->resource instanceof Model ? $this->resource->newCollection() : collect();
}
return $this->newQueryWithoutScopes()
->whereKey($resourceIds)
->get();
}
}

View File

@@ -0,0 +1,47 @@
<?php
namespace Laravel\Nova\Http\Requests;
use Illuminate\Database\Eloquent\Builder;
use LogicException;
class LensActionRequest extends ActionRequest
{
use InteractsWithLenses;
/**
* Transform the request into a query.
*
* @return \Illuminate\Database\Eloquent\Builder
*/
public function toQuery()
{
return tap($this->lens()->query(LensRequest::createFrom($this), $this->newSearchQuery()), function ($query) {
if (! $query instanceof Builder) {
throw new LogicException('Lens must return an Eloquent query instance in order to apply actions.');
}
});
}
/**
* Transform the request into a query without scope.
*
* @return \Illuminate\Database\Eloquent\Builder
*/
public function toQueryWithoutScopes()
{
return $this->toQuery();
}
/**
* Get the all actions for the request.
*
* @return \Illuminate\Support\Collection
*/
protected function resolveActions()
{
return $this->isPivotAction()
? $this->lens()->resolvePivotActions($this)
: $this->lens()->resolveActions($this);
}
}

View File

@@ -0,0 +1,18 @@
<?php
namespace Laravel\Nova\Http\Requests;
class LensCardRequest extends CardRequest
{
use InteractsWithLenses;
/**
* Get all of the possible metrics for the request.
*
* @return \Illuminate\Support\Collection
*/
public function availableCards()
{
return $this->lens()->availableCards($this);
}
}

View File

@@ -0,0 +1,38 @@
<?php
namespace Laravel\Nova\Http\Requests;
use Illuminate\Database\Eloquent\Builder;
use Laravel\Nova\Exceptions\LensCountException;
class LensCountRequest extends NovaRequest
{
use CountsResources;
use InteractsWithLenses;
/**
* Get the count of the lens resources.
*
* @return int
*/
public function toCount()
{
return rescue(function () {
return $this->toQuery()->toBase()->getCountForPagination();
}, 0);
}
/**
* Transform the request into a query.
*
* @return \Illuminate\Database\Eloquent\Builder
*/
public function toQuery()
{
return tap($this->lens()->query(LensRequest::createFrom($this), $this->newSearchQuery()), function ($query) {
if (! $query instanceof Builder) {
throw new LensCountException('Lens must return an Eloquent query instance in order to count lens resources.');
}
});
}
}

View File

@@ -0,0 +1,21 @@
<?php
namespace Laravel\Nova\Http\Requests;
use Laravel\Nova\Metrics\Metric;
class LensMetricRequest extends MetricRequest
{
use InteractsWithLenses;
/**
* Get all of the possible metrics for the request.
*
* @return \Illuminate\Support\Collection
*/
public function availableMetrics()
{
return $this->lens()->availableCards($this)
->whereInstanceOf(Metric::class);
}
}

View File

@@ -0,0 +1,182 @@
<?php
namespace Laravel\Nova\Http\Requests;
use Illuminate\Database\Eloquent\Relations\Relation;
use Illuminate\Support\Collection;
use Laravel\Nova\Contracts\RelatableField;
/**
* @property-read string|null $orderBy
* @property-read string|null $orderByDirection
*/
class LensRequest extends NovaRequest
{
use DecodesFilters;
use InteractsWithLenses;
/**
* Whether to include the table order prefix.
*
* @var bool
*/
protected $tableOrderPrefix = true;
/**
* Apply the specified filters to the given query.
*
* @param \Illuminate\Database\Eloquent\Builder $query
* @return \Illuminate\Database\Eloquent\Builder
*/
public function withFilters($query)
{
return $this->filter($query);
}
/**
* Apply the specified filters to the given query.
*
* @param \Illuminate\Database\Eloquent\Builder $query
* @return \Illuminate\Database\Eloquent\Builder
*/
public function filter($query)
{
$this->filters()->each->__invoke($this, $query);
return $query;
}
/**
* Apply the specified ordering to the given query.
*
* @template TValue of \Illuminate\Database\Eloquent\Builder
*
* @param TValue $query
* @param (callable(TValue): (TValue))|null $defaultCallback
* @return TValue
*/
public function withOrdering($query, $defaultCallback = null)
{
if (! $this->orderBy || ! $this->orderByDirection) {
with($query, $defaultCallback);
return $query;
}
$model = $this->model();
$fieldExists = $this->lens()->availableFields($this)
->transform(function ($field) use ($model) {
return $field instanceof RelatableField
? $this->getRelationForeignKeyName($model->{$field->attribute}())
: $field->attribute ?? null;
})->filter()
->first(function ($attribute) {
return $attribute == $this->orderBy;
});
if ($fieldExists) {
return $query->orderBy(
($this->tableOrderPrefix ? $query->getModel()->getTable().'.' : '').$this->orderBy,
$this->orderByDirection === 'asc' ? 'asc' : 'desc'
);
}
return $query;
}
/**
* Disable prepending of the table order.
*
* @return $this
*/
public function withoutTableOrderPrefix()
{
$this->tableOrderPrefix = false;
return $this;
}
/**
* Get all of the possibly available filters for the request.
*
* @return \Illuminate\Support\Collection
*/
protected function availableFilters()
{
return $this->lens()->availableFilters($this);
}
/**
* Map the given models to the appropriate resource for the request.
*
* @param \Illuminate\Support\Collection $models
* @return \Illuminate\Support\Collection
*/
public function toResources(Collection $models)
{
$resource = $this->resource();
return $models->map(function ($model) use ($resource) {
$lensResource = $this->lens()->setResource($model);
return transform((new $resource($model))->serializeForIndex(
$this, $lensResource->resolveFields($this)
), function ($payload) use ($model, $lensResource) {
$hasId = ! is_null($payload['id']->value);
$payload['actions'] = collect(
$hasId === true ? array_values($lensResource->actions($this)) : []
)->filter(function ($action) {
return $action->shownOnIndex() || $action->shownOnTableRow();
})
->filter->authorizedToSee($this)
->filter->authorizedToRun($this, $model)
->values();
return $payload;
});
});
}
/**
* Get foreign key name for relation.
*
* @param \Illuminate\Database\Eloquent\Relations\Relation $relation
* @return string
*/
protected function getRelationForeignKeyName(Relation $relation)
{
return method_exists($relation, 'getForeignKeyName')
? $relation->getForeignKeyName()
: $relation->getForeignKey();
}
/**
* Get per page.
*
* @return int
*/
public function perPage()
{
$resource = $this->resource();
$perPageOptions = $resource::perPageOptions();
if (empty($perPageOptions)) {
$perPageOptions = [$resource::newModel()->getPerPage()];
}
return (int) in_array($this->perPage, $perPageOptions) ? $this->perPage : $perPageOptions[0];
}
/**
* Determine if this request is an action request.
*
* @return bool
*/
public function isActionRequest()
{
return $this->segment(5) == 'actions';
}
}

View File

@@ -0,0 +1,65 @@
<?php
namespace Laravel\Nova\Http\Requests;
use Closure;
use Illuminate\Database\Eloquent\Builder;
use LogicException;
/**
* @property-read string|array<int, mixed> $resources
*/
class LensResourceDeletionRequest extends NovaRequest
{
use InteractsWithLenses;
use QueriesResources;
/**
* Get the selected models for the action in chunks.
*
* @param int $count
* @param \Closure(\Illuminate\Support\Collection):void $callback
* @param \Closure(\Illuminate\Support\Collection):\Illuminate\Support\Collection $authCallback
* @return mixed
*/
protected function chunkWithAuthorization($count, Closure $callback, Closure $authCallback)
{
$this->toSelectedResourceQuery()->when(! $this->allResourcesSelected(), function ($query) {
$query->whereKey($this->resources);
})->tap(function ($query) {
$query->getQuery()->orders = [];
})->chunkById($count, function ($models) use ($callback, $authCallback) {
$models = $authCallback($models);
if ($models->isNotEmpty()) {
$callback($models);
}
});
}
/**
* Get the query for the models that were selected by the user.
*
* @return \Illuminate\Database\Eloquent\Builder
*/
protected function toSelectedResourceQuery()
{
return $this->allResourcesSelected()
? $this->toQuery()
: $this->newQueryWithoutScopes();
}
/**
* Transform the request into a query.
*
* @return \Illuminate\Database\Eloquent\Builder
*/
public function toQuery()
{
return tap($this->lens()->query(LensRequest::createFrom($this), $this->newSearchQuery()), function ($query) {
if (! $query instanceof Builder) {
throw new LogicException('Lens must return an Eloquent query instance in order to perform this action.');
}
});
}
}

View File

@@ -0,0 +1,87 @@
<?php
namespace Laravel\Nova\Http\Requests;
use Laravel\Nova\Metrics\Metric;
/**
* @property-read string $metric
*/
class MetricRequest extends NovaRequest
{
/**
* Get the metric instance for the given request.
*
* @return \Laravel\Nova\Metrics\Metric
*/
public function metric()
{
return $this->availableMetrics()->first(function ($metric) {
return $this->metric === $metric->uriKey();
}) ?: abort(404);
}
/**
* Get the metric instance for the given detail request.
*
* @return \Laravel\Nova\Metrics\Metric
*/
public function detailMetric()
{
return $this->availableMetricsForDetail()->first(function ($metric) {
return $this->metric === $metric->uriKey();
}) ?: abort(404);
}
/**
* Get all of the possible metrics for the request.
*
* @return \Illuminate\Support\Collection<int, \Laravel\Nova\Metrics\Metric>
*/
public function availableMetrics()
{
$resource = $this->newResource();
abort_unless($resource::authorizedToViewAny($this), 403);
return $resource->availableCards($this)
->whereInstanceOf(Metric::class)
->map(function ($metric) use ($resource) {
/** @var \Laravel\Nova\Metrics\Metric $metric */
if ($metric->refreshWhenFiltersChange === true) {
$request = isset($this->resourceId)
? ResourceDetailRequest::createFromBase($this)
: ResourceIndexRequest::createFromBase($this);
return $metric->setAvailableFilters($resource->availableFilters($request));
}
return $metric;
});
}
/**
* Get all of the possible metrics for a detail request.
*
* @return \Illuminate\Support\Collection<int, \Laravel\Nova\Metrics\Metric>
*/
public function availableMetricsForDetail()
{
$resource = $this->newResource();
abort_unless($resource::authorizedToViewAny($this), 403);
return $resource->availableCardsForDetail($this)
->whereInstanceOf(Metric::class)
->map(function ($metric) use ($resource) {
/** @var \Laravel\Nova\Metrics\Metric $metric */
if ($metric->refreshWhenFiltersChange === true) {
return $metric->setAvailableFilters(
$resource->availableFilters(ResourceDetailRequest::createFromBase($this))
);
}
return $metric;
});
}
}

View File

@@ -0,0 +1,31 @@
<?php
namespace Laravel\Nova\Http\Requests;
use Illuminate\Http\Resources\Json\AnonymousResourceCollection;
use Laravel\Nova\Http\Resources\NotificationResource;
use Laravel\Nova\Notifications\Notification;
use Laravel\Nova\Nova;
class NotificationRequest extends NovaRequest
{
/**
* @return AnonymousResourceCollection
*/
public function notifications()
{
return NotificationResource::collection(
Notification::whereNotifiableId(Nova::user($this)->getKey())
->latest()
->take(100)
->get()
);
}
public function unreadCount(): int
{
return Notification::unread()->whereNotifiableId(
Nova::user($this)->getKey()
)->count();
}
}

View File

@@ -0,0 +1,157 @@
<?php
namespace Laravel\Nova\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Request as SymfonyRequest;
/**
* @property-read \Illuminate\Database\Eloquent\Model|string|null $resource
* @property-read mixed|null $resourceId
* @property-read string|null $relatedResource
* @property-read mixed|null $relatedResourceId
* @property-read string|null $viaResource
* @property-read mixed|null $viaResourceId
* @property-read string|null $viaRelationship
* @property-read string|null $relationshipType
*/
class NovaRequest extends FormRequest
{
use InteractsWithRelatedResources;
use InteractsWithResources;
use InteractsWithResourcesSelection;
/**
* Determine if this request is an inline create or attach request.
*
* @return bool
*/
public function isInlineCreateRequest()
{
return $this->isCreateOrAttachRequest() && $this->inline === 'true';
}
/**
* Determine if this request is a create or attach request.
*
* @return bool
*/
public function isCreateOrAttachRequest()
{
return $this instanceof ResourceCreateOrAttachRequest
|| ($this->editing === 'true' && in_array($this->editMode, ['create', 'attach']));
}
/**
* Determine if this request is an update or update-attached request.
*
* @return bool
*/
public function isUpdateOrUpdateAttachedRequest()
{
return $this instanceof ResourceUpdateOrUpdateAttachedRequest
|| ($this->editing === 'true' && in_array($this->editMode, ['update', 'update-attached']));
}
/**
* Determine if this request is a resource index request.
*
* @return bool
*/
public function isResourceIndexRequest()
{
return $this instanceof ResourceIndexRequest;
}
/**
* Determine if this request is a resource detail request.
*
* @return bool
*/
public function isResourceDetailRequest()
{
return $this instanceof ResourceDetailRequest;
}
/**
* Determine if this request is a resource preview request.
*
* @return bool
*/
public function isResourcePreviewRequest()
{
return $this instanceof ResourcePreviewRequest;
}
/**
* Determine if this request is a resource peeking request.
*
* @return bool
*/
public function isResourcePeekingRequest()
{
return $this instanceof ResourcePeekRequest;
}
/**
* Determine if this request is a lens request.
*
* @return bool
*/
public function isLensRequest()
{
return $this instanceof LensRequest;
}
/**
* Determine if this request is an action request.
*
* @return bool
*/
public function isActionRequest()
{
return $this->segment(3) == 'actions';
}
/**
* Determine if this request is either create, attach, update, update-attached or action request.
*
* @return bool
*/
public function isFormRequest()
{
return $this->isCreateOrAttachRequest()
|| $this->isUpdateOrUpdateAttachedRequest()
|| $this->isActionRequest();
}
/**
* Determine if this request is an index or detail request.
*
* @return bool
*/
public function isPresentationRequest()
{
return $this->isResourceIndexRequest()
|| $this->isResourceDetailRequest()
|| $this->isLensRequest();
}
/**
* Create an Illuminate request from a Symfony instance.
*
* @param \Symfony\Component\HttpFoundation\Request $request
* @return static
*/
public static function createFromBase(SymfonyRequest $request)
{
$newRequest = parent::createFromBase($request);
if ($request instanceof Request) {
$newRequest->setUserResolver($request->getUserResolver());
}
return $newRequest;
}
}

View File

@@ -0,0 +1,98 @@
<?php
namespace Laravel\Nova\Http\Requests;
use Laravel\Nova\Fields\File;
use Laravel\Nova\Nova;
class PivotFieldDestroyRequest extends NovaRequest
{
/**
* Authorize that the user may attach resources of the given type.
*
* @return void
*
* @throws \Symfony\Component\HttpKernel\Exception\HttpException
*/
public function authorizeForAttachment()
{
if (! $this->newResourceWith($this->findModelOrFail())->authorizedToAttach(
$this, $this->findRelatedModel()
)) {
abort(403);
}
}
/**
* Get the pivot model for the relationship.
*
* @return \Illuminate\Database\Eloquent\Model
*/
public function findPivotModel()
{
$resource = $this->findResourceOrFail();
abort_unless($resource->hasRelatableField($this, $this->viaRelationship), 404);
return once(function () use ($resource) {
return $this->findRelatedModel()->{
$resource->model()->{$this->viaRelationship}()->getPivotAccessor()
};
});
}
/**
* Find the related resource for the operation.
*
* @param string|int|null $resourceId
* @return \Laravel\Nova\Resource<\Illuminate\Database\Eloquent\Model>
*/
public function findRelatedResource($resourceId = null)
{
return Nova::newResourceFromModel(
$this->findRelatedModel($resourceId)
);
}
/**
* Find the related model for the operation.
*
* @param string|int|null $resourceId
* @return \Illuminate\Database\Eloquent\Model
*
* @throws \Illuminate\Database\Eloquent\ModelNotFoundException
*/
public function findRelatedModel($resourceId = null)
{
$resource = $this->findResourceOrFail();
abort_unless($resource->hasRelatableField($this, $this->viaRelationship), 404);
$query = $resource->model()->{$this->viaRelationship}()
->withoutGlobalScopes();
if (! is_null($resourceId)) {
return $query->lockForUpdate()->findOrFail($resourceId);
}
return once(function () use ($query) {
return $query->lockForUpdate()->findOrFail($this->relatedResourceId);
});
}
/**
* Find the field being deleted or fail if it is not found.
*
* @return \Laravel\Nova\Fields\Field&\Laravel\Nova\Fields\File
*
* @throws \Symfony\Component\HttpKernel\Exception\NotFoundHttpException
*/
public function findFieldOrFail()
{
return $this->findRelatedResource()->resolvePivotFields($this, $this->resource)
->whereInstanceOf(File::class)
->findFieldByAttribute($this->field, function () {
abort(404);
});
}
}

View File

@@ -0,0 +1,83 @@
<?php
namespace Laravel\Nova\Http\Requests;
trait QueriesResources
{
use DecodesFilters;
/**
* Transform the request into a query.
*
* @return \Illuminate\Database\Eloquent\Builder
*/
public function toQuery()
{
$resource = $this->resource();
return $resource::buildIndexQuery(
$this, $this->newQuery(), $this->search,
$this->filters()->all(), $this->orderings(), $this->trashed()
);
}
/**
* Get a new query builder for the underlying model.
*
* @return \Illuminate\Database\Eloquent\Builder
*/
public function newQuery()
{
if (! $this->viaRelationship()) {
return $this->model()->newQuery();
}
abort_unless($this->newViaResource()->hasRelatableField($this, $this->viaRelationship), 409);
return forward_static_call([$this->viaResource(), 'newModel'])
->newQueryWithoutScopes()->findOrFail(
$this->viaResourceId
)->{$this->viaRelationship}();
}
/**
* Get a new query builder for the underlying model.
*
* @return \Illuminate\Database\Eloquent\Builder
*/
public function newQueryWithoutScopes()
{
if (! $this->viaRelationship()) {
return $this->model()->newQueryWithoutScopes();
}
abort_unless($this->newViaResource()->hasRelatableField($this, $this->viaRelationship), 409);
return forward_static_call([$this->viaResource(), 'newModel'])
->newQueryWithoutScopes()->findOrFail(
$this->viaResourceId
)->{$this->viaRelationship}()->withoutGlobalScopes();
}
/**
* Get the orderings for the request.
*
* @return array
*/
public function orderings()
{
return ! empty($this->orderBy)
? [$this->orderBy => $this->orderByDirection]
: [];
}
/**
* Get the trashed status of the request.
*
* @return string
*/
protected function trashed()
{
return $this->trashed;
}
}

View File

@@ -0,0 +1,8 @@
<?php
namespace Laravel\Nova\Http\Requests;
class ResourceCreateOrAttachRequest extends NovaRequest
{
//
}

View File

@@ -0,0 +1,8 @@
<?php
namespace Laravel\Nova\Http\Requests;
class ResourceDetailRequest extends NovaRequest
{
//
}

View File

@@ -0,0 +1,59 @@
<?php
namespace Laravel\Nova\Http\Requests;
use Laravel\Nova\Contracts\QueryBuilder;
class ResourceIndexRequest extends NovaRequest
{
use CountsResources;
use QueriesResources;
/**
* Get the paginator instance for the index request.
*
* @return array
*/
public function searchIndex()
{
return app()->make(QueryBuilder::class, [$this->resource()])->search(
$this, $this->newQuery(), $this->search,
$this->filters()->all(), $this->orderings(), $this->trashed()
)->paginate((int) $this->perPage());
}
/**
* Get the count of the resources.
*
* @return int
*/
public function toCount()
{
return app()->make(QueryBuilder::class, [$this->resource()])->search(
$this, $this->newQuery(), $this->search,
$this->filters()->all(), $this->orderings(), $this->trashed()
)->toBaseQueryBuilder()->getCountForPagination();
}
/**
* Get per page.
*
* @return int
*/
public function perPage()
{
$resource = $this->resource();
if ($this->viaRelationship()) {
return (int) $resource::$perPageViaRelationship;
}
$perPageOptions = $resource::perPageOptions();
if (empty($perPageOptions)) {
$perPageOptions = [$resource::newModel()->getPerPage()];
}
return (int) in_array($this->perPage, $perPageOptions) ? $this->perPage : $perPageOptions[0];
}
}

View File

@@ -0,0 +1,8 @@
<?php
namespace Laravel\Nova\Http\Requests;
class ResourcePeekRequest extends NovaRequest
{
//
}

View File

@@ -0,0 +1,8 @@
<?php
namespace Laravel\Nova\Http\Requests;
class ResourcePreviewRequest extends NovaRequest
{
//
}

View File

@@ -0,0 +1,36 @@
<?php
namespace Laravel\Nova\Http\Requests;
use Laravel\Nova\Contracts\QueryBuilder;
class ResourceSearchRequest extends NovaRequest
{
use QueriesResources;
/**
* Get the paginator instance for the index request.
*
* @return \Illuminate\Database\Eloquent\Collection
*/
public function searchIndex()
{
$resource = $this->resource();
$model = $this->model();
$limit = $resource::usesScout()
? $resource::$scoutSearchResults
: $resource::$relatableSearchResults;
$query = app()->make(QueryBuilder::class, [$resource]);
$this->first === 'true'
? $query->whereKey($model->newQueryWithoutScopes(), $this->current)
: $query->search(
$this, $this->newQuery(), $this->search,
$this->filters()->all(), $this->orderings(), $this->trashed()
);
return $query->take($limit)->get();
}
}

View File

@@ -0,0 +1,8 @@
<?php
namespace Laravel\Nova\Http\Requests;
class ResourceUpdateOrUpdateAttachedRequest extends NovaRequest
{
//
}

View File

@@ -0,0 +1,49 @@
<?php
namespace Laravel\Nova\Http\Requests;
use Closure;
use Illuminate\Support\Collection;
class RestoreLensResourceRequest extends LensResourceDeletionRequest
{
/**
* Get the selected models for the action in chunks.
*
* @param int $count
* @param \Closure(\Illuminate\Support\Collection):void $callback
* @return mixed
*/
public function chunks($count, Closure $callback)
{
return $this->chunkWithAuthorization($count, $callback, function ($models) {
return $this->restorableModels($models);
});
}
/**
* Get the models that may be restored.
*
* @param \Illuminate\Support\Collection $models
* @return \Illuminate\Support\Collection
*/
protected function restorableModels(Collection $models)
{
return $models->mapInto($this->resource())
->filter
->isSoftDeleted()
->filter
->authorizedToRestore($this)
->map->model();
}
/**
* Get the trashed status of the request.
*
* @return string
*/
protected function trashed()
{
return 'with';
}
}

View File

@@ -0,0 +1,49 @@
<?php
namespace Laravel\Nova\Http\Requests;
use Closure;
use Illuminate\Support\Collection;
class RestoreResourceRequest extends DeletionRequest
{
/**
* Get the selected models for the action in chunks.
*
* @param int $count
* @param \Closure(\Illuminate\Support\Collection):void $callback
* @return mixed
*/
public function chunks($count, Closure $callback)
{
return $this->chunkWithAuthorization($count, $callback, function ($models) {
return $this->restorableModels($models);
});
}
/**
* Get the models that may be restored.
*
* @param \Illuminate\Support\Collection $models
* @return \Illuminate\Support\Collection
*/
protected function restorableModels(Collection $models)
{
return $models->mapInto($this->resource())
->filter
->isSoftDeleted()
->filter
->authorizedToRestore($this)
->map->model();
}
/**
* Get the trashed status of the request.
*
* @return string
*/
protected function trashed()
{
return 'with';
}
}

View File

@@ -0,0 +1,16 @@
<?php
namespace Laravel\Nova\Http\Requests;
class UpdateResourceRequest extends NovaRequest
{
/**
* Determine if this request is an update or update-attached request.
*
* @return bool
*/
public function isUpdateOrUpdateAttachedRequest()
{
return true;
}
}