wCMF  3.6
 All Classes Namespaces Files Functions Variables Groups Pages
class.PagingController.php
Go to the documentation of this file.
1 <?php
2 /**
3  * wCMF - wemove Content Management Framework
4  * Copyright (C) 2005-2014 wemove digital solutions GmbH
5  *
6  * Licensed under the terms of any of the following licenses
7  * at your choice:
8  *
9  * - GNU Lesser General Public License (LGPL)
10  * http://www.gnu.org/licenses/lgpl.html
11  * - Eclipse Public License (EPL)
12  * http://www.eclipse.org/org/documents/epl-v10.php
13  *
14  * See the license.txt file distributed with this work for
15  * additional information.
16  *
17  * $Id: class.PagingController.php 1462 2014-02-04 23:52:27Z iherwig $
18  */
19 require_once(BASE."wcmf/lib/presentation/class.Controller.php");
20 require_once(BASE."wcmf/lib/util/class.SessionData.php");
21 
22 /**
23  * @class PagingController
24  * @ingroup Controller
25  * @brief PagingController is a controller that allows to navigate lists
26  *
27  * This is accomplished by loading all object ids of the items to display
28  * at the first call and always assign a part of them to the view.
29  * The object ids are provided by the getOIDs() method that
30  * must be implemented by subclasses. The getLength() method provides
31  * the number of items to show per call (The default implementation
32  * returns 20).
33  *
34  * Actions 'jump', 'prev' and 'next' are used to navigate the list.
35  * If an oid is given in the data passed to the controller the controller
36  * tries to position the list according to that oid.
37  *
38  * A possible configuration could be:
39  *
40  * @code
41  * [actionmapping]
42  * ??showList = MyPagingController
43  * MyPagingController?? = MyPagingController
44  *
45  * [views]
46  * MyPagingController?? = list.tpl
47  * @endcode
48  *
49  * <b>Input actions:</b>
50  * - @em prev Navigate backwards
51  * - @em next Navigate forward
52  *
53  * <b>Output actions:</b>
54  * - @em ok In any case
55  *
56  * @param[in] oid The object id of the first object to display
57  * @param[out] nodes Array of Nodes (The current package)
58  * @param[out] hasPrev True/False whether prev navigation is possible
59  * @param[out] hasNext True/False whether next navigation is possible
60  * @param[out] total Total number of Nodes
61  * @param[out] index The start position of the current package
62  * @param[out] size The size of the current package
63  * @param[out] packageStartOids Array of package start oids
64  *
65  * @author ingo herwig <ingo@wemove.com>
66  */
68 {
69  // constants
70  var $OIDS_SESSION_VARNAME = 'PagingController.oids';
71  var $INDEX_SESSION_VARNAME = 'PagingController.index';
72 
73  // all oids in the list
74  var $_allOIDs = array();
75  // current oids to show
76  var $_curOIDs = array();
77 
78  // number of entries
79  var $_total = 0;
80  // state
81  var $_hasPrev = true;
82  var $_hasNext = true;
83  var $_startIndex = 0;
84  var $_size = 0;
85 
86  /**
87  * @see Controller::initialize()
88  */
89  function initialize(&$request, &$response)
90  {
91  parent::initialize($request, $response);
92 
93  $session = &SessionData::getInstance();
94  $length = $this->getLength();
95  if ($request->getAction() == 'prev' || $request->getAction() == 'next')
96  {
97  // navigate
98  // get state from session
99  if ($session->exist($this->OIDS_SESSION_VARNAME) && $session->exist($this->INDEX_SESSION_VARNAME))
100  {
101  //$allOIDs = $session->get($this->OIDS_SESSION_VARNAME);
102  $allOIDs = $this->getOIDs();
103  $lastIndex = $session->get($this->INDEX_SESSION_VARNAME);
104  }
105  else
106  WCMFException::throwEx("Error initializing PagingController: ".get_class($this), __FILE__, __LINE__);
107 
108  // navigate
109  if ($request->getAction() == 'next')
110  {
111  // calculate start index
112  $this->_startIndex = $lastIndex + $length;
113  if ($this->_startIndex >= sizeof($allOIDs))
114  $this->_startIndex = $lastIndex;
115  }
116  else if ($request->getAction() == 'prev')
117  {
118  // calculate start index
119  $this->_startIndex = $lastIndex - $length;
120  if ($this->_startIndex <= 0)
121  $this->_startIndex = 0;
122  }
123  }
124  else
125  {
126  // first call, initialize session variables
127  $allOIDs = $this->getOIDs();
128  $session->set($this->OIDS_SESSION_VARNAME, $allOIDs);
129 
130  if (in_array($request->getValue('oid'), $allOIDs))
131  {
132  // position on previous oid
133  $index = 0;
134  $this->_curOIDs = array_slice($allOIDs, $index, $length);
135  while (sizeof($this->_curOIDs) > 0)
136  {
137  if (in_array($request->getValue('oid'), $this->_curOIDs))
138  break;
139  $index += $length;
140  $this->_curOIDs = array_slice($allOIDs, $index, $length);
141  }
142  $this->_startIndex = $index;
143  }
144  else
145  $this->_startIndex = 0;
146  }
147 
148  // update state
149  $session->set($this->INDEX_SESSION_VARNAME, $this->_startIndex);
150  $this->_total = sizeof($allOIDs);
151  $this->_allOIDs = $allOIDs;
152  $this->_curOIDs = array_slice($allOIDs, $this->_startIndex, $length);
153  $this->_size = sizeof($this->_curOIDs);
154  $this->updateNavigation($this->_startIndex, $length, $this->_total);
155  }
156  /**
157  * @see Controller::hasView()
158  */
159  function hasView()
160  {
161  return true;
162  }
163  /**
164  * Do processing and assign Node data to View.
165  * @return False in every case.
166  * @see Controller::executeKernel()
167  */
168  function executeKernel()
169  {
170  $persistenceFacade = &PersistenceFacade::getInstance();
171  $rightsManager = &RightsManager::getInstance();
172 
173  $nodes = array();
174  foreach($this->_curOIDs as $curOID)
175  {
176  // check if we can read the object
177  if ($rightsManager->authorize($curOID, '', ACTION_READ))
178  {
179  $node = &$persistenceFacade->load($curOID, BUILDDEPTH_SINGLE);
180  $node->setValue('displaytext', $this->getDisplayText($node), DATATYPE_IGNORE);
181  $nodes[sizeof($nodes)] = &$node;
182  }
183  }
184  $this->modifyModel($nodes);
185 
186  $this->_response->setValue('nodes', $nodes);
187  $this->_response->setValue('hasPrev', $this->_hasPrev);
188  $this->_response->setValue('hasNext', $this->_hasNext);
189 
190  $this->_response->setValue('total', $this->_total);
191  $this->_response->setValue('index', $this->_startIndex);
192  $this->_response->setValue('size', $this->_size);
193 
194  // assign package start oids
195  $packageStartOids = array();
196  $length = $this->getLength();
197  $index = 0;
198  while ($index < sizeof($this->_allOIDs))
199  {
200  array_push($packageStartOids, $this->_allOIDs[$index]);
201  $index += $length;
202  }
203  $this->_response->setValue('packageStartOids', $packageStartOids);
204 
205  // success
206  $this->_response->setAction('ok');
207  return false;
208  }
209  /**
210  * Get oids of all items to display.
211  * @return Array of oids of all items
212  * @note subclasses must implement this method.
213  */
214  function getOIDs()
215  {
216  WCMFException::throwEx("getOIDs() must be implemented by derived class: ".get_class($this), __FILE__, __LINE__);
217  }
218  /**
219  * Get the text to display for a given node in the list.
220  * This text will be assigned to the value 'displaytext' (DATATYPE_IGNORE) in the node.
221  * @return Display text
222  * @note subclasses must implement this method.
223  */
224  function getDisplayText(&$node)
225  {
226  WCMFException::throwEx("getDisplayText() must be implemented by derived class: ".get_class($this), __FILE__, __LINE__);
227  }
228  /**
229  * Modify the model passed to the view.
230  * @note subclasses will override this to implement special application requirements.
231  * @param nodes A reference to the array of node references passed to the view
232  */
233  function modifyModel(&$nodes) {}
234  /**
235  * Get the number of items to show per call.
236  * @return Number of items
237  * @note The default implementation returns 10. Subclasses may
238  * override this to e.g. achive a user defined behaviour
239  */
240  function getLength()
241  {
242  return 20;
243  }
244  /**
245  * Set the navigation variables (hasPrev, hasNext) according to the current position
246  * @param startIndex The position of the first item
247  * @param length The number of items to show
248  * @param total The number of all items
249  */
250  function updateNavigation($startIndex, $length, $total)
251  {
252  // prev button
253  if ($startIndex <= 0)
254  $this->_hasPrev = false;
255  else
256  $this->_hasPrev = true;
257 
258  // next button
259  if ($startIndex >= $total || $startIndex+$length >= $total)
260  $this->_hasNext = false;
261  else
262  $this->_hasNext = true;
263  }
264  /**
265  * Resets the list (retrieves the oids, ...)
266  */
267  function reset()
268  {
269  $session = &SessionData::getInstance();
270  $session->remove($this->OIDS_SESSION_VARNAME);
271  $this->initialize($this->_request, $this->_response);
272  }
273 }
274 ?>
PagingController is a controller that allows to navigate lists.
throwEx($message, $file='', $line='')
Controller is the base class of all controllers. If a Controller has a view it is expected to reside ...
const DATATYPE_IGNORE
initialize(&$request, &$response)
updateNavigation($startIndex, $length, $total)
const BUILDDEPTH_SINGLE
const ACTION_READ