PageRenderTime 40ms CodeModel.GetById 11ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/OX/Admin/UI/Wizard.php

https://bitbucket.org/blackriver/openx
PHP | 412 lines | 188 code | 81 blank | 143 comment | 24 complexity | 2008c6c9403a0c7bacdffa5fbb5499ca MD5 | raw file
  1. <?php
  2. /*
  3. +---------------------------------------------------------------------------+
  4. | OpenX v2.8 |
  5. | ========== |
  6. | |
  7. | Copyright (c) 2003-2009 OpenX Limited |
  8. | For contact details, see: http://www.openx.org/ |
  9. | |
  10. | This program is free software; you can redistribute it and/or modify |
  11. | it under the terms of the GNU General Public License as published by |
  12. | the Free Software Foundation; either version 2 of the License, or |
  13. | (at your option) any later version. |
  14. | |
  15. | This program is distributed in the hope that it will be useful, |
  16. | but WITHOUT ANY WARRANTY; without even the implied warranty of |
  17. | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
  18. | GNU General Public License for more details. |
  19. | |
  20. | You should have received a copy of the GNU General Public License |
  21. | along with this program; if not, write to the Free Software |
  22. | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
  23. +---------------------------------------------------------------------------+
  24. $Id$
  25. */
  26. require_once MAX_PATH . '/lib/OX/Admin/UI/SessionStorage.php';
  27. /**
  28. * @package OX_Admin_UI
  29. * @author Bernard Lange <bernard@openx.org>
  30. */
  31. class OX_Admin_UI_Wizard
  32. {
  33. /**
  34. * Wizard id
  35. *
  36. * @var string
  37. */
  38. private $id;
  39. /**
  40. * An array of $stepId entries
  41. *
  42. * @var array
  43. */
  44. private $aStepIds;
  45. /*
  46. * An array of $stepId => $stepName entries
  47. * @var array
  48. */
  49. private $aSteps;
  50. /*
  51. * An array of $stepId => array entries. Metadata is an addiotional information
  52. * stored about step. This is not step data, this might eg. info if
  53. * step should be secure etc.
  54. *
  55. * @var array
  56. */
  57. private $aMetadata;
  58. /**
  59. * Current step id
  60. *
  61. * @var string
  62. */
  63. private $currentStepId;
  64. /**
  65. * A holder for wizard data
  66. *
  67. * @var OX_Admin_UI_Storage
  68. */
  69. private $oStorage;
  70. /**
  71. * Creates wizard object
  72. *
  73. * @param string $id identifier used by wizard internally when storing/retrieving its data
  74. * @param string $aOptions options array recognizes 'steps', 'current' and 'stepsMetadata' parameters atm.
  75. * @param OX_Admin_UI_Storage $oStorage optional storage to be used by wizard if not specified will use OX_Admin_UI_SessionStorage by default
  76. */
  77. public function __construct($id, $aOptions = null, $oStorage = null)
  78. {
  79. $this->id = "OX_UI_Install_Wizard-".$id;
  80. if (isset($aOptions['steps'])) {
  81. if (!is_array($aOptions['steps']) || empty($aOptions['steps'])) {
  82. throw new Exception('Please provide an array of steps');
  83. }
  84. $this->setSteps($aOptions['steps']);
  85. if (isset($aOptions['current'])) {
  86. $this->setCurrentStep($aOptions['current']);
  87. }
  88. else {
  89. $this->setCurrentStep($this->aStepIds[0]);
  90. }
  91. if (isset($aOptions['stepsMetadata'])) {
  92. $this->aMetadata = $aOptions['stepsMetadata'];
  93. }
  94. }
  95. if (empty($oStorage)) {
  96. $oStorage = new OX_Admin_UI_SessionStorage();
  97. }
  98. $this->oStorage = $oStorage;
  99. }
  100. /**
  101. * Set the wizard steps. Given param should be an associative array of stepId => stepName entries.
  102. * eg. * ('step1'=> 'Welcome!', 'step2' => 'Do sth', 'step3' => 'Done')
  103. *
  104. * @param array $aSteps
  105. */
  106. public function setSteps($aSteps)
  107. {
  108. if (!is_array($aSteps) || empty($aSteps)) {
  109. throw new Exception('Please provide an array of steps');
  110. }
  111. $this->aStepIds = array_keys($aSteps);
  112. $this->aSteps = $aSteps;
  113. $this->setCurrentStep($this->aStepIds[0]);
  114. }
  115. /**
  116. * Return wizard steps
  117. *
  118. * @return array of stepId => $stepName entries
  119. */
  120. public function getSteps()
  121. {
  122. return $this->aSteps;
  123. }
  124. /**
  125. * Sets the current step id
  126. *
  127. * @param string $stepId
  128. */
  129. public function setCurrentStep($stepId)
  130. {
  131. if (!in_array($stepId, $this->aStepIds)) {
  132. throw new Exception('Unable to set current step. Unknown step: '.$stepId);
  133. }
  134. $this->currentStepId = $stepId;
  135. }
  136. /**
  137. * Gets the current step id
  138. *
  139. * @param string $stepId
  140. */
  141. public function getCurrentStep()
  142. {
  143. return $this->currentStepId;
  144. }
  145. public function getFirstStep()
  146. {
  147. return !empty($this->aStepIds) ? $this->aStepIds[0] : null;
  148. }
  149. public function getLastStep()
  150. {
  151. return !empty($this->aStepIds)
  152. ? $this->aStepIds[count($this->aStepIds) - 1]
  153. : null;
  154. }
  155. public function getNextStep($stepId = null)
  156. {
  157. $stepId = empty($stepId) ? $this->currentStepId : $stepId;
  158. $idx = array_search($stepId, $this->aStepIds);
  159. if ($idx === false || $idx == count($this->aStepIds) - 1) {
  160. return null;
  161. }
  162. return $this->aStepIds[$idx + 1];
  163. }
  164. public function getPreviousStep($stepId = null)
  165. {
  166. $stepId = empty($stepId) ? $this->currentStepId : $stepId;
  167. $idx = array_search($stepId, $this->aStepIds);
  168. if ($idx === false || $idx == 0) {
  169. return null;
  170. }
  171. return $this->aStepIds[$idx - 1];
  172. }
  173. public function getStepName($stepId = null)
  174. {
  175. $stepId = empty($stepId) ? $this->currentStepId : $stepId;
  176. return $this->aStepNames[$stepId];
  177. }
  178. public function getStepData($stepId = null)
  179. {
  180. $stepId = empty($stepId) ? $this->currentStepId : $stepId;
  181. $storage = $this->getWizardData();
  182. $aStepData = $storage['stepData'];
  183. return !empty($aStepData) && isset($aStepData[$stepId]) ? $aStepData[$stepId] : null;
  184. }
  185. public function setStepData($aData, $stepId = null)
  186. {
  187. $stepId = empty($stepId) ? $this->currentStepId : $stepId;
  188. $storage = $this->getWizardData();
  189. $aStepData = $storage['stepData'];
  190. $aStepData = !empty($aStepData) ? $aStepData : array();
  191. $aStepData[$stepId] = $aData;
  192. $storage['stepData'] = $aStepData;
  193. $this->setWizardData($storage);
  194. }
  195. /**
  196. * Retrieves wizard step metdatada information (if any)
  197. *
  198. * @param string $stepId
  199. * @return mixed step metadata
  200. */
  201. public function getStepMeta($stepId = null)
  202. {
  203. $stepId = empty($stepId) ? $this->currentStepId : $stepId;
  204. return isset($this->aMetadata[$stepId]) ? $this->aMetadata[$stepId] : null;
  205. }
  206. public function setStepMeta($aData, $stepId = null)
  207. {
  208. $stepId = empty($stepId) ? $this->currentStepId : $stepId;
  209. $this->aMetadata[$stepId] = $aData;
  210. }
  211. /**
  212. * Marks step internally as completed. If $stepid is not given marks current
  213. * step as completed.
  214. *
  215. * Please note that this assumes wizard steps have been marked consecutively
  216. * as completed.
  217. * Wizard itself does not ensure continuity of the completed steps, ie. does
  218. * not check if previous steps have been marked as completed already.
  219. *
  220. * @param string $stepId step id
  221. */
  222. public function markStepAsCompleted($stepId = null)
  223. {
  224. $stepId = empty($stepId) ? $this->currentStepId : $stepId;
  225. $storage = $this->getWizardData();
  226. $aCompleted = $storage['completedSteps'];
  227. $aCompleted = !empty($aCompleted) ? $aCompleted : array();
  228. $aCompleted[$stepId] = true;
  229. $storage['completedSteps'] = $aCompleted;
  230. $this->setWizardData($storage);
  231. }
  232. /**
  233. * Checks if step is marked as completed. If $stepid is not given marks current
  234. * step as completed.
  235. *
  236. * Please note that this assumes wizard steps have been marked consecutively
  237. * as completed.
  238. * Wizard itself does not ensure continuity of the completed steps, ie. does
  239. * not check if previous steps have been marked as completed already.
  240. *
  241. * @param unknown_type $stepId
  242. * @return unknown
  243. */
  244. public function isStepCompleted($stepId = null)
  245. {
  246. $stepId = empty($stepId) ? $this->currentStepId : $stepId;
  247. $storage = $this->getWizardData();
  248. $aCompleted = $storage['completedSteps'];
  249. return !empty($aCompleted) && $aCompleted[$stepId] === true;
  250. }
  251. /**
  252. * Returns the id of the last step marked as completed. Starts at last step and
  253. * goes backward.
  254. *
  255. * Please note that this assumes wizard steps have been marked consecutively
  256. * as completed.
  257. * Wizard itself does not ensure continuity of the completed steps, ie. does
  258. * not check if previous steps have been marked as completed already.
  259. *
  260. * @return string stepId or null if not step marked as completed found
  261. */
  262. public function getLastCompletedStep()
  263. {
  264. $stepId = empty($this->currentStepId) ? $this->currentStepId : $this->getLastStep();
  265. $lastCompleted = null;
  266. while($stepId != null) {
  267. $completed = $this->isStepCompleted($stepId);
  268. if ($completed) {
  269. $lastCompleted = $stepId;
  270. break;
  271. }
  272. $stepId = $this->getPreviousStep($stepId);
  273. }
  274. return $lastCompleted;
  275. }
  276. public function isStep($stepId)
  277. {
  278. return in_array($stepId, $this->aStepIds);
  279. }
  280. /**
  281. * Indicates whether step is reachable.
  282. * Default implementation assumes that previous step has been makred as completed
  283. * with 'markStepAsCompleted' function. Also, first step is always reachable
  284. * by default.
  285. *
  286. * @param string $stepId
  287. * @return boolean
  288. */
  289. public function checkStepReachable($stepId = null)
  290. {
  291. $stepId = empty($stepId) ? $this->currentStepId : $stepId;
  292. if (!$this->isStep($stepId)) {
  293. return false;
  294. }
  295. $prevStep = $this->getPreviousStep($stepId);
  296. return $prevStep == null || $this->isStepCompleted($prevStep);
  297. }
  298. /**
  299. * Resets the wizard into a pristine form. That means all step data and wizard
  300. * progres is discarded
  301. */
  302. public function reset()
  303. {
  304. $storage = $this->getWizardData();
  305. $storage['completedSteps'] = null;
  306. $storage['stepData'] = null;
  307. $this->setWizardData($storage);
  308. }
  309. protected function getWizardData()
  310. {
  311. $oStorage = $this->getStorage();
  312. $wizardData = $oStorage->get($this->id);
  313. if (empty($wizardData)) {
  314. $wizardData = array();
  315. $this->setWizardData($wizardData);
  316. }
  317. return $wizardData;
  318. }
  319. protected function setWizardData($wizardData)
  320. {
  321. $this->getStorage()->set($this->id, $wizardData);
  322. }
  323. /**
  324. * @return OX_Admin_UI_Storage
  325. */
  326. protected function getStorage()
  327. {
  328. return $this->oStorage;
  329. }
  330. }
  331. ?>