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