ArrayQuery.php (5502B)
1 <?php 2 3 namespace Finwo\Datatools; 4 5 use Finwo\PropertyAccessor\PropertyAccessor; 6 7 class ArrayQuery 8 { 9 /** 10 * @var array 11 */ 12 protected $table = array(); 13 14 /** 15 * @var array 16 */ 17 protected $selects = array(); 18 19 /** 20 * @var array 21 */ 22 protected $filters = array(); 23 24 /** 25 * @var string 26 */ 27 protected $selectedField = ''; 28 29 /** 30 * @var PropertyAccessor 31 */ 32 protected $accessor; 33 34 /** 35 * @var integer 36 */ 37 protected $skip = 0; 38 39 /** 40 * @var integer 41 */ 42 protected $limit = -2; 43 44 /** 45 * @var array 46 */ 47 protected $columnNames = array(); 48 49 /** 50 * ArrayQuery constructor. 51 * 52 * @param array $data 53 */ 54 public function __construct($data = array()) 55 { 56 $this->table = $data; 57 } 58 59 /** 60 * @param array $input 61 * 62 * @return ArrayQuery 63 */ 64 public static function table($input = array()) 65 { 66 return new ArrayQuery($input); 67 } 68 69 /** 70 * @param $input 71 * 72 * @return ArrayQuery $this 73 */ 74 public function select( $input ) 75 { 76 if ( 77 is_callable($input) || 78 is_string($input) 79 ) { 80 $this->selects[] = $input; 81 } elseif (is_array($input)) { 82 foreach($input as $item) { 83 $this->select($item); 84 } 85 } 86 87 return $this; 88 } 89 90 /** 91 * @param $input 92 * 93 * @return $this 94 */ 95 public function field( $input ) 96 { 97 if(is_string($input)) { 98 $this->selectedField = $input; 99 } 100 101 return $this; 102 } 103 104 /** 105 * @param $input 106 * 107 * @return $this 108 */ 109 public function equals( $input ) 110 { 111 if(is_string($input)) { 112 $this->filters[]= array( 113 'field' => $this->selectedField, 114 'type' => 'equals', 115 'value' => $input, 116 ); 117 } 118 119 return $this; 120 } 121 122 /** 123 * @param $input 124 * 125 * @return $this 126 */ 127 public function validates( $input ) 128 { 129 if(is_callable($input)) { 130 $this->filters[]= array( 131 'field' => $this->selectedField, 132 'type' => 'validate', 133 'value' => $input, 134 ); 135 136 } 137 138 return $this; 139 } 140 141 /** 142 * @param $input 143 * 144 * @return $this 145 */ 146 public function columnName( $input ) 147 { 148 if (is_array($input)) { 149 $this->columnNames = $input; 150 } 151 152 if (is_string($input)) { 153 $this->columnNames[] = $input; 154 } 155 156 return $this; 157 } 158 159 /** 160 * @param integer $input 161 * 162 * @return $this 163 */ 164 public function skip( $input ) 165 { 166 $this->skip = intval($input); 167 return $this; 168 } 169 170 /** 171 * @param integer $input 172 * 173 * @return $this 174 */ 175 public function limit( $input ) 176 { 177 $this->limit = intval($input); 178 return $this; 179 } 180 181 /** 182 * @return PropertyAccessor 183 */ 184 protected function getAccessor() 185 { 186 if (is_null($this->accessor)) { 187 $this->accessor = new PropertyAccessor(); 188 } 189 return $this->accessor; 190 } 191 192 /** 193 * @return array 194 */ 195 public function execute() 196 { 197 $outputIndex = 0; 198 $output = array(); 199 200 //loop through table 201 foreach ($this->table as $row) { 202 203 // handle limit 204 if ( $this->limit-- == 0 ) { 205 break; 206 } 207 208 // reset the current row 209 $columnIndex = 0; 210 $outputRow = array(); 211 212 // fetch columns 213 foreach ($this->selects as $select) { 214 215 // allow associative column names 216 $colName = $columnIndex++; 217 if (isset($this->columnNames[$colName])) { 218 $colName = $this->columnNames[$colName]; 219 } 220 221 // fetch & store value 222 $outputRow[$colName] = $this->executeSelect($row, $select); 223 } 224 225 // run through filters 226 if ( $this->executeFilters($outputRow) ) { 227 228 // handle offset 229 if ( $this->skip-- > 0) { 230 continue; 231 } 232 233 // add row to output 234 $output[$outputIndex++] = $outputRow; 235 } else { 236 $this->limit++; 237 } 238 239 } 240 241 return $output; 242 } 243 244 protected function executeSelect($row, $select) 245 { 246 // Callable select statements 247 if (is_callable($select)) { 248 return call_user_func($select, $row); 249 } 250 251 // String selects 252 if (is_string($select)) { 253 return $this->getAccessor()->get($row, $select); 254 } 255 256 // Return empty column 257 return null; 258 } 259 260 protected function executeFilters($row) 261 { 262 foreach ($this->filters as $filter) { 263 switch($filter['type']) { 264 case 'equals': 265 if ($row[$filter['field']] !== $filter['value']) { 266 return false; 267 } 268 break; 269 case 'validate': 270 return call_user_func($filter['value'], $row[$filter['field']], $row); 271 default: 272 //unknown filter 273 break; 274 } 275 276 } 277 278 return true; 279 } 280 }