Grido@master
  • Namespace
  • Class
  • Tree
  • Deprecated
  • Todo
  • Download

Namespaces

  • Grido
    • Components
      • Actions
      • Columns
      • Filters
    • DataSources
    • PropertyAccessors
    • Translations

Classes

  • Grido\Translations\FileTranslator
  1 <?php
  2 
  3 /**
  4  * This file is part of the Grido (https://github.com/o5/grido)
  5  *
  6  * Copyright (c) 2011 Petr Bugyík (http://petr.bugyik.cz)
  7  *
  8  * For the full copyright and license information, please view
  9  * the file LICENSE.md that was distributed with this source code.
 10  */
 11 
 12 namespace Grido\DataSources;
 13 
 14 use Grido\Components\Filters\Condition;
 15 
 16 /**
 17  * Array data source.
 18  *
 19  * @package     Grido
 20  * @subpackage  DataSources
 21  * @author      Josef Kříž <pepakriz@gmail.com>
 22  * @author      Petr Bugyík
 23  *
 24  * @property-read array $data
 25  * @property-read int $count
 26  */
 27 class ArraySource extends \Nette\Object implements IDataSource
 28 {
 29     /** @var array */
 30     protected $data;
 31 
 32     /**
 33      * @param array $data
 34      */
 35     public function __construct(array $data)
 36     {
 37         $this->data = $data;
 38     }
 39 
 40     /**
 41      * @param Condition $condition
 42      * @param array $data
 43      * @return array
 44      */
 45     protected function makeWhere(Condition $condition, array $data = NULL)
 46     {
 47         $data = $data === NULL
 48             ? $this->data
 49             : $data;
 50 
 51         $that = $this;
 52         return array_filter($data, function ($row) use ($condition, $that) {
 53             if ($condition->callback) {
 54                 return callback($condition->callback)->invokeArgs(array($condition->value, $row));
 55             }
 56 
 57             $i = 0;
 58             $results = array();
 59             foreach ($condition->column as $column) {
 60                 if (Condition::isOperator($column)) {
 61                     $results[] = " $column ";
 62 
 63                 } else {
 64                     $i = count($condition->condition) > 1 ? $i : 0;
 65                     $results[] = (int) $that->compare(
 66                         $row[$column],
 67                         $condition->condition[$i],
 68                         isset($condition->value[$i]) ? $condition->value[$i] : NULL
 69                     );
 70 
 71                     $i++;
 72                 }
 73             }
 74 
 75             $result = implode('', $results);
 76             return count($condition->column) === 1
 77                 ? (bool) $result
 78                 : eval("return $result;");
 79         });
 80     }
 81 
 82     /**
 83      * @param string $actual
 84      * @param string $condition
 85      * @param mixed $expected
 86      * @throws \InvalidArgumentException
 87      * @return bool
 88      */
 89     public function compare($actual, $condition, $expected)
 90     {
 91         $expected = (array) $expected;
 92         $expected = current($expected);
 93         $cond = str_replace(' ?', '', $condition);
 94 
 95         if ($cond === 'LIKE') {
 96             $pattern = str_replace('%', '(.|\s)*', preg_quote($expected, '/'));
 97             return (bool) preg_match("/^{$pattern}$/i", $actual);
 98 
 99         } elseif ($cond === '=') {
100             return $actual == $expected;
101 
102         } elseif ($cond === '<>') {
103             return $actual != $expected;
104 
105         } elseif ($cond === 'IS NULL') {
106             return $actual === NULL;
107 
108         } elseif ($cond === 'IS NOT NULL') {
109             return $actual !== NULL;
110 
111         } elseif (in_array($cond, array('<', '<=', '>', '>='))) {
112             return eval("return {$actual} {$cond} {$expected};");
113 
114         } else {
115             throw new \InvalidArgumentException("Condition '$condition' not implemented yet.");
116         }
117     }
118 
119     /*********************************** interface IDataSource ************************************/
120 
121     /**
122      * @return int
123      */
124     public function getCount()
125     {
126         return count($this->data);
127     }
128 
129     /**
130      * @return array
131      */
132     public function getData()
133     {
134         return $this->data;
135     }
136 
137     /**
138      * @param array $conditions
139      */
140     public function filter(array $conditions)
141     {
142         foreach ($conditions as $condition) {
143             $this->data = $this->makeWhere($condition);
144         }
145     }
146 
147     /**
148      * @param int $offset
149      * @param int $limit
150      */
151     public function limit($offset, $limit)
152     {
153         $this->data = array_slice($this->data, $offset, $limit);
154     }
155 
156     /**
157      * @param array $sorting
158      * @throws \Exception
159      */
160     public function sort(array $sorting)
161     {
162         if (count($sorting) > 1) {
163             throw new \Exception('Multi-column sorting is not implemented yet.');
164         }
165 
166         foreach ($sorting as $column => $sort) {
167             $data = array();
168             foreach ($this->data as $item) {
169                 $sorter = (string) $item[$column];
170                 $data[$sorter][] = $item;
171             }
172 
173             if ($sort === 'ASC') {
174                 ksort($data);
175             } else {
176                 krsort($data);
177             }
178 
179             $this->data = array();
180             foreach ($data as $i) {
181                 foreach ($i as $item) {
182                     $this->data[] = $item;
183                 }
184             }
185         }
186     }
187 
188     /**
189      * @param mixed $column
190      * @param array $conditions
191      * @param int $limit
192      * @return array
193      * @throws \InvalidArgumentException
194      */
195     public function suggest($column, array $conditions, $limit)
196     {
197         $data = $this->data;
198         foreach ($conditions as $condition) {
199             $data = $this->makeWhere($condition, $data);
200         }
201 
202         array_slice($data, 1, $limit);
203 
204         $items = array();
205         foreach ($data as $row) {
206             if (is_string($column)) {
207                 $value = (string) $row[$column];
208             } elseif (is_callable($column)) {
209                 $value = (string) $column($row);
210             } else {
211                 $type = gettype($column);
212                 throw new \InvalidArgumentException("Column of suggestion must be string or callback, $type given.");
213             }
214 
215             $items[$value] = \Nette\Templating\Helpers::escapeHtml($value);
216         }
217 
218         return array_values($items);
219     }
220 }
221 
Grido@master API documentation generated by ApiGen