| 1 | <?php |
| 2 | /* -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
| 3 | /* |
| 4 | # ***** BEGIN LICENSE BLOCK ***** |
| 5 | # This file is part of InDefero, an open source project management application. |
| 6 | # Copyright (C) 2008 Céondo Ltd and contributors. |
| 7 | # |
| 8 | # InDefero is free software; you can redistribute it and/or modify |
| 9 | # it under the terms of the GNU General Public License as published by |
| 10 | # the Free Software Foundation; either version 2 of the License, or |
| 11 | # (at your option) any later version. |
| 12 | # |
| 13 | # InDefero is distributed in the hope that it will be useful, |
| 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 16 | # GNU General Public License for more details. |
| 17 | # |
| 18 | # You should have received a copy of the GNU General Public License |
| 19 | # along with this program; if not, write to the Free Software |
| 20 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
| 21 | # |
| 22 | # ***** END LICENSE BLOCK ***** */ |
| 23 | |
| 24 | Pluf::loadFunction('Pluf_HTTP_URL_urlForView'); |
| 25 | Pluf::loadFunction('Pluf_Shortcuts_RenderToResponse'); |
| 26 | Pluf::loadFunction('Pluf_Shortcuts_GetObjectOr404'); |
| 27 | Pluf::loadFunction('Pluf_Shortcuts_GetFormForModel'); |
| 28 | |
| 29 | /** |
| 30 | * Base views of InDefero. |
| 31 | */ |
| 32 | class IDF_Views |
| 33 | { |
| 34 | /** |
| 35 | * List all the projects managed by InDefero. |
| 36 | * |
| 37 | * Only the public projects are listed or the private with correct |
| 38 | * rights. |
| 39 | */ |
| 40 | public function index($request, $match) |
| 41 | { |
| 42 | $projects = self::getProjects($request->user); |
| 43 | return Pluf_Shortcuts_RenderToResponse('idf/index.html', |
| 44 | array('page_title' => __('Projects'), |
| 45 | 'projects' => $projects), |
| 46 | $request); |
| 47 | } |
| 48 | |
| 49 | /** |
| 50 | * Login view. |
| 51 | */ |
| 52 | public function login($request, $match) |
| 53 | { |
| 54 | if (isset($request->POST['action']) |
| 55 | and $request->POST['action'] == 'new-user') { |
| 56 | $login = (isset($request->POST['login'])) ? $request->POST['login'] : ''; |
| 57 | $url = Pluf_HTTP_URL_urlForView('IDF_Views::register', array(), |
| 58 | array('login' => $login)); |
| 59 | return new Pluf_HTTP_Response_Redirect($url); |
| 60 | } |
| 61 | $v = new Pluf_Views(); |
| 62 | $request->POST['login'] = (isset($request->POST['login'])) ? mb_strtolower($request->POST['login']) : ''; |
| 63 | return $v->login($request, $match, Pluf::f('login_success_url'), |
| 64 | array(), 'idf/login_form.html'); |
| 65 | } |
| 66 | |
| 67 | /** |
| 68 | * Logout view. |
| 69 | */ |
| 70 | function logout($request, $match) |
| 71 | { |
| 72 | $views = new Pluf_Views(); |
| 73 | return $views->logout($request, $match, Pluf::f('after_logout_page')); |
| 74 | } |
| 75 | |
| 76 | /** |
| 77 | * Registration. |
| 78 | * |
| 79 | * We just ask for login, email and to agree with the terms. Then, |
| 80 | * we go ahead and send a confirmation email. The confirmation |
| 81 | * email will allow to set the password, first name and last name |
| 82 | * of the user. |
| 83 | */ |
| 84 | function register($request, $match) |
| 85 | { |
| 86 | $title = __('Create Your Account'); |
| 87 | $params = array('request'=>$request); |
| 88 | if ($request->method == 'POST') { |
| 89 | $form = new IDF_Form_Register($request->POST, $params); |
| 90 | if ($form->isValid()) { |
| 91 | $user = $form->save(); // It is sending the confirmation email |
| 92 | $url = Pluf_HTTP_URL_urlForView('IDF_Views::registerInputKey'); |
| 93 | return new Pluf_HTTP_Response_Redirect($url); |
| 94 | } |
| 95 | } else { |
| 96 | if (isset($request->GET['login'])) { |
| 97 | $params['initial'] = array('login' => $request->GET['login']); |
| 98 | } |
| 99 | $form = new IDF_Form_Register(null, $params); |
| 100 | } |
| 101 | $context = new Pluf_Template_Context(array()); |
| 102 | $tmpl = new Pluf_Template('idf/terms.html'); |
| 103 | $terms = Pluf_Template::markSafe($tmpl->render($context)); |
| 104 | return Pluf_Shortcuts_RenderToResponse('idf/register/index.html', |
| 105 | array('page_title' => $title, |
| 106 | 'form' => $form, |
| 107 | 'terms' => $terms), |
| 108 | $request); |
| 109 | } |
| 110 | |
| 111 | /** |
| 112 | * Input the registration confirmation key. |
| 113 | * |
| 114 | * Very simple view just to redirect to the register confirmation |
| 115 | * views to input the password. |
| 116 | */ |
| 117 | function registerInputKey($request, $match) |
| 118 | { |
| 119 | $title = __('Confirm Your Account Creation'); |
| 120 | if ($request->method == 'POST') { |
| 121 | $form = new IDF_Form_RegisterInputKey($request->POST); |
| 122 | if ($form->isValid()) { |
| 123 | $url = $form->save(); |
| 124 | return new Pluf_HTTP_Response_Redirect($url); |
| 125 | } |
| 126 | } else { |
| 127 | $form = new IDF_Form_RegisterInputKey(); |
| 128 | } |
| 129 | return Pluf_Shortcuts_RenderToResponse('idf/register/inputkey.html', |
| 130 | array('page_title' => $title, |
| 131 | 'form' => $form), |
| 132 | $request); |
| 133 | } |
| 134 | |
| 135 | /** |
| 136 | * Registration confirmation. |
| 137 | * |
| 138 | * Input first/last name, password and sign in the user. |
| 139 | * |
| 140 | * Maybe in the future send the user to its personal page for |
| 141 | * customization. |
| 142 | */ |
| 143 | function registerConfirmation($request, $match) |
| 144 | { |
| 145 | $title = __('Confirm Your Account Creation'); |
| 146 | $key = $match[1]; |
| 147 | // first "check", full check is done in the form. |
| 148 | $email_id = IDF_Form_RegisterInputKey::checkKeyHash($key); |
| 149 | if (false == $email_id) { |
| 150 | $url = Pluf_HTTP_URL_urlForView('IDF_Views::registerInputKey'); |
| 151 | return new Pluf_HTTP_Response_Redirect($url); |
| 152 | } |
| 153 | $user = new Pluf_User($email_id[1]); |
| 154 | $extra = array('key' => $key, |
| 155 | 'user' => $user); |
| 156 | if ($request->method == 'POST') { |
| 157 | $form = new IDF_Form_RegisterConfirmation($request->POST, $extra); |
| 158 | if ($form->isValid()) { |
| 159 | $user = $form->save(); |
| 160 | $request->user = $user; |
| 161 | $request->session->clear(); |
| 162 | $request->session->setData('login_time', gmdate('Y-m-d H:i:s')); |
| 163 | $user->last_login = gmdate('Y-m-d H:i:s'); |
| 164 | $user->update(); |
| 165 | $request->user->setMessage(__('Welcome! You can now participate in the life of your project of choice.')); |
| 166 | $url = Pluf_HTTP_URL_urlForView('IDF_Views::index'); |
| 167 | return new Pluf_HTTP_Response_Redirect($url); |
| 168 | } |
| 169 | } else { |
| 170 | $form = new IDF_Form_RegisterConfirmation(null, $extra); |
| 171 | } |
| 172 | return Pluf_Shortcuts_RenderToResponse('idf/register/confirmation.html', |
| 173 | array('page_title' => $title, |
| 174 | 'new_user' => $user, |
| 175 | 'form' => $form), |
| 176 | $request); |
| 177 | } |
| 178 | |
| 179 | /** |
| 180 | * Password recovery. |
| 181 | * |
| 182 | * Request the login or the email of the user and if the login or |
| 183 | * email is available in the database, send an email with a key to |
| 184 | * reset the password. |
| 185 | * |
| 186 | * If the user is not yet confirmed, send the confirmation key one |
| 187 | * more time. |
| 188 | */ |
| 189 | function passwordRecoveryAsk($request, $match) |
| 190 | { |
| 191 | $title = __('Password Recovery'); |
| 192 | if ($request->method == 'POST') { |
| 193 | $form = new IDF_Form_Password($request->POST); |
| 194 | if ($form->isValid()) { |
| 195 | $url = $form->save(); |
| 196 | return new Pluf_HTTP_Response_Redirect($url); |
| 197 | } |
| 198 | } else { |
| 199 | $form = new IDF_Form_Password(); |
| 200 | } |
| 201 | return Pluf_Shortcuts_RenderToResponse('idf/user/passrecovery-ask.html', |
| 202 | array('page_title' => $title, |
| 203 | 'form' => $form), |
| 204 | $request); |
| 205 | } |
| 206 | |
| 207 | /** |
| 208 | * If the key is valid, provide a nice form to reset the password |
| 209 | * and automatically login the user. |
| 210 | * |
| 211 | * This is also firing the password change event for the plugins. |
| 212 | */ |
| 213 | public function passwordRecovery($request, $match) |
| 214 | { |
| 215 | $title = __('Password Recovery'); |
| 216 | $key = $match[1]; |
| 217 | // first "check", full check is done in the form. |
| 218 | $email_id = IDF_Form_PasswordInputKey::checkKeyHash($key); |
| 219 | if (false == $email_id) { |
| 220 | $url = Pluf_HTTP_URL_urlForView('IDF_Views::passwordRecoveryInputKey'); |
| 221 | return new Pluf_HTTP_Response_Redirect($url); |
| 222 | } |
| 223 | $user = new Pluf_User($email_id[1]); |
| 224 | $extra = array('key' => $key, |
| 225 | 'user' => $user); |
| 226 | if ($request->method == 'POST') { |
| 227 | $form = new IDF_Form_PasswordReset($request->POST, $extra); |
| 228 | if ($form->isValid()) { |
| 229 | $user = $form->save(); |
| 230 | $request->user = $user; |
| 231 | $request->session->clear(); |
| 232 | $request->session->setData('login_time', gmdate('Y-m-d H:i:s')); |
| 233 | $user->last_login = gmdate('Y-m-d H:i:s'); |
| 234 | $user->update(); |
| 235 | $request->user->setMessage(__('Welcome back! Next time, you can use your broswer options to remember the password.')); |
| 236 | $url = Pluf_HTTP_URL_urlForView('IDF_Views::index'); |
| 237 | return new Pluf_HTTP_Response_Redirect($url); |
| 238 | } |
| 239 | } else { |
| 240 | $form = new IDF_Form_PasswordReset(null, $extra); |
| 241 | } |
| 242 | return Pluf_Shortcuts_RenderToResponse('idf/user/passrecovery.html', |
| 243 | array('page_title' => $title, |
| 244 | 'new_user' => $user, |
| 245 | 'form' => $form), |
| 246 | $request); |
| 247 | |
| 248 | } |
| 249 | |
| 250 | /** |
| 251 | * Just a simple input box to provide the code and redirect to |
| 252 | * passwordRecovery |
| 253 | */ |
| 254 | public function passwordRecoveryInputCode($request, $match) |
| 255 | { |
| 256 | $title = __('Password Recovery'); |
| 257 | if ($request->method == 'POST') { |
| 258 | $form = new IDF_Form_PasswordInputKey($request->POST); |
| 259 | if ($form->isValid()) { |
| 260 | $url = $form->save(); |
| 261 | return new Pluf_HTTP_Response_Redirect($url); |
| 262 | } |
| 263 | } else { |
| 264 | $form = new IDF_Form_PasswordInputKey(); |
| 265 | } |
| 266 | return Pluf_Shortcuts_RenderToResponse('idf/user/passrecovery-inputkey.html', |
| 267 | array('page_title' => $title, |
| 268 | 'form' => $form), |
| 269 | $request); |
| 270 | } |
| 271 | |
| 272 | /** |
| 273 | * FAQ. |
| 274 | */ |
| 275 | public function faq($request, $match) |
| 276 | { |
| 277 | $title = __('Here to Help You!'); |
| 278 | $projects = self::getProjects($request->user); |
| 279 | return Pluf_Shortcuts_RenderToResponse('idf/faq.html', |
| 280 | array( |
| 281 | 'page_title' => $title, |
| 282 | 'projects' => $projects, |
| 283 | ), |
| 284 | $request); |
| 285 | |
| 286 | } |
| 287 | |
| 288 | /** |
| 289 | * API FAQ. |
| 290 | */ |
| 291 | public function faqApi($request, $match) |
| 292 | { |
| 293 | $title = __('InDefero API (Application Programming Interface)'); |
| 294 | $projects = self::getProjects($request->user); |
| 295 | return Pluf_Shortcuts_RenderToResponse('idf/faq-api.html', |
| 296 | array( |
| 297 | 'page_title' => $title, |
| 298 | 'projects' => $projects, |
| 299 | ), |
| 300 | $request); |
| 301 | |
| 302 | } |
| 303 | |
| 304 | /** |
| 305 | * Returns a list of projects accessible for the user. |
| 306 | * |
| 307 | * @param Pluf_User |
| 308 | * @return ArrayObject IDF_Project |
| 309 | */ |
| 310 | public static function getProjects($user) |
| 311 | { |
| 312 | $db =& Pluf::db(); |
| 313 | $false = Pluf_DB_BooleanToDb(false, $db); |
| 314 | if ($user->isAnonymous()) { |
| 315 | $sql = sprintf('%s=%s', $db->qn('private'), $false); |
| 316 | return Pluf::factory('IDF_Project')->getList(array('filter'=> $sql, |
| 317 | 'order' => 'shortname ASC')); |
| 318 | } |
| 319 | if ($user->administrator) { |
| 320 | return Pluf::factory('IDF_Project')->getList(array('order' => 'shortname ASC')); |
| 321 | } |
| 322 | // grab the list of projects where the user is admin, member |
| 323 | // or authorized |
| 324 | $perms = array( |
| 325 | Pluf_Permission::getFromString('IDF.project-member'), |
| 326 | Pluf_Permission::getFromString('IDF.project-owner'), |
| 327 | Pluf_Permission::getFromString('IDF.project-authorized-user') |
| 328 | ); |
| 329 | $sql = new Pluf_SQL("model_class='IDF_Project' AND owner_class='Pluf_User' AND owner_id=%s AND negative=".$false, $user->id); |
| 330 | $rows = Pluf::factory('Pluf_RowPermission')->getList(array('filter' => $sql->gen())); |
| 331 | |
| 332 | $sql = sprintf('%s=%s', $db->qn('private'), $false); |
| 333 | if ($rows->count() > 0) { |
| 334 | $ids = array(); |
| 335 | foreach ($rows as $row) { |
| 336 | $ids[] = $row->model_id; |
| 337 | } |
| 338 | $sql .= sprintf(' OR id IN (%s)', implode(', ', $ids)); |
| 339 | } |
| 340 | return Pluf::factory('IDF_Project')->getList(array('filter' => $sql, |
| 341 | 'order' => 'shortname ASC')); |
| 342 | } |
| 343 | } |