1: <?php namespace mechanicious\Tableman;
2:
3: use mechanicious\Columnizer\ColumnBag;
4: use mechanicious\Columnizer\Column;
5: use mechanicious\Columnizer\Columnizer;
6: use mechanicious\TablemanExtension\TablemanExtension;
7: use mechanicious\TablemanExtension\Config;
8: use Illuminate\Support\Collection;
9:
10: 11: 12: 13: 14:
15: class Tableman extends TablemanCollection
16: {
17: use \mechanicious\Support\ArrayableTrait;
18:
19: 20: 21: 22:
23: protected $exts = array();
24:
25: public function __construct(ColumnBag $cols)
26: {
27: $this->items = $cols->all();
28: }
29:
30: 31: 32: 33: 34:
35: public function getJson($format = 'column')
36: {
37: switch ($format) {
38: case 'column':
39: return $json = $this->toJson();
40: break;
41:
42: default:
43: $collection = new Collection($this->getRows());
44: return $json = $collection->toJson();
45: break;
46: }
47: }
48:
49:
50: private function getHtml(){
51: }
52:
53: private function getXml(){
54: }
55:
56: 57: 58: 59: 60: 61:
62: public function withdraw(\closure $callback)
63: {
64: return $callback($this);
65: }
66:
67: 68: 69: 70: 71: 72: 73: 74:
75: public function sortColumns(\closure $callback)
76: {
77: $this->sort($callback);
78: return $this;
79: }
80:
81: 82: 83: 84: 85:
86: public function reverse()
87: {
88: $this->items = array_reverse($this->items);
89: return $this;
90: }
91:
92: 93: 94: 95: 96:
97: public function reverseColumns()
98: {
99: $this->reverse();
100: return $this;
101: }
102:
103: 104: 105: 106: 107:
108: public function orderColumns(array $order = array())
109: {
110: array_walk($order, function() use(&$order) {
111: $this->sort(function($previous, $current) use($order) {
112:
113:
114: $prevOffset = array_search($previous->getHeader(), $order);
115: $currentOffset = array_search($current->getHeader(), $order);
116:
117: if($prevOffset == $currentOffset) return 0;
118: return ($prevOffset < $currentOffset) ? -1 : 1;
119: });
120: });
121: }
122:
123: 124: 125: 126: 127:
128: public function getColumns()
129: {
130: return $this->items;
131: }
132:
133: 134: 135: 136: 137:
138: public function getColumnOrder()
139: {
140: return array_keys($this->items);
141: }
142:
143: 144: 145: 146: 147:
148: public function getColumnHeaders()
149: {
150: return array_keys($this->items);
151: }
152:
153: 154: 155: 156: 157:
158: public function columnExists($header)
159: {
160: return in_array($header, $this->getColumnHeaders());
161: }
162:
163: 164: 165: 166: 167: 168: 169:
170: public function columnHas($header, $needle)
171: {
172: return in_array($needle, $this->items[$header]->toArray());
173: }
174:
175: 176: 177: 178: 179: 180:
181: public function addColumn(Column $col, $offset)
182: {
183: $header = $col->getHeader();
184:
185:
186: if($this->columnExists($header)) $this->forget($header);
187:
188: $columnOrder = $this->getColumnHeaders();
189: array_splice($columnOrder, $offset, 0, $header);
190:
191: $this->items[$header] = $this->padData($col);
192:
193: $this->orderColumns($columnOrder);
194: return $this;
195: }
196:
197: 198: 199: 200: 201: 202:
203: public function padData(Column $col, $padValue = null)
204: {
205: if( ( $colSize = count($col) ) > ( $dataSize = count($this->first()) ) )
206: {
207: $this->eachColumn(function(&$ref, &$column, $header) use($colSize, $padValue) {
208: $column->items = array_pad($column->all(), $colSize, $padValue);
209: });
210: }
211: else
212: {
213: $col->items = array_pad($col->all(), $dataSize, $padValue);
214: }
215:
216: return $col;
217: }
218:
219: 220: 221: 222: 223: 224:
225: public function prependColumn(Column $col)
226: {
227: $this->items[$col->getHeader()] = $this->padData($col);
228: $order = $this->getColumnHeaders();
229: array_unshift($order, $col->getHeader());
230: $this->orderColumns($order);
231: return $this;
232: }
233:
234: 235: 236: 237: 238: 239:
240: public function appendColumn(Column $col)
241: {
242: $this->items[$col->getHeader()] = $this->padData($col);
243: return $this;
244: }
245:
246: 247: 248: 249: 250: 251:
252: public function popColumn()
253: {
254: $this->pop();
255: return $this;
256: }
257:
258: 259: 260: 261: 262: 263:
264: public function shiftColumn()
265: {
266: $this->shift();
267: return $this;
268: }
269:
270: 271: 272: 273: 274: 275:
276: public function removeColumn($header)
277: {
278: $this->forget($header);
279: return $this;
280: }
281:
282: 283: 284: 285: 286: 287: 288:
289: public function compareColumnContent($colA, $colB)
290: {
291: return (bool) ($colA->toJson() === $colB->toJson());
292: }
293:
294: 295: 296: 297: 298: 299: 300:
301: public function replaceColumn(Column $col, $header)
302: {
303: if( ! in_array($header, array_keys($this->items))) throw new \Exception("column {$header} don't exist in " . implode(', ', array_keys($this->items)));
304:
305: $this->items[$header] = $col;
306: if($header !== $col->getHeader())
307: {
308: $this->renameColumns(array($header => $col->getHeader()));
309: }
310:
311: return $this;
312: }
313:
314: 315: 316: 317: 318: 319: 320:
321: public function eachRowOf($header, \closure $callback)
322: {
323: array_walk($this->items[$header]->items, function(&$row, $rowIndex) use($callback)
324: {
325: $callback($this, $row, $rowIndex);
326: });
327: return $this;
328: }
329:
330: 331: 332: 333: 334: 335: 336:
337: public function eachRow(\closure $callback)
338: {
339: array_walk($this->getRows(), function(&$row, $rowIndex) use($callback)
340: {
341: $callback($this, $row, $rowIndex);
342: });
343: return $this;
344: }
345:
346: 347: 348: 349: 350: 351: 352:
353: public function eachCell(\closure $callback)
354: {
355: array_walk($this->getRows(), function(&$row, $rowIndex) use(&$rows, $callback) {
356: foreach($row as $index => &$cell)
357: {
358: $callback($this, $cell, $row, $rowIndex);
359: }
360: });
361: return $this;
362: }
363:
364: 365: 366: 367: 368: 369: 370:
371: public function eachColumn(\closure $callback)
372: {
373: array_walk($this->items, function(&$column, &$columnHeader) use($callback, &$columns) {
374: $callback($this, $column, $columnHeader);
375: });
376: return $this;
377: }
378:
379: 380: 381: 382: 383: 384:
385: public function getColumn($header)
386: {
387: return $this[$header];
388: }
389:
390: 391: 392: 393: 394:
395: public function getAllColumns()
396: {
397: return $this->items;
398: }
399:
400: 401: 402: 403: 404:
405: public function getRows()
406: {
407: $items = &$this->items;
408: $mergee = array();
409: $columnNames = array_keys($this->items);
410:
411: for($i = 0; $i < count($this->first()); $i++)
412: {
413: $row = array();
414: foreach($items as $header => &$column)
415: {
416: $row[$header] = &$column->items[$i];
417: }
418: $mergee[] = $row;
419: }
420: return $mergee;
421: }
422:
423: 424: 425: 426: 427:
428: public function renameColumns(array $headers = array())
429: {
430: $items = $this->items;
431:
432:
433:
434: $headersCopy = $this->getColumnHeaders();
435: array_walk($headers, function($newKey, $oldKey) use(&$items, &$headersCopy) {
436: if($newKey !== $oldKey)
437: {
438: $column = new Column($items[$oldKey]->all(), $newKey);
439: $this->forget($oldKey);
440: $this->put($newKey, $column);
441:
442: $headersCopy[array_search($oldKey, $headersCopy)] = $newKey;
443: }
444: });
445:
446: $this->orderColumns($headersCopy);
447: return $this;
448: }
449:
450: public function __call($name, $args)
451: {
452: $autloadedClasses = get_declared_classes();
453:
454:
455: if(in_array($name, array_keys($this->exts))) return $this->exts[$name]->make($this, new Config($args[0]));
456:
457: 458: 459:
460: $found = false;
461:
462: array_walk($autloadedClasses, function($class, $index) use($name, &$found) {
463: if(is_string($found)) return;
464: $segments = explode('\\', $class);
465:
466:
467: if(last($segments) === $name) return $found = $class;
468: });
469:
470: if($found && ($instance = new $found) instanceof TablemanExtension)
471: {
472: $this->exts[$name] = $instance;
473: return $this->exts[$name]->make($this, new Config($args[0]));
474: }
475:
476: 477: 478:
479: $ext_reg = require "/../Config/ExtensionRegister.php";
480: if( ! in_array($name, array_keys($ext_reg))) throw new \Exception("method {$name} is not a part of " . __CLASS__);
481: require_once $ext_reg[$name]['relative_path'];
482: $classname = $ext_reg[$name]['fully_qualified_classname'];
483: $instance = new $classname;
484: $this->exts[$name] = $instance;
485: if( ! isset($args[0])) throw new \Exception("you must provide a config for {$name}");
486: if( ! is_array($args[0])) throw new \Exception("config for {$name} must be an array");
487: return $this->exts[$name]->make($this, new Config($args[0]));
488: }
489: }