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