user gets notified interatively or by email in case of a CIS error
[living-lab-site.git] / application / controllers / video.php
1 <?php
2
3 /**
4  * Class Video controls video items handling: watching, commenting, rating,
5  * adding etc.
6  *
7  * @category    Controller
8  * @author              Călin-Andrei Burloiu
9  */
10 class Video extends CI_Controller {
11
12         protected $uploaded_file;
13         protected $av_info;
14         
15         public function __construct()
16         {
17                 parent::__construct();
18                 
19                 $this->lang->load('video');
20         }
21         
22         public function index()
23         {
24                 //phpinfo();
25         }
26         
27         public function test($param)
28         {
29                 $this->load->model('videos_model');
30                 
31                 echo $this->videos_model->send_upload_error_email($param,
32                                 CIS_RESP_UNREACHABLE) ? 's-a trimis' : 'nu s-a trimis';
33         }
34         
35         /**
36          * The page used for watching a video
37          *
38          * @param       string $id      DB id of the video
39          * @param       string $name    `name` of the video from DB
40          * @param       string $plugin  video plugin ('ns-vlc', 'ns-html5'). If it's set 
41          * to NULL or 'auto', the plugin is automatically selected.
42          */
43         public function watch($id, $name = NULL, $plugin = NULL)
44         {
45                 // **
46                 // ** LOADING MODEL
47                 // **
48                 $this->load->model('videos_model');
49                 
50                 $data['user_id'] = $this->session->userdata('user_id');
51                 if ($data['user_id'] === FALSE)
52                         $data['user_id'] = '';
53                 else
54                         $data['user_id'] = intval($data['user_id']);
55                 $user_roles = intval($this->session->userdata('roles'));
56 //              echo USER_ROLE_ADMIN . ' / ';
57 //              var_dump($user_roles);
58 //              var_dump($user_roles | USER_ROLE_ADMIN);
59 //              die();
60                 
61                 // Retrieve video information.
62                 $data['video'] = $this->videos_model->get_video($id, $name);
63                 if ($data['video'] === FALSE)
64                 {       
65                         $this->load->helper('message');
66                         show_error_msg_page($this, 
67                                 $this->lang->line('video_msg_no_video'));
68                         return;
69                 }
70                 
71                 // Video is being processed by CIS.
72                 if ($data['video']['activation_code']
73                                 && $data['video']['cis_response'] == CIS_RESP_NONE)
74                 {
75                         $this->load->helper('message');
76                         show_error_msg_page($this, 
77                                 $this->lang->line('video_msg_video_not_ready'));
78                         return;
79                 }
80                 
81                 // Unlogged in user can't see unactivated videos.
82                 if (empty($data['user_id']))
83                         $allow_unactivated = FALSE;
84                 else
85                 {
86                         if (($user_roles & USER_ROLE_ADMIN) == 0
87                                         && $data['user_id'] != $data['video']['user_id'])
88                                 $allow_unactivated = FALSE;
89                         else
90                                 $allow_unactivated = TRUE;
91                 }
92                 
93                 // Video is not activated; can be seen by owner and admin.
94                 if ($data['video']['activation_code'] && !$allow_unactivated)
95                 {
96                         $this->load->helper('message');
97                         show_error_msg_page($this, 
98                                 $this->lang->line('video_msg_video_unactivated'));
99                         return;
100                 }                       
101                 
102                 $categories = $this->config->item('categories');
103                 $data['video']['category_name'] = 
104                         $categories[ $data['video']['category_id'] ];
105                 $data['plugin_type'] = ($plugin === NULL ? 'auto' : $plugin);
106                 
107                 // Increment the number of views for the video.
108                 $this->videos_model->inc_views($id);
109                 
110                 // Display page.
111                 $params = array(        'title' => $data['video']['title'] . ' &ndash; '
112                                                                 . $this->config->item('site_name'),
113                                                         'css' => array(
114                                                                 'jquery.ui.nsvideo.css',
115                                                                 'video.css'
116                                                         ),
117                                                         'js' => array(
118                                                                 'jquery.ui.nsvideo.js',
119                                                                 'jquery.ui.ajax_links_maker.js'
120                                                         ),
121                                                         //'metas' => array('description'=>'','keywords'=>'')
122                                                         );
123                 $this->load->library('html_head_params', $params);
124                 
125                 // Preloading video plugin.
126                 // TODO plugin auto: type and format
127                 if ($data['plugin_type'] == 'auto')
128                         $data['plugin_type'] = 'ns-html5';
129                 $data['asset_index'] = 0;
130                 
131                 // TODO remove old AJAX plugin content
132 //              $data['plugin_content'] = $this->_plugin('ns-html5', 
133 //                      $data['video']['url'][0], TRUE);
134
135                 // Comments
136                 $data['comments'] = $this->_ajax_comment(TRUE, $id);
137                 
138                 // **
139                 // ** LOADING VIEWS
140                 // **
141                 $this->load->view('html_begin', $this->html_head_params);
142                 $this->load->view('header');
143                 
144                 //$main_params['content'] = $this->load->view('video/watch_view', $data, TRUE);
145                 $this->load->view('video/watch_view', $data);
146                 
147                 $this->load->view('footer');
148                 $this->load->view('html_end');
149         }
150                 
151         public function upload()
152         {
153                 $user_id = $this->session->userdata('user_id');
154                 
155                 // Action not possible if an user is not logged in.
156                 if (!$user_id)
157                 {
158                         $this->load->helper('message');
159                         show_error_msg_page($this, 
160                                 $this->lang->line('ui_msg_login_restriction'));
161                         return;
162                 }
163                 
164                 $this->load->library('form_validation');
165
166                 $this->form_validation->set_error_delimiters('<span class="error">',
167                                 '</span>');
168                 
169                 if ($this->form_validation->run('upload') === FALSE)
170                 {
171                         $params = array('title' =>
172                                                                 $this->lang->line('ui_nav_menu_upload')
173                                                                         .' &ndash; '
174                                                                         . $this->config->item('site_name'),
175                                                         //'metas' => array('description'=>'')
176                         );
177                         $this->load->library('html_head_params', $params);
178
179                         // **
180                         // ** LOADING VIEWS
181                         // **
182                         $this->load->view('html_begin', $this->html_head_params);
183                         $this->load->view('header',
184                                         array('selected_menu' => 'upload'));
185
186                         $main_params['content'] = $this->load->view(
187                                         'video/upload_view', array(), TRUE);
188                         $main_params['side'] = $this->load->view('side_default', NULL, TRUE);
189                         $this->load->view('main', $main_params);
190
191                         $this->load->view('footer');
192                         $this->load->view('html_end');
193                 }
194                 else
195                 {
196                         $this->load->model('videos_model');
197                         $this->load->helper('video');
198                         $this->config->load('content_ingestion');
199                         
200                         $name = urlencode(str_replace(' ', '-',
201                                         $this->input->post('video-title')));
202                         $category_id = $this->input->post('video-category');
203                         
204                         // Prepare formats
205                         $formats = $this->config->item('formats');
206                         $prepared_formats = prepare_formats($formats, $this->av_info,
207                                         $this->config->item('elim_dupl_res'));
208                         
209                         // Add video to DB.
210                         $activation_code = $this->videos_model->add_video($name,
211                                         $this->input->post('video-title'),
212                                         $this->input->post('video-description'),
213                                         $this->input->post('video-tags'),
214                                         $this->av_info['duration'],
215                                         $prepared_formats['db_formats'], $category_id, $user_id,
216                                         $this->uploaded_file);
217                         if ($activation_code == FALSE)
218                         {
219                                 $this->load->helper('message');
220                                 show_error_msg_page($this, 
221                                         $this->lang->line('video_msg_add_video_db_error'));
222                                 return;
223                         }
224                         
225                         // Send a content ingestion request to
226                         // CIS (Content Ingestion Server).
227                         $r = $this->videos_model->send_content_ingestion($activation_code,
228                                         $this->uploaded_file,
229                                         $name, $this->av_info['size'],
230                                         $prepared_formats['transcode_configs']);
231                         if ($r == FALSE)
232                         {
233                                 $this->videos_model->set_cis_response($activation_code,
234                                                 CIS_RESP_UNREACHABLE);
235                                 
236                                 $this->load->helper('message');
237                                 show_error_msg_page($this, 
238                                                 $this->lang->line(
239                                                                 'video_msg_send_content_ingestion_error'));
240                                 return;
241                         }
242                         
243                         $this->load->helper('message');
244                         show_info_msg_page($this, 
245                                 $this->lang->line('video_msg_video_uploaded'));
246                 }
247         }
248         
249         /**
250          * URL used by CIS service to announce its content ingestion completion.
251          * 
252          * @param string $activation_code 
253          */
254         public function cis_completion($activation_code)
255         {
256                 $this->load->model('videos_model');
257                 
258                 if ($this->config->item('require_moderation'))
259                         $this->videos_model->set_cis_response($activation_code,
260                                         CIS_RESP_COMPLETION);
261                 else
262                         $this->videos_model->activate_video($activation_code);
263                 
264 //              log_message('info', "cis_completion $activation_code");
265         }
266         
267         /**
268          * URL used by CIS service to annouce an error which occured while
269          * ingesting content.
270          * 
271          * @param string $activation_code
272          * @param string $error_name 'internal_error' corresponds to constant
273          * CIS_RESP_INTERNAL_ERROR and 'unreachable' corresponds to constant
274          * CIS_RESP_UNREACHABLE
275          */
276         public function cis_error($activation_code, $error_name = 'internal_error')
277         {
278                 $this->load->model('videos_model');
279                 
280                 if ($error_name == 'internal_error')
281                 {
282                         $this->videos_model->set_cis_response ($activation_code,
283                                         CIS_RESP_INTERNAL_ERROR);
284                         log_message('error',
285                                         "Internal CIS error for activation code $activation_code");
286                         $this->videos_model->send_upload_error_email($activation_code,
287                                         CIS_RESP_INTERNAL_ERROR);
288                 }
289                 // Unreachable error is announced by a CIS-LB which was unable to
290                 // contact an CIS.
291                 else if ($error_name == 'unreachable')
292                 {
293                         $this->videos_model->set_cis_response($activation_code,
294                                         CIS_RESP_UNREACHABLE);
295                         log_message('error',
296                                         "CIS-LB could not reach any CIS for activation code $activation_code");
297                         $this->videos_model->send_upload_error_email($activation_code,
298                                         CIS_RESP_UNREACHABLE);
299                 }
300                 else
301                 {
302                         log_message('error',
303                                         "Invalid error name received from CIS / CIS-LB for activation code $activation_code");
304                 }
305                 
306         }
307         
308         /**
309         * Increments (dis)likes count for video with the specified id and returns to
310         * the client as plain text the number if likes.
311         *
312         * @param string $action 'like' or 'dislike'
313         * @param string $video_id
314         * @param string $user_id
315         */
316         public function ajax_vote($action, $video_id)
317         {
318                 $video_id = intval($video_id);
319                 $user_id = $this->session->userdata('user_id');
320                 $this->load->model('videos_model');
321         
322                 $res = $this->videos_model->vote($video_id, $user_id,
323                         (strcmp($action, 'like') == 0 ? TRUE : FALSE));
324         
325                 if ($res !== -1)
326                         echo $res;
327         }
328         /**
329          * Increments (dis)likes count for a comment with a specified id and returns
330          * to the client as plain text the number if likes. 
331          * 
332          * @param string $action        'like' or 'dislike'
333          * @param string $comment_id
334          */
335         public function ajax_vote_comment($action, $comment_id)
336         {
337                 $comment_id = intval($comment_id);
338                 $user_id = $this->session->userdata('user_id');
339                 $this->load->model('videos_model');
340                 
341                 $res = $this->videos_model->vote_comment($comment_id, $user_id,
342                         (strcmp($action, 'like') == 0 ? TRUE : FALSE));
343                 
344                 if ($res !== -1)
345                         echo $res;
346         }
347         
348         public function ajax_comment($video_id,
349                         $ordering = 'newest', $offset = '0')
350         {
351                 $this->_ajax_comment(FALSE, $video_id, $ordering, $offset);
352         }
353         
354         public function _ajax_comment($return_output, $video_id,
355                         $ordering = 'newest', $offset = '0')
356         {
357                 $video_id = intval($video_id);
358                 
359                 $this->load->library('form_validation');
360                 $this->form_validation->set_error_delimiters('<span class="error">',
361                                         '</span>');
362                 
363                 if ($this->form_validation->run('comment_video'))
364                 {
365                         $this->load->model('videos_model');
366                         $user_id = intval($this->session->userdata('user_id'));
367                         $comment = $this->input->post('comment');
368                         
369                         $this->videos_model->comment_video($video_id, $user_id, $comment);
370                 }
371                 
372                 // **
373                 // ** MODEL **
374                 // **           
375                 $this->load->model('videos_model');
376                 $data['comments'] = $this->videos_model->get_video_comments($video_id,
377                         $offset, $this->config->item('video_comments_per_page'), $ordering);
378                 $data['comments_count'] =
379                         $this->videos_model->get_video_comments_count($video_id);
380                 $data['hottest_comments'] = $this->videos_model->get_video_comments(
381                         $video_id, 0, 2, 'hottest');
382                 $data['video_id'] = $video_id;
383                 $data['user_id'] = $this->session->userdata('user_id');
384                 
385                 // Pagination
386                 $this->load->library('pagination');
387                 $pg_config['base_url'] = site_url("video/ajax_comment/$video_id/$ordering/");
388                 $pg_config['uri_segment'] = 5;
389                 $pg_config['total_rows'] = $data['comments_count'];
390                 $pg_config['per_page'] = $this->config->item('video_comments_per_page');
391                 $this->pagination->initialize($pg_config);
392                 $data['comments_pagination'] = $this->pagination->create_links();
393                 
394                 // **
395                 // ** VIEWS **
396                 // **
397                 $output = $this->load->view('video/comments_view',
398                         $data, $return_output);
399                 
400                 if ($return_output)
401                         return $output;
402         }
403         
404         public function _is_user_loggedin($param)
405         {
406                 if (! $this->session->userdata('user_id'))
407                         return FALSE;
408                 
409                 return TRUE;
410         }
411         
412         public function _do_comment($comment)
413         {
414                 // Note: Videos_model must be already loaded.
415                 $this->load->model('videos_model');
416                 
417                 $video_id = intval($this->input->post('video-id'));
418                 $user_id = intval($this->session->userdata('user_id'));
419                 
420                 $this->videos_model->comment_video($video_id, $user_id, $comment);
421         }
422         
423         public function _valid_tags($tags)
424         {
425                 $tok = strtok($tags, ',');
426                 while ($tok != FALSE)
427                 {
428                         $tok = trim($tok);
429                         if (!ctype_alnum($tok))
430                                 return FALSE;
431                         
432                         $tok = strtok(',');
433                 }
434                 
435                 return TRUE;
436         }
437         
438         public function _valid_upload($file)
439         {
440                 if ($_FILES['video-upload-file']['tmp_name'])
441                 {
442                         // Upload library
443                         $config_upload = array();
444                         $config_upload['upload_path'] = './data/upload';
445                         $config_upload['allowed_types'] = '*';
446                         $this->load->library('upload', $config_upload);
447
448                         if ($this->upload->do_upload('video-upload-file'))
449                         {
450                                 $upload_data = $this->upload->data();
451                                 $this->uploaded_file = $upload_data['file_name'];
452                                 
453                                 $this->load->helper('video');
454                                 $this->av_info = get_av_info($upload_data['full_path']);
455                                 if (!$this->av_info)
456                                         return FALSE;
457                                 
458                                 return TRUE;
459                         }
460                         else
461                         {
462                                 $this->form_validation->set_message('_valid_upload',
463                                                 $this->upload->display_errors('<span class="error">',
464                                                                 '</span>'));
465                                 return FALSE;
466                         }
467                 }
468                 
469                 $this->form_validation->set_message('_valid_upload',
470                                 $this->lang->line('_required_upload'));
471                 return FALSE;
472         }
473         
474         /**
475          * OBSOLETE: AJAX page which retrieves a video plugin.
476          *
477          * The view associated with this controller should be parameter type
478          * concatenated with '_plugin_view' and must be located in
479          * 'application/views/video'.
480          *
481          * @param       string $type    'ns-vlc', 'ns-html5'
482          */
483         public function plugin($type)
484         {
485                 $url = $this->input->post('url', TRUE);
486                 
487                 $this->_plugin($type, $url);
488         }
489         
490         /**
491          * OBSOLETE: Video plugin controller
492          *
493          * See plugin function for details. If the second parameter is TRUE
494          * the output is return instead of being displayed (used in preloading).
495          */
496         public function _plugin($type, $url, $return_output=FALSE)
497         {       
498                 if ($type == 'ns-html5')
499                         $data['url'] = 'tribe://' . $url;
500                 else if ($type == 'ns-vlc')
501                         $data['url'] = $url;
502                 
503                 $output = $this->load->view('video/'. $type . '_plugin_view', $data, 
504                         $return_output);
505                 
506                 if ($return_output)
507                         return $output;
508         }
509         
510 }
511
512 /* End of file video.php */
513 /* Location: ./application/controllers/video.php */