wCMF  3.6
 All Classes Namespaces Files Functions Variables Groups Pages
class.BatchController.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.BatchController.php 1462 2014-02-04 23:52:27Z iherwig $
18  */
19 require_once(BASE."wcmf/application/controller/class.LongTaskController.php");
20 
21 /**
22  * @class BatchController
23  * @ingroup Controller
24  * @brief BatchController allows to define work packages that will be processed
25  * in a sequence. It simplifies the usage of LongTaskController functionality
26  * for splitting different bigger tasks into many smaller (similar) tasks where
27  * the whole number of tasks isn't known at designtime.
28  *
29  * <b>Input actions:</b>
30  * - @em continue Process next work package if any
31  * - unspecified: Initialized work packages
32  *
33  * <b>Output actions:</b>
34  * - see LongTaskController
35  *
36  * @author ingo herwig <ingo@wemove.com>
37  */
39 {
40  // session name constants
41  var $WORK_PACKAGES_VARNAME = 'BatchController.workPackages';
42  var $NUM_STEPS_VARNAME = 'BatchController.numSteps';
43 
44  var $_workPackages = array();
45 
46  /**
47  * @see Controller::initialize()
48  */
49  function initialize(&$request, &$response)
50  {
51  parent::initialize($request, $response);
52 
53  // define work packages
54  $session = &SessionData::getInstance();
55  if ($request->getAction() == 'continue')
56  {
57  // get export definition for current call from session
58  if ($session->exist($this->WORK_PACKAGES_VARNAME))
59  $this->_workPackages = $session->get($this->WORK_PACKAGES_VARNAME);
60  else
61  WCMFException::throwEx("Error initializing BatchController: ".get_class($this), __FILE__, __LINE__);
62  }
63  else
64  {
65  // first call, initialize session variable
66  $persistenceFacade = &PersistenceFacade::getInstance();
67  $tmpArray = array();
68  $session->set($this->WORK_PACKAGES_VARNAME, $tmpArray);
69 
70  // define work packages
71  $number = 0;
72  while (($workPackage = $this->getWorkPackage($number)) !== null)
73  {
74  if (!isset($workPackage['name']) || !isset($workPackage['size']) ||
75  !isset($workPackage['oids']) || !isset($workPackage['callback']))
76  WCMFException::throwEx("Incomplete work package description.", __FILE__, __LINE__);
77  else
78  {
79  $this->addWorkPackage($workPackage['name'], $workPackage['size'], $workPackage['oids'], $workPackage['callback'], $workPackage['args']);
80  $number++;
81  }
82  }
83  if ($number == 0)
84  WCMFException::throwEx("Error initializing BatchController: ".get_class($this).": No work package defined.", __FILE__, __LINE__);
85  }
86  }
87  /**
88  * Add a work package to session. This package will be devided into sub packages of given size.
89  * @param name Display name of the package (will be supplemented by startNumber-endNumber, e.g. '1-7', '8-14', ...)
90  * @param size Size of one sub package. This defines how many of the oids will be passed to the callback in one call (e.g. '7' means pass 7 oids per call)
91  * @param oids An array of oids (or other application specific package identifiers) that will be distributed into sub packages of given size
92  * @note The array must contain at least one value
93  * @param callback The name of method to call for this package type
94  * @note The callback method must accept the following parameters:
95  * - one array parameter (the oids to process in the current call)
96  * - optionally array parameter (the additional arguments)
97  * @param args Assoziative array of additional callback arguments (application specific) [default: null]
98  */
99  function addWorkPackage($name, $size, $oids, $callback, $args=null)
100  {
101  if ($size < 1)
102  {
103  WCMFException::throwEx("Wrong work package description '".$name."': Size must be at least 1.", __FILE__, __LINE__);
104  return;
105  }
106  if (sizeOf($oids) == 0)
107  {
108  WCMFException::throwEx("Wrong work package description '".$name."': No oids given.", __FILE__, __LINE__);
109  return;
110  }
111  if (strlen($callback) == 0)
112  {
113  WCMFException::throwEx("Wrong work package description '".$name."': No callback given.", __FILE__, __LINE__);
114  return;
115  }
116 
117  $session = &SessionData::getInstance();
118  $workPackages = $session->get($this->WORK_PACKAGES_VARNAME);
119 
120  $counter = 1;
121  $total = sizeOf($oids);
122  while(sizeOf($oids) > 0)
123  {
124  $items = array();
125  for($i=0; $i<$size; $i++)
126  {
127  $nextItem = array_shift($oids);
128  if($nextItem !== null)
129  array_push($items, $nextItem);
130  }
131 
132  // define status text
133  $start = $counter;
134  $end = ($counter+sizeOf($items)-1);
135  $stepsText = $counter;
136  if ($start != $end) {
137  $stepsText .= '-'.($counter+sizeOf($items)-1);
138  }
139  $statusText = "";
140  if ($total > 1) {
141  $statusText = $stepsText.'/'.$total;
142  }
143 
144  $curWorkPackage = array('name' => $name.' '.$statusText,
145  'oids' => $items,
146  'callback' => $callback,
147  'args' => $args);
148  array_push($workPackages, $curWorkPackage);
149  $counter += $size;
150  }
151  $session->set($this->WORK_PACKAGES_VARNAME, $workPackages);
152  $session->set($this->NUM_STEPS_VARNAME, sizeOf($workPackages));
153 
154  $this->_workPackages = $workPackages;
155  }
156  /**
157  * Get definitions of work packages.
158  * @param number The number of the work package (first number is 0, number is incremented on every call)
159  * @note This function gets called on first initialization run as often until it returns null.
160  * This allows to define different static work packages. If you would like to add work packages dynamically on
161  * subsequent runs this may be done by directly calling the BatchController::addWorkPackage() method.
162  * @return A work packages description as assoziative array with keys 'name', 'size', 'oids', 'callback'
163  * as required for BatchController::addWorkPackage() method or null to terminate.
164  * @note subclasses must implement this method.
165  */
166  function getWorkPackage($number)
167  {
168  WCMFException::throwEx("getWorkPackage() must be implemented by derived class: ".get_class($this), __FILE__, __LINE__);
169  }
170  /**
171  * @see LongTaskController::getNumberOfSteps()
172  */
173  function getNumberOfSteps()
174  {
175  $session = &SessionData::getInstance();
176  return $session->get($this->NUM_STEPS_VARNAME);
177  }
178  /**
179  * @see LongTaskController::getDisplayText()
180  */
181  function getDisplayText($step)
182  {
183  return Message::get("Processing")." ".$this->_workPackages[$step-1]['name']." ...";
184  }
185  /**
186  * @see LongTaskController::getSummaryText()
187  * The default implementation returns an empty string
188  */
189  function getSummaryText()
190  {
191  return "";
192  }
193  /**
194  * @see LongTaskController::processPart()
195  */
196  function processPart()
197  {
198  if ($this->getStepNumber()-1 == $this->getNumberOfSteps()) {
199  return;
200  }
201 
202  $curWorkPackageDef = $this->_workPackages[$this->getStepNumber()-1];
203  if (strlen($curWorkPackageDef['callback']) == 0) {
204  WCMFException::throwEx("Empty callback name.", __FILE__, __LINE__);
205  }
206  else
207  {
208  if (!method_exists($this, $curWorkPackageDef['callback']))
209  WCMFException::throwEx("Method '".$curWorkPackageDef['callback']."' must be implemented by ".get_class($this), __FILE__, __LINE__);
210  else
211  call_user_method($curWorkPackageDef['callback'], $this, $curWorkPackageDef['oids'], $curWorkPackageDef['args']);
212  }
213  }
214 }
215 ?>
LongTaskController is a controller that may be used as base class for tasks, that require a long exec...
get($message, $parameters=null, $domain='', $lang='')
initialize(&$request, &$response)
throwEx($message, $file='', $line='')
addWorkPackage($name, $size, $oids, $callback, $args=null)
BatchController allows to define work packages that will be processed in a sequence. It simplifies the usage of LongTaskController functionality for splitting different bigger tasks into many smaller (similar) tasks where the whole number of tasks isn't known at designtime.