diff --git a/src/Pike/DataTable/Adapter/AbstractAdapter.php b/src/Pike/DataTable/Adapter/AbstractAdapter.php index 2bde655..c592dc6 100644 --- a/src/Pike/DataTable/Adapter/AbstractAdapter.php +++ b/src/Pike/DataTable/Adapter/AbstractAdapter.php @@ -5,6 +5,7 @@ use Zend\View\Model\ViewModel; use Pike\DataTable\DataSource\DataSourceInterface; use Pike\DataTable\ColumnBag; +use Pike\DataTable; abstract class AbstractAdapter implements AdapterInterface { @@ -69,6 +70,47 @@ public function __construct() $this->setAutoEscapeFilter(); } + /** + * Get items should return the current page datatable + * data with callbacks and filters already being processed. + * + * @return array + */ + protected function getItems(DataTable $dataTable, $offset, $limit) + { + $items = $dataTable->getDataSource()->getItems($offset, $limit); + + foreach ($items as &$row) { + $newRow = array(); + + foreach ($this->columnBag as $columnName => $column) { + $newRow[$columnName] = $column['data']($row); + } + + $row = $newRow; + } + + $items = $this->filterItems($items); + + return $items; + } + + /** + * @param array $items + * + * @return array + */ + protected function filterItems($items) + { + foreach ($items as &$item) { + foreach (array_values($item) as $index => $string) { + $item[$index] = $this->filter($string, $this->columnBag->getOffset($index)); + } + } + + return $items; + } + /** * @return string */ diff --git a/src/Pike/DataTable/Adapter/DataTables.php b/src/Pike/DataTable/Adapter/DataTables.php index 10c663c..0a0bf2d 100644 --- a/src/Pike/DataTable/Adapter/DataTables.php +++ b/src/Pike/DataTable/Adapter/DataTables.php @@ -5,6 +5,7 @@ use Pike\DataTable; use Pike\DataTable\DataSource\DataSourceInterface; use Zend\View\Model\JsonModel; +use Zend\View\Model\ViewModel; use Zend\Json; class DataTables extends AbstractAdapter @@ -35,7 +36,7 @@ public function __construct() } /** - * @return string + * @return ViewModel */ public function render(DataTable $dataTable) { @@ -49,10 +50,7 @@ public function render(DataTable $dataTable) $this->viewModel->setVariable('attributes', $this->getAttributes()); if (null !== $this->getOption('iDeferLoading')) { - $items = $dataTable->getDataSource() - ->getItems(0, $this->getOption('iDeferLoading')); - $items = $this->filterItems($items); - $this->viewModel->setVariable('items', $items); + $this->viewModel->setVariable('items', $this->getItems($dataTable, 0, $this->getOption('iDeferLoading'))); } return $this->viewModel; @@ -84,31 +82,17 @@ public function getResponse(DataTable $dataTable) } $count = count($dataSource); - $items = $dataSource->getItems($offset, $limit); + $items = $this->getItems($dataTable, $offset, $limit); $data = array(); $data['sEcho'] = (int) $this->parameters['sEcho']; $data['iTotalRecords'] = $count; $data['iTotalDisplayRecords'] = $count; - $data['aaData'] = $this->filterItems($items); + $data['aaData'] = $items; return new JsonModel($data); } - /** - * @param array $items - * @return array - */ - protected function filterItems($items) - { - foreach ($items as &$item) { - foreach (array_values($item) as $index => $string) { - $item[$index] = $this->filter($string, $this->columnBag->getOffset($index)); - } - } - - return $items; - } /** * {@inheritdoc} diff --git a/src/Pike/DataTable/ColumnBag.php b/src/Pike/DataTable/ColumnBag.php index 0cd327a..eb6e9c1 100644 --- a/src/Pike/DataTable/ColumnBag.php +++ b/src/Pike/DataTable/ColumnBag.php @@ -27,26 +27,48 @@ public function __construct(array $columns = array()) /** * Adds a column to the column bag * - * @param string $column The column name - * @param string $label The friendly name used for this column as heading - * @param string $field The field name to be used when sorting is isseud - * @param integer $position The position number, can be any number - * @param boolean $display Show column + * @param string $columnName The column name + * @param string $label The friendly name used for this column as heading + * @param string $field The field name to be used when sorting is isseud + * @param integer $position The position number, can be any number + * @param boolean $display Show column + * @param Closure $data A callback which called everyrow this column needs to be drawed with row data as argument */ - public function add($column, $label = null, $field = null, $position = null, - $display = true + public function add($columnName, $label = null, $field = null, $position = null, + $display = true, \Closure $data = null ) { - $label = isset($label) ? $label : $column; - $field = isset($field) ? $field : $column; + $label = isset($label) ? $label : $columnName; + $field = isset($field) ? $field : $columnName; $position = isset($position) ? $position : count($this->columns) + 1; - $this->columns[$column] = array( - 'column' => $column, + $column = array( + 'column' => $columnName, 'label' => $label, 'field' => $field, 'position' => $position, - 'display' => $display + 'display' => $display, + 'data' => $data, ); + + if (!is_callable($data)) { + $column['data'] = function($row) use ($columnName, $data) { + if (is_string($data) || is_integer($data)) { + return $data; + } + + if ($row[$columnName] instanceof \DateTime) { + return $row[$columnName]->format(\DateTime::ISO8601); + } + + return $row[$columnName]; + }; + } + + if ($this->has($columnName)) { + $column = array_merge($column,$this->get($columnName)); + } + + $this->columns[$columnName] = $column; } /** @@ -60,7 +82,7 @@ public function setLabel($column, $label) { $this->get($column); - $this->columns[$column] = $label; + $this->columns[$column]['label'] = $label; return $this; } @@ -89,7 +111,7 @@ public function setField($column, $field) { $this->get($column); - $this->columns[$column] = $field; + $this->columns[$column]['field'] = $field; return $this; } @@ -118,7 +140,7 @@ public function setPosition($column, $position) { $this->get($column); - $this->columns[$column] = $position; + $this->columns[$column]['position'] = $position; return $this; } @@ -147,7 +169,7 @@ public function setDisplay($column, $display) { $this->get($column); - $this->columns[$column] = $display; + $this->columns[$column]['display'] = $display; return $this; } @@ -156,6 +178,7 @@ public function setDisplay($column, $display) * Returns the display for the specified column * * @param string $column + * * @return boolean */ public function getDisplay($column) @@ -168,8 +191,10 @@ public function getDisplay($column) /** * Returns the specified column * - * @param string $column + * @param string $column + * * @return array + * * @throws \Pike\Exception */ public function get($column) @@ -185,6 +210,7 @@ public function get($column) * Returns the column for the specified offset * * @param integer $offset + * * @return array */ public function getOffset($offset) @@ -199,6 +225,33 @@ public function getOffset($offset) return current($columns); } + /** + * Set the callback for a specific column. + * + * @param string $column + * @param \Closure $callback + * + * @return ColumnBag + */ + public function setDataCallback($column, \Closure $callback) + { + $this->columns[$column]['data'] = $callback; + + return $this; + } + + /** + * Get the closure for a given column. + * + * @return \Closure + */ + public function getDataCallback($column) + { + $column = $this->get($column); + + return $column['data']; + } + /** * Returns all columns * diff --git a/src/Pike/DataTable/DataSource/Doctrine.php b/src/Pike/DataTable/DataSource/Doctrine.php index dcab0da..440960c 100644 --- a/src/Pike/DataTable/DataSource/Doctrine.php +++ b/src/Pike/DataTable/DataSource/Doctrine.php @@ -78,12 +78,6 @@ public function getItems($offset, $limit) $data = $paginateQuery->getArrayResult(); - array_walk_recursive($data, function(&$item, $key) { - if ($item instanceof \DateTime) { - $item = $item->format('c'); - } - }); - return $data; }