Commit | Line | Data |
---|---|---|
2a54eb4d | 1 | <?php |
2 | /*************************************************************************** | |
179afa7f | 3 | * Copyright (C) 2003-2008 Polytechnique.org * |
2a54eb4d | 4 | * http://opensource.polytechnique.org/ * |
5 | * * | |
6 | * This program is free software; you can redistribute it and/or modify * | |
7 | * it under the terms of the GNU General Public License as published by * | |
8 | * the Free Software Foundation; either version 2 of the License, or * | |
9 | * (at your option) any later version. * | |
10 | * * | |
11 | * This program is distributed in the hope that it will be useful, * | |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * | |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * | |
14 | * GNU General Public License for more details. * | |
15 | * * | |
16 | * You should have received a copy of the GNU General Public License * | |
17 | * along with this program; if not, write to the Free Software * | |
18 | * Foundation, Inc., * | |
19 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * | |
20 | **************************************************************************/ | |
21 | ||
22 | /** A Wizard Page is a page of a wizard. It is a self-contained step which | |
23 | * handles both the creation and initialisation of the step (by using the | |
24 | * Wizard global state, if needed) and the processing of the action the | |
25 | * user made on it. | |
26 | */ | |
27 | interface PlWizardPage | |
28 | { | |
29 | /** Build a new instance of the class | |
30 | * associated with the given wizard master. | |
31 | */ | |
32 | public function __construct(PlWizard &$wiz); | |
33 | ||
34 | /** Return the name of the templace describing the page. | |
35 | */ | |
36 | public function template(); | |
37 | ||
38 | /** Prepare the page by assigning to it any useful value. | |
39 | */ | |
04334c61 | 40 | public function prepare(PlPage &$page, $id); |
2a54eb4d | 41 | |
42 | /** Process information resulting of the application of the page. | |
43 | * This function must return a clue indicating the next page to show. | |
44 | * This clue can be either a page id, a page number or a navigation | |
45 | * id (PlWizard::FIRST_PAGE, PlWizard::NEXT_PAGE, PlWizard::CURRENT_PAGE | |
46 | * PlWizard::PREVIOUS_PAGE, PlWizard::LAST_PAGE). | |
47 | */ | |
48 | public function process(); | |
49 | } | |
50 | ||
51 | /** A PlWizard is a set of pages through which the user can navigate, | |
52 | * his action on a page determining which the next one will be. | |
53 | * | |
54 | * A Wizard can either a stateless wizard (which is only a set of | |
55 | * independent pages through which the user can easily navigate) or | |
56 | * stateful (a suite of steps where each step gives clue for the next | |
57 | * one). | |
58 | */ | |
59 | class PlWizard | |
60 | { | |
8fc4efa3 | 61 | const FIRST_PAGE = 'bt_first'; |
62 | const NEXT_PAGE = 'bt_next'; | |
63 | const CURRENT_PAGE = 'bt_current'; | |
64 | const PREVIOUS_PAGE = 'bt_previous'; | |
65 | const LAST_PAGE = 'bt_last'; | |
2a54eb4d | 66 | |
1ec4547f FB |
67 | private $userdata = array(); |
68 | ||
2a54eb4d | 69 | protected $name; |
70 | protected $layout; | |
71 | protected $stateless; | |
ddb64990 | 72 | protected $ajax; |
2a54eb4d | 73 | |
74 | protected $pages; | |
e1635d16 | 75 | protected $titles; |
2a54eb4d | 76 | protected $lookup; |
fd38b30e | 77 | protected $inv_lookup; |
2a54eb4d | 78 | |
ddb64990 | 79 | public function __construct($name, $layout, $stateless = false, $ajax = true) |
2a54eb4d | 80 | { |
e1635d16 FB |
81 | $this->name = 'wiz_' . $name; |
82 | $this->layout = $layout; | |
2a54eb4d | 83 | $this->stateless = $stateless; |
84 | $this->pages = array(); | |
85 | $this->lookup = array(); | |
e1635d16 | 86 | $this->titles = array(); |
ddb64990 | 87 | $this->ajax = $ajax; |
2a54eb4d | 88 | if (!isset($_SESSION[$this->name])) { |
89 | $_SESSION[$this->name] = array(); | |
fd38b30e FB |
90 | $_SESSION[$this->name . '_page'] = null; |
91 | $_SESSION[$this->name . '_stack'] = array(); | |
2a54eb4d | 92 | } |
2a54eb4d | 93 | } |
94 | ||
fd38b30e | 95 | public function addPage($class, $title, $id = null) |
2a54eb4d | 96 | { |
fd38b30e FB |
97 | if ($id == null) { |
98 | $id = count($this->pages); | |
2a54eb4d | 99 | } |
fd38b30e FB |
100 | $this->lookup[$id] = count($this->pages); |
101 | $this->inv_lookup[] = $id; | |
102 | $this->pages[] = $class; | |
103 | $this->titles[] = $title; | |
2a54eb4d | 104 | } |
105 | ||
1ec4547f FB |
106 | public function addUserData($name, $value) |
107 | { | |
108 | $this->userdata[$name] = $value; | |
109 | } | |
110 | ||
111 | public function getUserData($name, $default = null) | |
112 | { | |
113 | return $this->userdata[$name]; | |
114 | } | |
115 | ||
2a54eb4d | 116 | public function set($varname, $value) |
117 | { | |
118 | $_SESSION[$this->name][$varname] = $value; | |
119 | } | |
120 | ||
121 | public function get($varname, $default = null) | |
122 | { | |
123 | return isset($_SESSION[$this->name][$varname]) ? | |
124 | $_SESSION[$this->name][$varname] : $default; | |
125 | } | |
126 | ||
127 | public function v($varname, $default = "") | |
128 | { | |
129 | return $this->get($varname, $default); | |
130 | } | |
131 | ||
132 | public function i($varname, $default = 0) | |
133 | { | |
134 | return (int)$this->get($varname, $default); | |
135 | } | |
136 | ||
137 | public function clear($varname = null) | |
138 | { | |
139 | if (is_null($varname)) { | |
140 | $_SESSION[$this->name] = array(); | |
141 | } else { | |
142 | unset($_SESSION[$this->name][$varname]); | |
143 | } | |
144 | $_SESSION[$this->name . '_page'] = null; | |
145 | } | |
146 | ||
e1635d16 | 147 | private function getPage($id) |
2a54eb4d | 148 | { |
149 | $page = $this->pages[$id]; | |
150 | return new $page($this); | |
151 | } | |
152 | ||
04334c61 | 153 | public function apply(PlPage &$smarty, $baseurl, $pgid = null, $mode = 'normal') |
2a54eb4d | 154 | { |
fd38b30e FB |
155 | if ($this->stateless && (isset($this->lookup[$pgid]) || isset($this->pages[$pgid]))) { |
156 | $curpage = is_numeric($pgid) ? $pgid : $this->lookup[$pgid]; | |
157 | } else if ($this->stateless && is_null($pgid)) { | |
158 | $curpage = 0; | |
159 | } else { | |
160 | $curpage = $_SESSION[$this->name . '_page']; | |
161 | } | |
162 | $oldpage = $curpage; | |
2a54eb4d | 163 | |
164 | // Process the previous page | |
93553cea | 165 | if (Post::has('valid_page')) { |
37c45da5 VZ |
166 | S::assert_xsrf_token(); |
167 | ||
93553cea FB |
168 | $page = $this->getPage(Post::i('valid_page')); |
169 | $curpage = Post::i('valid_page'); | |
2a54eb4d | 170 | $next = $page->process(); |
e1635d16 | 171 | $last = $curpage; |
2a54eb4d | 172 | switch ($next) { |
173 | case PlWizard::FIRST_PAGE: | |
174 | $curpage = 0; | |
175 | break; | |
176 | case PlWizard::PREVIOUS_PAGE: | |
e1635d16 FB |
177 | if (!$this->stateless && count($_SESSION[$this->name . '_stack'])) { |
178 | $curpage = array_pop($_SESSION[$this->name . '_stack']); | |
179 | } elseif ($curpage && $this->stateless) { | |
180 | $curpage--; | |
181 | } else { | |
182 | $curpage = 0; | |
183 | } | |
2a54eb4d | 184 | break; |
185 | case PlWizard::NEXT_PAGE: | |
e1635d16 FB |
186 | if ($curpage < count($this->pages) - 1) { |
187 | $curpage++; | |
188 | } | |
2a54eb4d | 189 | break; |
190 | case PlWizard::LAST_PAGE: | |
191 | $curpage = count($this->pages) - 1; | |
192 | break; | |
193 | case PlWizard::CURRENT_PAGE: break; // don't change the page | |
194 | default: | |
fd38b30e | 195 | $curpage = is_numeric($next) ? $next : $this->lookup[$next]; |
2a54eb4d | 196 | break; |
197 | } | |
e1635d16 FB |
198 | if (!$this->stateless) { |
199 | array_push($_SESSION[$this->name . '_stack'], $last); | |
200 | } | |
2a54eb4d | 201 | } |
e1635d16 FB |
202 | if (is_null($curpage)) { |
203 | $curpage = 0; | |
204 | } | |
2a54eb4d | 205 | |
206 | // Prepare the page | |
fd38b30e FB |
207 | $_SESSION[$this->name . '_page'] = $curpage; |
208 | if ($curpage != $oldpage) { | |
209 | pl_redirect($baseurl . '/' . $this->inv_lookup[$curpage]); | |
210 | } else if (!isset($page)) { | |
211 | $page = $this->getPage($curpage); | |
212 | } | |
ddb64990 FB |
213 | if ($mode == 'ajax') { |
214 | header('Content-Type: text/html; charset=utf-8'); | |
215 | $smarty->changeTpl($page->template(), NO_SKIN); | |
216 | } else { | |
217 | $smarty->changeTpl($this->layout); | |
218 | } | |
e1635d16 FB |
219 | $smarty->assign('pages', $this->titles); |
220 | $smarty->assign('current', $curpage); | |
fd38b30e | 221 | $smarty->assign('lookup', $this->inv_lookup); |
e1635d16 FB |
222 | $smarty->assign('stateless', $this->stateless); |
223 | $smarty->assign('wiz_baseurl', $baseurl); | |
ddb64990 | 224 | $smarty->assign('wiz_ajax', $this->ajax); |
e1635d16 | 225 | $smarty->assign('tab_width', (int)(99 / count($this->pages))); |
2a54eb4d | 226 | $smarty->assign('wiz_page', $page->template()); |
91ebb7ff | 227 | $smarty->assign('pl_no_errors', true); |
ddb64990 | 228 | $page->prepare($smarty, isset($this->inv_lookup[$curpage]) ? $this->inv_lookup[$curpage] : $curpage); |
2a54eb4d | 229 | } |
230 | } | |
231 | ||
232 | // vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8: | |
233 | ?> |