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