Grid/Source/Source.php
public function executeFromData($columns, $page = 0, $limit = 0, $maxResults = null)
    {
        // Populate from data
        $items = $this->getItemsFromData($columns);
        $serializeColumns = [];

        foreach ($this->data as $key => $item) {

            foreach ($columns as $column) {
                $fieldName = $column->getField();
                $fieldValue = $items[$key][$fieldName];
                $dataIsNumeric = ($column->getType() == 'number' || $column->getType() == 'boolean');

                if ($column->getType() === 'array') {
                    $serializeColumns[] = $column->getId();
                }

                // Filter
                if ($column->isFiltered()) {
                    // Some attributes of the column can be changed in this function
                    $filters = $column->getFilters('vector');

                    if ($column->getDataJunction() === Column::DATA_DISJUNCTION) {
                        $disjunction = true;
                        $keep = false;
                    } else {
                        $disjunction = false;
                        $keep = true;
                    }

                    $found = false;
                    foreach ($filters as $filter) {
                        $operator = $filter->getOperator();
                        $value = $filter->getValue();

                        // Normalize value
                        if (!$dataIsNumeric && !($value instanceof \DateTime)) {
                            $value = $this->prepareStringForLikeCompare($value);
                            switch ($operator) {
                                case Column::OPERATOR_EQ:
                                    $value = '/^' . preg_quote($value, '/') . '$/i';
                                    break;
                                case Column::OPERATOR_NEQ:
                                    $value = '/^(?!' . preg_quote($value, '/') . '$).*$/i';
                                    break;
                                case Column::OPERATOR_LIKE:
                                    $value = '/' . preg_quote($value, '/') . '/i';
                                    break;
                                case Column::OPERATOR_NLIKE:
                                    $value = '/^((?!' . preg_quote($value, '/') . ').)*$/i';
                                    break;
                                case Column::OPERATOR_LLIKE:
                                    $value = '/' . preg_quote($value, '/') . '$/i';
                                    break;
                                case Column::OPERATOR_RLIKE:
                                    $value = '/^' . preg_quote($value, '/') . '/i';
                                    break;
                                case Column::OPERATOR_SLIKE:
                                    $value = '/' . preg_quote($value, '/') . '/';
                                    break;
                                case Column::OPERATOR_NSLIKE:
                                    $value = '/^((?!' . preg_quote($value, '/') . ').)*$/';
                                    break;
                                case Column::OPERATOR_LSLIKE:
                                    $value = '/' . preg_quote($value, '/') . '$/';
                                    break;
                                case Column::OPERATOR_RSLIKE:
                                    $value = '/^' . preg_quote($value, '/') . '/';
                                    break;
                            }
                        }

                        // Test
                        switch ($operator) {
                            case Column::OPERATOR_EQ:
                                if ($dataIsNumeric) {
                                    $found = abs($fieldValue - $value) < 0.00001;
                                    break;
                                }
                            case Column::OPERATOR_NEQ:
                                if ($dataIsNumeric) {
                                    $found = abs($fieldValue - $value) > 0.00001;
                                    break;
                                }
                            case Column::OPERATOR_LIKE:
                            case Column::OPERATOR_NLIKE:
                            case Column::OPERATOR_LLIKE:
                            case Column::OPERATOR_RLIKE:
                            case Column::OPERATOR_SLIKE:
                            case Column::OPERATOR_NSLIKE:
                            case Column::OPERATOR_LSLIKE:
                            case Column::OPERATOR_RSLIKE:
                                $fieldValue = $this->prepareStringForLikeCompare($fieldValue, $column->getType());

                                $found = preg_match($value, $fieldValue);
                                break;
                            case Column::OPERATOR_GT:
                                $found = $fieldValue > $value;
                                break;
                            case Column::OPERATOR_GTE:
                                $found = $fieldValue >= $value;
                                break;
                            case Column::OPERATOR_LT:
                                $found = $fieldValue < $value;
                                break;
                            case Column::OPERATOR_LTE:
                                $found = $fieldValue <= $value;
                                break;
                            case Column::OPERATOR_ISNULL:
                                $found = $fieldValue === null;
                                break;
                            case Column::OPERATOR_ISNOTNULL:
                                $found = $fieldValue !== null;
                                break;
                        }

                        // AND
                        if (!$found && !$disjunction) {
                            $keep = false;
                            break;
                        }

                        // OR
                        if ($found && $disjunction) {
                            $keep = true;
                            break;
                        }
                    }

                    if (!$keep) {
                        unset($items[$key]);
                        break;
                    }
                }
            }
        }

        // Order
        foreach ($columns as $column) {
            if ($column->isSorted()) {
                $sortType = SORT_REGULAR;
                $sortedItems = [];
                foreach ($items as $key => $item) {
                    $value = $item[$column->getField()];

                    // Format values for sorting and define the type of sort
                    switch ($column->getType()) {
                        case 'text':
                            $sortedItems[$key] = strtolower($value);
                            $sortType = SORT_STRING;
                            break;
                        case 'datetime':
                        case 'date':
                        case 'time':
                            if ($value instanceof \DateTime) {
                                $sortedItems[$key] = $value->getTimestamp();
                            } else {
                                $sortedItems[$key] = strtotime($value);
                            }
                            $sortType = SORT_NUMERIC;
                            break;
                        case 'boolean':
                            $sortedItems[$key] = $value ? 1 : 0;
                            $sortType = SORT_NUMERIC;
                            break;
                        case 'array':
                            $sortedItems[$key] = json_encode($value);
                            $sortType = SORT_STRING;
                            break;
                        case 'number':
                            $sortedItems[$key] = $value;
                            $sortType = SORT_NUMERIC;
                            break;
                        default:
                            $sortedItems[$key] = $value;
                            $sortType = SORT_REGULAR;
                    }
                }

                if (!empty($sortedItems)) {
                    array_multisort($sortedItems, ($column->getOrder() == 'asc') ? SORT_ASC : SORT_DESC, $sortType, $items);
                }

                break;
            }
        }

        $this->count = count($items);

        // Pagination
        if ($limit > 0) {
            $maxResults = ($maxResults !== null && ($maxResults - $page * $limit < $limit)) ? $maxResults - $page * $limit : $limit;

            $items = array_slice($items, $page * $limit, $maxResults);
        } elseif ($maxResults !== null) {
            $items = array_slice($items, 0, $maxResults);
        }

        $rows = new Rows();
        foreach ($items as $item) {
            $row = new Row();

            if ($this instanceof Vector) {
                $row->setPrimaryField($this->getId());
            }

            foreach ($item as $fieldName => $fieldValue) {
                if ($this instanceof Entity) {
                    if (in_array($fieldName, $serializeColumns)) {
                        if (is_string($fieldValue)) {
                            $fieldValue = unserialize($fieldValue);
                        }
                    }
                }

                $row->setField($fieldName, $fieldValue);
            }

            //call overridden prepareRow or associated closure
            if (($modifiedRow = $this->prepareRow($row)) != null) {
                $rows->addRow($modifiedRow);
            }
        }

        $this->items = $items;

        return $rows;
    }
public function executeFromData($columns, $page = 0, $limit = 0, $maxResults = null)
    {
        // Populate from data
        $items = $this->getItemsFromData($columns);
        $serializeColumns = [];

        foreach ($this->data as $key => $item) {

            foreach ($columns as $column) {
                $fieldName = $column->getField();
                $fieldValue = $items[$key][$fieldName];
                $dataIsNumeric = ($column->getType() == 'number' || $column->getType() == 'boolean');

                if ($column->getType() === 'array') {
                    $serializeColumns[] = $column->getId();
                }

                // Filter
                if ($column->isFiltered()) {
                    // Some attributes of the column can be changed in this function
                    $filters = $column->getFilters('vector');

                    if ($column->getDataJunction() === Column::DATA_DISJUNCTION) {
                        $disjunction = true;
                        $keep = false;
                    } else {
                        $disjunction = false;
                        $keep = true;
                    }

                    $found = false;
                    foreach ($filters as $filter) {
                        $operator = $filter->getOperator();
                        $value = $filter->getValue();

                        // Normalize value
                        if (!$dataIsNumeric && !($value instanceof \DateTime)) {
                            $value = $this->prepareStringForLikeCompare($value);
                            switch ($operator) {
                                case Column::OPERATOR_EQ:
                                    $value = '/^' . preg_quote($value, '/') . '$/i';
                                    break;
                                case Column::OPERATOR_NEQ:
                                    $value = '/^(?!' . preg_quote($value, '/') . '$).*$/i';
                                    break;
                                case Column::OPERATOR_LIKE:
                                    $value = '/' . preg_quote($value, '/') . '/i';
                                    break;
                                case Column::OPERATOR_NLIKE:
                                    $value = '/^((?!' . preg_quote($value, '/') . ').)*$/i';
                                    break;
                                case Column::OPERATOR_LLIKE:
                                    $value = '/' . preg_quote($value, '/') . '$/i';
                                    break;
                                case Column::OPERATOR_RLIKE:
                                    $value = '/^' . preg_quote($value, '/') . '/i';
                                    break;
                                case Column::OPERATOR_SLIKE:
                                    $value = '/' . preg_quote($value, '/') . '/';
                                    break;
                                case Column::OPERATOR_NSLIKE:
                                    $value = '/^((?!' . preg_quote($value, '/') . ').)*$/';
                                    break;
                                case Column::OPERATOR_LSLIKE:
                                    $value = '/' . preg_quote($value, '/') . '$/';
                                    break;
                                case Column::OPERATOR_RSLIKE:
                                    $value = '/^' . preg_quote($value, '/') . '/';
                                    break;
                            }
                        }

                        // Test
                        switch ($operator) {
                            case Column::OPERATOR_EQ:
                                if ($dataIsNumeric) {
                                    $found = abs($fieldValue - $value) < 0.00001;
                                    break;
                                }
                            case Column::OPERATOR_NEQ:
                                if ($dataIsNumeric) {
                                    $found = abs($fieldValue - $value) > 0.00001;
                                    break;
                                }
                            case Column::OPERATOR_LIKE:
                            case Column::OPERATOR_NLIKE:
                            case Column::OPERATOR_LLIKE:
                            case Column::OPERATOR_RLIKE:
                            case Column::OPERATOR_SLIKE:
                            case Column::OPERATOR_NSLIKE:
                            case Column::OPERATOR_LSLIKE:
                            case Column::OPERATOR_RSLIKE:
                                $fieldValue = $this->prepareStringForLikeCompare($fieldValue, $column->getType());

                                $found = preg_match($value, $fieldValue);
                                break;
                            case Column::OPERATOR_GT:
                                $found = $fieldValue > $value;
                                break;
                            case Column::OPERATOR_GTE:
                                $found = $fieldValue >= $value;
                                break;
                            case Column::OPERATOR_LT:
                                $found = $fieldValue < $value;
                                break;
                            case Column::OPERATOR_LTE:
                                $found = $fieldValue <= $value;
                                break;
                            case Column::OPERATOR_ISNULL:
                                $found = $fieldValue === null;
                                break;
                            case Column::OPERATOR_ISNOTNULL:
                                $found = $fieldValue !== null;
                                break;
                        }

                        // AND
                        if (!$found && !$disjunction) {
                            $keep = false;
                            break;
                        }

                        // OR
                        if ($found && $disjunction) {
                            $keep = true;
                            break;
                        }
                    }

                    if (!$keep) {
                        unset($items[$key]);
                        break;
                    }
                }
            }
        }

        // Order
        foreach ($columns as $column) {
            if ($column->isSorted()) {
                $sortType = SORT_REGULAR;
                $sortedItems = [];
                foreach ($items as $key => $item) {
                    $value = $item[$column->getField()];

                    // Format values for sorting and define the type of sort
                    switch ($column->getType()) {
                        case 'text':
                            $sortedItems[$key] = strtolower($value);
                            $sortType = SORT_STRING;
                            break;
                        case 'datetime':
                        case 'date':
                        case 'time':
                            if ($value instanceof \DateTime) {
                                $sortedItems[$key] = $value->getTimestamp();
                            } else {
                                $sortedItems[$key] = strtotime($value);
                            }
                            $sortType = SORT_NUMERIC;
                            break;
                        case 'boolean':
                            $sortedItems[$key] = $value ? 1 : 0;
                            $sortType = SORT_NUMERIC;
                            break;
                        case 'array':
                            $sortedItems[$key] = json_encode($value);
                            $sortType = SORT_STRING;
                            break;
                        case 'number':
                            $sortedItems[$key] = $value;
                            $sortType = SORT_NUMERIC;
                            break;
                        default:
                            $sortedItems[$key] = $value;
                            $sortType = SORT_REGULAR;
                    }
                }

                if (!empty($sortedItems)) {
                    array_multisort($sortedItems, ($column->getOrder() == 'asc') ? SORT_ASC : SORT_DESC, $sortType, $items);
                }

                break;
            }
        }

        $this->count = count($items);

        // Pagination
        if ($limit > 0) {
            $maxResults = ($maxResults !== null && ($maxResults - $page * $limit < $limit)) ? $maxResults - $page * $limit : $limit;

            $items = array_slice($items, $page * $limit, $maxResults);
        } elseif ($maxResults !== null) {
            $items = array_slice($items, 0, $maxResults);
        }

        $rows = new Rows();
        foreach ($items as $item) {
            $row = new Row();

            if ($this instanceof Vector) {
                $row->setPrimaryField($this->getId());
            }

            foreach ($item as $fieldName => $fieldValue) {
                if ($this instanceof Entity) {
                    if (in_array($fieldName, $serializeColumns)) {
                        if (is_string($fieldValue)) {
                            $fieldValue = unserialize($fieldValue);
                        }
                    }
                }

                $row->setField($fieldName, $fieldValue);
            }

            //call overridden prepareRow or associated closure
            if (($modifiedRow = $this->prepareRow($row)) != null) {
                $rows->addRow($modifiedRow);
            }
        }

        $this->items = $items;

        return $rows;
    }
Find data from array|object.

@param Column[] $columns
@param int      $page
@param int      $limit
@param int      $maxResults

@return Rows