/[drupal]/contributions/modules/twistage/twistage_publish.module
ViewVC logotype

Contents of /contributions/modules/twistage/twistage_publish.module

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.2 - (show annotations) (download) (as text)
Tue Oct 7 15:16:56 2008 UTC (13 months, 2 weeks ago) by xmattus
Branch: MAIN
CVS Tags: HEAD
Branch point for: DRUPAL-6--1
Changes since 1.1: +194 -107 lines
File MIME type: text/x-php
Adding multi-video posting functionality, and a few bug fixes-
1 <?php
2
3 /**
4 * Implementation of hook_menu, for admin content type selection form.
5 */
6 function twistage_publish_menu($may_cache) {
7 $items = array();
8
9 $items[] = array(
10 'path' => 'admin/settings/twistage/publishing',
11 'title' => t('Publishing settings'),
12 'type' => MENU_CALLBACK,
13 'callback' => 'drupal_get_form',
14 'callback arguments' => array('twistage_publish_admin_form', arg(4)),
15 'access' => user_access('administer twistage'),
16 );
17
18 return $items;
19 }
20
21 /**
22 * Implementation of hook_form_alter, to add the video submission fieldset to the node form.
23 */
24 function twistage_publish_form_alter($form_id, &$form) {
25 if (isset($form['type'])) {
26 $type = $form['type']['#value'];
27 } else {
28 return;
29 }
30
31 $avail_profiles = array();
32 $result = db_query("SELECT * FROM {twistage_profiles} WHERE 1");
33 while ($profile = db_fetch_object($result)) {
34 $types = unserialize($profile->publish_types);
35 if ($types[$type]) {
36 $avail_profiles[$profile->pid] = $profile->name;
37 }
38 }
39
40 if (!$avail_profiles) {
41 return;
42 }
43
44 drupal_add_js(drupal_get_path('module','twistage') . '/twistage_publish.js');
45
46 // Add elements for existing videos
47 $videos = twistage_publish_get_videos_by_nid($form['#node']->nid);
48 if ($videos) {
49 $form['twistage_edit'] = array(
50 '#type' => 'fieldset',
51 '#title' => t('Maintain videos'),
52 '#collapsible' => true,
53 '#tree' => true,
54 );
55
56 foreach($videos as $video) {
57 $form['twistage_edit'][$video->vid] = twistage_publish_form_element($avail_profiles, 0, $video);
58 }
59 }
60
61 // Allow now video uploads.
62
63 // The hidden value of twistage_sequence is manipulated by jQuery as the user adds videos on the fly.
64 // This is somewhat unorthodox, but we can "cheat" and look at the post vars to see how many internal forms API members of this array to create,
65 // thereby giving us access to them in hook_nodeapi later on.
66 $seq = $_POST['twistage_sequence'] ? $_POST['twistage_sequence'] : 0;
67
68 $form['twistage_sequence'] = array(
69 '#type' => 'hidden',
70 '#value' => $seq,
71 );
72
73 $form['twistage_upload'] = array(
74 '#tree' => true,
75 '#prefix' => '<div id="twistage-add-replicate">',
76 '#suffix' => '</div>',
77 );
78
79 for($i = 0; $i <= $seq; $i++) {
80 $elem = array(
81 '#type' => 'fieldset',
82 '#title' => t('Video Upload'),
83 '#collapsible' => true,
84 );
85
86 if ($i == 0) {
87 $elem['#attributes'] = array('class' => 'twistage-add-original');
88 }
89
90 $form['twistage_upload'][$i] = array_merge($elem, twistage_publish_form_element($avail_profiles, $seq));
91 }
92
93
94 }
95
96 /**
97 * Implementation of hook_nodeapi
98 */
99 function twistage_publish_nodeapi(&$node, $op, $teaser, $page) {
100 switch($op) {
101 case 'load':
102 $result = db_query("SELECT * FROM {twistage_video_node} WHERE nid=%d", $node->nid);
103 $node->twistage_video = array();
104 while ($link = db_fetch_object($result)) {
105 $node->twistage_video[] = twistage_get_video($link->vid, $link->pid);
106 }
107 break;
108
109 case 'validate':
110 foreach ($node->twistage_edit as $vid => $edit) {
111 if (!$edit['twistage_title']) {
112 form_set_error('twistage_edit][' . $vid . '][twistage_title', t('Title is required'));
113 }
114 }
115
116 foreach ($node->twistage_upload as $seq => $upload) {
117 if (twistage_publish_upload_exists($seq) && !$upload['twistage_title']) {
118 form_set_error('twistage_upload][' . $seq . '][twistage_title', t('Title is required'));
119 }
120 }
121 break;
122
123 case 'insert':
124 case 'update':
125 //print_r($node); print_r($_FILES); die();
126 // The twistage_video property is set by hook_nodeapi on load only, so its our indicator of whether a video already exists.
127 // All the other properties are set only in the node form.
128 // This half of this if statement handles the case whereby a video exists, has not been overwritten, but some metadata may have been changed.
129
130 foreach ($node->twistage_edit as $vid => $edit) {
131 //if ($node->twistage_video && !twistage_publish_upload_exists()) {
132 $video = twistage_get_video($vid, $edit['twistage_pid']);
133 $query = '';
134
135 $availability = $edit['twistage_availability'] ? "available" : "hidden";
136 if ($availability != $video->availability) {
137 $query .= "&video[available_for_display]=" . $availability;
138 }
139
140 if ($edit['twistage_title'] != $video->title) {
141 $query .= "&video[title]=" . urlencode($edit['twistage_title']);
142 }
143
144 if ($edit['description'] != $video->description) {
145 $query .= "&video[description]=" . urlencode($edit['twistage_description']);
146 }
147
148 // An unfortunate workaround for the fact that trim() does not operate on arrays.
149 $in = explode(',', $edit['twistage_tags']);
150 $tags = array();
151 foreach ($in as $tag) {
152 $tags[] = trim($tag);
153 }
154
155 if ($tags != $video->tags) {
156 $send = array();
157 foreach ($tags as $tag) {
158 $send[] = urlencode($tag);
159 }
160 $query .= "&video[tag_list]=" . implode(',', $send);
161 }
162
163 // Video exists; check to see if we need to turn it off via the make avail. checkbox
164 if ($query) {
165 $profile = twistage_get_profile($video->pid);
166 $signature = _twistage_authenticate($profile->site_key, $profile->site_username);
167 $url = "http://service.twistage.com./videos/" . $video->vid . "?signature=" . urlencode($signature) . $query;
168 $f = tmpfile();
169 $ch = curl_init();
170 curl_setopt($ch, CURLOPT_URL, $url);
171 curl_setopt($ch, CURLOPT_PUT, true);
172 curl_setopt($ch, CURLOPT_INFILE, $f);
173 curl_setopt($ch, CURLOPT_INFILESIZE, 0);
174 curl_setopt($ch, CURLOPT_TIMEOUT, 900);
175 curl_setopt($ch, CURLOPT_CONNECTIONTIMEOUT, 30);
176 curl_setopt($ch, CURLOPT_FAILONERROR, false);
177 curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
178 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
179 curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
180 curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
181 $ret = curl_exec($ch);
182 fclose($f);
183 }
184 // This half of the if statement handles adding a new video to Twistage.
185 // It doesn't matter here if an old video exists -- the node-video association table will be updated in hook_twistage_api below
186 // after the video is done processing/transcoding. The old video will just remain stored on Twistage until an admin chooses to delete it.
187 }
188 // TODO: perform some cursory check on MIME types before forging ahead with the video
189
190 // This will be filled in the for loop.
191 $elements = array('add' => array('publish-profile' => 'development', 'list' => array()));
192 $proc = false;
193
194 foreach ($node->twistage_upload as $seq => $upload) {
195 // Break out if there's no upload.
196 if (!twistage_publish_upload_exists($seq)) {
197 continue;
198 }
199 $proc = true;
200
201 // First, move the uploaded file to a temp files directory, since Twistage must get the video over HTTP.
202 if (!is_dir(file_directory_path() . '/twistage_temp')) {
203 mkdir(file_directory_path() . '/twistage_temp');
204 }
205 $info = file_save_upload('twistage_upload._' . $seq, file_directory_path() . '/twistage_temp');
206 $url = url($info->filepath, NULL, NULL, TRUE);
207
208 $tags = explode(',', $upload['twistage_tags']);
209 $tags_arr = array();
210 foreach ($tags as $t) {
211 $tags_arr[] = array('key' => 'tag', 'value' => trim($t));
212 }
213
214 // Create an array to represent the XML we must submit to Twistage.
215 $elements['add']['list'][] = array(
216 'key' => 'entry',
217 'value' => array(
218 'src' => $url,
219 'title' => $upload['twistage_title'],
220 'description' => $upload['twistage_description'],
221 'tags' => $tags_arr,
222 'customdata' => array(
223 'nid' => $node->nid,
224 ),
225 ),
226 );
227 }
228 if ($proc) {
229 $profile = twistage_get_profile($upload['twistage_pid']);
230 $signature = _twistage_authenticate($profile->site_key, $profile->site_username);
231 $post = '<?xml version="1.0" encoding="UTF-8"?>' . "\n" . format_xml_elements($elements);
232 $header = array("Content-type: text/xml");
233 $ch = curl_init();
234 curl_setopt($ch, CURLOPT_URL, "http://service.twistage.com/videos/create_many?signature=" . $signature);
235 curl_setopt($ch, CURLOPT_TIMEOUT, 900);
236 curl_setopt($ch, CURLOPT_CONNECTIONTIMEOUT, 30);
237 curl_setopt($ch, CURLOPT_FAILONERROR, false);
238 curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
239 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
240 curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
241 curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
242 curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
243 curl_setopt($ch, CURLOPT_POST);
244 curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
245 $ret = curl_exec($ch);
246 print_r($post);
247 print "ret: $ret\n";
248 curl_close($ch);
249 }
250 break;
251
252 case 'view':
253 // Make the video available in the node display.
254 $node->content['twistage_video'] = array('#value' => '', '#weight' => -1);
255 foreach($node->twistage_video as $video) {
256 $profile = twistage_get_profile($video->pid);
257 $preroll = twistage_get_preroll_video($video->pid);
258 // theme_twistage_video will return nothing if the video is still processing or has been marked unavailable.
259 // The default weight will place it just above the node body, but of course themes can override this and show the video code wherever they like.
260 $node->content['twistage_video']['#value'] .= theme('twistage_video', $video, $preroll, $profile->preroll_url, $profile->width, $profile->height, false);
261 }
262 break;
263 }
264 }
265
266 /**
267 * Implementation of hook_twistage_api (see twistage.module)
268 * Note that here we will get $video->nid in the event that it was passed down from Twistage.
269 * This indicates we've seeing the results of a one-click publish when we submitted the video back in hook_nodeapi.
270 */
271 function twistage_publish_twistage_api($op, $video) {
272 // All we're interested in here is to see whether we need to maintain/delete node/video associations.
273 switch ($op) {
274 case 'update':
275 case 'create':
276 if ($video->nid) {
277 //db_query("DELETE FROM {twistage_video_node} WHERE nid=%d", $video->nid);
278 db_query("INSERT INTO {twistage_video_node} (nid, pid, vid) VALUES (%d, %d, '%s')", $video->nid, $video->pid, $video->vid);
279 }
280 break;
281
282 case 'delete':
283 db_query("DELETE FROM {twistage_video_node} WHERE vid='%s' AND pid=%d", $video->vid, $video->pid);
284 break;
285 }
286 }
287
288 function twistage_publish_admin_form($pid) {
289 $form = array();
290
291 $form['info'] = array(
292 '#value' => t('Select the content types which will allow uploading to this Twistage site.'),
293 );
294
295
296 $result = db_query("SELECT type,name FROM {node_type} WHERE 1");
297 $types = array();
298 while ($type = db_fetch_object($result)) {
299 $types[$type->type] = $type->name;
300 }
301
302 $profile = twistage_get_profile($pid);
303 $selected = unserialize($profile->publish_types);
304
305 $form['pid'] = array(
306 '#type' => 'hidden',
307 '#value' => $pid,
308 );
309
310 $form['types'] = array(
311 '#type' => 'checkboxes',
312 '#title' => t('Content types'),
313 '#options' => $types,
314 '#default_value' => $selected
315 );
316
317 return system_settings_form($form);
318 }
319
320 function twistage_publish_admin_form_submit($form_id, $form_values) {
321 $profile = twistage_get_profile($form_values['pid']);
322 db_query("UPDATE {twistage_profiles} SET publish_types='%s' WHERE pid=%d", serialize($form_values['types']), $form_values['pid']);
323 return 'admin/settings/twistage';
324 }
325
326 function twistage_publish_upload_exists($seq) {
327 if ($_FILES['files']['name']['twistage_upload_' . $seq]) {
328 return true;
329 } else {
330 return false;
331 }
332 }
333
334 function twistage_publish_get_video_by_nid($nid) {
335 $result = db_fetch_object(db_query("SELECT * FROM {twistage_video_node} WHERE nid=%d", $nid));
336 return twistage_get_video($result->vid, $result->pid);
337 }
338
339 function twistage_publish_get_videos_by_nid($nid) {
340 $result = db_query("SELECT * FROM {twistage_video_node} WHERE nid=%d", $nid);
341 $videos = array();
342 while ($video = db_fetch_object($result)) {
343 $videos[] = $video;
344 }
345 return $videos;
346 }
347
348 function twistage_publish_form_element($profiles, $seq = 0, $video = NULL) {
349 $form = array();
350
351 $form = array(
352 '#tree' => TRUE,
353 );
354
355 $form['notice'] = array(
356 '#value' => t('<p><b>Video note</b>: All video uploads and edits must be sent to Twistage and processed before taking effect locally. There will be a brief delay before changes are visible locally.'),
357 );
358
359 $avail = $video->availability == 'available' ? true : false;
360 $form['twistage_availability'] = array(
361 '#type' => 'checkbox',
362 '#title' => t('Make video available for viewing'),
363 '#default_value' => ($video) ? $avail : true,
364 );
365
366 $form['twistage_title'] = array(
367 '#type' => 'textfield',
368 '#title' => t('Video Title'),
369 '#default_value' => $video->title,
370 );
371
372 $form['twistage_tags'] = array(
373 '#type' => 'textfield',
374 '#title' => t('Video Tags'),
375 '#description' => t('Separate tags with commas'),
376 '#default_value' => implode(',', $video->tags),
377 );
378
379 $form['twistage_description'] = array(
380 '#type' => 'textarea',
381 '#title' => t('Video Description'),
382 '#default_value' => $video->description,
383 );
384
385 if (!$video) {
386 // These fields are only to be shown on nodes with no prior video uploaded; we don't want the user thinking they can change them later.
387 $form['twistage_pid'] = array(
388 '#type' => 'select',
389 '#title' => t('Profile'),
390 '#description' => t('Select the Twistage site profile to add this video to.'),
391 '#options' => $profiles,
392 );
393
394 $form['twistage_file_0'] = array(
395 '#type' => 'file',
396 '#title' => t('Select Video File'),
397 );
398
399 $form['more'] = array(
400 '#value' => '<a class="twistage-add-more">Add another video...</a>',
401 );
402 } else {
403 // Get current video name (also the nid of this node will be available, since existing video means existing node)
404 $existing = $video;
405 $existing_profile = twistage_get_profile($existing->pid);
406 $form['info'] = array(
407 '#value' => t('<p><b>Current video</b>: @title</p>', array('@title' => $existing->title)),
408 );
409 $form['info2'] = array(
410 '#value' => t('<p><b>Current profile</b>: @profile</p>', array('@profile' => $existing_profile->name)),
411 );
412
413 $form['twistage_vid'] = array(
414 '#type' => 'hidden',
415 '#value' => $video->vid,
416 );
417
418 /*$form['twistage_file_0'] = array(
419 '#type' => 'file',
420 '#title' => t('Upload a new video'),
421 '#description' => t('This will overwrite the old video. Leave this field blank to keep the old video as-is.'),
422 );*/
423 }
424
425 return $form;
426 }

  ViewVC Help
Powered by ViewVC 1.1.2