still working at OpenID
[living-lab-site.git] / application / controllers / user.php
1 <?php
2
3 /**
4  * Class User controls video hierarchy and searching
5  *
6  * @category    Controller
7  * @author              Călin-Andrei Burloiu
8  */
9 class User extends CI_Controller {
10
11         private $import = FALSE;
12         private $activated_account = TRUE;
13         private $user_id = NULL;
14
15         public function __construct()
16         {
17                 parent::__construct();
18
19                 $this->lang->load('user');
20                 $this->load->model('users_model');
21         }
22
23         public function index()
24         {
25         }
26         
27         public function test($user_id = 1)
28         {
29
30         }
31
32         /**
33         * Login a user and then redirect it to the last page which must be encoded
34         * in $redirect.
35         *
36         * @param string $redirect       contains the last page URI segments encoded
37         * with helper url_encode_segments.
38         */
39         public function login($redirect = '')
40         {
41                 $this->load->library('form_validation');
42                 $this->form_validation->set_error_delimiters('<span class="error">',
43                         '</span>');
44                 
45                 // Normal or OpenID login?
46                 if ($this->input->post('openid') !== FALSE)
47                         $b_openid = TRUE;
48                 else
49                         $b_openid = FALSE;
50                 // Validate the correct form.
51                 $res_form_validation = FALSE;
52                 if (!$b_openid)
53                         $res_form_validation = $this->form_validation->run('login');
54                 else
55                         $res_form_validation = $this->form_validation->run('login_openid');
56
57                 if ($res_form_validation === FALSE)
58                 {
59                         $params = array(        'title' =>
60                                                                         $this->lang->line('ui_nav_menu_login')
61                                                                                 .' &ndash; '
62                                                                                 . $this->config->item('site_name'),
63                                                                 //'metas' => array('description'=>'')
64                         );
65                         $this->load->library('html_head_params', $params);
66                                 
67                         // **
68                         // ** LOADING VIEWS
69                         // **
70                         $this->load->view('html_begin', $this->html_head_params);
71                         $this->load->view('header', array('selected_menu' => 'login'));
72
73                         $main_params['content'] = $this->load->view('user/login_view',
74                                 array('redirect'=> $redirect), TRUE);
75                         $main_params['side'] = $this->load->view('side_default', NULL, TRUE);
76                         $this->load->view('main', $main_params);
77                                 
78                         $this->load->view('footer');
79                         $this->load->view('html_end');
80                 }
81                 else
82                 {
83                         if ($b_openid)
84                         {
85                                 $this->lang->load('openid');
86                                 $this->load->library('openid');
87                                 $this->config->load('openid');
88                                 $request_to = site_url('user/check_openid_login');
89                                 $req = $this->config->item('openid_required');
90                                 $opt = $this->config->item('openid_optional');
91                                 $policy = site_url('user/openid_policy');
92                                 $pape_policy_uris = $this->config->item('openid_papa_policies');
93                                 
94                                 $this->openid->set_request_to($request_to);
95                                 $this->openid->set_trust_root(base_url());
96                                 $this->openid->set_args(null);
97                                 $this->openid->set_sreg(true, $req, $opt, $policy);
98                                 if (!empty($pape_policy_uris))
99                                         $this->openid->set_pape(true, $pape_policy_uris);
100                                 
101                                 // Redirection to OP site will follow.
102                                 $this->openid->authenticate($this->input->post('openid'));
103                                 return;
104                         }
105                         
106                         // Without OpenID
107                         if (! $this->activated_account)
108                                 header('Location: '
109                                         . site_url("user/activate/{$this->user_id}"));
110                         else if (! $this->import)
111                         {
112                                 // Redirect to last page before login. 
113                                 header('Location: '. site_url(urldecode_segments($redirect)));
114                         }
115                         else
116                         {
117                                 // Redirect to account page because an user authenticates here
118                                 // for the first time with external authentication. The page
119                                 // will display imported data.
120                                 header('Location: '. site_url('user/account'));
121                         }
122                 }
123         }
124         
125         public function check_openid_login()
126         {
127                 $this->lang->load('openid');
128                 $this->load->library('openid');
129                 $this->config->load('openid');
130                 $request_to = site_url('user/check_openid_login');
131
132                 $this->openid->set_request_to($request_to);
133                 $response = $this->openid->get_response();
134
135                 switch ($response->status)
136                 {
137                 case Auth_OpenID_CANCEL:
138                         $this->load->helper('message');
139                         show_info_msg_page($this, $this->lang->line('openid_cancel'));
140                         break;
141                 case Auth_OpenID_FAILURE:
142                         $this->load->helper('message');
143                         show_error_msg_page($this,
144                                         $this->_format_message('openid_failure',
145                                                         $response->message));
146                         break;
147                 case Auth_OpenID_SUCCESS:
148                         $openid = $response->getDisplayIdentifier();
149                         $esc_identity = htmlspecialchars($openid, ENT_QUOTES);
150
151                         $sreg_resp = Auth_OpenID_SRegResponse::fromSuccessResponse($response);
152                         $sreg = $sreg_resp->contents();
153                         
154                         // Get registration informations
155                     $ax = new Auth_OpenID_AX_FetchResponse();
156                         $obj = $ax->fromSuccessResponse($response);
157
158                         //echo 'nickname('. $sreg_resp->get('nickname'). ')';
159                         echo var_dump($obj->data);
160                         echo '<br />';
161                         echo var_dump($sreg);
162 //                      foreach ($sreg as $key => $value)
163 //                      {
164 //                              $data['success'] .= $this->_set_message('openid_content', array($key, $value), array('%s', '%t'));
165 //                      }
166
167                         break;
168                 }
169         }
170         
171         public function openid_policy()
172         {
173                 $this->load->view('openid_policy_view');
174         }
175         
176         /**
177          * Logout user and then redirect it to the last page which must be encoded
178          * in $redirect.
179          * 
180          * @param string $redirect      contains the last page URI segments encoded
181          * with helper url_encode_segments.
182          */
183         public function logout($redirect = '')
184         {
185                 $this->session->unset_userdata('user_id');
186                 $this->session->unset_userdata('username');
187                 $this->session->unset_userdata('auth_src');
188                 $this->session->unset_userdata('time_zone');
189                 
190                 header('Location: '. site_url(urldecode_segments($redirect)));
191         }
192         
193         public function register($redirect = '')
194         {
195                 $this->load->library('form_validation');
196                 $this->load->helper('localization');
197                 $this->load->helper('date');
198                         
199                 $this->form_validation->set_error_delimiters('<span class="error">',
200                                         '</span>');
201                 $error_upload = '';
202
203                 if ($this->form_validation->run('register'))
204                 {
205                         $b_validation = TRUE;
206                         
207                         if ($_FILES['picture']['tmp_name'])
208                         {
209                                 // Upload library
210                                 $config_upload['upload_path'] = './data/user_pictures';
211                                 $config_upload['file_name'] = 
212                                         str_replace('.', '-', $this->input->post('username')) .'-';
213                                 $config_upload['allowed_types'] = 'gif|jpg|png';
214                                 $config_upload['max_size'] = '10240';
215                                 $this->load->library('upload', $config_upload);
216                                 
217                                 $b_validation = $this->upload->do_upload('picture');
218                                 $error_upload = 
219                                         $this->upload->display_errors('<span class="error">',
220                                                         '</span>');
221                         }
222                 }
223                 else
224                         $b_validation = FALSE;
225                 
226                 if (! $b_validation)
227                 {
228                         // Edit account data if logged in, otherwise register.
229                         if ($user_id = $this->session->userdata('user_id'))
230                         {
231                                 $userdata = $this->users_model->get_userdata(intval($user_id));
232                                 $selected_menu = 'account';
233                         }
234                         else
235                         {
236                                 $userdata = FALSE;
237                                 $selected_menu = 'register';
238                         }
239                         
240                         $params = array('title' =>
241                                                                 $this->lang->line('ui_nav_menu_register')
242                                                                         .' &ndash; '
243                                                                         . $this->config->item('site_name'),
244                                                         //'metas' => array('description'=>'')
245                         );
246                         $this->load->library('html_head_params', $params);
247                 
248                         // **
249                         // ** LOADING VIEWS
250                         // **
251                         $this->load->view('html_begin', $this->html_head_params);
252                         $this->load->view('header', 
253                                 array('selected_menu' => $selected_menu));
254                         
255                         $main_params['content'] = $this->load->view('user/register_view', 
256                                 array('userdata'=> $userdata, 'redirect'=> $redirect,
257                                         'error_upload'=> $error_upload),
258                                 TRUE);
259                         $main_params['side'] = $this->load->view('side_default', NULL, TRUE);
260                         $this->load->view('main', $main_params);
261                 
262                         $this->load->view('footer');
263                         $this->load->view('html_end');
264                 }
265                 else
266                 {
267                         $user_id = $this->input->post('user-id');
268                         $data['email'] = $this->input->post('email');
269                         $data['first_name'] = $this->input->post('first-name');
270                         $data['last_name'] = $this->input->post('last-name');
271                         $data['birth_date'] = $this->input->post('birth-date');
272                         $data['country'] = $this->input->post('country');
273                         $data['locality'] = $this->input->post('locality');
274                         $data['ui_lang'] = $this->input->post('ui-lang');
275                         $data['time_zone'] = $this->input->post('time-zone');
276                         
277                         // Handle picture if one was uploaded.
278                         if ($_FILES['picture']['tmp_name'])
279                         {
280                                 $upload_data = $this->upload->data();
281                                 $this->load->library('image');
282                                 $this->image->load($upload_data['full_path']);
283                                 // Resize original to a maximum size.
284                                 if ($this->image->get_width() * $this->image->get_height()
285                                                 > 640*480)
286                                 {
287                                         $this->image->save_thumbnail(
288                                                 $upload_data['full_path'],
289                                                 640, 480, IMAGETYPE_AUTO);
290                                 }
291                                 // Create thumbnail.
292                                 $data['picture'] = $upload_data['file_name'];
293                                 $this->image->save_thumbnail($upload_data['file_path']
294                                                 . $upload_data['file_name']. '-thumb.jpg', 120, 90);
295                         }
296                         
297                         // Update session user data.
298                         $this->_update_session_userdata($data);
299                         
300                         // Edit account data
301                         if ($user_id)
302                         {
303                                 $password = $this->input->post('new-password');
304                                 if ($password)
305                                         $data['password'] = $this->input->post('new-password');
306                                 
307                                 $this->users_model->set_userdata($user_id, $data);
308                                 
309                                 // Redirect to last page before login.
310                                 header('Location: '. site_url(urldecode_segments($redirect)));
311                         }
312                         // Registration
313                         else
314                         {
315                                 $data['username'] = $this->input->post('username');
316                                 $data['password'] = $this->input->post('password');
317                                 
318                                 $this->users_model->register($data);
319                                 $user_id = $this->users_model->get_userdata($data['username'],
320                                                 "id");
321                                 $user_id = $user_id['id'];
322                                 
323                                 // Redirect account activation page.
324                                 header('Location: '. site_url("user/activate/$user_id"));
325                         }
326                 }
327         }
328         
329         public function account($redirect = '')
330         {
331                 $this->register($redirect);
332         }
333         
334         public function profile($username, $videos_offset = 0)
335         {
336                 // TODO handle user not found
337                 
338                 $this->load->config('localization');
339                 $this->load->helper('date');
340                 $this->lang->load('date');
341                 
342                 // **
343                 // ** LOADING MODEL
344                 // **
345                 // Logged in user time zone
346                 $time_zone = $this->session->userdata('time_zone');
347                 
348                 // User data
349                 $userdata = $this->users_model->get_userdata($username);
350                 $userdata['roles'] = Users_model::roles_to_string($userdata['roles']);
351                 $country_list = $this->config->item('country_list');
352                 $userdata['country_name'] = $country_list[ $userdata['country'] ];
353                 $userdata['last_login'] = human_gmt_to_human_local(
354                         $userdata['last_login'], $time_zone); 
355                 $userdata['time_zone'] = $this->lang->line($userdata['time_zone']);
356                 
357                 // User's videos
358                 $this->load->model('videos_model');
359                 $vs_data['videos'] = $this->videos_model->get_videos_summary(
360                         NULL, $username, intval($videos_offset),
361                         $this->config->item('videos_per_page'));
362                 
363                 // Pagination
364                 $this->load->library('pagination');
365                 $pg_config['base_url'] = site_url("user/profile/$username/");
366                 $pg_config['uri_segment'] = 4;
367                 $pg_config['total_rows'] = $this->videos_model->get_videos_count(
368                         NULL, $username);
369                 $pg_config['per_page'] = $this->config->item('videos_per_page');
370                 $this->pagination->initialize($pg_config);
371                 $vs_data['pagination'] = $this->pagination->create_links();
372                 $vs_data['title'] = NULL;
373                 $vs_data['category_name'] = ''; // TODO videos_summary with AJAX
374                 
375                 $params = array(
376                         'title'=> $this->lang->line('user_appelation').' '.$username
377                                 .' &ndash; '
378                                 . $this->config->item('site_name'),
379                         'css'=> array('catalog.css')
380                         //'metas' => array('description'=>'')
381                 );
382                 $this->load->library('html_head_params', $params);
383                 
384                 // Current user profile tab
385                 $tab = (! $videos_offset ? 0 : 1);
386                 
387                 // **
388                 // ** LOADING VIEWS
389                 // **
390                 $this->load->view('html_begin', $this->html_head_params);
391                 $this->load->view('header', array());
392                 
393                 $vs = $this->load->view('catalog/videos_summary_view', $vs_data, TRUE);
394                 
395                 $main_params['content'] = $this->load->view('user/profile_view',
396                         array('userdata'=> $userdata, 'videos_summary'=> $vs, 'tab'=>$tab),
397                         TRUE);
398                 $main_params['side'] = $this->load->view('side_default', NULL, TRUE);
399                 $this->load->view('main', $main_params);
400                 
401                 $this->load->view('footer');
402                 $this->load->view('html_end');
403         }
404         
405         public function activate($user_id, $method='', $activation_code='')
406         {
407                 $user_id = intval($user_id);            
408                 $res_form_validation = FALSE;
409                 
410                 if ($method == 'code')
411                 {
412                         if (! $activation_code)
413                                 $res_form_validation = $this->form_validation->run('activate');
414                         // Activation code is provided in URL.
415                         else
416                         {
417                                 if ($this->_valid_activation_code($activation_code)
418                                                 && $this->users_model->activate_account($user_id,
419                                                         $activation_code))
420                                 {
421                                         $this->load->helper('message');
422                                         show_info_msg_page($this, sprintf(
423                                                 $this->lang->line('user_msg_activated_account'), 
424                                                 site_url('user/login')));
425                                         return;
426                                 }
427                                 else
428                                 {
429                                         $this->load->helper('message');
430                                         show_error_msg_page($this, 
431                                                         $this->lang->line(
432                                                                         'user_msg_wrong_activation_code'));
433                                         return;
434                                 }
435                         }
436                 }
437                 else if ($method == 'resend')
438                 {
439                         $res_form_validation =
440                                 $this->form_validation->run('resend_activation');
441                 }
442                 
443                 $userdata = $this->users_model->get_userdata($user_id,
444                                 'email, a.activation_code');
445                 $email = $userdata['email'];
446                 $activated_account = ($userdata['activation_code'] == NULL);
447                 
448                 if ($activated_account)
449                 {
450                         $this->load->helper('message');
451                         show_info_msg_page($this, sprintf(
452                                 $this->lang->line('user_msg_activated_account'), 
453                                 site_url('user/login')));
454                         return;
455                 }
456                 
457                 $this->load->library('form_validation');
458                         
459                 $this->form_validation->set_error_delimiters('<span class="error">',
460                                         '</span>');
461                 
462                 if ($res_form_validation === FALSE)
463                 {
464                         $params = array(
465                                 'title'=> $this->lang->line('user_title_activation')
466                                         .' &ndash; '
467                                         . $this->config->item('site_name'),
468                                 //'metas' => array('description'=>'')
469                         );
470                         $this->load->library('html_head_params', $params);
471                 
472                         // **
473                         // ** LOADING VIEWS
474                         // **
475                         $this->load->view('html_begin', $this->html_head_params);
476                         $this->load->view('header', array());
477
478                         // Show form
479                         $main_params['content'] = 
480                                 $this->load->view('user/activate_view',
481                                 array(  'user_id'=> $user_id,
482                                                 'email'=> $userdata['email']),
483                                 TRUE);
484                         
485                         $main_params['side'] = $this->load->view('side_default', NULL, TRUE);
486                         $this->load->view('main', $main_params);
487                 
488                         $this->load->view('footer');
489                         $this->load->view('html_end');
490                 }
491                 else
492                 {
493                         if ($method == 'code')
494                         {
495                                 // A message which tells the user that the
496                                 // activation was successful.
497                                 $this->load->helper('message');
498                                 show_info_msg_page($this, sprintf(
499                                         $this->lang->line('user_msg_activated_account'), 
500                                         site_url('user/login')));
501                                 return;
502                         }
503                         else if ($method == 'resend')
504                         {
505                                 // Redirect to resent message
506                                 $this->load->helper('message');
507                                 show_info_msg_page($this, sprintf(
508                                                 $this->lang->line('user_msg_activation_resent'),
509                                                 $this->input->post('email')));
510                                 return;
511                         }
512                 }
513         }
514         
515         public function recover_password()
516         {
517                 $this->load->library('form_validation');
518                         
519                 $this->form_validation->set_error_delimiters('<span class="error">',
520                         '</span>');
521
522                 if ($this->form_validation->run('recover_password') === FALSE)
523                 {
524                         $params = array(        'title' =>
525                                                                         $this->lang->line(
526                                                                                 'user_title_password_recovery')
527                                                                                 .' &ndash; '
528                                                                                 . $this->config->item('site_name'),
529                                                                 //'metas' => array('description'=>'')
530                         );
531                         $this->load->library('html_head_params', $params);
532                                 
533                         // **
534                         // ** LOADING VIEWS
535                         // **
536                         $this->load->view('html_begin', $this->html_head_params);
537                         $this->load->view('header', array('selected_menu' => 
538                                         'recover_password'));
539
540                         $main_params['content'] = $this->load->view(
541                                 'user/recover_password_view', array(),
542                                 TRUE);
543                         
544                         $main_params['side'] = $this->load->view('side_default', NULL, TRUE);
545                         $this->load->view('main', $main_params);
546                                 
547                         $this->load->view('footer');
548                         $this->load->view('html_end');
549                 }
550                 else
551                 {
552                         // Resent message
553                         $this->load->helper('message');
554                         show_info_msg_page($this, sprintf(
555                                         $this->lang->line('user_msg_password_recovery_email_sent'),
556                                         $this->input->post('username'),
557                                         $this->input->post('email')));
558                         return;
559                 }
560         }
561         
562         public function _format_message($msg, $val = '', $sub = '%s')
563         {
564                 return str_replace($sub, $val, $this->lang->line($msg));
565         }
566         
567         public function _update_session_userdata($data)
568         {
569                 foreach ($data as $key=> $val)
570                         $this->session->set_userdata($key, $val);
571         }
572         
573         public function _valid_username($username)
574         {
575                 return (preg_match('/^[a-z0-9\._]+$/', $username) === 1);
576         }
577
578         public function _valid_username_or_email($username)
579         {
580                 $this->load->helper('email');
581
582                 if (valid_email($username))
583                         return TRUE;
584                 else
585                         return $this->_valid_username($username);
586         }
587         
588         public function _valid_date($date)
589         {
590                 if (! $date)
591                         return TRUE;
592                 
593                 return (preg_match('/[\d]{4}-[\d]{2}-[\d]{2}/', $date) === 1);
594         }
595         
596         public function _postprocess_birth_date($date)
597         {
598                 // If the user entered no birth date NULL needs to be inserted into DB.
599                 if (! $date)
600                         return NULL;
601                 
602                 return $date;
603         }
604         
605         public function _valid_old_password($old_password, $field_username)
606         {
607                 if (! $old_password)
608                         return TRUE;
609                 
610                 $username= $this->input->post($field_username);
611                 
612                 if ($this->users_model->login($username, $old_password))
613                         return TRUE;
614                 
615                 return FALSE;
616         }
617         
618         public function _change_password_cond($param)
619         {
620                 $old = $this->input->post('old-password');
621                 $new = $this->input->post('new-password');
622                 $newc = $this->input->post('new-password-confirmation');
623                 
624                 return (!$old && !$new && !$newc)
625                         || ($old && $new && $newc);
626         }
627         
628         public function _required_by_register($param)
629         {
630                 $user_id = $this->input->post('user-id');
631                 
632                 if (! $user_id && ! $param)
633                         return FALSE;
634                 
635                 return TRUE;
636         }
637         
638         public function _valid_activation_code($activation_code)
639         {
640                 return (preg_match('/^[a-fA-F0-9]{16}$/', $activation_code) == 1);
641         }
642
643         public function _do_login($username, $field_password)
644         {
645                 $password = $this->input->post($field_password);
646
647                 $user = $this->users_model->login($username, $password);
648
649                 // Authentication failed.
650                 if ($user === FALSE)
651                         return FALSE;
652                 
653                 // User has not activated the account.
654                 if ($user['activation_code'] !== NULL)
655                 {
656                         $this->activated_account = FALSE;
657                         $this->user_id = $user['id'];
658                         return TRUE;
659                 }
660                 
661                 // Authentication successful: set session with user data.
662                 $this->session->set_userdata(array(
663                         'user_id'=> $user['id'],
664                         'username'=> $user['username'],
665                         'auth_src'=> $user['auth_src'],
666                         'time_zone'=> $user['time_zone']
667                 ));
668                 $this->import = (isset($user['import']) ? $user['import'] : FALSE);
669                 return TRUE;
670         }
671         
672         public function _do_activate($activation_code)
673         {
674                 $user_id = $this->input->post('user-id');
675                 if ($user_id === FALSE)
676                         return FALSE;
677                 $user_id = intval($user_id);
678                 
679                 return $this->users_model->activate_account($user_id,
680                                 $activation_code);
681         }
682         
683         public function _do_resend_activation($email)
684         {
685                 $user_id = $this->input->post('user-id');
686                 if ($user_id === FALSE)
687                         return FALSE;
688                 $user_id = intval($user_id);
689                 
690                 $this->users_model->set_userdata($user_id,
691                         array('email'=> $email));
692                 
693                 return $this->users_model->send_activation_email($user_id, $email);
694         }
695         
696         public function _username_exists($username)
697         {
698                 $userdata = $this->users_model->get_userdata($username);
699                 
700                 if (! $userdata)
701                         return FALSE;
702                 
703                 return TRUE;
704         }
705         
706         public function _internal_account($username)
707         {
708                 $userdata = $this->users_model->get_userdata($username, 'auth_src');
709                 if (! $userdata)
710                         return FALSE;
711
712                 if ($userdata['auth_src'] != 'internal')
713                         return FALSE;
714                 
715                 return TRUE;
716         }
717         
718         public function _do_recover_password($username)
719         {
720                 $email = $this->input->post('email');
721                 if (! $email)
722                         return FALSE;
723                 
724                 return $this->users_model->recover_password($username, $email);
725         }
726 }
727
728 /* End of file user.php */
729 /* Location: ./application/controllers/user.php */