18 require_once SQ_PACKAGES_PATH.
'/cms/form/form_action/form_action.inc';
19 require_once SQ_ATTRIBUTES_PATH.
'/oauth/oauth.inc';
44 parent::__construct();
57 $settings[
'consumer_key'] = array_get_index($settings,
'consumer_key');
58 $settings[
'consumer_secret'] = array_get_index($settings,
'consumer_secret');
59 $settings[
'request_token'] = array_get_index($settings,
'request_token');
60 $settings[
'request_token_secret'] = array_get_index($settings,
'request_token_secret');
61 $settings[
'access_token'] = array_get_index($settings,
'access_token');
62 $settings[
'access_token_secret'] = array_get_index($settings,
'access_token_secret');
63 $settings[
'developer_key'] = array_get_index($settings,
'developer_key');
64 $settings[
'privacy'] = array_get_index($settings,
'privacy',
'public');
65 $settings[
'title'] = array_get_index($settings,
'title');
66 $settings[
'title_question_id'] = array_get_index($settings,
'title_question_id', 0);
67 $settings[
'description'] = array_get_index($settings,
'description');
68 $settings[
'description_question_id'] = array_get_index($settings,
'description_question_id', 0);
69 $settings[
'category'] = array_get_index($settings,
'category');
70 $settings[
'category_question_id'] = array_get_index($settings,
'category_question_id', 0);
71 $settings[
'video_question_id'] = array_get_index($settings,
'video_question_id', 0);
72 $settings[
'delete_video_file'] = array_get_index($settings,
'delete_video_file', 1);
73 $settings[
'upload_timeout'] = array_get_index($settings,
'upload_timeout', 300);
75 $consumer_details_locked = (!empty($settings[
'request_token'])) ? TRUE : FALSE;
79 if (!empty($_REQUEST[
'oauth_verifier'])) hidden_field(
'oauth_verifier', $_REQUEST[
'oauth_verifier']);
82 <div style=
"padding: 5px">
83 <p
class=
"sq-backend-section-subheading"><?php echo translate(
'form_action_upload_youtube_video_client_credentials_header') ?></p>
85 <table
class=
"sq-backend-table">
89 <th><?php echo translate(
'form_action_upload_youtube_video_client_credentials_key') ?></th>
91 if (($consumer_details_locked === FALSE)) {
92 text_box($prefix.
'[consumer_key]', $settings[
'consumer_key'], 50);
94 echo $settings[
'consumer_key'];
95 hidden_field($prefix.
'[consumer_key]', $settings[
'consumer_key']);
100 <th><?php echo translate(
'form_action_upload_youtube_video_client_credentials_secret') ?></th>
102 if (($consumer_details_locked === FALSE)) {
103 text_box($prefix.
'[consumer_secret]', $settings[
'consumer_secret'], 50);
105 echo $settings[
'consumer_secret'];
106 hidden_field($prefix.
'[consumer_secret]', $settings[
'consumer_secret']);
111 <th><?php echo translate(
'form_action_upload_youtube_video_client_dev_key') ?></th>
113 text_box($prefix.
'[developer_key]', $settings[
'developer_key'], 50);
117 <th><?php echo translate(
'form_action_upload_youtube_video_client_credentials_step') ?></th>
119 if ((empty($settings[
'consumer_key']) === TRUE) || (empty($settings[
'consumer_secret']) === TRUE)) {
120 echo translate(
'form_action_upload_youtube_video_client_credentials_status_no_consumer');
122 if (!empty($settings[
'access_token'])){
123 echo translate(
'form_action_upload_youtube_video_client_credentials_connected');
124 }
else if (empty($settings[
'access_token']) && !empty($_REQUEST[
'oauth_verifier'])){
125 $value = translate(
'form_action_upload_youtube_video_client_credentials_access_token');
126 submit_button($prefix.
'[get_access_token]', $value,
'main_form.submit()');
127 if (!empty($settings[
'access_token_errors'])){
128 ?><br /><strong style=
"color: #f00">Error: failed to gain access token</strong><?php
129 foreach ($settings[
'access_token_errors'] as $error) {
130 ?><br/><?php echo $error ?><?php
133 }
else if (!empty($settings[
'request_token'])){
134 $callback_url = self::_getCallbackURL($prefix);
135 $url =
'https://www.google.com/accounts/OAuthAuthorizeToken?oauth_token='.$settings[
'request_token'].
'&oauth_callback='.urlencode($callback_url);
136 echo
'<a target="_blank" href="'.$url.
'">'.translate(
'form_action_upload_youtube_video_client_credentials_auth_token').
'</a>';
138 $value = translate(
'form_action_upload_youtube_video_client_credentials_request_token');
139 submit_button($prefix.
'[get_request_token]', $value,
'main_form.submit()');
140 if (!empty($settings[
'request_token_errors'])){
141 ?><br /><strong style=
"color: #f00">Error: failed to gain request token</strong><?php
142 foreach ($settings[
'request_token_errors'] as $error) {
143 ?><br/><?php echo $error ?><?php
151 <th><?php echo translate(
'form_action_upload_youtube_video_client_credentials_deauthorise') ?></th>
153 check_box($prefix.
'[deauthorise]');
158 <div style=
"padding: 5px">
159 <?php echo translate(
'form_action_upload_youtube_video_client_credentials_note') ?>
162 <div style=
"padding: 5px">
163 <p
class=
"sq-backend-section-subheading"><?php echo translate(
'form_action_upload_youtube_video_settings_header') ?></p>
165 <table
class=
"sq-backend-table">
168 <th>Video Settings</th>
169 <th>
Form Question Id</th>
172 <th><?php echo translate(
'form_action_upload_youtube_video_settings_privacy') ?></th>
175 'public' =>
'Public',
176 'private' =>
'Private',
177 'unlisted' =>
'Unlisted'
179 combo_box($prefix.
'[privacy]', $options, FALSE, $settings[
'privacy']);
185 <th><?php echo translate(
'form_action_upload_youtube_video_settings_title') ?></th>
187 text_box($prefix.
'[title]', $settings[
'title'], 50, 100);
190 $type_codes = Array (
191 'form_question_type_text' =>
'I',
193 asset_finder($prefix.
'[title_question_id]', $settings[
'title_question_id'], $type_codes);
197 <th><?php echo translate(
'form_action_upload_youtube_video_settings_description') ?></th>
199 text_area($prefix.
'[description]', $settings[
'description'], 46, 10, 5000);
202 $type_codes = Array (
203 'form_question_type_text' =>
'I',
205 asset_finder($prefix.
'[description_question_id]', $settings[
'description_question_id'], $type_codes);
209 <th><?php echo translate(
'form_action_upload_youtube_video_settings_category') ?></th>
211 text_box($prefix.
'[category]', $settings[
'category'], 50);
214 $type_codes = Array (
215 'form_question_type_text' =>
'I',
216 'form_question_type_select' =>
'I',
218 asset_finder($prefix.
'[category_question_id]', $settings[
'category_question_id'], $type_codes);
222 <th><?php echo translate(
'form_action_upload_youtube_video_settings_file') ?></th>
225 $type_codes = Array (
226 'form_question_type_file_upload' =>
'I',
228 asset_finder($prefix.
'[video_question_id]', $settings[
'video_question_id'], $type_codes);
232 <th><?php echo translate(
'form_action_upload_youtube_video_settings_delete_file') ?></th>
238 combo_box($prefix.
'[delete_video_file]', $options, FALSE, $settings[
'delete_video_file']);
243 <th><?php echo translate(
'form_action_upload_youtube_video_upload_timeout') ?></th>
245 int_text_box($prefix.
'[upload_timeout]', $settings[
'upload_timeout'], FALSE);
251 <div style=
"padding: 5px">
252 <?php echo translate(
'form_action_upload_youtube_video_settings_note') ?>
257 $contents = ob_get_clean();
271 $settings[
'before_submit'] = TRUE;
273 $request_data = $_REQUEST[$prefix];
274 $deauthorise = (boolean)array_get_index($request_data,
'deauthorise', FALSE);
276 if ($deauthorise === TRUE) {
278 $settings[
'request_token'] = NULL;
279 $settings[
'request_token_secret'] = NULL;
280 $settings[
'request_token_errors'] = NULL;
282 $settings[
'access_token'] = NULL;
283 $settings[
'access_token_secret'] = NULL;
284 $settings[
'access_token_errors'] = NULL;
286 unset($_REQUEST[
'oauth_verifier']);
291 $settings[
'consumer_key'] = array_get_index($request_data,
'consumer_key');
292 $settings[
'consumer_secret'] = array_get_index($request_data,
'consumer_secret');
293 $settings[
'developer_key'] = array_get_index($request_data,
'developer_key');
294 $settings[
'request_token_errors'] = NULL;
295 $settings[
'access_token_errors'] = NULL;
297 if (isset($request_data[
'get_request_token'])) {
298 self::processRequestToken($settings ,$prefix);
299 }
else if (isset($request_data[
'get_access_token'])) {
300 self::processAccessToken($settings, $_REQUEST[
'oauth_verifier']);
303 $settings[
'privacy'] = array_get_index($request_data,
'privacy',
'public');
304 $settings[
'title'] = array_get_index($request_data,
'title');
305 $settings[
'title_question_id'] = array_get_index(array_get_index($request_data,
'title_question_id', Array()),
'assetid', 0);
306 $settings[
'description'] = array_get_index($request_data,
'description');
307 $settings[
'description_question_id'] = array_get_index(array_get_index($request_data,
'description_question_id', Array()),
'assetid', 0);
308 $settings[
'category'] = array_get_index($request_data,
'category');
309 $settings[
'category_question_id'] = array_get_index(array_get_index($request_data,
'category_question_id', Array()),
'assetid', 0);
310 $settings[
'video_question_id'] = array_get_index(array_get_index($request_data,
'video_question_id', Array()),
'assetid', 0);
311 $settings[
'delete_video_file'] = array_get_index($request_data,
'delete_video_file', 1);
312 $settings[
'upload_timeout'] = (!empty($request_data[
'upload_timeout'])) ? $request_data[
'upload_timeout'] : 300;
327 private function _getCallbackURL($prefix){
329 $callback_url = replace_query_string_vars(Array(), NULL, NULL, TRUE);
330 $additional_params =
'SQ_BACKEND_PAGE=frames';
331 $action_id = array_get_index($_REQUEST, $prefix.
'_new_selected_action',
'');
332 if (strlen($action_id) == 0) $action_id = array_get_index($_REQUEST, $prefix.
'_selected_action',
'');
333 $additional_params .=
'&'.$prefix.
'_new_selected_action='.$action_id;
334 if (strpos($callback_url,
'?') === FALSE) {
335 $callback_url .=
'?'.$additional_params;
337 $callback_url .=
'&'.$additional_params;
340 return $callback_url;
357 $callback_url = self::_getCallbackURL($prefix);
360 $oauth_attr_values = Array(
361 'consumer_key' => $settings[
'consumer_key'],
362 'consumer_secret' => $settings[
'consumer_secret'],
363 'request_token_url' =>
'https://www.google.com/accounts/OAuthGetRequestToken?scope=http://gdata.youtube.com',
365 'callback_url' => $callback_url,
366 'signature_method' =>
'HMAC-SHA1',
367 'request_headers' => Array(),
368 'request_body' =>
'',
370 'cache_options' =>
'NEVER',
371 'follow_redirect' => FALSE,
373 $oauth_attr->setValue($oauth_attr_values);
375 $settings[
'request_token'] = NULL;
376 $settings[
'request_token_secret'] = NULL;
377 $settings[
'request_token_errors'] = NULL;
379 $settings[
'access_token'] = NULL;
380 $settings[
'access_token_secret'] = NULL;
381 $settings[
'access_token_errors'] = NULL;
383 $result = $oauth_attr->getRequestToken();
385 if (!isset($result[
'request_token'][
'oauth_token']) || !isset($result[
'request_token'][
'oauth_token_secret'])) {
386 $settings[
'request_token_errors'] = $oauth_attr->getErrors();
388 $settings[
'request_token'] = $result[
'request_token'][
'oauth_token'];
389 $settings[
'request_token_secret'] = $result[
'request_token'][
'oauth_token_secret'];
408 $oauth_attr_values = Array(
409 'consumer_key' => $settings[
'consumer_key'],
410 'consumer_secret' => $settings[
'consumer_secret'],
411 'access_token_url' =>
'https://www.google.com/accounts/OAuthGetAccessToken',
413 'callback_url' =>
'',
414 'signature_method' =>
'HMAC-SHA1',
415 'request_headers' => Array(),
416 'request_body' =>
'',
418 'cache_options' =>
'NEVER',
419 'follow_redirect' => FALSE,
421 $oauth_attr->setValue($oauth_attr_values);
424 $settings[
'access_token'] = NULL;
425 $settings[
'access_token_secret'] = NULL;
426 $settings[
'access_token_errors'] = NULL;
429 $result = $oauth_attr->getAccessToken(urldecode($settings[
'request_token']), $oauth_verifier, urldecode($settings[
'request_token_secret']));
431 if (!isset($result[
'access_token'][
'oauth_token']) || !isset($result[
'access_token'][
'oauth_token_secret'])) {
432 $settings[
'access_token_errors'] = $oauth_attr->getErrors();
434 $settings[
'access_token'] = $result[
'access_token'][
'oauth_token'];
435 $settings[
'access_token_secret'] = $result[
'access_token'][
'oauth_token_secret'];
448 ?><table
class=
"no-borders">
455 <td
class=
"sq-backend-table-cell" style=
"vertical-align: top"><p><strong>
Authentication:</strong></p></td>
456 <td
class=
"sq-backend-table-cell" style=
"vertical-align: top"><p><?php
457 if (!empty($settings[
'access_token'])) {
458 echo translate(
'form_action_upload_youtube_video_client_credentials_connected');
460 ?><span
class=
"sq-backend-warning">No Access Token.</span><?php
465 <td
class=
"sq-backend-table-cell" style=
"vertical-align: top"><p><strong>Video Source:</strong></p></td>
466 <td
class=
"sq-backend-table-cell" style=
"vertical-align: top"><p><?php
467 if (!empty($settings[
'video_question_id'])) {
468 echo get_asset_tag_line($settings[
'video_question_id']);
470 ?><span
class=
"sq-backend-warning">No video source specified.</span><?php
488 $submission = (isset($form->submission_asset)) ? $form->submission_asset->
attr(
'attributes') : NULL;
489 if (empty($submission)){
490 trigger_error(
"Unable to extract submission from ".$form->
type().
" (Id: #$form->id)", E_USER_WARNING);
491 $form->submission_errors[] =
'Failed to upload video file to Youtube';
495 if (!empty($settings[
'video_question_id'])){
496 if (!empty($submission[
'answers'][$settings[
'video_question_id']][
'extra_data'][
'filesystem_path'])){
497 $video_path = $submission[
'answers'][$settings[
'video_question_id']][
'extra_data'][
'filesystem_path'];
499 }
else if (!empty($submission[
'answers'][$settings[
'video_question_id']][
'extra_data'][
'temp_filesystem_path'])){
500 $video_path = $submission[
'answers'][$settings[
'video_question_id']][
'extra_data'][
'temp_filesystem_path'];
505 if (empty($video_path)){
506 trigger_error(
"Unable to locate video source from ".$form->
type().
" (Id: #$form->id)", E_USER_WARNING);
507 $form->submission_errors[] =
'Failed to upload video file to Youtube';
511 if (!empty($settings[
'category_question_id']) && !empty($submission[
'answers'][$settings[
'category_question_id']][
'answer'])){
512 $settings[
'category'] = $submission[
'answers'][$settings[
'category_question_id']][
'answer'];
514 if (!empty($settings[
'title_question_id']) && !empty($submission[
'answers'][$settings[
'title_question_id']][
'answer'])){
515 $settings[
'title'] = $submission[
'answers'][$settings[
'title_question_id']][
'answer'];
518 if (empty($settings[
'title'])) $settings[
'title'] = basename($video_path);
520 if (!empty($settings[
'description_question_id']) && !empty($submission[
'answers'][$settings[
'description_question_id']][
'answer'])){
521 $settings[
'description'] = $submission[
'answers'][$settings[
'description_question_id']][
'answer'];
525 if (self::processUploadVideo($settings, $video_path, $keywords) === TRUE){
526 $form->form_action_keywords = $keywords;
527 if ($settings[
'delete_video_file'] == 1 && !$temp_path){
528 if (unlink($video_path) == TRUE){
529 $extra_data = $form->submission_asset->getExtraData($settings[
'video_question_id']);
530 unset($extra_data[
'filesystem_path']);
531 $form->submission_asset->setExtraData($settings[
'video_question_id'], $extra_data);
532 $GLOBALS[
'SQ_SYSTEM']->setRunLevel(SQ_RUN_LEVEL_FORCED);
534 $GLOBALS[
'SQ_SYSTEM']->restoreRunLevel();
538 trigger_error(
"Failed to upload video file to Youtube for ".$form->
type().
" (Id: #$form->id)", E_USER_WARNING);
539 $form->submission_errors[] =
'Failed to upload video file to Youtube';
554 if (empty($settings[
'access_token']))
return FALSE;
555 if (empty($settings[
'developer_key']))
return FALSE;
556 if (empty($settings[
'video_question_id']))
return FALSE;
557 if (empty($settings[
'category']) && empty($settings[
'category_question_id']))
return FALSE;
576 $url =
'http://uploads.gdata.youtube.com/feeds/api/users/default/uploads';
578 $xml_api =
'<?xml version="1.0"?><entry xmlns="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" xmlns:yt="http://gdata.youtube.com/schemas/2007">';
579 if ($settings[
'privacy'] ==
'unlisted') $xml_api .=
'<yt:accessControl action=\'list\' permission=\'denied\' />';
580 $xml_api .=
'<media:group><yt:incomplete/>';
581 if ($settings[
'privacy'] ==
'private') $xml_api .=
'<yt:private/>';
582 if (!empty($settings[
'title'])) $xml_api .=
'<media:title type="plain">'.$settings[
'title'].
'</media:title>';
583 if (!empty($settings[
'description'])) $xml_api .=
'<media:description type="plain">'.$settings[
'description'].
'</media:description>';
584 if (!empty($settings[
'category'])) $xml_api .=
'<media:category scheme="http://gdata.youtube.com/schemas/2007/categories.cat">'.$settings[
'category'].
'</media:category>';
585 $xml_api .=
'</media:group></entry>';
588 $oauth_attr_values = Array(
589 'consumer_key' => $settings[
'consumer_key'],
590 'consumer_secret' => $settings[
'consumer_secret'],
592 'signature_method' =>
'HMAC-SHA1',
593 'request_headers' =>
'',
594 'request_body' =>
'',
596 'cache_options' =>
'NEVER',
597 'follow_redirect' => FALSE,
599 $oauth_attr->setValue($oauth_attr_values);
601 $auth_header = $oauth_attr->getUserDataAuthHeader($url, $settings[
'access_token'], $settings[
'access_token_secret'], FALSE);
602 $request = self::_HTTPUploadRequest($url, $xml_api, $video_path, $auth_header, $settings);
604 if($request[
'status'] ==
'ok'){
606 $xml =
new SimpleXMLElement($request[
'content']);
607 }
catch(Exception $e){
608 trigger_error(
"Failed to parse Youtube API XML: ".$e->getMessage().
"\n", E_USER_WARNING);
612 $video_id = (isset($xml->id)) ? (
string)$xml->id :
'';
614 $video_id = (strpos($video_id,
'video:') !== FALSE) ? substr($video_id, strpos($video_id,
'video:') + strlen(
'video:')) : $video_id;
616 $published_date = (isset($xml->published)) ? substr((
string)$xml->published, 0, strpos((
string)$xml->published,
'T')) :
'';
618 if (isset($xml->link)){
619 foreach($xml->link as $link){
620 $attr = $link->attributes();
621 if (isset($attr[
'rel']) && $attr[
'rel'] ==
'alternate'){
622 $video_link = (string)$attr[
'href'];
629 'youtube_video_id' => $video_id,
630 'youtube_video_published_date' => $published_date,
631 'youtube_video_link' => $video_link
635 }
else if (isset($xml->error)){
636 foreach($xml->error as $error){
637 $errors[] = (Array)$error;
639 trigger_error(
"Youtube API Error:\n".print_r($errors, TRUE).
"\n", E_USER_WARNING);
643 }
else if($request[
'status'] ==
'err'){
644 trigger_error(
'Youtube File Upload Fail: '.$request[
'error'], E_USER_WARNING);
665 private function _HTTPUploadRequest($url, $api_xml, $video_path, $auth_header, $settings) {
667 $vide_h = fopen($video_path,
"rb");
668 if ($vide_h === FALSE)
return Array(
670 'error' =>
"Unable to open video file: $video_path"
673 $video_size = filesize($video_path);
674 $video = fread($vide_h, $video_size);
677 $file_name = basename($video_path);
679 $url = parse_url($url);
680 $host = $url[
'host'];
681 $path = $url[
'path'];
683 $fp = fsockopen($host, 80, $errno, $errstr, $settings[
'upload_timeout']);
687 $boundary_string = uniqid();
690 $post_body .=
"--$boundary_string\r\n";
691 $post_body .=
"Content-Type: application/atom+xml; charset=UTF-8\r\n\r\n";
692 $post_body .= $api_xml;
693 $post_body .=
"\r\n--$boundary_string\r\n";
694 $post_body .=
"Content-Type: application/octet-stream\r\n";
695 $post_body .=
"Content-Transfer-Encoding: binary\r\n\r\n";
697 $post_end =
"\r\n--$boundary_string--\r\n";
699 $size = strlen($post_body) + $video_size + strlen($post_end);
700 $post_body .= $video;
701 $post_body .= $post_end;
704 $header =
"POST $path HTTP/1.1\r\n";
705 $header .=
"Host: $host\r\n";
706 $header .= $auth_header.
"\r\n";
707 $header .=
"GData-Version: 2\r\n";
708 $header .=
"X-GData-Key: key=".$settings[
'developer_key'].
"\r\n";
709 $header .=
"Slug: $file_name\r\n";
710 $header .=
"Content-Type: multipart/related; boundary=$boundary_string\r\n";
711 $header .=
"Content-Length: ". $size .
"\r\n";
712 $header .=
"Connection: close\r\n\r\n";
714 fwrite($fp, $header.$post_body);
717 $result .= fgets($fp);
723 'error' =>
"$errstr ($errno)"
731 $result = explode(
"\r\n\r\n", $result, 2);
732 $header = isset($result[0]) ? $result[0] :
'';
733 $content = isset($result[1]) ? $result[1] :
'';
739 'content' => $content