From 125e7d647511bf748e6764824fb1f1c53f3e8689 Mon Sep 17 00:00:00 2001 From: Robert Ross Date: Wed, 25 May 2011 15:22:52 -0700 Subject: [PATCH 01/11] Float values for totals instead of integers --- views/elements/csv/column_actions.ctp | 0 views/elements/csv/grid_empty_row.ctp | 1 - views/elements/csv/grid_full.ctp | 2 - views/elements/csv/grid_headers.ctp | 1 - views/elements/csv/grid_row.ctp | 1 - views/elements/table/column_actions.ctp | 3 - views/elements/table/grid_empty_row.ctp | 3 - views/elements/table/grid_full.ctp | 8 - views/elements/table/grid_headers.ctp | 5 - views/elements/table/grid_row.ctp | 7 - views/helpers/grid.php | 435 ------------------------ 11 files changed, 466 deletions(-) delete mode 100644 views/elements/csv/column_actions.ctp delete mode 100644 views/elements/csv/grid_empty_row.ctp delete mode 100644 views/elements/csv/grid_full.ctp delete mode 100644 views/elements/csv/grid_headers.ctp delete mode 100644 views/elements/csv/grid_row.ctp delete mode 100644 views/elements/table/column_actions.ctp delete mode 100644 views/elements/table/grid_empty_row.ctp delete mode 100644 views/elements/table/grid_full.ctp delete mode 100644 views/elements/table/grid_headers.ctp delete mode 100644 views/elements/table/grid_row.ctp delete mode 100644 views/helpers/grid.php diff --git a/views/elements/csv/column_actions.ctp b/views/elements/csv/column_actions.ctp deleted file mode 100644 index e69de29..0000000 diff --git a/views/elements/csv/grid_empty_row.ctp b/views/elements/csv/grid_empty_row.ctp deleted file mode 100644 index 89d1899..0000000 --- a/views/elements/csv/grid_empty_row.ctp +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/views/elements/csv/grid_full.ctp b/views/elements/csv/grid_full.ctp deleted file mode 100644 index 9f2d7a9..0000000 --- a/views/elements/csv/grid_full.ctp +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/views/elements/csv/grid_headers.ctp b/views/elements/csv/grid_headers.ctp deleted file mode 100644 index 333ba07..0000000 --- a/views/elements/csv/grid_headers.ctp +++ /dev/null @@ -1 +0,0 @@ -Grid->csvData(Set::extract('/title', array_values($headers))); ?> \ No newline at end of file diff --git a/views/elements/csv/grid_row.ctp b/views/elements/csv/grid_row.ctp deleted file mode 100644 index 6f4b244..0000000 --- a/views/elements/csv/grid_row.ctp +++ /dev/null @@ -1 +0,0 @@ -Grid->csvData($rowColumns); ?> \ No newline at end of file diff --git a/views/elements/table/column_actions.ctp b/views/elements/table/column_actions.ctp deleted file mode 100644 index 52e0315..0000000 --- a/views/elements/table/column_actions.ctp +++ /dev/null @@ -1,3 +0,0 @@ - $action): ?> - Html->link($title, $action['url'], $action['options'] + array('class' => 'cg_action')); ?> - \ No newline at end of file diff --git a/views/elements/table/grid_empty_row.ctp b/views/elements/table/grid_empty_row.ctp deleted file mode 100644 index 57ce3a6..0000000 --- a/views/elements/table/grid_empty_row.ctp +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/views/elements/table/grid_full.ctp b/views/elements/table/grid_full.ctp deleted file mode 100644 index 7697044..0000000 --- a/views/elements/table/grid_full.ctp +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - -
\ No newline at end of file diff --git a/views/elements/table/grid_headers.ctp b/views/elements/table/grid_headers.ctp deleted file mode 100644 index 3e8a3fb..0000000 --- a/views/elements/table/grid_headers.ctp +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/views/elements/table/grid_row.ctp b/views/elements/table/grid_row.ctp deleted file mode 100644 index 7866c10..0000000 --- a/views/elements/table/grid_row.ctp +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/views/helpers/grid.php b/views/helpers/grid.php deleted file mode 100644 index 2a997c7..0000000 --- a/views/helpers/grid.php +++ /dev/null @@ -1,435 +0,0 @@ -options(array()); - } - - /** - * Set options for headers and such - * - * @param string $options - * @return void - * @author Robert Ross - */ - function options($options){ - $defaults = array( - 'class_header' => 'cg_header', - 'class_row' => 'cg_row', - 'class_table' => 'cg_table', - 'empty_message' => 'No Results', - 'separator' => ' ', - 'type' => 'table' - ); - - $options = array_merge($defaults, $options); - - $this->__settings = $options; - - //-- Set the directory we'll be looking for elements - $this->elemDir = $this->__settings['type']; - } - - /** - * Resets columns and actions so multiple grids may be created - * - * @return void - * @author Robert Ross - */ - function reset(){ - $this->__columns = array(); - $this->__actions = array(); - } - - /** - * Adds a column to the grid - * - * @param string $title - * @param string $valuePath - * @param array $options - * @return void - * @author Robert Ross - */ - function addColumn($title, $valuePath, array $options = array()){ - $defaults = array( - 'editable' => false, - 'type' => 'string', - 'element' => false, - 'linkable' => false, - 'total' => false - ); - - $options = array_merge($defaults, $options); - - $titleSlug = Inflector::slug($title); - - $this->__columns[$titleSlug] = array( - 'title' => $title, - 'valuePath' => $valuePath, - 'options' => $options - ); - - if($options['total'] == true){ - $this->__totals[$title] = 0; - } - - return $titleSlug; - } - - /** - * Adds an actions column if it doesnt exist, then creates - * - * @param string $name - * @param array $url - * @param array $trailingParams - This is the stuff after /controller/action. Such as /orders/edit/{id}. It's the action parameters in other words - * @return void - * @author Robert Ross - */ - function addAction($name, array $url, array $trailingParams = array(), array $options = array()){ - $this->__actions[$name] = array( - 'url' => $url, - 'trailingParams' => $trailingParams, - 'options' => $options - ); - - if(!isset($this->__columns['actions'])){ - $this->addColumn('Actions', null, array('type' => 'actions')); - } - - return true; - } - - /** - * Generates the entire grid including headers and results - * - * @param string $results - * @return void - * @author Robert Ross - */ - function generate($results){ - $View = $this->__view(); - - $directory = $this->__settings['type']; - - if($this->__settings['type'] == 'csv' && !empty($this->__totals)){ - array_unshift($this->__columns, array( - 'title' => '', - 'valuePath' => '', - 'options' => array( - 'type' => 'empty' - ) - )); - } - - //-- Build the columns - $headers = $View->element($this->elemDir . DS . 'grid_headers', array( - 'plugin' => $this->plugin_name, - 'headers' => $this->__columns, - 'options' => $this->__settings - )); - $results = $this->results($results); - - $generated = $View->element($this->elemDir . DS . 'grid_full', array( - 'plugin' => $this->plugin_name, - 'headers' => $headers, - 'results' => $results, - 'options' => $this->__settings - )); - - return $generated; - } - - /** - * Creates the result set inclusive of the actions column (if applied) - * - * @param string $results - * @return void - * @author Robert Ross - */ - function results($results = array()){ - $rows = array(); - $View = $this->__view(); - - foreach($results as $key => $result){ - //-- Loop through columns - $rowColumns = array(); - - foreach($this->__columns as $column){ - $rowColumns[] = $this->__generateColumn($result, $column); - } - - $rows[] = $View->element($this->elemDir . DS . 'grid_row', array( - 'plugin' => $this->plugin_name, - 'zebra' => $key % 2 == 0 ? 'odd' : 'even', - 'rowColumns' => $rowColumns, - 'options' => $this->__settings - )); - } - - if(!empty($this->__totals)){ - $totalColumns = array(); - - $i = 0; - foreach($this->__columns as $column){ - if($i == 0){ - $totalColumns[] = 'Total'; - $i++; - continue; - } - $i++; - - if(isset($this->__totals[$column['title']])){ - if($column['options']['type'] == 'money'){ - $total = money_format("%n", $this->__totals[$column['title']]); - } else if($column['options']['type'] == 'number'){ - $total = number_format($this->__totals[$column['title']]); - } - - if($this->__settings['type'] == 'csv'){ - $total = intval(str_replace(array('$', ','), '', $total)); - $totalColumns[] = $total; - continue; - } - - $totalColumns[] = $total . ' (total)'; - continue; - } - - $totalColumns[] = ''; - } - - $rows[] = $View->element($this->elemDir . DS . 'grid_row', array( - 'plugin' => $this->plugin_name, - 'rowColumns' => $totalColumns, - 'options' => $this->__settings, - 'zebra' => 'totals' - )); - } - - //-- Upon review, this if statement is hilarious - if(empty($rows) && !empty($this->__settings['empty_message'])){ - $rows[] = $View->element($this->elemDir . DS . 'grid_empty_row', array( - 'plugin' => $this->plugin_name, - 'colspan' => sizeof($this->__columns) + (sizeof($this->__actions) ? 1 : 0), - 'options' => $this->__settings - )); - } - - return implode("\n", $rows); - } - - /** - * Creates the column based on the type. If there's no type, just a plain ol' string. - * - * @param string $result - * @param string $column - * @return void - * @author Robert Ross - */ - private function __generateColumn($result, $column){ - if($column['options']['type'] == 'empty'){ - return ''; - } - - if(!isset($column['valuePath'])){ - $value = $result; - } else if(!is_array($column['valuePath'])) { - $value = Set::extract($column['valuePath'], $result); - $value = array_pop($value); - } else if(is_array($column['valuePath'])){ - $valuePath = $column['valuePath']; - - if($valuePath['type'] == 'concat'){ - $separator = isset($valuePath['separator']) ? $valuePath['separator'] : $this->__settings['separator']; - unset($valuePath['type'], $valuePath['separator']); - - $values = array(); - foreach($valuePath as $path){ - $extracted = Set::extract($path, $result); - $values[] = array_pop($extracted); - } - - $value = implode($separator, $values); - } else if($valuePath['type'] == 'format'){ - $format = $valuePath['with']; - unset($valuePath['type'], $valuePath['with']); - - $values = array($format); - foreach($valuePath as $path){ - $extracted = (array) Set::extract($path, $result); - $values[] = array_pop($extracted); - } - - $value = call_user_func_array('sprintf', $values); - } - } - - //-- Total things up if needed - if(isset($column['options']['total']) && $column['options']['total'] == true){ - $this->__totals[$column['title']] += $value; - } - - if(isset($column['options']['element']) && $column['options']['element'] != false){ - $View = $this->__view(); - - return $View->element($this->elemDir . DS . $column['options']['element'], array('result' => $value)); - } else { - if(isset($column['options']['type']) && $column['options']['type'] == 'date'){ - $value = date('m/d/Y', strtotime($value)); - } else if(isset($column['options']['type']) && $column['options']['type'] == 'datetime'){ - $value = date('m/d/Y h:ia', strtotime($value)); - } else if(isset($column['options']['type']) && $column['options']['type'] == 'money' && $this->__settings['type'] != 'csv'){ - $value = money_format('%n', $value); - } else if(isset($column['options']['type']) && $column['options']['type'] == 'actions'){ - $View = $this->__view(); - $actions = array(); - - //-- Need to retrieve the results of the trailing params - foreach($this->__actions as $name => $action){ - //-- Check to see if the action is supposed to be hidden for this result (set in the controller) - if(isset($result['show_actions']) && is_array($result['show_actions']) && !in_array($name, $result['show_actions'])){ - continue; - } - - //-- Need to find the trailing parameters (id, action type, etc) - $trailingParams = array(); - if(!empty($action['trailingParams'])){ - foreach($action['trailingParams'] as $key => $param){ - $trailingParams[$key] = array_pop(Set::extract($param, $result)); - } - } - - $actions[$name] = array( - 'url' => Router::url($action['url'] + $trailingParams), - 'options' => $action['options'] - ); - } - - return $View->element($this->elemDir . DS . 'column_actions', array('plugin' => $this->plugin_name, 'actions' => $actions), array('Html')); - } - } - - //-- Check if it's linkable - if(is_array($column['options']['linkable']) && !empty($column['options']['linkable'])){ - $trailingParams = array(); - - $linkable = $column['options']['linkable']; - - if(!empty($linkable['trailingParams']) && is_array($linkable['trailingParams'])){ - foreach($linkable['trailingParams'] as $key => $param){ - $trailingParams[$key] = array_pop(Set::extract($param, $result)); - } - } - - $url = $linkable['url'] + $trailingParams; - $linkable['options'] = !isset($linkable['options']) ? array() : $linkable['options']; - - $value = $this->Html->link($value, $url, $linkable['options']); - } - - return $value; - } - - /** - * Function to return escaped csv data since PHP doesn't have a function out of the box - * Taken from http://php.net/manual/en/function.fputcsv.php comment - * - * @param string $data - * @return void - * @author Robert Ross - */ - function csvData($data){ - $fp = false; - $eol = "\n"; - - if ($fp === false) { - $fp = fopen('php://temp', 'r+'); - } else { - rewind($fp); - } - - if (fputcsv($fp, $data) === false) { - return false; - } - - rewind($fp); - $csv = fgets($fp); - - if ($eol != PHP_EOL){ - $csv = substr($csv, 0, (0 - strlen(PHP_EOL))) . $eol; - } - - //-- For out purpose... we don't want another \n - $csv = substr($csv, 0, strlen($eol) * -1); - - return $csv; - } - - /** - * Retrieves the view instance from the registry - * - * @return void - * @author Robert Ross - */ - private function __view() { - if (!empty($this->globalParams['viewInstance'])) { - $View = $this->globalParams['viewInstance']; - } else { - $View = ClassRegistry::getObject('view'); - } - - return $View; - } -} \ No newline at end of file From 8a7d93ba1ab986daae26c1fe375138b3dacf6efc Mon Sep 17 00:00:00 2001 From: Saleh Souzanchi Date: Sun, 7 Aug 2011 12:41:18 +0430 Subject: [PATCH 02/11] Upgrade For CakePHP 2 --- View/Element/csv/column_actions.ctp | 0 View/Element/csv/grid_empty_row.ctp | 1 + View/Element/csv/grid_full.ctp | 2 + View/Element/csv/grid_headers.ctp | 1 + View/Element/csv/grid_row.ctp | 1 + View/Element/table/column_actions.ctp | 3 + View/Element/table/grid_empty_row.ctp | 3 + View/Element/table/grid_full.ctp | 8 + View/Element/table/grid_headers.ctp | 5 + View/Element/table/grid_row.ctp | 7 + View/Helper/Grid.php | 435 ++++++++++++++++++++++++++ 11 files changed, 466 insertions(+) create mode 100644 View/Element/csv/column_actions.ctp create mode 100644 View/Element/csv/grid_empty_row.ctp create mode 100644 View/Element/csv/grid_full.ctp create mode 100644 View/Element/csv/grid_headers.ctp create mode 100644 View/Element/csv/grid_row.ctp create mode 100644 View/Element/table/column_actions.ctp create mode 100644 View/Element/table/grid_empty_row.ctp create mode 100644 View/Element/table/grid_full.ctp create mode 100644 View/Element/table/grid_headers.ctp create mode 100644 View/Element/table/grid_row.ctp create mode 100644 View/Helper/Grid.php diff --git a/View/Element/csv/column_actions.ctp b/View/Element/csv/column_actions.ctp new file mode 100644 index 0000000..e69de29 diff --git a/View/Element/csv/grid_empty_row.ctp b/View/Element/csv/grid_empty_row.ctp new file mode 100644 index 0000000..89d1899 --- /dev/null +++ b/View/Element/csv/grid_empty_row.ctp @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/View/Element/csv/grid_full.ctp b/View/Element/csv/grid_full.ctp new file mode 100644 index 0000000..9f2d7a9 --- /dev/null +++ b/View/Element/csv/grid_full.ctp @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/View/Element/csv/grid_headers.ctp b/View/Element/csv/grid_headers.ctp new file mode 100644 index 0000000..333ba07 --- /dev/null +++ b/View/Element/csv/grid_headers.ctp @@ -0,0 +1 @@ +Grid->csvData(Set::extract('/title', array_values($headers))); ?> \ No newline at end of file diff --git a/View/Element/csv/grid_row.ctp b/View/Element/csv/grid_row.ctp new file mode 100644 index 0000000..6f4b244 --- /dev/null +++ b/View/Element/csv/grid_row.ctp @@ -0,0 +1 @@ +Grid->csvData($rowColumns); ?> \ No newline at end of file diff --git a/View/Element/table/column_actions.ctp b/View/Element/table/column_actions.ctp new file mode 100644 index 0000000..52e0315 --- /dev/null +++ b/View/Element/table/column_actions.ctp @@ -0,0 +1,3 @@ + $action): ?> + Html->link($title, $action['url'], $action['options'] + array('class' => 'cg_action')); ?> + \ No newline at end of file diff --git a/View/Element/table/grid_empty_row.ctp b/View/Element/table/grid_empty_row.ctp new file mode 100644 index 0000000..57ce3a6 --- /dev/null +++ b/View/Element/table/grid_empty_row.ctp @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/View/Element/table/grid_full.ctp b/View/Element/table/grid_full.ctp new file mode 100644 index 0000000..7697044 --- /dev/null +++ b/View/Element/table/grid_full.ctp @@ -0,0 +1,8 @@ + + + + + + + +
\ No newline at end of file diff --git a/View/Element/table/grid_headers.ctp b/View/Element/table/grid_headers.ctp new file mode 100644 index 0000000..3e8a3fb --- /dev/null +++ b/View/Element/table/grid_headers.ctp @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/View/Element/table/grid_row.ctp b/View/Element/table/grid_row.ctp new file mode 100644 index 0000000..7866c10 --- /dev/null +++ b/View/Element/table/grid_row.ctp @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/View/Helper/Grid.php b/View/Helper/Grid.php new file mode 100644 index 0000000..eb6c5f1 --- /dev/null +++ b/View/Helper/Grid.php @@ -0,0 +1,435 @@ +options(array()); + } + + /** + * Set options for headers and such + * + * @param string $options + * @return void + * @author Robert Ross + */ + function options($options){ + $defaults = array( + 'class_header' => 'cg_header', + 'class_row' => 'cg_row', + 'class_table' => 'cg_table', + 'empty_message' => 'No Results', + 'separator' => ' ', + 'type' => 'table' + ); + + $options = array_merge($defaults, $options); + + $this->__settings = $options; + + //-- Set the directory we'll be looking for elements + $this->elemDir = $this->__settings['type']; + } + + /** + * Resets columns and actions so multiple grids may be created + * + * @return void + * @author Robert Ross + */ + function reset(){ + $this->__columns = array(); + $this->__actions = array(); + } + + /** + * Adds a column to the grid + * + * @param string $title + * @param string $valuePath + * @param array $options + * @return void + * @author Robert Ross + */ + function addColumn($title, $valuePath, array $options = array()){ + $defaults = array( + 'editable' => false, + 'type' => 'string', + 'element' => false, + 'linkable' => false, + 'total' => false + ); + + $options = array_merge($defaults, $options); + + $titleSlug = Inflector::slug($title); + + $this->__columns[$titleSlug] = array( + 'title' => $title, + 'valuePath' => $valuePath, + 'options' => $options + ); + + if($options['total'] == true){ + $this->__totals[$title] = 0; + } + + return $titleSlug; + } + + /** + * Adds an actions column if it doesnt exist, then creates + * + * @param string $name + * @param array $url + * @param array $trailingParams - This is the stuff after /controller/action. Such as /orders/edit/{id}. It's the action parameters in other words + * @return void + * @author Robert Ross + */ + function addAction($name, array $url, array $trailingParams = array(), array $options = array()){ + $this->__actions[$name] = array( + 'url' => $url, + 'trailingParams' => $trailingParams, + 'options' => $options + ); + + if(!isset($this->__columns['actions'])){ + $this->addColumn('Actions', null, array('type' => 'actions')); + } + + return true; + } + + /** + * Generates the entire grid including headers and results + * + * @param string $results + * @return void + * @author Robert Ross + */ + function generate($results){ + $View = $this->__view(); + + $directory = $this->__settings['type']; + + if($this->__settings['type'] == 'csv' && !empty($this->__totals)){ + array_unshift($this->__columns, array( + 'title' => '', + 'valuePath' => '', + 'options' => array( + 'type' => 'empty' + ) + )); + } + + //-- Build the columns + $headers = $View->element($this->elemDir . DS . 'grid_headers', array( + 'plugin' => $this->plugin_name, + 'headers' => $this->__columns, + 'options' => $this->__settings + )); + $results = $this->results($results); + + $generated = $View->element($this->elemDir . DS . 'grid_full', array( + 'plugin' => $this->plugin_name, + 'headers' => $headers, + 'results' => $results, + 'options' => $this->__settings + )); + + return $generated; + } + + /** + * Creates the result set inclusive of the actions column (if applied) + * + * @param string $results + * @return void + * @author Robert Ross + */ + function results($results = array()){ + $rows = array(); + $View = $this->__view(); + + foreach($results as $key => $result){ + //-- Loop through columns + $rowColumns = array(); + + foreach($this->__columns as $column){ + $rowColumns[] = $this->__generateColumn($result, $column); + } + + $rows[] = $View->element($this->elemDir . DS . 'grid_row', array( + 'plugin' => $this->plugin_name, + 'zebra' => $key % 2 == 0 ? 'odd' : 'even', + 'rowColumns' => $rowColumns, + 'options' => $this->__settings + )); + } + + if(!empty($this->__totals)){ + $totalColumns = array(); + + $i = 0; + foreach($this->__columns as $column){ + if($i == 0){ + $totalColumns[] = 'Total'; + $i++; + continue; + } + $i++; + + if(isset($this->__totals[$column['title']])){ + if($column['options']['type'] == 'money'){ + $total = money_format("%n", $this->__totals[$column['title']]); + } else if($column['options']['type'] == 'number'){ + $total = number_format($this->__totals[$column['title']]); + } + + if($this->__settings['type'] == 'csv'){ + $total = floatval(str_replace(array('$', ','), '', $total)); + $totalColumns[] = $total; + continue; + } + + $totalColumns[] = $total . ' (total)'; + continue; + } + + $totalColumns[] = ''; + } + + $rows[] = $View->element($this->elemDir . DS . 'grid_row', array( + 'plugin' => $this->plugin_name, + 'rowColumns' => $totalColumns, + 'options' => $this->__settings, + 'zebra' => 'totals' + )); + } + + //-- Upon review, this if statement is hilarious + if(empty($rows) && !empty($this->__settings['empty_message'])){ + $rows[] = $View->element($this->elemDir . DS . 'grid_empty_row', array( + 'plugin' => $this->plugin_name, + 'colspan' => sizeof($this->__columns) + (sizeof($this->__actions) ? 1 : 0), + 'options' => $this->__settings + )); + } + + return implode("\n", $rows); + } + + /** + * Creates the column based on the type. If there's no type, just a plain ol' string. + * + * @param string $result + * @param string $column + * @return void + * @author Robert Ross + */ + private function __generateColumn($result, $column){ + if($column['options']['type'] == 'empty'){ + return ''; + } + + if(!isset($column['valuePath'])){ + $value = $result; + } else if(!is_array($column['valuePath'])) { + $value = Set::extract($column['valuePath'], $result); + $value = array_pop($value); + } else if(is_array($column['valuePath'])){ + $valuePath = $column['valuePath']; + + if($valuePath['type'] == 'concat'){ + $separator = isset($valuePath['separator']) ? $valuePath['separator'] : $this->__settings['separator']; + unset($valuePath['type'], $valuePath['separator']); + + $values = array(); + foreach($valuePath as $path){ + $extracted = Set::extract($path, $result); + $values[] = array_pop($extracted); + } + + $value = implode($separator, $values); + } else if($valuePath['type'] == 'format'){ + $format = $valuePath['with']; + unset($valuePath['type'], $valuePath['with']); + + $values = array($format); + foreach($valuePath as $path){ + $extracted = (array) Set::extract($path, $result); + $values[] = array_pop($extracted); + } + + $value = call_user_func_array('sprintf', $values); + } + } + + //-- Total things up if needed + if(isset($column['options']['total']) && $column['options']['total'] == true){ + $this->__totals[$column['title']] += $value; + } + + if(isset($column['options']['element']) && $column['options']['element'] != false){ + $View = $this->__view(); + + return $View->element($this->elemDir . DS . $column['options']['element'], array('result' => $value)); + } else { + if(isset($column['options']['type']) && $column['options']['type'] == 'date'){ + $value = date('m/d/Y', strtotime($value)); + } else if(isset($column['options']['type']) && $column['options']['type'] == 'datetime'){ + $value = date('m/d/Y h:ia', strtotime($value)); + } else if(isset($column['options']['type']) && $column['options']['type'] == 'money' && $this->__settings['type'] != 'csv'){ + $value = money_format('%n', $value); + } else if(isset($column['options']['type']) && $column['options']['type'] == 'actions'){ + $View = $this->__view(); + $actions = array(); + + //-- Need to retrieve the results of the trailing params + foreach($this->__actions as $name => $action){ + //-- Check to see if the action is supposed to be hidden for this result (set in the controller) + if(isset($result['show_actions']) && is_array($result['show_actions']) && !in_array($name, $result['show_actions'])){ + continue; + } + + //-- Need to find the trailing parameters (id, action type, etc) + $trailingParams = array(); + if(!empty($action['trailingParams'])){ + foreach($action['trailingParams'] as $key => $param){ + $trailingParams[$key] = array_pop(Set::extract($param, $result)); + } + } + + $actions[$name] = array( + 'url' => Router::url($action['url'] + $trailingParams), + 'options' => $action['options'] + ); + } + + return $View->element($this->elemDir . DS . 'column_actions', array('plugin' => $this->plugin_name, 'actions' => $actions), array('Html')); + } + } + + //-- Check if it's linkable + if(is_array($column['options']['linkable']) && !empty($column['options']['linkable'])){ + $trailingParams = array(); + + $linkable = $column['options']['linkable']; + + if(!empty($linkable['trailingParams']) && is_array($linkable['trailingParams'])){ + foreach($linkable['trailingParams'] as $key => $param){ + $trailingParams[$key] = array_pop(Set::extract($param, $result)); + } + } + + $url = $linkable['url'] + $trailingParams; + $linkable['options'] = !isset($linkable['options']) ? array() : $linkable['options']; + + $value = $this->Html->link($value, $url, $linkable['options']); + } + + return $value; + } + + /** + * Function to return escaped csv data since PHP doesn't have a function out of the box + * Taken from http://php.net/manual/en/function.fputcsv.php comment + * + * @param string $data + * @return void + * @author Robert Ross + */ + function csvData($data){ + $fp = false; + $eol = "\n"; + + if ($fp === false) { + $fp = fopen('php://temp', 'r+'); + } else { + rewind($fp); + } + + if (fputcsv($fp, $data) === false) { + return false; + } + + rewind($fp); + $csv = fgets($fp); + + if ($eol != PHP_EOL){ + $csv = substr($csv, 0, (0 - strlen(PHP_EOL))) . $eol; + } + + //-- For out purpose... we don't want another \n + $csv = substr($csv, 0, strlen($eol) * -1); + + return $csv; + } + + /** + * Retrieves the view instance from the registry + * + * @return void + * @author Robert Ross + */ + private function __view() { + if (!empty($this->globalParams['viewInstance'])) { + $View = $this->globalParams['viewInstance']; + } else { + $View = ClassRegistry::getObject('view'); + } + + return $View; + } +} \ No newline at end of file From 964d870846c20be8fad3431a5a0933045e7982c9 Mon Sep 17 00:00:00 2001 From: Saleh Souzanchi Date: Sun, 7 Aug 2011 19:37:48 +0430 Subject: [PATCH 03/11] for test --- README.md | 2 +- View/Element/csv/column_actions.ctp | 0 View/Element/csv/grid_empty_row.ctp | 1 - View/Element/csv/grid_full.ctp | 2 -- View/Element/csv/grid_headers.ctp | 1 - View/Element/csv/grid_row.ctp | 1 - View/Element/table/column_actions.ctp | 3 --- View/Element/table/grid_empty_row.ctp | 3 --- View/Element/table/grid_full.ctp | 8 ------ View/Element/table/grid_headers.ctp | 5 ---- View/Element/table/grid_row.ctp | 7 ----- View/Helper/Grid.php | 37 ++++++++++++++------------- 12 files changed, 20 insertions(+), 50 deletions(-) delete mode 100644 View/Element/csv/column_actions.ctp delete mode 100644 View/Element/csv/grid_empty_row.ctp delete mode 100644 View/Element/csv/grid_full.ctp delete mode 100644 View/Element/csv/grid_headers.ctp delete mode 100644 View/Element/csv/grid_row.ctp delete mode 100644 View/Element/table/column_actions.ctp delete mode 100644 View/Element/table/grid_empty_row.ctp delete mode 100644 View/Element/table/grid_full.ctp delete mode 100644 View/Element/table/grid_headers.ctp delete mode 100644 View/Element/table/grid_row.ctp diff --git a/README.md b/README.md index 052a0fc..d7b10a2 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ Easy tabular data for CakePHP (cakephp.org) -- by Robert Ross (rross@sdreader.com) -- available at http://github.com/rross0227 - -- requires CakePHP 1.3.x + -- requires CakePHP 2 Beta Copyright (c) 2011 The Daily Save, LLC. All rights reserved. diff --git a/View/Element/csv/column_actions.ctp b/View/Element/csv/column_actions.ctp deleted file mode 100644 index e69de29..0000000 diff --git a/View/Element/csv/grid_empty_row.ctp b/View/Element/csv/grid_empty_row.ctp deleted file mode 100644 index 89d1899..0000000 --- a/View/Element/csv/grid_empty_row.ctp +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/View/Element/csv/grid_full.ctp b/View/Element/csv/grid_full.ctp deleted file mode 100644 index 9f2d7a9..0000000 --- a/View/Element/csv/grid_full.ctp +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/View/Element/csv/grid_headers.ctp b/View/Element/csv/grid_headers.ctp deleted file mode 100644 index 333ba07..0000000 --- a/View/Element/csv/grid_headers.ctp +++ /dev/null @@ -1 +0,0 @@ -Grid->csvData(Set::extract('/title', array_values($headers))); ?> \ No newline at end of file diff --git a/View/Element/csv/grid_row.ctp b/View/Element/csv/grid_row.ctp deleted file mode 100644 index 6f4b244..0000000 --- a/View/Element/csv/grid_row.ctp +++ /dev/null @@ -1 +0,0 @@ -Grid->csvData($rowColumns); ?> \ No newline at end of file diff --git a/View/Element/table/column_actions.ctp b/View/Element/table/column_actions.ctp deleted file mode 100644 index 52e0315..0000000 --- a/View/Element/table/column_actions.ctp +++ /dev/null @@ -1,3 +0,0 @@ - $action): ?> - Html->link($title, $action['url'], $action['options'] + array('class' => 'cg_action')); ?> - \ No newline at end of file diff --git a/View/Element/table/grid_empty_row.ctp b/View/Element/table/grid_empty_row.ctp deleted file mode 100644 index 57ce3a6..0000000 --- a/View/Element/table/grid_empty_row.ctp +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/View/Element/table/grid_full.ctp b/View/Element/table/grid_full.ctp deleted file mode 100644 index 7697044..0000000 --- a/View/Element/table/grid_full.ctp +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - -
\ No newline at end of file diff --git a/View/Element/table/grid_headers.ctp b/View/Element/table/grid_headers.ctp deleted file mode 100644 index 3e8a3fb..0000000 --- a/View/Element/table/grid_headers.ctp +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/View/Element/table/grid_row.ctp b/View/Element/table/grid_row.ctp deleted file mode 100644 index 7866c10..0000000 --- a/View/Element/table/grid_row.ctp +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/View/Helper/Grid.php b/View/Helper/Grid.php index eb6c5f1..a0f11ee 100644 --- a/View/Helper/Grid.php +++ b/View/Helper/Grid.php @@ -2,7 +2,7 @@ class GridHelper extends AppHelper { public $name = 'Grid'; - public $plugin_name = 'cake_grid'; + public $plugin_name = 'CakeGrid'; /** * Load html helper for links and such @@ -53,7 +53,8 @@ class GridHelper extends AppHelper { * * @author Robert Ross */ - function __construct(){ + function __construct(View $View, $settings = array()){ + parent::__construct( $View,$settings); $this->options(array()); } @@ -159,8 +160,8 @@ function addAction($name, array $url, array $trailingParams = array(), array $op * @author Robert Ross */ function generate($results){ - $View = $this->__view(); - + $View = $this->_View; + $directory = $this->__settings['type']; if($this->__settings['type'] == 'csv' && !empty($this->__totals)){ @@ -187,7 +188,7 @@ function generate($results){ 'results' => $results, 'options' => $this->__settings )); - + pr($generated); return $generated; } @@ -200,7 +201,7 @@ function generate($results){ */ function results($results = array()){ $rows = array(); - $View = $this->__view(); + $View = $this->_View; foreach($results as $key => $result){ //-- Loop through columns @@ -322,9 +323,9 @@ private function __generateColumn($result, $column){ } if(isset($column['options']['element']) && $column['options']['element'] != false){ - $View = $this->__view(); + $View = $this->_View; - return $View->element($this->elemDir . DS . $column['options']['element'], array('result' => $value)); + return $View->element($this->elemDir . DS . $column['options']['element'], array('result' => $value)); } else { if(isset($column['options']['type']) && $column['options']['type'] == 'date'){ $value = date('m/d/Y', strtotime($value)); @@ -333,7 +334,7 @@ private function __generateColumn($result, $column){ } else if(isset($column['options']['type']) && $column['options']['type'] == 'money' && $this->__settings['type'] != 'csv'){ $value = money_format('%n', $value); } else if(isset($column['options']['type']) && $column['options']['type'] == 'actions'){ - $View = $this->__view(); + $View = $this->_View; $actions = array(); //-- Need to retrieve the results of the trailing params @@ -423,13 +424,13 @@ function csvData($data){ * @return void * @author Robert Ross */ - private function __view() { - if (!empty($this->globalParams['viewInstance'])) { - $View = $this->globalParams['viewInstance']; - } else { - $View = ClassRegistry::getObject('view'); - } - - return $View; - } +// private function __view() { +// if (!empty($this->globalParams['viewInstance'])) { +// $View = $this->globalParams['viewInstance']; +// } else { +// $View = ClassRegistry::getObject('view'); +// } +// +// return $View; +// } } \ No newline at end of file From 7a69a7b46819805d69376d506dacd1b2c5ba6b2c Mon Sep 17 00:00:00 2001 From: Saleh Souzanchi Date: Sun, 7 Aug 2011 20:11:51 +0430 Subject: [PATCH 04/11] Fixed plugin parameter in $this->element() --- View/Helper/Grid.php | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/View/Helper/Grid.php b/View/Helper/Grid.php index a0f11ee..76c823c 100644 --- a/View/Helper/Grid.php +++ b/View/Helper/Grid.php @@ -179,15 +179,21 @@ function generate($results){ 'plugin' => $this->plugin_name, 'headers' => $this->__columns, 'options' => $this->__settings - )); + ), + array( 'plugin' => $this->plugin_name) + ); $results = $this->results($results); $generated = $View->element($this->elemDir . DS . 'grid_full', array( - 'plugin' => $this->plugin_name, + 'plugin' => $this->plugin_name, 'headers' => $headers, 'results' => $results, 'options' => $this->__settings - )); + ), + array( 'plugin' => $this->plugin_name) + ); + + pr($generated); return $generated; } @@ -216,7 +222,9 @@ function results($results = array()){ 'zebra' => $key % 2 == 0 ? 'odd' : 'even', 'rowColumns' => $rowColumns, 'options' => $this->__settings - )); + ), + array( 'plugin' => $this->plugin_name) + ); } if(!empty($this->__totals)){ @@ -256,7 +264,9 @@ function results($results = array()){ 'rowColumns' => $totalColumns, 'options' => $this->__settings, 'zebra' => 'totals' - )); + ), + array( 'plugin' => $this->plugin_name) + ); } //-- Upon review, this if statement is hilarious @@ -265,7 +275,8 @@ function results($results = array()){ 'plugin' => $this->plugin_name, 'colspan' => sizeof($this->__columns) + (sizeof($this->__actions) ? 1 : 0), 'options' => $this->__settings - )); + ), + array( 'plugin' => $this->plugin_name)); } return implode("\n", $rows); @@ -358,7 +369,7 @@ private function __generateColumn($result, $column){ ); } - return $View->element($this->elemDir . DS . 'column_actions', array('plugin' => $this->plugin_name, 'actions' => $actions), array('Html')); + return $View->element($this->elemDir . DS . 'column_actions', array( 'actions' => $actions), array('Html','plugin' => $this->plugin_name,)); } } From 042f3833a56b310967b5e52cc3073709a67b2f0c Mon Sep 17 00:00:00 2001 From: Saleh Souzanchi Date: Sun, 7 Aug 2011 20:11:51 +0430 Subject: [PATCH 05/11] remove & clean debug commands --- View/Helper/Grid.php | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/View/Helper/Grid.php b/View/Helper/Grid.php index a0f11ee..4f03446 100644 --- a/View/Helper/Grid.php +++ b/View/Helper/Grid.php @@ -179,16 +179,22 @@ function generate($results){ 'plugin' => $this->plugin_name, 'headers' => $this->__columns, 'options' => $this->__settings - )); + ), + array( 'plugin' => $this->plugin_name) + ); $results = $this->results($results); $generated = $View->element($this->elemDir . DS . 'grid_full', array( - 'plugin' => $this->plugin_name, + 'plugin' => $this->plugin_name, 'headers' => $headers, 'results' => $results, 'options' => $this->__settings - )); - pr($generated); + ), + array( 'plugin' => $this->plugin_name) + ); + + + return $generated; } @@ -216,7 +222,9 @@ function results($results = array()){ 'zebra' => $key % 2 == 0 ? 'odd' : 'even', 'rowColumns' => $rowColumns, 'options' => $this->__settings - )); + ), + array( 'plugin' => $this->plugin_name) + ); } if(!empty($this->__totals)){ @@ -256,7 +264,9 @@ function results($results = array()){ 'rowColumns' => $totalColumns, 'options' => $this->__settings, 'zebra' => 'totals' - )); + ), + array( 'plugin' => $this->plugin_name) + ); } //-- Upon review, this if statement is hilarious @@ -265,7 +275,8 @@ function results($results = array()){ 'plugin' => $this->plugin_name, 'colspan' => sizeof($this->__columns) + (sizeof($this->__actions) ? 1 : 0), 'options' => $this->__settings - )); + ), + array( 'plugin' => $this->plugin_name)); } return implode("\n", $rows); @@ -358,7 +369,7 @@ private function __generateColumn($result, $column){ ); } - return $View->element($this->elemDir . DS . 'column_actions', array('plugin' => $this->plugin_name, 'actions' => $actions), array('Html')); + return $View->element($this->elemDir . DS . 'column_actions', array( 'actions' => $actions), array('Html','plugin' => $this->plugin_name,)); } } From 1223fee03e65d1c0f6a66524f8262c9d1a46aba3 Mon Sep 17 00:00:00 2001 From: Saleh Souzanchi Date: Sun, 7 Aug 2011 12:41:18 +0430 Subject: [PATCH 06/11] Upgrade For CakePHP 2 --- README.md | 2 +- View/Elements/csv/column_actions.ctp | 0 View/Elements/csv/grid_empty_row.ctp | 1 + View/Elements/csv/grid_full.ctp | 2 + View/Elements/csv/grid_headers.ctp | 1 + View/Elements/csv/grid_row.ctp | 1 + View/Elements/table/column_actions.ctp | 3 + View/Elements/table/grid_empty_row.ctp | 3 + View/Elements/table/grid_full.ctp | 8 + View/Elements/table/grid_headers.ctp | 5 + View/Elements/table/grid_row.ctp | 7 + View/Helper/Grid.php | 445 +++++++++++++++++++++++++ 12 files changed, 477 insertions(+), 1 deletion(-) create mode 100644 View/Elements/csv/column_actions.ctp create mode 100644 View/Elements/csv/grid_empty_row.ctp create mode 100644 View/Elements/csv/grid_full.ctp create mode 100644 View/Elements/csv/grid_headers.ctp create mode 100644 View/Elements/csv/grid_row.ctp create mode 100644 View/Elements/table/column_actions.ctp create mode 100644 View/Elements/table/grid_empty_row.ctp create mode 100644 View/Elements/table/grid_full.ctp create mode 100644 View/Elements/table/grid_headers.ctp create mode 100644 View/Elements/table/grid_row.ctp create mode 100644 View/Helper/Grid.php diff --git a/README.md b/README.md index 052a0fc..5a06e4f 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ Easy tabular data for CakePHP (cakephp.org) -- by Robert Ross (rross@sdreader.com) -- available at http://github.com/rross0227 - -- requires CakePHP 1.3.x + -- requires CakePHP 2.x beta Copyright (c) 2011 The Daily Save, LLC. All rights reserved. diff --git a/View/Elements/csv/column_actions.ctp b/View/Elements/csv/column_actions.ctp new file mode 100644 index 0000000..e69de29 diff --git a/View/Elements/csv/grid_empty_row.ctp b/View/Elements/csv/grid_empty_row.ctp new file mode 100644 index 0000000..89d1899 --- /dev/null +++ b/View/Elements/csv/grid_empty_row.ctp @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/View/Elements/csv/grid_full.ctp b/View/Elements/csv/grid_full.ctp new file mode 100644 index 0000000..9f2d7a9 --- /dev/null +++ b/View/Elements/csv/grid_full.ctp @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/View/Elements/csv/grid_headers.ctp b/View/Elements/csv/grid_headers.ctp new file mode 100644 index 0000000..333ba07 --- /dev/null +++ b/View/Elements/csv/grid_headers.ctp @@ -0,0 +1 @@ +Grid->csvData(Set::extract('/title', array_values($headers))); ?> \ No newline at end of file diff --git a/View/Elements/csv/grid_row.ctp b/View/Elements/csv/grid_row.ctp new file mode 100644 index 0000000..6f4b244 --- /dev/null +++ b/View/Elements/csv/grid_row.ctp @@ -0,0 +1 @@ +Grid->csvData($rowColumns); ?> \ No newline at end of file diff --git a/View/Elements/table/column_actions.ctp b/View/Elements/table/column_actions.ctp new file mode 100644 index 0000000..52e0315 --- /dev/null +++ b/View/Elements/table/column_actions.ctp @@ -0,0 +1,3 @@ + $action): ?> + Html->link($title, $action['url'], $action['options'] + array('class' => 'cg_action')); ?> + \ No newline at end of file diff --git a/View/Elements/table/grid_empty_row.ctp b/View/Elements/table/grid_empty_row.ctp new file mode 100644 index 0000000..57ce3a6 --- /dev/null +++ b/View/Elements/table/grid_empty_row.ctp @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/View/Elements/table/grid_full.ctp b/View/Elements/table/grid_full.ctp new file mode 100644 index 0000000..7697044 --- /dev/null +++ b/View/Elements/table/grid_full.ctp @@ -0,0 +1,8 @@ + + + + + + + +
\ No newline at end of file diff --git a/View/Elements/table/grid_headers.ctp b/View/Elements/table/grid_headers.ctp new file mode 100644 index 0000000..3e8a3fb --- /dev/null +++ b/View/Elements/table/grid_headers.ctp @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/View/Elements/table/grid_row.ctp b/View/Elements/table/grid_row.ctp new file mode 100644 index 0000000..7866c10 --- /dev/null +++ b/View/Elements/table/grid_row.ctp @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/View/Helper/Grid.php b/View/Helper/Grid.php new file mode 100644 index 0000000..503572c --- /dev/null +++ b/View/Helper/Grid.php @@ -0,0 +1,445 @@ +options(array()); + } + + /** + * Set options for headers and such + * + * @param string $options + * @return void + * @author Robert Ross + */ + function options($options){ + $defaults = array( + 'class_header' => 'cg_header', + 'class_row' => 'cg_row', + 'class_table' => 'cg_table', + 'empty_message' => 'No Results', + 'separator' => ' ', + 'type' => 'table' + ); + + $options = array_merge($defaults, $options); + + $this->__settings = $options; + + //-- Set the directory we'll be looking for elements + $this->elemDir = $this->__settings['type']; + } + + /** + * Resets columns and actions so multiple grids may be created + * + * @return void + * @author Robert Ross + */ + function reset(){ + $this->__columns = array(); + $this->__actions = array(); + } + + /** + * Adds a column to the grid + * + * @param string $title + * @param string $valuePath + * @param array $options + * @return void + * @author Robert Ross + */ + function addColumn($title, $valuePath, array $options = array()){ + $defaults = array( + 'editable' => false, + 'type' => 'string', + 'element' => false, + 'linkable' => false, + 'total' => false + ); + + $options = array_merge($defaults, $options); + + $titleSlug = Inflector::slug($title); + + $this->__columns[$titleSlug] = array( + 'title' => $title, + 'valuePath' => $valuePath, + 'options' => $options + ); + + if($options['total'] == true){ + $this->__totals[$title] = 0; + } + + return $titleSlug; + } + + /** + * Adds an actions column if it doesnt exist, then creates + * + * @param string $name + * @param array $url + * @param array $trailingParams - This is the stuff after /controller/action. Such as /orders/edit/{id}. It's the action parameters in other words + * @return void + * @author Robert Ross + */ + function addAction($name, array $url, array $trailingParams = array(), array $options = array()){ + $this->__actions[$name] = array( + 'url' => $url, + 'trailingParams' => $trailingParams, + 'options' => $options + ); + + if(!isset($this->__columns['actions'])){ + $this->addColumn('Actions', null, array('type' => 'actions')); + } + + return true; + } + + /** + * Generates the entire grid including headers and results + * + * @param string $results + * @return void + * @author Robert Ross + */ + function generate($results){ + $View = $this->_View; + + $directory = $this->__settings['type']; + + if($this->__settings['type'] == 'csv' && !empty($this->__totals)){ + array_unshift($this->__columns, array( + 'title' => '', + 'valuePath' => '', + 'options' => array( + 'type' => 'empty' + ) + )); + } + + //-- Build the columns + $headers = $View->element($this->elemDir . DS . 'grid_headers', array( + 'plugin' => $this->plugin_name, + 'headers' => $this->__columns, + 'options' => $this->__settings + ), + array( 'plugin' => $this->plugin_name) + ); + + $results = $this->results($results); + $generated = $View->element($this->elemDir . DS . 'grid_full', array( + // 'plugin' => $this->plugin_name, + 'headers' => $headers, + 'results' => $results, + 'options' => $this->__settings + ), + array( 'plugin' => $this->plugin_name) + ); + + return $generated; + } + + /** + * Creates the result set inclusive of the actions column (if applied) + * + * @param string $results + * @return void + * @author Robert Ross + */ + function results($results = array()){ + $rows = array(); + $View = $this->_View; + + foreach($results as $key => $result){ + //-- Loop through columns + $rowColumns = array(); + + foreach($this->__columns as $column){ + $rowColumns[] = $this->__generateColumn($result, $column); + } + + $rows[] = $View->element($this->elemDir . DS . 'grid_row', array( + 'plugin' => $this->plugin_name, + 'zebra' => $key % 2 == 0 ? 'odd' : 'even', + 'rowColumns' => $rowColumns, + 'options' => $this->__settings + ), + array( 'plugin' => $this->plugin_name) + ); + } + + if(!empty($this->__totals)){ + $totalColumns = array(); + + $i = 0; + foreach($this->__columns as $column){ + if($i == 0){ + $totalColumns[] = 'Total'; + $i++; + continue; + } + $i++; + + if(isset($this->__totals[$column['title']])){ + if($column['options']['type'] == 'money'){ + $total = money_format("%n", $this->__totals[$column['title']]); + } else if($column['options']['type'] == 'number'){ + $total = number_format($this->__totals[$column['title']]); + } + + if($this->__settings['type'] == 'csv'){ + $total = floatval(str_replace(array('$', ','), '', $total)); + $totalColumns[] = $total; + continue; + } + + $totalColumns[] = $total . ' (total)'; + continue; + } + + $totalColumns[] = ''; + } + + $rows[] = $View->element($this->elemDir . DS . 'grid_row', array( + 'plugin' => $this->plugin_name, + 'rowColumns' => $totalColumns, + 'options' => $this->__settings, + 'zebra' => 'totals' + ), + array( 'plugin' => $this->plugin_name) + ); + } + + //-- Upon review, this if statement is hilarious + if(empty($rows) && !empty($this->__settings['empty_message'])){ + $rows[] = $View->element($this->elemDir . DS . 'grid_empty_row', array( + 'plugin' => $this->plugin_name, + 'colspan' => sizeof($this->__columns) + (sizeof($this->__actions) ? 1 : 0), + 'options' => $this->__settings + ), + array( 'plugin' => $this->plugin_name)); + } + + return implode("\n", $rows); + } + + /** + * Creates the column based on the type. If there's no type, just a plain ol' string. + * + * @param string $result + * @param string $column + * @return void + * @author Robert Ross + */ + private function __generateColumn($result, $column){ + if($column['options']['type'] == 'empty'){ + return ''; + } + + if(!isset($column['valuePath'])){ + $value = $result; + } else if(!is_array($column['valuePath'])) { + $value = Set::extract($column['valuePath'], $result); + $value = array_pop($value); + } else if(is_array($column['valuePath'])){ + $valuePath = $column['valuePath']; + + if($valuePath['type'] == 'concat'){ + $separator = isset($valuePath['separator']) ? $valuePath['separator'] : $this->__settings['separator']; + unset($valuePath['type'], $valuePath['separator']); + + $values = array(); + foreach($valuePath as $path){ + $extracted = Set::extract($path, $result); + $values[] = array_pop($extracted); + } + + $value = implode($separator, $values); + } else if($valuePath['type'] == 'format'){ + $format = $valuePath['with']; + unset($valuePath['type'], $valuePath['with']); + + $values = array($format); + foreach($valuePath as $path){ + $extracted = (array) Set::extract($path, $result); + $values[] = array_pop($extracted); + } + + $value = call_user_func_array('sprintf', $values); + } + } + + //-- Total things up if needed + if(isset($column['options']['total']) && $column['options']['total'] == true){ + $this->__totals[$column['title']] += $value; + } + + if(isset($column['options']['element']) && $column['options']['element'] != false){ + $View = $this->_View; + + return $View->element($this->elemDir . DS . $column['options']['element'], array('result' => $value)); + } else { + if(isset($column['options']['type']) && $column['options']['type'] == 'date'){ + $value = date('m/d/Y', strtotime($value)); + } else if(isset($column['options']['type']) && $column['options']['type'] == 'datetime'){ + $value = date('m/d/Y h:ia', strtotime($value)); + } else if(isset($column['options']['type']) && $column['options']['type'] == 'money' && $this->__settings['type'] != 'csv'){ + $value = money_format('%n', $value); + } else if(isset($column['options']['type']) && $column['options']['type'] == 'actions'){ + $View = $this->_View; + $actions = array(); + + //-- Need to retrieve the results of the trailing params + foreach($this->__actions as $name => $action){ + //-- Check to see if the action is supposed to be hidden for this result (set in the controller) + if(isset($result['show_actions']) && is_array($result['show_actions']) && !in_array($name, $result['show_actions'])){ + continue; + } + + //-- Need to find the trailing parameters (id, action type, etc) + $trailingParams = array(); + if(!empty($action['trailingParams'])){ + foreach($action['trailingParams'] as $key => $param){ + $trailingParams[$key] = array_pop(Set::extract($param, $result)); + } + } + + $actions[$name] = array( + 'url' => Router::url($action['url'] + $trailingParams), + 'options' => $action['options'] + ); + } + + return $View->element($this->elemDir . DS . 'column_actions', array( 'actions' => $actions), array('plugin' => $this->plugin_name)); + } + } + + //-- Check if it's linkable + if(is_array($column['options']['linkable']) && !empty($column['options']['linkable'])){ + $trailingParams = array(); + + $linkable = $column['options']['linkable']; + + if(!empty($linkable['trailingParams']) && is_array($linkable['trailingParams'])){ + foreach($linkable['trailingParams'] as $key => $param){ + $trailingParams[$key] = array_pop(Set::extract($param, $result)); + } + } + + $url = $linkable['url'] + $trailingParams; + $linkable['options'] = !isset($linkable['options']) ? array() : $linkable['options']; + + $value = $this->Html->link($value, $url, $linkable['options']); + } + + return $value; + } + + /** + * Function to return escaped csv data since PHP doesn't have a function out of the box + * Taken from http://php.net/manual/en/function.fputcsv.php comment + * + * @param string $data + * @return void + * @author Robert Ross + */ + function csvData($data){ + $fp = false; + $eol = "\n"; + + if ($fp === false) { + $fp = fopen('php://temp', 'r+'); + } else { + rewind($fp); + } + + if (fputcsv($fp, $data) === false) { + return false; + } + + rewind($fp); + $csv = fgets($fp); + + if ($eol != PHP_EOL){ + $csv = substr($csv, 0, (0 - strlen(PHP_EOL))) . $eol; + } + + //-- For out purpose... we don't want another \n + $csv = substr($csv, 0, strlen($eol) * -1); + + return $csv; + } + + /** + * Retrieves the view instance from the registry + * + * @return void + * @author Robert Ross + */ +// private function __view() { +// if (!empty($this->globalParams['viewInstance'])) { +// $View = $this->globalParams['viewInstance']; +// } else { +// $View = ClassRegistry::getObject('view'); +// } +// +// return $View; +// } +} \ No newline at end of file From 41e5cc67bc63a9eb7502ee3a6a033464041f483f Mon Sep 17 00:00:00 2001 From: Saleh Souzanchi Date: Sun, 7 Aug 2011 23:12:48 +0430 Subject: [PATCH 07/11] rename Helper for cakephp2 Standard --- View/Helper/{Grid.php => GridHelper.php} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename View/Helper/{Grid.php => GridHelper.php} (100%) diff --git a/View/Helper/Grid.php b/View/Helper/GridHelper.php similarity index 100% rename from View/Helper/Grid.php rename to View/Helper/GridHelper.php From 1a5c7ed9149c08364194c8ce0407aed85cb3e16f Mon Sep 17 00:00:00 2001 From: Saleh Souzanchi Date: Sun, 7 Aug 2011 23:31:02 +0430 Subject: [PATCH 08/11] add style --- webroot/css/cakegrid.css | 183 ++++++++++++++++++++++++++++++++++++++ webroot/img/bg.gif | Bin 0 -> 854 bytes webroot/img/captionbg.gif | Bin 0 -> 868 bytes 3 files changed, 183 insertions(+) create mode 100644 webroot/css/cakegrid.css create mode 100644 webroot/img/bg.gif create mode 100644 webroot/img/captionbg.gif diff --git a/webroot/css/cakegrid.css b/webroot/css/cakegrid.css new file mode 100644 index 0000000..3f5fa10 --- /dev/null +++ b/webroot/css/cakegrid.css @@ -0,0 +1,183 @@ +.DataGrid{ + clear: both; + display: block; + + +} + +.RTL { + direction: rtl; +} + + +.DataGrid div.Caption{ + display: block; + background:url("/CakeGrid/img/captionbg.gif") repeat-x scroll center top transparent; + font-weight:bold; + overflow:hidden; + + white-space:nowrap; + //padding: 5px 10px; + border-left:1px solid #CCCCCC; + border-right:1px solid #CCCCCC; + +} + +.DataGrid div.ButtomsGroup{ + background:url("/CakeGrid/img/captionbg.gif") repeat-x scroll center top #FAFAFA; + border-top: 1px solid #ccc; + border-bottom: 1px solid #fff; + border-left:1px solid #CCCCCC; + border-right:1px solid #CCCCCC; + overflow: hidden; + padding: 3px 3px; + +} + + +.DataGrid div.ButtomsGroup a.buttom{ + display: inline-block; + vertical-align: top; + padding: 5px 30px 5px 10px; + border: 1px solid transparent; + margin: 0px 2px; + cursor: pointer; + font-family: tahoma; + font-size: 12px; + text-shadow:0 1px 0 #ccc; + color: #333; + background-repeat: no-repeat; + background-position: 90% center; + + +} + +.DataGrid div.ButtomsGroup .icon-add{ + background-image: url("/irsa/img/icons/add.png") ; +} + +.DataGrid div.ButtomsGroup a.buttom:hover{ + + border-right: 1px solid #fff; + border-top: 1px solid #fff; + border-left: 1px solid #eee; + outline: 1px solid #ccc; + +} + + +.DataGrid div.ButtomsGroup div.Spliter{ + border-left:1px solid #CCCCCC; + border-right:1px solid #FFFFFF; + height:22px; + margin:1px; + display: inline-block; +} + +.DataGrid div.ButtomsGroup div.RTL{ + float: right; +} + + +.DataGrid .GridScroller { + overflow:auto ; + border: none; + +} + +.DataGrid table{ + border-collapse: separate; + table-layout: fixed; + border-spacing: 1px 1px; + border-left:1px solid #CCCCCC; + border-top:1px solid #c7c7c7; + +} + +.DataGrid table thead tr.cg_header { + background: -moz-linear-gradient(center top , #EFEFEF, #CACACA) repeat scroll 0 0 transparent; + + +} + + + .DataGrid table thead tr.cg_header th , .DataGrid table tbody tr td{ + padding: 5px 5px; + border-right:1px solid #CCCCCC; + border-left:1px solid #fff; + vertical-align: middle; + white-space: nowrap; + + } + + .DataGrid table tbody tr.cg_row td{ + padding: 8px 5px; + } + + .DataGrid table thead tr.tableHeader th { + padding: 8px 5px; + + } + + .DataGrid table thead tr.tableHeader th div.Col{ + height: 22px; + line-height: 22px; + padding-right: 30px; + min-width: 100px; + } + + .DataGrid table thead tr.tableHeader th div.RowNumber{ + height: 22px; + line-height: 22px; + } + +.DataGrid table thead tr.tableHeader th span.Scroller{ + cursor: e-resize; + width: 2px; + height: 22px; + float: right; + + } + + .DataGrid table thead tr.tableHeader th span.RTL{ + float: left; + } + +.DataGrid table thead tr.tableHeader th div.Sorter{ + cursor: pointer; + float: left; + height: 16px; + width: 16px; + margin: 2px 5px ; + border:1px solid transparent; + } +.DataGrid table thead tr.tableHeader th div.Sorter:hover{ + border:1px solid #fff; + outline: 1px solid #ddd; +} + .DataGrid table thead tr.tableHeader th div.RTL{ + float: right; + margin: 2px 5px 0px 0px; + } + + + .DataGrid table tbody tr.cg_row.odd td{ + background: #f7f7f7; + border-bottom: 1px solid #f7f7f7; + + } + + + .DataGrid div.Footer{ + + border: none; + background:url("/irsa/img/wbg.gif") repeat-x scroll center top transparent; + font-weight:bold; + overflow:hidden; + white-space:nowrap; + border-bottom:1px solid #CCCCCC; + border-left:1px solid #CCCCCC; + border-right:1px solid #CCCCCC; + padding: 5px; + height: 10px; + } \ No newline at end of file diff --git a/webroot/img/bg.gif b/webroot/img/bg.gif new file mode 100644 index 0000000000000000000000000000000000000000..9ab78a2ec788d6dfbbcd6212a4d3b1d9917d55e7 GIT binary patch literal 854 zcmZ?wbhEHbWMZ&jXlGz}_Uzg7=g(ifc=7V(%U7>ny?*`r&6_uG-@bkK?%n(M?>~I_ z@c;jRhEXsY0>d-}6o0Y+efFP02jo9co?zfGW)Rn5a1d~4Xl7*5h_P7kkby}+S!_nc jfrg{q>_&192R0@*^>d1J$arpAa&odp@G2Wg0S0RTW*Ik7 literal 0 HcmV?d00001 diff --git a/webroot/img/captionbg.gif b/webroot/img/captionbg.gif new file mode 100644 index 0000000000000000000000000000000000000000..8046089a9de7680673de4bc9dbf45ffedf72aa52 GIT binary patch literal 868 zcmZ?wbhEHbWMt4`Y-eD&e*OB58#iv-HPoF=3 z{^G@pmoHzwe*OB*n>TOYzJ2%Z-G>h!{{R2aFbYOPVCaW{;!hT!C;l_&fV=|A6AT=V z46Gg<3=bQd*?7b>JQ^4dGBUGr2}md?Ff?>a7-!u%v2pS7eg)?)8P7|LTPAA+uZlUj WY3b?d2Fa)9cy3 Date: Fri, 9 Dec 2011 13:48:49 +0200 Subject: [PATCH 09/11] Removed CakePHP 2.0 "beta" as prerequisite --- README.md | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 62c785d..6f50445 100644 --- a/README.md +++ b/README.md @@ -8,11 +8,7 @@ Easy tabular data for CakePHP (cakephp.org) -- by Robert Ross (rross@sdreader.com) -- available at http://github.com/rross0227 -<<<<<<< HEAD - -- requires CakePHP 2.x beta -======= - -- requires CakePHP 2 Beta ->>>>>>> CakePHP2 + -- requires CakePHP 2.x Copyright (c) 2011 The Daily Save, LLC. All rights reserved. @@ -51,7 +47,7 @@ In your view file you can now create grids easily by doing something like this: $this->Grid->addAction('Edit', array('controller' => 'orders', 'action' => 'edit'), array('/Order/id')); - echo $this->Grid->generate($results); + echo $this->Grid->generate($orders); This will create a 4 column grid (including actions) for all of your orders or whatever you like! CakeGrid uses the Set::extract format found here: http://book.cakephp.org/view/1501/extract From cd10283b1b270298abbd88e2c939a7919f4a9af2 Mon Sep 17 00:00:00 2001 From: John Date: Fri, 9 Dec 2011 13:52:32 +0200 Subject: [PATCH 10/11] Removed call to Router::url causing the HTML->link in the element to proccess the url twice (if app is not in root will cause errors) --- View/Helper/GridHelper.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/View/Helper/GridHelper.php b/View/Helper/GridHelper.php index 503572c..b50eb32 100644 --- a/View/Helper/GridHelper.php +++ b/View/Helper/GridHelper.php @@ -362,7 +362,7 @@ private function __generateColumn($result, $column){ } $actions[$name] = array( - 'url' => Router::url($action['url'] + $trailingParams), + 'url' => $action['url'] + $trailingParams, 'options' => $action['options'] ); } From ec49c138e4370af7b0b4a1bfebb7bb97ad79e81e Mon Sep 17 00:00:00 2001 From: John Date: Fri, 9 Dec 2011 17:28:48 +0200 Subject: [PATCH 11/11] Added Pagination funcionality in headers Updated readme.md with pagination usage --- README.md | 7 +++++++ View/Elements/table/grid_headers.ctp | 12 +++++++++--- View/Helper/GridHelper.php | 3 ++- 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 6f50445..368d0da 100644 --- a/README.md +++ b/README.md @@ -133,6 +133,13 @@ This will output in the cell the users first and last name together. Concat uses '/User/register_ip' )); +## Paginate +By setting paginate as true you instruct CakeGrid to use the Paginator::sort method to create the headers of your table + + $this->Grid->addColumn('User', '/User/name', array('paginate'=>true)); + +CakeGrid won't add pagination links at the end of the table, you should add them yourself if you need them. + ## Elements CakeGrid allows the usage of your own elements to be used in cells. This is useful if you're wanting to use a hasMany relationship into a dropdown or something similar. diff --git a/View/Elements/table/grid_headers.ctp b/View/Elements/table/grid_headers.ctp index 3e8a3fb..cc6aa26 100644 --- a/View/Elements/table/grid_headers.ctp +++ b/View/Elements/table/grid_headers.ctp @@ -1,5 +1,11 @@ - - - + + + Paginator->sort(strtolower($header['title'])); + } else { + echo $header['title']; + }?> + + \ No newline at end of file diff --git a/View/Helper/GridHelper.php b/View/Helper/GridHelper.php index b50eb32..cd4aae2 100644 --- a/View/Helper/GridHelper.php +++ b/View/Helper/GridHelper.php @@ -109,7 +109,8 @@ function addColumn($title, $valuePath, array $options = array()){ 'type' => 'string', 'element' => false, 'linkable' => false, - 'total' => false + 'total' => false, + 'paginate' => false ); $options = array_merge($defaults, $options);