Open Monograph Press  1.1
 All Classes Namespaces Functions Variables Groups Pages
CategoryGridHandler.inc.php
1 <?php
2 
16 // import grid classes
17 import('lib.pkp.classes.controllers.grid.GridHandler');
18 import('lib.pkp.classes.controllers.grid.GridCategoryRow');
19 
20 // empty category constant
21 define('GRID_CATEGORY_NONE', 'NONE');
22 
24 
26  var $_emptyCategoryRowText = 'grid.noItems';
27 
29  var $_currentCategoryId = null;
30 
34  function CategoryGridHandler($dataProvider = null) {
35  parent::GridHandler($dataProvider);
36 
37  import('lib.pkp.classes.controllers.grid.NullGridCellProvider');
38  $this->addColumn(new GridColumn('indent', null, null, 'controllers/grid/gridCell.tpl',
39  new NullGridCellProvider(), array('indent' => true)));
40  }
41 
42 
43  //
44  // Getters and setters.
45  //
50  function getEmptyCategoryRowText() {
52  }
53 
58  function setEmptyCategoryRowText($translationKey) {
59  $this->_emptyCategoryRowText = $translationKey;
60  }
61 
69  function hasGridDataElementsInCategory($categoryDataElement, $request) {
70  $filter = $this->getFilterSelectionData($request);
71  $data =& $this->getCategoryData($categoryDataElement, $filter);
72  assert (is_array($data));
73  return (boolean) count($data);
74  }
75 
80  function getCurrentCategoryId() {
82  }
83 
92  function getDataElementInCategorySequence($categoryId, &$gridDataElement) {
93  assert(false);
94  }
95 
104  function setDataElementInCategorySequence($categoryId, &$gridDataElement, $newSequence) {
105  assert(false);
106  }
107 
114  function isDataElementInCategorySelected($categoryId, &$gridDataElement) {
115  assert(false);
116  }
117 
118 
119  //
120  // Public handler methods
121  //
129  function fetchCategory(&$args, $request) {
130  // Instantiate the requested row (includes a
131  // validity check on the row id).
132  $row = $this->getRequestedCategoryRow($request, $args);
133 
134  $json = new JSONMessage(true);
135  if (is_null($row)) {
136  // Inform the client that the category does no longer exist.
137  $json->setAdditionalAttributes(array('elementNotFound' => (int)$args['rowId']));
138  } else {
139  // Render the requested category
140  $this->setFirstDataColumn();
141  $json->setContent($this->_renderCategoryInternally($request, $row));
142  }
143 
144  // Render and return the JSON message.
145  return $json->getString();
146  }
147 
148 
149  //
150  // Extended methods from GridHandler
151  //
152  function initialize($request) {
153  parent::initialize($request);
154 
155  if (!is_null($request->getUserVar('rowCategoryId'))) {
156  $this->_currentCategoryId = (string) $request->getUserVar('rowCategoryId');
157  }
158  }
159 
163  function getRequestArgs() {
164  $args = parent::getRequestArgs();
165 
166  // If grid is rendering grid rows inside category,
167  // add current category id value so rows will also know
168  // their parent category.
169  if (!is_null($this->_currentCategoryId)) {
170  if ($this->getCategoryRowIdParameterName()) {
172  }
173  }
174 
175  return $args;
176  }
177 
178 
182  public function getJSHandler() {
183  return '$.pkp.controllers.grid.CategoryGridHandler';
184  }
185 
189  function setUrls($request) {
190  $router = $request->getRouter();
191  $url = array('fetchCategoryUrl' => $router->url($request, null, null, 'fetchCategory', null, $this->getRequestArgs()));
192  parent::setUrls($request, $url);
193  }
194 
198  protected function getRowsSequence($request) {
199  $filter = $this->getFilterSelectionData($request);
200  return array_keys($this->getCategoryData($this->getCurrentCategoryId(), $filter));
201  }
202 
206  protected function doSpecificFetchGridActions($args, $request, &$templateMgr) {
207  // Render the body elements (category groupings + rows inside a <tbody>)
208  $gridBodyParts = $this->_renderCategoriesInternally($request);
209  $templateMgr->assign('gridBodyParts', $gridBodyParts);
210  }
211 
215  protected function getRowDataElement($request, $rowId) {
216  $rowData = parent::getRowDataElement($request, $rowId);
217  $rowCategoryId = $request->getUserVar('rowCategoryId');
218 
219  if (is_null($rowData) && !is_null($rowCategoryId)) {
220  // Try to get row data inside category.
221  $categoryRowData = parent::getRowDataElement($request, $rowCategoryId);
222  if (!is_null($categoryRowData)) {
223  $categoryElements = $this->getCategoryData($categoryRowData, null);
224 
225  assert(is_array($categoryElements));
226  if (!isset($categoryElements[$rowId])) return null;
227 
228  // Let grid (and also rows) knowing the current category id.
229  // This value will be published by the getRequestArgs method.
230  $this->_currentCategoryId = $rowCategoryId;
231 
232  return $categoryElements[$rowId];
233  }
234  } else {
235  return $rowData;
236  }
237  }
238 
242  protected function setFirstDataColumn() {
243  $columns =& $this->getColumns();
244  reset($columns);
245  // Category grids will always have indent column firstly,
246  // so we need to consider the first column the second one.
247  $secondColumn = next($columns); /* @var $secondColumn GridColumn */
248  $secondColumn->addFlag('firstColumn', true);
249  }
250 
254  protected function renderRowInternally($request, $row) {
255  if ($this->getCategoryRowIdParameterName()) {
256  $param = $this->getRequestArg($this->getCategoryRowIdParameterName());
257  $templateMgr = TemplateManager::getManager($request);
258  $templateMgr->assign('categoryId', $param);
259  }
261  return parent::renderRowInternally($request, $row);
262  }
263 
275  protected function getRequestedCategoryRow($request, $args) {
276  if (isset($args['rowId'])) {
277  // A row ID was specified. Fetch it
278  $elementId = $args['rowId'];
279 
280  // Retrieve row data for the requested row id
281  // (we can use the default getRowData element, works for category grids as well).
282  $dataElement = $this->getRowDataElement($request, $elementId);
283  if (is_null($dataElement)) {
284  // If the row doesn't exist then
285  // return null. It may be that the
286  // row has been deleted in the meantime
287  // and the client does not yet know about this.
288  $nullVar = null;
289  return $nullVar;
290  }
291  }
292 
293  // Instantiate a new row
294  return $this->_getInitializedCategoryRowInstance($request, $elementId, $dataElement);
295  }
296 
297 
298  //
299  // Protected methods to be overridden/used by subclasses
300  //
307  protected function getCategoryRowInstance() {
308  //provide a sensible default category row definition
309  return new GridCategoryRow();
310  }
311 
316  protected function getCategoryRowIdParameterName() {
317  // Must be implemented by subclasses.
318  return null;
319  }
320 
326  protected function &getCategoryData(&$categoryDataElement, $filter = null) {
327  $gridData = array();
328  $dataProvider = $this->getDataProvider();
329  if (is_a($dataProvider, 'CategoryGridDataProvider')) {
330  // Populate the grid with data from the
331  // data provider.
332  $gridData =& $dataProvider->getCategoryData($categoryDataElement, $filter);
333  }
334  return $gridData;
335  }
336 
337 
338  //
339  // Private helper methods
340  //
349  private function _getInitializedCategoryRowInstance($request, $elementId, $element) {
350  // Instantiate a new row
351  $row = $this->getCategoryRowInstance();
352  $row->setGridId($this->getId());
353  $row->setId($elementId);
354  $row->setData($element);
355  $row->setRequestArgs($this->getRequestArgs());
356 
357  // Initialize the row before we render it
358  $row->initialize($request);
359  $this->callFeaturesHook('getInitializedCategoryRowInstance',
360  array('request' => $request,
361  'grid' => $this,
362  'categoryId' => $this->_currentCategoryId,
363  'row' => $row));
364  return $row;
365  }
366 
371  private function _renderCategoriesInternally($request) {
372  // Iterate through the rows and render them according
373  // to the row definition.
374  $renderedCategories = array();
375 
376  $elements = $this->getGridDataElements($request);
377  foreach($elements as $key => $element) {
378 
379  // Instantiate a new row
380  $categoryRow = $this->_getInitializedCategoryRowInstance($request, $key, $element);
381 
382  // Render the row
383  $renderedCategories[] = $this->_renderCategoryInternally($request, $categoryRow);
384  }
385 
386  return $renderedCategories;
387  }
388 
395  private function _renderCategoryInternally($request, $categoryRow) {
396  // Prepare the template to render the category.
397  $templateMgr = TemplateManager::getManager($request);
398  $templateMgr->assign('grid', $this);
399  $columns = $this->getColumns();
400  $templateMgr->assign('columns', $columns);
401 
402  $categoryDataElement = $categoryRow->getData();
403  $filter = $this->getFilterSelectionData($request);
404  $rowData = $this->getCategoryData($categoryDataElement, $filter);
405 
406  // Render the data rows
407  $templateMgr->assign('categoryRow', $categoryRow);
408 
409  // Let grid (and also rows) knowing the current category id.
410  // This value will be published by the getRequestArgs method.
411  $this->_currentCategoryId = $categoryRow->getId();
412 
413  $renderedRows = $this->renderRowsInternally($request, $rowData);
414  $templateMgr->assign('rows', $renderedRows);
415 
416  $renderedCategoryRow = $this->renderRowInternally($request, $categoryRow);
417 
418  // Finished working with this category, erase the current id value.
419  $this->_currentCategoryId = null;
420 
421  $templateMgr->assign('renderedCategoryRow', $renderedCategoryRow);
422  return $templateMgr->fetch('controllers/grid/gridBodyPartWithCategory.tpl');
423  }
424 }
425 
426 ?>
fetchCategory(&$args, $request)
renderRowsInternally($request, &$elements)
hasGridDataElementsInCategory($categoryDataElement, $request)
& getCategoryData(&$categoryDataElement, $filter=null)
getDataElementInCategorySequence($categoryId, &$gridDataElement)
Class defining basic operations for handling the category row in a grid.
setDataElementInCategorySequence($categoryId, &$gridDataElement, $newSequence)
addColumn($column)
Class defining basic operations for handling HTML grids.
getRowDataElement($request, $rowId)
Class to represent a JSON (Javascript Object Notation) message.
isDataElementInCategorySelected($categoryId, &$gridDataElement)
Class defining basic operations for handling HTML grids with categories.
getRequestedCategoryRow($request, $args)
renderRowInternally($request, $row)
& getGridDataElements($request)
doSpecificFetchGridActions($args, $request, &$templateMgr)
getFilterSelectionData($request)
setEmptyCategoryRowText($translationKey)
Class to return null when render method is called by a grid handler. Use this when you want to create...
CategoryGridHandler($dataProvider=null)
Represents a column within a grid. It is used to configure the way cells within a column are displaye...
callFeaturesHook($hookName, $args)