/home/bdqbpbxa/api-uniferx.goodface.com.ua/vendor/laravel/nova/src/Fields/MorphToMany.php
<?php
namespace Laravel\Nova\Fields;
use Illuminate\Http\Request;
use Illuminate\Support\Str;
use Laravel\Nova\Contracts\Deletable as DeletableContract;
use Laravel\Nova\Contracts\ListableField;
use Laravel\Nova\Contracts\PivotableField;
use Laravel\Nova\Contracts\QueryBuilder;
use Laravel\Nova\Contracts\RelatableField;
use Laravel\Nova\Http\Requests\NovaRequest;
use Laravel\Nova\Panel;
use Laravel\Nova\Rules\RelatableAttachment;
use Laravel\Nova\TrashedStatus;
/**
* @method static static make(mixed $name, string|null $attribute = null, string|null $resource = null)
*/
class MorphToMany extends Field implements DeletableContract, ListableField, PivotableField, RelatableField
{
use AttachableRelation,
Deletable,
DetachesPivotModels,
DeterminesIfCreateRelationCanBeShown,
FormatsRelatableDisplayValues,
ManyToManyCreationRules,
Searchable,
Collapsable;
/**
* The field's component.
*
* @var string
*/
public $component = 'morph-to-many-field';
/**
* The class name of the related resource.
*
* @var class-string<\Laravel\Nova\Resource>
*/
public $resourceClass;
/**
* The URI key of the related resource.
*
* @var string
*/
public $resourceName;
/**
* The name of the Eloquent "morph to many" relationship.
*
* @var string
*/
public $manyToManyRelationship;
/**
* The callback that should be used to resolve the pivot fields.
*
* @var callable(\Laravel\Nova\Http\Requests\NovaRequest, \Illuminate\Database\Eloquent\Model):array<int, \Laravel\Nova\Fields\Field>
*/
public $fieldsCallback;
/**
* The callback that should be used to resolve the pivot actions.
*
* @var callable(\Laravel\Nova\Http\Requests\NovaRequest):array<int, \Laravel\Nova\Actions\Action>
*/
public $actionsCallback;
/**
* The displayable name that should be used to refer to the pivot class.
*
* @var string
*/
public $pivotName;
/**
* The displayable singular label of the relation.
*
* @var string|null
*/
public $singularLabel;
/**
* Create a new field.
*
* @param string $name
* @param string|null $attribute
* @param class-string<\Laravel\Nova\Resource>|null $resource
* @return void
*/
public function __construct($name, $attribute = null, $resource = null)
{
parent::__construct($name, $attribute);
$resource = $resource ?? ResourceRelationshipGuesser::guessResource($name);
$this->resourceClass = $resource;
$this->resourceName = $resource::uriKey();
$this->manyToManyRelationship = $this->attribute;
$this->deleteCallback = $this->detachmentCallback();
$this->fieldsCallback = function () {
return [];
};
$this->actionsCallback = function () {
return [];
};
$this->noDuplicateRelations();
}
/**
* Get the relationship name.
*
* @return string
*/
public function relationshipName()
{
return $this->manyToManyRelationship;
}
/**
* Get the relationship type.
*
* @return string
*/
public function relationshipType()
{
return 'morphToMany';
}
/**
* Determine if the field should be displayed for the given request.
*
* @param \Illuminate\Http\Request $request
* @return bool
*/
public function authorize(Request $request)
{
return call_user_func(
[$this->resourceClass, 'authorizedToViewAny'], $request
) && parent::authorize($request);
}
/**
* Resolve the field's value.
*
* @param mixed $resource
* @param string|null $attribute
* @return void
*/
public function resolve($resource, $attribute = null)
{
//
}
/**
* Get the validation rules for this field.
*
* @param \Laravel\Nova\Http\Requests\NovaRequest $request
* @return array
*/
public function getRules(NovaRequest $request)
{
$withTrashed = $request->{$this->attribute.'_trashed'} === 'true';
return array_merge_recursive(parent::getRules($request), [
$this->attribute => array_filter([
'required', new RelatableAttachment($request, $this->buildAttachableQuery($request, $withTrashed)->toBase()),
]),
]);
}
/**
* Get the creation rules for this field.
*
* @param \Laravel\Nova\Http\Requests\NovaRequest $request
* @return array<string, array<int, string|\Illuminate\Validation\Rule|\Illuminate\Contracts\Validation\Rule|callable>>
*/
public function getCreationRules(NovaRequest $request)
{
return array_merge_recursive(parent::getCreationRules($request), [
$this->attribute => array_filter($this->getManyToManyCreationRules($request)),
]);
}
/**
* Build an attachable query for the field.
*
* @param \Laravel\Nova\Http\Requests\NovaRequest $request
* @param bool $withTrashed
* @return \Laravel\Nova\Contracts\QueryBuilder
*/
public function buildAttachableQuery(NovaRequest $request, $withTrashed = false)
{
$model = forward_static_call([$resourceClass = $this->resourceClass, 'newModel']);
$query = app()->make(QueryBuilder::class, [$resourceClass]);
$request->first === 'true'
? $query->whereKey($model->newQueryWithoutScopes(), $request->current)
: $query->search(
$request, $model->newQuery(), $request->search,
[], [], TrashedStatus::fromBoolean($withTrashed)
);
return $query->tap(function ($query) use ($request, $model) {
forward_static_call($this->attachableQueryCallable($request, $model), $request, $query, $this);
});
}
/**
* Get the attachable query method name.
*
* @param \Laravel\Nova\Http\Requests\NovaRequest $request
* @param \Illuminate\Database\Eloquent\Model $model
* @return array
*/
protected function attachableQueryCallable(NovaRequest $request, $model)
{
return ($method = $this->attachableQueryMethod($request, $model))
? [$request->resource(), $method]
: [$this->resourceClass, 'relatableQuery'];
}
/**
* Get the attachable query method name.
*
* @param \Laravel\Nova\Http\Requests\NovaRequest $request
* @param \Illuminate\Database\Eloquent\Model $model
* @return string|null
*/
protected function attachableQueryMethod(NovaRequest $request, $model)
{
$method = 'relatable'.Str::plural(class_basename($model));
if (method_exists($request->resource(), $method)) {
return $method;
}
}
/**
* Format the given attachable resource.
*
* @param \Laravel\Nova\Http\Requests\NovaRequest $request
* @param mixed $resource
* @return array
*/
public function formatAttachableResource(NovaRequest $request, $resource)
{
return array_filter([
'avatar' => $resource->resolveAvatarUrl($request),
'display' => $this->formatDisplayValue($resource),
'value' => $resource->getKey(),
'subtitle' => $resource->subtitle(),
]);
}
/**
* Specify the callback to be executed to retrieve the pivot fields.
*
* @param callable(\Laravel\Nova\Http\Requests\NovaRequest, \Illuminate\Database\Eloquent\Model):array<int, \Laravel\Nova\Fields\Field> $callback
* @return $this
*/
public function fields($callback)
{
$this->fieldsCallback = $callback;
return $this;
}
/**
* Specify the callback to be executed to retrieve the pivot actions.
*
* @param callable(\Laravel\Nova\Http\Requests\NovaRequest):array<int, \Laravel\Nova\Actions\Action> $callback
* @return $this
*/
public function actions($callback)
{
$this->actionsCallback = $callback;
return $this;
}
/**
* Set the displayable name that should be used to refer to the pivot class.
*
* @param string $pivotName
* @return $this
*/
public function referToPivotAs($pivotName)
{
$this->pivotName = $pivotName;
return $this;
}
/**
* Set the displayable singular label of the resource.
*
* @param string $singularLabel
* @return $this
*/
public function singularLabel($singularLabel)
{
$this->singularLabel = $singularLabel;
return $this;
}
/**
* Make current field behaves as panel.
*
* @return \Laravel\Nova\Panel
*/
public function asPanel()
{
return Panel::make($this->name, [$this])
->withMeta([
'prefixComponent' => true,
])->withComponent('relationship-panel');
}
/**
* Prepare the field for JSON serialization.
*
* @return array<string, mixed>
*/
public function jsonSerialize(): array
{
return array_merge([
'collapsable' => $this->collapsable,
'collapsedByDefault' => $this->collapsedByDefault,
'debounce' => $this->debounce,
'relatable' => true,
'morphToManyRelationship' => $this->manyToManyRelationship,
'relationshipType' => $this->relationshipType(),
'perPage' => $this->resourceClass::$perPageViaRelationship,
'resourceName' => $this->resourceName,
'searchable' => $this->searchable,
'withSubtitles' => $this->withSubtitles,
'singularLabel' => $this->singularLabel ?? $this->resourceClass::singularLabel(),
'showCreateRelationButton' => $this->createRelationShouldBeShown(app(NovaRequest::class)),
], parent::jsonSerialize());
}
}