PageRenderTime 24ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/library/Core/Grid.php

https://code.google.com/p/zfcore/
PHP | 284 lines | 158 code | 36 blank | 90 comment | 28 complexity | df3abde963886dac9d5826bd2b1107ef MD5 | raw file
  1. <?php
  2. /**
  3. * Copyright (c) 2012 by PHP Team of NIX Solutions Ltd
  4. *
  5. * Permission is hereby granted, free of charge, to any person obtaining a copy
  6. * of this software and associated documentation files (the "Software"), to deal
  7. * in the Software without restriction, including without limitation the rights
  8. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9. * copies of the Software, and to permit persons to whom the Software is
  10. * furnished to do so, subject to the following conditions:
  11. *
  12. * The above copyright notice and this permission notice shall be included in
  13. * all copies or substantial portions of the Software.
  14. *
  15. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  21. * THE SOFTWARE.
  22. */
  23. /**
  24. * Grid
  25. *
  26. * @category Core
  27. * @package Core_Grid
  28. */
  29. class Core_Grid extends Core_Grid_Abstract
  30. {
  31. /**
  32. * types
  33. */
  34. const TYPE_DATA = 'data';
  35. const TYPE_EMPTY = 'empty';
  36. /**
  37. * paginator
  38. *
  39. * @var Zend_Paginator
  40. */
  41. protected $_paginator = null;
  42. /**
  43. * get headers
  44. *
  45. * @throws Core_Exception
  46. * @return array
  47. */
  48. public function getHeaders()
  49. {
  50. if ($this->_headers === null) {
  51. /** init paginator if it wasn't initialized */
  52. $this->getPaginator();
  53. $this->_headers = array();
  54. foreach ($this->_columns as $columnId => $column) {
  55. if (empty($column['name'])) {
  56. throw new Core_Exception('Column "' . $columnId . '" does not have name');
  57. }
  58. $header = new stdClass();
  59. $header->id = $columnId;
  60. $header->name = $column['name'];
  61. $header->type = $this->_getColumnType($columnId);
  62. $header->isOrdered = isset($column['order']) && $column['order'] ? true : false;
  63. $header->orderDirection = isset($column['order']) ? $column['order'] : '';
  64. $header->attribs = isset($column['attribs']) ? $column['attribs'] : array();
  65. $this->_headers[] = $header;
  66. }
  67. }
  68. return $this->_headers;
  69. }
  70. /**
  71. * get data
  72. *
  73. * @throws Core_Exception
  74. * @return array
  75. */
  76. public function getData()
  77. {
  78. if ($this->_data === null) {
  79. $items = $this->getPaginator()->getCurrentItems();
  80. if ($items instanceof Zend_Db_Table_Rowset_Abstract) {
  81. $items = $items->toArray();
  82. }
  83. $this->_data = array();
  84. foreach ($items as $item) {
  85. $row = array();
  86. foreach ($this->_columns as $id => $column) {
  87. $value = '';
  88. $type = $this->_getColumnType($id);
  89. if ($type === self::TYPE_DATA) {
  90. $index = $this->_getColumnIndex($id);
  91. if (!array_key_exists($index, $item)) {
  92. throw new Core_Exception('Index "' . $index . '" does not exist in data source');
  93. }
  94. $value = $item[$index];
  95. }
  96. // apply formatters
  97. if (isset($column['formatter'])) {
  98. if (is_array($column['formatter'][1])) {
  99. $obj = $column['formatter'][0];
  100. foreach ($column['formatter'][1] as $func) {
  101. $function = '';
  102. $formatter = array($obj, $func);
  103. if (!is_callable($formatter, null, $function)) {
  104. throw new Core_Exception('"' . $function . '" is not callable');
  105. }
  106. $value = call_user_func($formatter, $value, $item, $column);
  107. }
  108. } else {
  109. $function = '';
  110. $formatter = $column['formatter'];
  111. if (!is_callable($formatter, null, $function)) {
  112. throw new Core_Exception('"' . $function . '" is not callable');
  113. }
  114. $value = call_user_func($formatter, $value, $item, $column);
  115. }
  116. }
  117. $row[$id] = $value;
  118. }
  119. $this->_data[] = $row;
  120. }
  121. }
  122. return $this->_data;
  123. }
  124. /**
  125. * get paginator
  126. *
  127. * @return Zend_Paginator
  128. */
  129. public function getPaginator()
  130. {
  131. if (empty($this->_paginator)) {
  132. $this->_buildPaginator();
  133. }
  134. return $this->_paginator;
  135. }
  136. /**
  137. * build paginator
  138. *
  139. * @throws Core_Exception
  140. * @return void
  141. */
  142. protected function _buildPaginator()
  143. {
  144. if (!$this->_adapter instanceof Core_Grid_Adapter_AdapterInterface) {
  145. throw new Core_Exception('Adapter is not set');
  146. }
  147. if (empty($this->_columns)) {
  148. throw new Core_Exception('There are no any columns');
  149. }
  150. /** default ordering */
  151. if (empty($this->_orders)) {
  152. if ($this->_defaultOrders) {
  153. $this->_orders = $this->_defaultOrders;
  154. } else {
  155. /** order by first column if default order isn't set */
  156. foreach ($this->_columns as $key => $column) {
  157. if (isset($column->type) && self::TYPE_DATA == $column->type) {
  158. $this->setOrder($key);
  159. break;
  160. }
  161. }
  162. }
  163. }
  164. /** ordering */
  165. foreach ($this->_orders as $columnId => $direction) {
  166. $this->_adapter->order($this->_getColumnIndex($columnId), $direction);
  167. $this->_columns[$columnId]['order'] = $direction;
  168. }
  169. /** filtering */
  170. if ($this->_filters) {
  171. foreach ($this->_filters as $columnId => $filters) {
  172. $index = $this->_getColumnIndex($columnId);
  173. foreach ($filters as $filter) {
  174. $this->_adapter->filter($index, $filter);
  175. }
  176. }
  177. }
  178. if (empty($this->_itemCountPerPage)) {
  179. throw new Core_Exception('Item count per page is not set');
  180. }
  181. if (empty($this->_currentPageNumber)) {
  182. throw new Core_Exception('Current page is not set');
  183. }
  184. $this->_paginator = Zend_Paginator::factory($this->_adapter->getSource())
  185. ->setItemCountPerPage($this->_itemCountPerPage)
  186. ->setCurrentPageNumber($this->_currentPageNumber);
  187. }
  188. /**
  189. * get column
  190. *
  191. * @throws Core_Exception
  192. * @param $columnId
  193. * @return
  194. */
  195. protected function _getColumn($columnId)
  196. {
  197. if (empty($this->_columns[$columnId])) {
  198. throw new Core_Exception('Column "' . $columnId . '" does not exist');
  199. }
  200. return $this->_columns[$columnId];
  201. }
  202. /**
  203. * get column index
  204. *
  205. * @throws Core_Exception
  206. * @param $columnId
  207. * @return string
  208. */
  209. protected function _getColumnIndex($columnId)
  210. {
  211. $column = $this->_getColumn($columnId);
  212. if (empty($column['index'])) {
  213. throw new Core_Exception('Index of column "' . $columnId . '" does not exist');
  214. }
  215. return $column['index'];
  216. }
  217. /**
  218. * get column type
  219. *
  220. * @throws Core_Exception
  221. * @param $columnId
  222. * @return string
  223. */
  224. protected function _getColumnType($columnId)
  225. {
  226. $column = $this->_getColumn($columnId);
  227. $type = 'empty';
  228. if (isset($column['type'])) {
  229. $type = $column['type'];
  230. }
  231. if (!in_array($type, $this->_getAllowedTypes())) {
  232. throw new Core_Exception('Type "' . $type . '" of column "' . $columnId . '" is not allowed');
  233. }
  234. return $type;
  235. }
  236. /**
  237. * get allowed types
  238. *
  239. * @return array
  240. */
  241. protected function _getAllowedTypes()
  242. {
  243. return array(
  244. self::TYPE_DATA,
  245. self::TYPE_EMPTY
  246. );
  247. }
  248. }