-
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
38 changed files
with
1,654 additions
and
37 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
<?php | ||
|
||
namespace Symfony\Component\DependencyInjection\Loader\Configurator; | ||
|
||
use Zenstruck\Collection\Doctrine\ObjectRepositoryFactory; | ||
use Zenstruck\Collection\Doctrine\ORM\EntityRepositoryFactory; | ||
use Zenstruck\Collection\Symfony\Doctrine\ChainObjectRepositoryFactory; | ||
|
||
return static function(ContainerConfigurator $configurator) { | ||
$configurator->services() | ||
->set('.zenstruck_collection.doctrine.orm.object_repo_factory', EntityRepositoryFactory::class) | ||
->args([service('doctrine')]) | ||
|
||
->set('.zenstruck_collection.doctrine.chain_object_repo_factory', ChainObjectRepositoryFactory::class) | ||
->args([service('.zenstruck_collection.doctrine.orm.object_repo_factory')]) | ||
->tag('kernel.reset', ['method' => 'reset']) | ||
|
||
->alias(ObjectRepositoryFactory::class, '.zenstruck_collection.doctrine.chain_object_repo_factory') | ||
; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
<?php | ||
|
||
namespace Symfony\Component\DependencyInjection\Loader\Configurator; | ||
|
||
use Zenstruck\Collection\Symfony\Grid\GridFactory; | ||
|
||
return static function(ContainerConfigurator $configurator) { | ||
$configurator->services() | ||
->set('.zenstruck_collection.grid_factory', GridFactory::class) | ||
->args([ | ||
tagged_locator('zenstruck_collection.grid_definition', indexAttribute: 'key'), | ||
]) | ||
|
||
->alias(GridFactory::class, '.zenstruck_collection.grid_factory') | ||
; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
<?php | ||
|
||
/* | ||
* This file is part of the zenstruck/collection package. | ||
* | ||
* (c) Kevin Bond <[email protected]> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
namespace Zenstruck\Collection\Doctrine\Grid; | ||
|
||
use Zenstruck\Collection\Doctrine\ObjectRepositoryFactory; | ||
use Zenstruck\Collection\Grid\GridBuilder; | ||
use Zenstruck\Collection\Grid\GridDefinition; | ||
|
||
/** | ||
* @author Kevin Bond <[email protected]> | ||
* | ||
* @implements GridDefinition<object> | ||
*/ | ||
final class ObjectGridDefinition implements GridDefinition | ||
{ | ||
/** | ||
* @param class-string<object> $class | ||
* @param GridDefinition<object> $inner | ||
*/ | ||
public function __construct( | ||
private string $class, | ||
private ObjectRepositoryFactory $repositoryFactory, | ||
private GridDefinition $inner, | ||
) { | ||
} | ||
|
||
public function configure(GridBuilder $builder): void | ||
{ | ||
$this->inner->configure($builder); | ||
|
||
if ($builder->source) { | ||
return; | ||
} | ||
|
||
$builder->source = $this->repositoryFactory->create($this->class); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
<?php | ||
|
||
/* | ||
* This file is part of the zenstruck/collection package. | ||
* | ||
* (c) Kevin Bond <[email protected]> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
namespace Zenstruck\Collection; | ||
|
||
use Zenstruck\Collection\Grid\Column; | ||
use Zenstruck\Collection\Grid\Columns; | ||
use Zenstruck\Collection\Grid\Filter; | ||
use Zenstruck\Collection\Grid\Filters; | ||
use Zenstruck\Collection\Grid\Input; | ||
use Zenstruck\Collection\Grid\PerPage; | ||
use Zenstruck\Collection\Grid\PerPage\FixedPerPage; | ||
use Zenstruck\Collection\Specification\Filter\Contains; | ||
use Zenstruck\Collection\Specification\Logic\AndX; | ||
use Zenstruck\Collection\Specification\Logic\OrX; | ||
|
||
/** | ||
* @author Kevin Bond <[email protected]> | ||
* | ||
* @template T of array<string,mixed>|object | ||
* | ||
* @implements \IteratorAggregate<T> | ||
*/ | ||
final class Grid implements \IteratorAggregate | ||
{ | ||
public readonly PerPage $perPage; | ||
|
||
/** @var Page<int,T> */ | ||
private Page $page; | ||
|
||
/** | ||
* @internal | ||
* | ||
* @param Matchable<mixed,T> $source | ||
*/ | ||
public function __construct( | ||
public readonly Input $input, | ||
public readonly Matchable $source, | ||
public readonly Columns $columns, | ||
public readonly Filters $filters, | ||
?PerPage $perPage = null, | ||
private ?object $defaultSpecification = null, | ||
) { | ||
$this->perPage = $perPage ?? new FixedPerPage(); | ||
} | ||
|
||
public function getIterator(): \Traversable | ||
{ | ||
return $this->page(); | ||
} | ||
|
||
/** | ||
* @return Page<int,T> | ||
*/ | ||
public function page(): Page | ||
{ | ||
if (isset($this->page)) { | ||
return $this->page; | ||
} | ||
|
||
$specification = new AndX(...\array_filter([ | ||
$this->defaultSpecification, | ||
$this->columns->sort(), | ||
$this->searchSpecification(), | ||
new AndX(...\array_filter($this->filterSpecification())), | ||
])); | ||
|
||
return $this->page = $this->source->filter($specification) | ||
->paginate($this->input->page(), $this->perPage->value($this->input->perPage()))->strict() | ||
; | ||
} | ||
|
||
private function searchSpecification(): OrX | ||
{ | ||
if (!$query = $this->input->query()) { | ||
return new OrX(); | ||
} | ||
|
||
return new OrX(...$this->columns | ||
->searchable() | ||
->all() | ||
->map(fn(Column $column) => new Contains($column->name(), $query)) | ||
->values() | ||
->all() | ||
); | ||
} | ||
|
||
/** | ||
* @return list<object|null> | ||
*/ | ||
private function filterSpecification(): array | ||
{ | ||
return $this->filters->all() | ||
->map(fn(Filter $filter, string $name) => $filter->apply($this->input->filter($name))) | ||
->values() | ||
->all() | ||
; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
<?php | ||
|
||
/* | ||
* This file is part of the zenstruck/collection package. | ||
* | ||
* (c) Kevin Bond <[email protected]> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
namespace Zenstruck\Collection\Grid; | ||
|
||
use Zenstruck\Collection\Grid\Definition\ColumnDefinition; | ||
use Zenstruck\Collection\Specification\OrderBy; | ||
|
||
/** | ||
* @author Kevin Bond <[email protected]> | ||
*/ | ||
final class Column | ||
{ | ||
/** | ||
* @internal | ||
*/ | ||
public function __construct( | ||
private ColumnDefinition $definition, | ||
private Input $input, | ||
) { | ||
} | ||
|
||
public function name(): string | ||
{ | ||
return $this->definition->name; | ||
} | ||
|
||
public function isSearchable(): bool | ||
{ | ||
return $this->definition->searchable; | ||
} | ||
|
||
public function isSortable(): bool | ||
{ | ||
return $this->definition->sortable; | ||
} | ||
|
||
public function sort(): ?OrderBy | ||
{ | ||
if (!($sort = $this->input->sort()) || $this->name() !== $sort->field) { | ||
return null; | ||
} | ||
|
||
return $sort; | ||
} | ||
|
||
public function applyAscSort(): Input | ||
{ | ||
return $this->input->applySort(OrderBy::asc($this->name())); | ||
} | ||
|
||
public function applyDescSort(): Input | ||
{ | ||
return $this->input->applySort(OrderBy::desc($this->name())); | ||
} | ||
|
||
public function applyOppositeSort(): Input | ||
{ | ||
if (!$sort = $this->sort()) { | ||
return $this->applyAscSort(); | ||
} | ||
|
||
return $this->input->applySort($sort->opposite()); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
<?php | ||
|
||
/* | ||
* This file is part of the zenstruck/collection package. | ||
* | ||
* (c) Kevin Bond <[email protected]> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
namespace Zenstruck\Collection\Grid; | ||
|
||
use Zenstruck\Collection\ArrayCollection; | ||
use Zenstruck\Collection\Specification\OrderBy; | ||
|
||
/** | ||
* @author Kevin Bond <[email protected]> | ||
* | ||
* @implements \IteratorAggregate<string,Column> | ||
*/ | ||
final class Columns implements \IteratorAggregate, \Countable | ||
{ | ||
private self $searchable; | ||
private self $sortable; | ||
|
||
/** | ||
* @internal | ||
* | ||
* @param ArrayCollection<string,Column> $columns | ||
*/ | ||
public function __construct(private ArrayCollection $columns, private Input $input, private ?OrderBy $defaultSort) | ||
{ | ||
} | ||
|
||
public function get(string $name): ?Column | ||
{ | ||
return $this->columns->get($name); | ||
} | ||
|
||
public function has(string $name): bool | ||
{ | ||
return $this->columns->has($name); | ||
} | ||
|
||
public function searchable(): self | ||
{ | ||
return $this->searchable ??= new self($this->columns->filter(fn(Column $c) => $c->isSearchable()), $this->input, $this->defaultSort); | ||
} | ||
|
||
public function sortable(): self | ||
{ | ||
return $this->sortable ??= new self($this->columns->filter(fn(Column $c) => $c->isSortable()), $this->input, $this->defaultSort); | ||
} | ||
|
||
public function sort(): ?OrderBy | ||
{ | ||
if (!$sort = $this->input->sort()) { | ||
return $this->defaultSort; | ||
} | ||
|
||
return $this->sortable()->has($sort->field) ? $sort : $this->defaultSort; | ||
} | ||
|
||
/** | ||
* @return ArrayCollection<string,Column> | ||
*/ | ||
public function all(): ArrayCollection | ||
{ | ||
return $this->columns; | ||
} | ||
|
||
public function getIterator(): \Traversable | ||
{ | ||
return $this->columns; | ||
} | ||
|
||
public function count(): int | ||
{ | ||
return $this->columns->count(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
<?php | ||
|
||
/* | ||
* This file is part of the zenstruck/collection package. | ||
* | ||
* (c) Kevin Bond <[email protected]> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
namespace Zenstruck\Collection\Grid\Definition; | ||
|
||
/** | ||
* @author Kevin Bond <[email protected]> | ||
*/ | ||
final class ColumnDefinition | ||
{ | ||
public function __construct( | ||
public string $name, | ||
public bool $searchable = false, | ||
public bool $sortable = false, | ||
) { | ||
} | ||
} |
Oops, something went wrong.