Skip to content

Commit

Permalink
DataSources: ArrayDataSource - added filtering
Browse files Browse the repository at this point in the history
  • Loading branch information
janpecha committed Jan 5, 2024
1 parent d5a9bc3 commit 3ffad69
Showing 1 changed file with 99 additions and 10 deletions.
109 changes: 99 additions & 10 deletions src/DataSources/ArrayDataSource.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@
use CzProject\Assert\Assert;
use Inteve\DataGrid\DataPaging;
use Inteve\DataGrid\DataSourceResult;
use Inteve\DataGrid\FilterCondition;
use Inteve\DataGrid\IColumn;
use Inteve\DataGrid\IDataSource;
use Inteve\DataGrid\IFilter;
use Nette\Utils\Strings;


class ArrayDataSource implements IDataSource
Expand Down Expand Up @@ -60,30 +62,117 @@ public function getRowId($row)

public function getData(array $columns, array $filters, array $sorts, DataPaging $paging)
{
if (!empty($filters)) {
if (!empty($sorts)) {
throw new \Inteve\DataGrid\Exception('Not implemented yet.');
}

if (!empty($sorts)) {
throw new \Inteve\DataGrid\Exception('Not implemented yet.');
$data = $this->rows;

// filtering
foreach ($filters as $filter) {
if (!$filter->isActive()) {
continue;
}

$data = $this->filterData($data, $filter->prepareCondition());
}

// pager
$data = NULL;
$totalCount = count($data);

// pager
if ($paging->hasOffset() && $paging->hasLimit()) { // offset + limit
$data = array_slice($this->rows, $paging->getOffset(), $paging->getLimit(), FALSE /*preserve keys*/);
$data = array_slice($data, $paging->getOffset(), $paging->getLimit(), FALSE /*preserve keys*/);

} elseif (!$paging->hasOffset() && $paging->hasLimit()) { // only limit
$data = array_slice($this->rows, 0, $paging->getLimit(), FALSE /*preserve keys*/);
$data = array_slice($data, 0, $paging->getLimit(), FALSE /*preserve keys*/);

} elseif (!$paging->hasOffset() && !$paging->hasLimit()) { // all
$data = $this->rows;
$data = $data;

} else { // only offset
$data = array_slice($this->rows, $paging->getOffset(), NULL, FALSE /*preserve keys*/);
$data = array_slice($data, $paging->getOffset(), NULL, FALSE /*preserve keys*/);
}

return new DataSourceResult($data, $totalCount);
}


/**
* @param array<array<string, mixed>|object> $rows
* @param FilterCondition|FilterCondition[] $conditions
* @return array<array<string, mixed>|object>
*/
protected function filterData(array $rows, $conditions)
{
if (!is_array($conditions)) {
$conditions = [$conditions];
}

foreach ($conditions as $condition) {
if (count($condition->getModifiers()) > 0) {
throw new \Inteve\DataGrid\Exception('Modifiers are not implemented yet.');
}
}

$matchedRows = [];

foreach ($rows as $row) {
$hasMatch = FALSE;

foreach ($conditions as $condition) {
$rowValue = $this->fetchValue($row, $condition->getField());
$filterValue = $condition->getValue();
$comparison = $condition->getComparison();

if ($comparison === IFilter::EQUAL) {
if (is_null($filterValue)) {
$hasMatch = $hasMatch || ($rowValue === NULL);

} elseif (is_array($filterValue)) {
$hasMatch = $hasMatch || in_array($rowValue, $filterValue, TRUE);

} else {
$hasMatch = $hasMatch || ($rowValue === $filterValue);
}

} elseif ($comparison === IFilter::LIKE) {
if (is_scalar($rowValue) && is_scalar($filterValue)) {
$hasMatch = $hasMatch || Strings::contains(
Strings::lower((string) $rowValue),
Strings::lower((string) $filterValue)
);
}

} else {
throw new \Inteve\DataGrid\InvalidArgumentException("Unknow comparison '$comparison'.");
}
}

if ($hasMatch) {
$matchedRows[] = $row;
}
}

return $matchedRows;
}


/**
* @param array<string, mixed>|object $row
* @param string $column
* @return mixed
*/
protected function fetchValue($row, $column)
{
if (is_object($row)) {
return $row->{$column};
}

if (!array_key_exists($column, $row)) {
throw new \Inteve\DataGrid\InvalidArgumentException("Missing column '$column' in row.
");
}

return new DataSourceResult($data, count($this->rows));
return $row[$column];
}
}

0 comments on commit 3ffad69

Please sign in to comment.