add nova
This commit is contained in:
89
nova/src/Query/Search/Column.php
Normal file
89
nova/src/Query/Search/Column.php
Normal file
@@ -0,0 +1,89 @@
|
||||
<?php
|
||||
|
||||
namespace Laravel\Nova\Query\Search;
|
||||
|
||||
use Illuminate\Database\Query\Expression;
|
||||
|
||||
class Column
|
||||
{
|
||||
/**
|
||||
* The search column.
|
||||
*
|
||||
* @var \Illuminate\Database\Query\Expression|string
|
||||
*/
|
||||
public $column;
|
||||
|
||||
/**
|
||||
* Construct a new search.
|
||||
*
|
||||
* @param \Illuminate\Database\Query\Expression|string $column
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($column)
|
||||
{
|
||||
$this->column = $column;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create Column instance for raw expression value.
|
||||
*
|
||||
* @param string $column
|
||||
* @return mixed
|
||||
*/
|
||||
public static function raw($column)
|
||||
{
|
||||
return new static(new Expression($column));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create Column instance from raw expression or fluent string.
|
||||
*
|
||||
* @param \Illuminate\Database\Query\Expression|string $column
|
||||
* @return mixed
|
||||
*/
|
||||
public static function from($column)
|
||||
{
|
||||
if ($column instanceof Expression) {
|
||||
return new static($column);
|
||||
}
|
||||
|
||||
if (strpos($column, '->') !== false) {
|
||||
return new SearchableJson($column);
|
||||
} elseif (strpos($column, '.') !== false) {
|
||||
[$relation, $columnName] = explode('.', $column, 2);
|
||||
|
||||
return new SearchableRelation($relation, $columnName);
|
||||
}
|
||||
|
||||
return new static($column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the search.
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Relations\Relation $query
|
||||
* @param string $search
|
||||
* @param string $connectionType
|
||||
* @param string $whereOperator
|
||||
* @return \Illuminate\Database\Eloquent\Builder
|
||||
*/
|
||||
public function __invoke($query, $search, string $connectionType, string $whereOperator = 'orWhere')
|
||||
{
|
||||
return $query->{$whereOperator}(
|
||||
$this->columnName($query),
|
||||
$connectionType == 'pgsql' ? 'ilike' : 'like',
|
||||
"%{$search}%"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the column name.
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Relations\Relation $query
|
||||
* @return string
|
||||
*/
|
||||
protected function columnName($query)
|
||||
{
|
||||
return $this->column instanceof Expression ? $this->column : $query->qualifyColumn($this->column);
|
||||
}
|
||||
}
|
||||
50
nova/src/Query/Search/PrimaryKey.php
Normal file
50
nova/src/Query/Search/PrimaryKey.php
Normal file
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
namespace Laravel\Nova\Query\Search;
|
||||
|
||||
class PrimaryKey extends Column
|
||||
{
|
||||
/**
|
||||
* Max primary key size.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $maxPrimaryKeySize;
|
||||
|
||||
/**
|
||||
* Construct a new search.
|
||||
*
|
||||
* @param \Illuminate\Database\Query\Expression|string $column
|
||||
* @param int $maxPrimaryKeySize
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($column, $maxPrimaryKeySize = PHP_INT_MAX)
|
||||
{
|
||||
$this->column = $column;
|
||||
$this->maxPrimaryKeySize = $maxPrimaryKeySize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the search.
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Relations\Relation $query
|
||||
* @param string|int $search
|
||||
* @param string $connectionType
|
||||
* @param string $whereOperator
|
||||
* @return \Illuminate\Database\Eloquent\Builder
|
||||
*/
|
||||
public function __invoke($query, $search, string $connectionType, string $whereOperator = 'orWhere')
|
||||
{
|
||||
$model = $query->getModel();
|
||||
|
||||
$canSearchPrimaryKey = ctype_digit($search) &&
|
||||
in_array($model->getKeyType(), ['int', 'integer']) &&
|
||||
($connectionType != 'pgsql' || $search <= $this->maxPrimaryKeySize);
|
||||
|
||||
if (! $canSearchPrimaryKey) {
|
||||
return parent::__invoke($query, $search, $connectionType, $whereOperator);
|
||||
}
|
||||
|
||||
return $query->{$whereOperator}($model->getQualifiedKeyName(), $search);
|
||||
}
|
||||
}
|
||||
47
nova/src/Query/Search/SearchableJson.php
Normal file
47
nova/src/Query/Search/SearchableJson.php
Normal file
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
namespace Laravel\Nova\Query\Search;
|
||||
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class SearchableJson extends Column
|
||||
{
|
||||
/**
|
||||
* The search JSON seletor path.
|
||||
*
|
||||
* @var \Illuminate\Database\Query\Expression|string
|
||||
*/
|
||||
public $jsonSelectorPath;
|
||||
|
||||
/**
|
||||
* Construct a new search.
|
||||
*
|
||||
* @param \Illuminate\Database\Query\Expression|string $jsonSelectorPath
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($jsonSelectorPath)
|
||||
{
|
||||
$this->jsonSelectorPath = $jsonSelectorPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the search.
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Relations\Relation $query
|
||||
* @param string $search
|
||||
* @param string $connectionType
|
||||
* @param string $whereOperator
|
||||
* @return \Illuminate\Database\Eloquent\Builder
|
||||
*/
|
||||
public function __invoke($query, $search, string $connectionType, string $whereOperator = 'orWhere')
|
||||
{
|
||||
$path = $query->getGrammar()->wrap($this->jsonSelectorPath);
|
||||
$likeOperator = $connectionType == 'pgsql' ? 'ilike' : 'like';
|
||||
|
||||
if (in_array($connectionType, ['pgsql', 'sqlite'])) {
|
||||
return $query->{$whereOperator}($this->jsonSelectorPath, $likeOperator, "%{$search}%");
|
||||
}
|
||||
|
||||
return $query->{$whereOperator.'Raw'}("lower({$path}) {$likeOperator} ?", ['%'.Str::lower($search).'%']);
|
||||
}
|
||||
}
|
||||
63
nova/src/Query/Search/SearchableMorphToRelation.php
Normal file
63
nova/src/Query/Search/SearchableMorphToRelation.php
Normal file
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
namespace Laravel\Nova\Query\Search;
|
||||
|
||||
class SearchableMorphToRelation extends SearchableRelation
|
||||
{
|
||||
/**
|
||||
* The available morph types.
|
||||
*
|
||||
* @var array<int, class-string<\Illuminate\Database\Eloquent\Model|\Laravel\Nova\Resource>|string>
|
||||
*/
|
||||
public $types = [];
|
||||
|
||||
/**
|
||||
* Construct a new search.
|
||||
*
|
||||
* @param string $relation
|
||||
* @param \Illuminate\Database\Query\Expression|string $column
|
||||
* @param array<int, class-string<\Illuminate\Database\Eloquent\Model|\Laravel\Nova\Resource>|string> $types
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(string $relation, $column, array $types = [])
|
||||
{
|
||||
$this->types = $types;
|
||||
|
||||
parent::__construct($relation, $column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the search.
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Relations\Relation $query
|
||||
* @param string $search
|
||||
* @param string $connectionType
|
||||
* @param string $whereOperator
|
||||
* @return \Illuminate\Database\Eloquent\Builder
|
||||
*/
|
||||
public function __invoke($query, $search, string $connectionType, string $whereOperator = 'orWhere')
|
||||
{
|
||||
return $query->{$whereOperator.'HasMorph'}($this->relation, $this->morphTypes(), function ($query) use ($search, $connectionType) {
|
||||
return Column::from($this->column)->__invoke(
|
||||
$query, $search, $connectionType, 'where'
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get available morph types.
|
||||
*
|
||||
* @return array<int, class-string<\Illuminate\Database\Eloquent\Model>|string>|string
|
||||
*/
|
||||
protected function morphTypes()
|
||||
{
|
||||
if (empty($this->types)) {
|
||||
return '*';
|
||||
}
|
||||
|
||||
return collect($this->types)
|
||||
->map(function ($resource) {
|
||||
return $resource::$model ?? $resource;
|
||||
})->all();
|
||||
}
|
||||
}
|
||||
45
nova/src/Query/Search/SearchableRelation.php
Normal file
45
nova/src/Query/Search/SearchableRelation.php
Normal file
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
namespace Laravel\Nova\Query\Search;
|
||||
|
||||
class SearchableRelation extends Column
|
||||
{
|
||||
/**
|
||||
* The relationship name.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $relation;
|
||||
|
||||
/**
|
||||
* Construct a new search.
|
||||
*
|
||||
* @param string $relation
|
||||
* @param \Illuminate\Database\Query\Expression|string $column
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(string $relation, $column)
|
||||
{
|
||||
$this->relation = $relation;
|
||||
|
||||
parent::__construct($column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the search.
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Relations\Relation $query
|
||||
* @param string $search
|
||||
* @param string $connectionType
|
||||
* @param string $whereOperator
|
||||
* @return \Illuminate\Database\Eloquent\Builder
|
||||
*/
|
||||
public function __invoke($query, $search, string $connectionType, string $whereOperator = 'orWhere')
|
||||
{
|
||||
return $query->{$whereOperator.'Has'}($this->relation, function ($query) use ($search, $connectionType) {
|
||||
return Column::from($this->column)->__invoke(
|
||||
$query, $search, $connectionType, 'where'
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
26
nova/src/Query/Search/SearchableText.php
Normal file
26
nova/src/Query/Search/SearchableText.php
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace Laravel\Nova\Query\Search;
|
||||
|
||||
class SearchableText extends Column
|
||||
{
|
||||
/**
|
||||
* Apply the search.
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Relations\Relation $query
|
||||
* @param string $search
|
||||
* @param string $connectionType
|
||||
* @param string $whereOperator
|
||||
* @return \Illuminate\Database\Eloquent\Builder
|
||||
*/
|
||||
public function __invoke($query, $search, string $connectionType, string $whereOperator = 'orWhere')
|
||||
{
|
||||
if (in_array($connectionType, ['mysql', 'pgsql'])) {
|
||||
$query->{$whereOperator.'FullText'}(
|
||||
$this->columnName($query), $search
|
||||
);
|
||||
}
|
||||
|
||||
return $query;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user