source: branches/1.1dev/lib/PageSequence.inc.php

Last change on this file was 708, checked in by anonymous, 4 years ago

Update class constructor method names to construct

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