source: branches/eli_branch/lib/PageSequence.inc.php @ 530

Last change on this file since 530 was 439, checked in by anonymous, 11 years ago

added public and private keywords to all properties and methods, changed old classname constructor function to construct, removed more ?> closing tags

File size: 12.8 KB
Line 
1<?php
2/**
3 * The Strangecode Codebase - a general application development framework for PHP
4 * For details visit the project site: <http://trac.strangecode.com/codebase/>
5 * Copyright 2001-2012 Strangecode, LLC
6 *
7 * This file is part of The Strangecode Codebase.
8 *
9 * The Strangecode Codebase is free software: you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as published by the
11 * Free Software Foundation, either version 3 of the License, or (at your option)
12 * any later version.
13 *
14 * The Strangecode Codebase is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
17 * details.
18 *
19 * You should have received a copy of the GNU General Public License along with
20 * The Strangecode Codebase. If not, see <http://www.gnu.org/licenses/>.
21 */
22
23/**
24 * PageSequence.inc.php
25 *
26 * The PageSequence class provides an interface to simplify the creation of a multi-step form.
27 *
28 * @requires  This class requires Prefs.inc.php
29 * @author    Quinn Comendant <quinn@strangecode.com>
30 * @version   1.01
31 */
32
33require_once dirname(__FILE__) . '/Prefs.inc.php';
34
35class PageSequence
36{
37    public $current_step_id = 0;
38    public $start_url;
39    public $sequence_title = '';
40    public $seq = '_sequence_';
41    public $idle_timeout;
42
43    /**
44     * Constructor. Sets the title of this sequence and initializes session variables.
45     *
46     * @param  array $params   An associative array of PageSequence parameters.
47     * @access public
48     */
49    public function __construct($params)
50    {
51        if (isset($params['sequence_title'])) {
52            $this->sequence_title = $params['sequence_title'];
53            $this->seq .= $params['sequence_title'];
54        }
55
56        // How long before resetting session? 60 minutes.
57        $this->idle_timeout = isset($params['idle_timeout']) ? $params['idle_timeout'] : 3600;
58
59        // Where is user to be redirected after startOver function call?
60        $this->start_url = isset($params['start_url']) ? $params['start_url'] : $_SERVER['PHP_SELF'];
61
62        // Initialize vars if not set.
63        if (!isset($_SESSION[$this->seq]['steps'])) {
64            $_SESSION[$this->seq]['steps'] = array();
65        }
66        if (!isset($_SESSION[$this->seq]['data'])) {
67            $_SESSION[$this->seq]['data'] = array();
68        }
69        if (!isset($_SESSION[$this->seq]['defaults'])) {
70            $_SESSION[$this->seq]['defaults'] = array();
71        }
72
73        // Manage timeout.
74        $this->_auto_timeout();
75    }
76
77    /**
78     * Create a new step at the end (or specified position) of the $steps array.
79     *
80     * @param  string $step_id      Uniqie identifyer for this step.
81     * @param  array  $params       Values for the creation of the step.
82     *
83     * @return boolean    Success of the addition
84     * @access public
85     */
86    public function addStep($step_id, $params)
87    {
88        // Keys for the steps array cannot be numeric.
89        if (is_numeric($step_id)) {
90            trigger_error('Step ID for function addStep cannot be numeric.', E_USER_WARNING);
91        }
92        // This step ID already exists.
93        if (!is_null($this->getPosition($step_id))) {
94            return false;
95        }
96        $_SESSION[$this->seq]['steps'][] = array(
97            'id'        => $step_id,
98            'title'     => isset($params['title'])     ? $params['title']     : '',
99            'active'    => isset($params['active'])    ? $params['active']    : false,
100            'form_tpl'  => isset($params['form_tpl'])  ? $params['form_tpl']  : '',
101            'disp_tpl'  => isset($params['disp_tpl'])  ? $params['disp_tpl']  : '',
102            'required'  => isset($params['required'])  ? $params['required']  : false,
103            'completed' => isset($params['completed']) ? $params['completed'] : false,
104            'editable'  => isset($params['editable'])  ? $params['editable']  : true,
105        );
106    }
107
108    /**
109     * Set the features of a step. Current step if step_id not specified.
110     *
111     * @param  string $page_id    ID of page. Leave null if modifying current step features.
112     * @param  array  $feature    Array of feature keys and values to set.
113     *
114     * @return bool true on success, false on failure
115     */
116    public function setFeature($step_id=null, $features)
117    {
118        $pos = isset($step_id) ? $this->getPosition($step_id) : $this->getPosition();
119
120        if (isset($features) && is_array($features) && isset($_SESSION[$this->seq]['steps'][$pos])) {
121            $_SESSION[$this->seq]['steps'][$pos] = array_merge($_SESSION[$this->seq]['steps'][$pos], $features);
122        }
123    }
124
125    /**
126     * Returns a specified value from a registered step.
127     *
128     * @access public
129     *
130     * @param string $step_id  Id of step with feature to return.
131     * @param string $key      Which value to return.
132     * @param mixed  $default  Value to return if key not found in user_data.
133     *
134     * @return mixed          Value stored in session.
135     */
136    public function getFeature($step_id, $key, $default='')
137    {
138        $pos = isset($step_id) ? $this->getPosition($step_id) : $this->getPosition();
139        if (isset($_SESSION[$this->seq]['steps'][$pos][$key])) {
140            return $_SESSION[$this->seq]['steps'][$pos][$key];
141        } else {
142            return $default;
143        }
144    }
145
146    /**
147     * Set the current step id. Which step are we on?
148     *
149     * @param  string $step_id      ID or number of current step.
150     * @return string    Actual step ID
151     * @access public
152     */
153    public function setCurrent($step_id)
154    {
155        $app =& App::getInstance();
156
157        if (false !== ($pos = $this->getPosition($step_id))) {
158            // Specified step exists (even if numeric).
159            $this->current_step_id = $this->getID($pos);
160        } else {
161            // Step with specified key does not exist.
162            $app->logMsg(sprintf('Step %s not defined in sequence %s', $step_id, $this->sequence_title), LOG_INFO, __FILE__, __LINE__);
163            return false;
164        }
165    }
166
167    /**
168     * Get the current step id.
169     *
170     * @return int $pos    Actual step position
171     * @access public
172     */
173    public function getID($pos=null)
174    {
175        if (isset($pos)) {
176            return $_SESSION[$this->seq]['steps'][$pos]['id'];
177        } else {
178            return $this->current_step_id;
179        }
180    }
181
182    /**
183     * Get the current step number.
184     *
185     * @param  string $step_id      ID or number of step to convert to position.
186     *
187     * @return string               Actual step number
188     * @access public
189     */
190    public function getPosition($step_id=null)
191    {
192        // Get current step id if step not provided.
193        if (!isset($step_id)) {
194            $step_id = $this->current_step_id;
195        }
196        if (is_numeric($step_id) && isset($_SESSION[$this->seq]['steps'][$step_id])) {
197            // Step ID provided is a number...go directly to key.
198            return $step_id;
199        } else {
200            // Step ID is a string. Loop through searching for match.
201            foreach ($_SESSION[$this->seq]['steps'] as $pos=>$step) {
202                if ($step['id'] == $step_id) {
203                    return $pos;
204                }
205            }
206            // Step not found matching ID.
207            return null;
208        }
209    }
210
211    /**
212     * Returns the ID of the step with required=true and completed=false
213     * and active=true that falls before specified step_id.
214     *
215     * @param  string $curr_step_id ID or number of current step.
216     * @return string               Prerequisite step ID or false if none.
217     * @access public
218     */
219    public function getRequiredID($curr_step_id)
220    {
221        if ('' === $curr_step_id) {
222            return $this->current_step_id;
223        }
224        foreach ($_SESSION[$this->seq]['steps'] as $pos=>$step) {
225            if (is_numeric($curr_step_id) && $pos == $curr_step_id && $step['active']) {
226                return $curr_step_id;
227            } else if ($step['id'] == $curr_step_id && $step['active']) {
228                return $curr_step_id;
229            }
230            if ($step['active'] && $step['required'] && !$step['completed']) {
231                return $step['id'];
232            }
233        }
234        return $curr_step_id;
235    }
236
237    /**
238     * Returns the next step in the steps array or the first active required
239     * uncompleted step.
240     *
241     * @return string  Step identifier of the next step.
242     * @access public
243     */
244    public function getNextID()
245    {
246        // Loop through all steps.
247        foreach ($_SESSION[$this->seq]['steps'] as $pos=>$step) {
248            // If a step is found that is active, required, and not completed, we must do that one.
249            if ($step['active'] && $step['required'] && !$step['completed']) {
250                return $step['id'];
251            }
252            // Otherwise do the first step after the current one that is active.
253            if ($step['active'] && $pos > $this->getPosition()) {
254                return $step['id'];
255            }
256        }
257        return null;
258    }
259
260    /**
261     * To set a set as 'completed'.
262     * @return string  Step identifier of the next step.
263     * @access public
264     */
265    public function complete($step_id=null)
266    {
267        $pos = isset($step_id) ? $this->getPosition($step_id) : $this->getPosition();
268        $_SESSION[$this->seq]['steps'][$pos]['completed'] = true;
269    }
270
271    /**
272     * Prints the a link that returns to the form for a step.
273     *
274     * @param  string $form_type  'form' or 'disp'.
275     * @param  string $step_id    ID of step.
276     * @return string             Filename of template.
277     * @access public
278     */
279    public function printEditLink($step_id=null)
280    {
281        $app =& App::getInstance();
282
283        $pos = isset($step_id) ? $this->getPosition($step_id) : $this->getPosition();
284        if ($_SESSION[$this->seq]['steps'][$pos]['editable']) {
285            printf('[<a href="%s">%s</a>]', $app->oHREF($_SERVER['PHP_SELF'] . '?step=' . $pos . '&boomerang=confirmation'), _("edit"));
286        }
287    }
288
289    /**
290     * Saves given $step_data (usually coming from $_POST) into $_SESSION
291     * array with the $step_id as the key.
292     *
293     * @param  string $step_id   ID of current step.
294     * @param  mixed  $step_data Data to place into session storage.
295     * @return string  Step identifier of the next step.
296     * @access public
297     */
298    public function setDataDefault($data_key, $data_val)
299    {
300        if (!isset($_SESSION[$this->seq]['data'][$data_key])) {
301            $_SESSION[$this->seq]['data'][$data_key] = $data_val;
302            $_SESSION[$this->seq]['defaults'][$data_key] = $data_val;
303        }
304    }
305
306    /**
307     * Returns the value saved in $_SESSION for a specific data key.
308     *
309     * @param  mixed  $data_key  Key of data to return from session data.
310     * @access public
311     */
312    public function getData($data_key=null)
313    {
314        if (!isset($data_key)) {
315            return $_SESSION[$this->seq]['data'];
316        }
317        if (isset($_SESSION[$this->seq]['data'][$data_key])) {
318            return $_SESSION[$this->seq]['data'][$data_key];
319        } else {
320            return null;
321        }
322    }
323
324    /**
325     * Deletes all data saved in $_SESSION.
326     *
327     * @param  mixed  $data_key  Key of data to return from session data.
328     * @access public
329     */
330    public function clearData($data_key=null)
331    {
332        if (isset($data_key)) {
333            // Clear a specific key.
334            $_SESSION[$this->seq]['data'][$key] = array();
335        } else {
336            // Clear the whole thing.
337            $_SESSION[$this->seq]['data'] = array();
338        }
339    }
340
341    /**
342     * Deletes all data that are older than auto_timeout. Set current time if not not expired or not set.
343     */
344    private function _auto_timeout()
345    {
346        $app =& App::getInstance();
347
348        if (isset($_SESSION[$this->seq]['last_access_time'])
349        && $_SESSION[$this->seq]['last_access_time'] < time() - $this->idle_timeout) {
350            // Session has expired, flush all vars to start over.
351            $this->startOver();
352            $app->dieURL($this->start_url);
353        } else {
354            // Set timer.
355            $_SESSION[$this->seq]['last_access_time'] = time();
356        }
357    }
358
359    /**
360     * Saves given array (usually coming from $_POST) into $_SESSION
361     *
362     * @param  mixed  $step_data  Array of data to merge with session data.
363     * @access public
364     */
365    public function registerData($step_data)
366    {
367        $_SESSION[$this->seq]['data'] = array_merge($_SESSION[$this->seq]['data'], $step_data);
368    }
369
370    /**
371     * Reset all vars.
372     *
373     */
374    public function startOver()
375    {
376        $this->current_step_id = 0;
377        $_SESSION[$this->seq]['steps'] = array();
378        $_SESSION[$this->seq]['data'] = array();
379        $_SESSION[$this->seq]['defaults'] = array();
380        $_SESSION[$this->seq]['last_access_time'] = time();
381    }
382
383} // END CLASS
384
Note: See TracBrowser for help on using the repository browser.