Parent Directory
|
Revision Log
|
Revision Graph
Adding multi-video posting functionality, and a few bug fixes-
| 1 | <?php |
| 2 | |
| 3 | /** |
| 4 | * Twistage Module -- a Drupal module to interact with the Twistage API |
| 5 | * Copyright 2008 Matt Johnson, Observer Media Group |
| 6 | * License: GPL V.2 |
| 7 | * Read the license here: http://www.gnu.org/licenses/old-licenses/gpl-2.0.html |
| 8 | */ |
| 9 | |
| 10 | /** |
| 11 | * Implementation of hook_menu |
| 12 | */ |
| 13 | function twistage_menu($may_cache) { |
| 14 | $items = array(); |
| 15 | |
| 16 | if (!$may_cache) { |
| 17 | $items[] = array( |
| 18 | 'path' => 'admin/settings/twistage', |
| 19 | 'title' => t('Twistage settings'), |
| 20 | 'description' => t('Manage Twistage integration.'), |
| 21 | 'type' => MENU_NORMAL_ITEM, |
| 22 | 'callback' => 'twistage_settings_page', |
| 23 | 'access' => user_access('administer twistage'), |
| 24 | ); |
| 25 | |
| 26 | $items[] = array( |
| 27 | 'path' => 'admin/settings/twistage/profile', |
| 28 | 'title' => t('Twistage Profile'), |
| 29 | 'type' => MENU_CALLBACK, |
| 30 | 'callback' => 'drupal_get_form', |
| 31 | 'callback arguments' => array('twistage_profile_admin_form', arg(4)), |
| 32 | 'access' => user_access('administer twistage'), |
| 33 | ); |
| 34 | |
| 35 | $items[] = array( |
| 36 | 'path' => 'admin/settings/twistage/order', |
| 37 | 'title' => t('Twistage Play Order'), |
| 38 | 'type' => MENU_CALLBACK, |
| 39 | 'callback' => 'drupal_get_form', |
| 40 | 'callback arguments' => array('twistage_order_admin_form', arg(4)), |
| 41 | 'access' => user_access('administer twistage'), |
| 42 | ); |
| 43 | |
| 44 | $items[] = array( |
| 45 | 'path' => 'admin/settings/twistage/list', |
| 46 | 'title' => t('Manage profiles'), |
| 47 | 'type' => MENU_DEFAULT_LOCAL_TASK, |
| 48 | 'weight' => -5, |
| 49 | ); |
| 50 | |
| 51 | $items[] = array( |
| 52 | 'path' => 'admin/settings/twistage/global', |
| 53 | 'title' => t('Global settings'), |
| 54 | 'type' => MENU_LOCAL_TASK, |
| 55 | 'callback' => 'drupal_get_form', |
| 56 | 'callback arguments' => array('twistage_global_admin_form'), |
| 57 | 'weight' => -2, |
| 58 | ); |
| 59 | |
| 60 | // Workaround for problems with adding MENU_LOCAL_TASKs to this menu in an add-on module... |
| 61 | if (module_exists('twistage_syndicate')) { |
| 62 | $items[] = array( |
| 63 | 'path' => 'admin/settings/twistage/synconfig', |
| 64 | 'title' => t('Syndication settings'), |
| 65 | 'type' => MENU_LOCAL_TASK, |
| 66 | 'callback' => 'drupal_get_form', |
| 67 | 'callback arguments' => array('twistage_syndicate_admin_form'), |
| 68 | ); |
| 69 | } |
| 70 | |
| 71 | $items[] = array( |
| 72 | 'path' => 'admin/settings/twistage/create', |
| 73 | 'title' => t('Create profile'), |
| 74 | 'type' => MENU_LOCAL_TASK, |
| 75 | 'callback' => 'drupal_get_form', |
| 76 | 'callback arguments' => array('twistage_profile_admin_form', 0), |
| 77 | 'access' => user_access('administer twistage'), |
| 78 | 'weight' => 5, |
| 79 | ); |
| 80 | |
| 81 | $items[] = array( |
| 82 | 'path' => 'admin/settings/twistage/sync', |
| 83 | 'title' => t('Sync Twistage videos'), |
| 84 | 'type' => MENU_CALLBACK, |
| 85 | 'callback' => 'twistage_sync_videos', |
| 86 | 'access' => user_access('administer twistage'), |
| 87 | ); |
| 88 | |
| 89 | $items[] = array( |
| 90 | 'path' => 'twistage/hook', |
| 91 | 'type' => MENU_CALLBACK_ITEM, |
| 92 | 'callback' => 'twistage_process_hook', |
| 93 | 'access' => user_access('access content'), |
| 94 | ); |
| 95 | |
| 96 | $items[] = array( |
| 97 | 'path' => 'twistage/preroll/hook', |
| 98 | 'type' => MENU_CALLBACK_ITEM, |
| 99 | 'callback' => 'twistage_preroll_hook', |
| 100 | 'access' => user_access('access content'), |
| 101 | ); |
| 102 | } |
| 103 | |
| 104 | twistage_add_page_menu_items($items); |
| 105 | |
| 106 | return $items; |
| 107 | } |
| 108 | |
| 109 | /** |
| 110 | * Implementation of hook_perm |
| 111 | */ |
| 112 | function twistage_perm() { |
| 113 | return array('administer twistage', 'view twistage pages'); |
| 114 | } |
| 115 | |
| 116 | /** |
| 117 | * Implementation of hook_block |
| 118 | */ |
| 119 | function twistage_block($op = 'list', $delta = 0, $edit = array()) { |
| 120 | switch ($op) { |
| 121 | case 'list': |
| 122 | $blocks = array(); |
| 123 | $result = db_query("SELECT pid, name FROM {twistage_profiles} WHERE type='block'"); |
| 124 | while ($profile = db_fetch_object($result)) { |
| 125 | $blocks[$profile->pid] = array('info' => 'Twistage: ' . $profile->name); |
| 126 | } |
| 127 | return $blocks; |
| 128 | case 'view': |
| 129 | $profile = twistage_get_profile($delta); |
| 130 | return array('subject' => $profile->name, 'content' => theme('twistage_block', $delta)); |
| 131 | } |
| 132 | } |
| 133 | |
| 134 | /** |
| 135 | * Function to generate menu item arrays for page profiles. |
| 136 | */ |
| 137 | function twistage_add_page_menu_items(&$items) { |
| 138 | $result = db_query("SELECT * FROM {twistage_profiles} WHERE type='page'"); |
| 139 | |
| 140 | while ($profile = db_fetch_object($result)) { |
| 141 | $items[] = array( |
| 142 | 'path' => $profile->path, |
| 143 | 'title' => $profile->description, |
| 144 | 'type' => MENU_CALLBACK, |
| 145 | 'callback' => 'twistage_profile_page', |
| 146 | 'callback arguments' => array($profile->name), |
| 147 | 'access' => user_access('view twistage pages'), |
| 148 | ); |
| 149 | } |
| 150 | } |
| 151 | |
| 152 | /** |
| 153 | * Function to generate output for profiles with 'page' type. |
| 154 | * Pipe through a theme function to let themers override this easily if they like. |
| 155 | * In the New York Observer's use case, we need most pages to actually be nodes in order |
| 156 | * to maintain block control, ads, etc, so it's useful to embed Twistage content by putting the following |
| 157 | * into a php filter in the node body... |
| 158 | * <?php print theme('twistage_page', 'profile_name'); ?> |
| 159 | * ...rather than directing web users directly to $profile->path. |
| 160 | */ |
| 161 | function twistage_profile_page($name) { |
| 162 | return theme('twistage_page', $name); |
| 163 | } |
| 164 | |
| 165 | /** |
| 166 | * Function to generate the admin form |
| 167 | */ |
| 168 | function twistage_profile_admin_form($pid) { |
| 169 | $form = array(); |
| 170 | |
| 171 | if (!is_numeric($pid)) { |
| 172 | drupal_goto('admin/settings/twistage'); |
| 173 | } |
| 174 | |
| 175 | if ($pid) { |
| 176 | $profile = twistage_get_profile($pid); |
| 177 | } else { |
| 178 | $profile = new stdClass; // will remain empty |
| 179 | } |
| 180 | |
| 181 | $form['pid'] = array( |
| 182 | '#type' => 'hidden', |
| 183 | '#value' => $pid, |
| 184 | ); |
| 185 | |
| 186 | $form['profile'] = array( |
| 187 | '#type' => 'fieldset', |
| 188 | '#title' => t('Profile settings'), |
| 189 | ); |
| 190 | |
| 191 | $form['profile']['name'] = array( |
| 192 | '#type' => 'textfield', |
| 193 | '#title' => t('Profile name'), |
| 194 | '#description' => t('An machine-readable Drupal identifier for this Twistage player.'), |
| 195 | '#default_value' => $profile->name, |
| 196 | '#required' => TRUE, |
| 197 | ); |
| 198 | |
| 199 | $form['profile']['description'] = array( |
| 200 | '#type' => 'textfield', |
| 201 | '#title' => t('Profile description'), |
| 202 | '#description' => t('A description of this profile (for public display).'), |
| 203 | '#default_value' => $profile->description, |
| 204 | '#required' => TRUE, |
| 205 | ); |
| 206 | |
| 207 | $form['profile']['company'] = array( |
| 208 | '#type' => 'textfield', |
| 209 | '#title' => t('Company ID'), |
| 210 | '#description' => t('This can be found in the "Company Info" section of the "Accounts" tab in the Twistage admin area.'), |
| 211 | '#default_value' => $profile->company, |
| 212 | '#required' => TRUE, |
| 213 | ); |
| 214 | |
| 215 | $form['profile']['site_name'] = array( |
| 216 | '#type' => 'textfield', |
| 217 | '#title' => t('Site name'), |
| 218 | '#description' => t('The name of the Twistage site associated with this profile. This can be found in the "Sites" section of the "Settings" tab.'), |
| 219 | '#default_value' => $profile->site_name, |
| 220 | '#required' => TRUE, |
| 221 | ); |
| 222 | |
| 223 | $form['profile']['site_key'] = array( |
| 224 | '#type' => 'textfield', |
| 225 | '#title' => t('Site license key'), |
| 226 | '#description' => t('This can be also found in the "Sites" section of the "Settings" tab.'), |
| 227 | '#default_value' => $profile->site_key, |
| 228 | '#required' => TRUE, |
| 229 | ); |
| 230 | |
| 231 | $form['profile']['site_username'] = array( |
| 232 | '#type' => 'textfield', |
| 233 | '#title' => t('Site publishing username'), |
| 234 | '#description' => t('The username you use to log in to Twistage. Needed only for publishing videos through your Drupal site.'), |
| 235 | '#default_value' => $profile->site_username, |
| 236 | ); |
| 237 | |
| 238 | $form['profile']['type'] = array( |
| 239 | '#type' => 'radios', |
| 240 | '#title' => t('Show player as a'), |
| 241 | '#options' => array('page' => t('Page'), 'block' => t('Block')), |
| 242 | '#default_value' => $profile->type, |
| 243 | ); |
| 244 | |
| 245 | $form['profile']['page'] = array( |
| 246 | '#type' => 'fieldset', |
| 247 | '#title' => t('Page settings'), |
| 248 | ); |
| 249 | |
| 250 | $form['profile']['page']['path'] = array( |
| 251 | '#type' => 'textfield', |
| 252 | '#title' => t('Path'), |
| 253 | '#description' => t('Only valid for page profiles'), |
| 254 | '#default_value' => $profile->path, |
| 255 | '#weight' => 1, |
| 256 | ); |
| 257 | |
| 258 | $form['profile']['page']['page_header'] = array( |
| 259 | '#type' => 'textarea', |
| 260 | '#title' => t('Page header'), |
| 261 | '#default_value' => $profile->page_header, |
| 262 | '#weight' => 2, |
| 263 | ); |
| 264 | |
| 265 | $form['profile']['page']['page_header_format'] = filter_form($profile->page_header_format, 3, array('page_header_format')); |
| 266 | |
| 267 | $form['profile']['page']['page_footer'] = array( |
| 268 | '#type' => 'textarea', |
| 269 | '#title' => t('Page footer'), |
| 270 | '#default_value' => $profile->page_footer, |
| 271 | '#weight' => 4 |
| 272 | ); |
| 273 | |
| 274 | $form['profile']['page']['page_footer_format'] = filter_form($profile->page_footer_format, 5, array('page_footer_format')); |
| 275 | |
| 276 | $form['profile']['page']['show_table'] = array( |
| 277 | '#type' => 'checkbox', |
| 278 | '#title' => t('Show table of videos'), |
| 279 | '#description' => t('Allow users to select other videos in the profile to view from a table on the page'), |
| 280 | '#default_value' => $profile->show_table, |
| 281 | '#weight' => 6, |
| 282 | ); |
| 283 | |
| 284 | if($profile->pid) { |
| 285 | $form['profile']['sync'] = array( |
| 286 | '#value' => t('<p>If you have set up your site to receive pings from Twistage, the local databse of videos will be updated continuously.</p> |
| 287 | <p>You can also <a href="/admin/settings/twistage/sync/' . $profile->pid . '">manually sync now</a>.</p>'), |
| 288 | ); |
| 289 | } |
| 290 | |
| 291 | $form['player'] = array( |
| 292 | '#type' => 'fieldset', |
| 293 | '#title' => t('Player settings'), |
| 294 | ); |
| 295 | |
| 296 | $form['player']['width'] = array( |
| 297 | '#type' => 'textfield', |
| 298 | '#title' => t('Player width'), |
| 299 | '#size' => 5, |
| 300 | '#default_value' => $profile->width, |
| 301 | ); |
| 302 | |
| 303 | $form['player']['height'] = array( |
| 304 | '#type' => 'textfield', |
| 305 | '#title' => t('Player height'), |
| 306 | '#size' => 5, |
| 307 | '#default_value' => $profile->height, |
| 308 | ); |
| 309 | |
| 310 | $form['player']['autoplay'] = array( |
| 311 | '#type' => 'checkbox', |
| 312 | '#title' => t('Autoplay'), |
| 313 | '#description' => t('Auto-start video playback once the page loads'), |
| 314 | '#default_value' => $profile->autoplay, |
| 315 | ); |
| 316 | |
| 317 | $form['preroll'] = array( |
| 318 | '#type' => 'fieldset', |
| 319 | '#title' => t('Pre-roll settings'), |
| 320 | ); |
| 321 | |
| 322 | $form['preroll']['info'] = array( |
| 323 | '#value' => t('Some applications will want to show a mandatory "pre-roll" video before the actual payload video (generally for ads). To use pre-rolls, enter a company ID and site license key from which to draw pre-roll clips. Note that they may be the same as your primary company and key.'), |
| 324 | ); |
| 325 | |
| 326 | $form['preroll']['preroll_company'] = array( |
| 327 | '#type' => 'textfield', |
| 328 | '#title' => t('Pre-roll company ID'), |
| 329 | '#default_value' => $profile->preroll_company, |
| 330 | ); |
| 331 | |
| 332 | $form['preroll']['preroll_site_name'] = array( |
| 333 | '#type' => 'textfield', |
| 334 | '#title' => t('Pre-roll site name'), |
| 335 | '#default_value' => $profile->preroll_site_name, |
| 336 | ); |
| 337 | |
| 338 | $form['preroll']['preroll_site_key'] = array( |
| 339 | '#type' => 'textfield', |
| 340 | '#title' => t('Pre-roll site license key'), |
| 341 | '#default_value' => $profile->preroll_site_key, |
| 342 | ); |
| 343 | |
| 344 | $form['preroll']['preroll_url'] = array( |
| 345 | '#type' => 'textfield', |
| 346 | '#title' => t('Pre-roll video link'), |
| 347 | '#default_value' => $profile->preroll_url, |
| 348 | '#maxlength' => 1024, |
| 349 | ); |
| 350 | |
| 351 | $form['hook'] = array( |
| 352 | '#type' => 'fieldset', |
| 353 | '#title' => t('Hook settings'), |
| 354 | ); |
| 355 | |
| 356 | $form['hook']['info'] = array( |
| 357 | '#value' => t('<p>To receive "pings" from Twistage, you must create a username and password that Twistage will use to send data to your site.</p> |
| 358 | <p>While it is technically possible to have a hook URL with no authentication, this module does not allow such a configuration for security reasons. If either of these fields are blank, pings will be acknowledged.</p>'), |
| 359 | ); |
| 360 | |
| 361 | |
| 362 | if ($profile->username && $profile->password) { |
| 363 | $form['hook']['url'] = array( |
| 364 | '#value' => t('<p>You have entered a username and password. You should set the following as your Twistage hook URL:</p> |
| 365 | <p><i>http://' . $_SERVER['SERVER_NAME'] . '/twistage/hook/' . $profile->name. '/' . $profile->username . '/' . $profile->password . '</i></p>'), |
| 366 | ); |
| 367 | } else { |
| 368 | $form['hook']['url'] = array( |
| 369 | '#value' => t('<p>You have not saved a username and password yet. A hook URL will be available when you have.</p>'), |
| 370 | ); |
| 371 | } |
| 372 | |
| 373 | |
| 374 | |
| 375 | $form['hook']['username'] = array( |
| 376 | '#type' => 'textfield', |
| 377 | '#title' => t('Username'), |
| 378 | '#default_value' => $profile->username, |
| 379 | ); |
| 380 | |
| 381 | $form['hook']['password'] = array( |
| 382 | '#type' => 'textfield', |
| 383 | '#title' => t('Password'), |
| 384 | '#description' => t('(will be shown in clear text)'), |
| 385 | '#default_value' => $profile->password, |
| 386 | ); |
| 387 | |
| 388 | return system_settings_form($form); |
| 389 | } |
| 390 | |
| 391 | /** |
| 392 | * Function to validate the admin form |
| 393 | */ |
| 394 | function twistage_profile_admin_form_validate($form_id, $form_values) { |
| 395 | if (preg_match('/[^a-zA-Z0-9_]/', $form_values['name'])) { |
| 396 | form_set_error('name', 'Name may contain only alphanumeric characters and underscores.'); |
| 397 | } |
| 398 | |
| 399 | if (!is_numeric($form_values['width'])) { |
| 400 | form_set_error('width', 'Non-numeric width entered.'); |
| 401 | } |
| 402 | |
| 403 | if (!is_numeric($form_values['height'])) { |
| 404 | form_set_error('height', 'Non-numeric height entered.'); |
| 405 | } |
| 406 | } |
| 407 | |
| 408 | /** |
| 409 | * Function to process the admin form |
| 410 | */ |
| 411 | function twistage_profile_admin_form_submit($form_id, $form_values) { |
| 412 | if ($form_values['pid']) { |
| 413 | // Update |
| 414 | db_query("UPDATE {twistage_profiles} SET name='%s', description='%s', type='%s', path='%s', company='%s', site_name='%s', site_key='%s', site_username='%s', width=%d, height=%d, show_table=%d, autoplay=%d, page_header='%s', page_header_format=%d, page_footer='%s', page_footer_format=%d, preroll_company='%s', preroll_site_name='%s', preroll_site_key='%s', preroll_url='%s', username='%s', password='%s' WHERE pid=%d", |
| 415 | $form_values['name'], |
| 416 | $form_values['description'], |
| 417 | $form_values['type'], |
| 418 | $form_values['path'], |
| 419 | $form_values['company'], |
| 420 | $form_values['site_name'], |
| 421 | $form_values['site_key'], |
| 422 | $form_values['site_username'], |
| 423 | $form_values['width'], |
| 424 | $form_values['height'], |
| 425 | $form_values['show_table'], |
| 426 | $form_values['autoplay'], |
| 427 | $form_values['page_header'], |
| 428 | $form_values['page_header_format'], |
| 429 | $form_values['page_footer'], |
| 430 | $form_values['page_footer_format'], |
| 431 | $form_values['preroll_company'], |
| 432 | $form_values['preroll_site_name'], |
| 433 | $form_values['preroll_site_key'], |
| 434 | $form_values['preroll_url'], |
| 435 | $form_values['username'], |
| 436 | $form_values['password'], |
| 437 | $form_values['pid']); |
| 438 | drupal_set_message('Updated profile "' . $form_values['name'] . '".'); |
| 439 | twistage_sync_videos($form_values['pid']); |
| 440 | } else { |
| 441 | // Insert |
| 442 | $pid = db_next_id("{twistage_profiles}_pid"); |
| 443 | db_query("INSERT INTO {twistage_profiles} (pid, name, description, type, path, company, site_name, site_key, site_username, width, height, show_table, autoplay, page_header, page_header_format, page_footer, page_footer_format, preroll_company, preroll_site_name, preroll_site_key, preroll_url, username, password) |
| 444 | VALUES (%d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, %d, %d, '%s', %d, '%s', %d, '%s', '%s', '%s', '%s', '%s', '%s')", |
| 445 | $pid, |
| 446 | $form_values['name'], |
| 447 | $form_values['description'], |
| 448 | $form_values['type'], |
| 449 | $form_values['path'], |
| 450 | $form_values['company'], |
| 451 | $form_values['site_name'], |
| 452 | $form_values['site_key'], |
| 453 | $form_values['site_username'], |
| 454 | $form_values['width'], |
| 455 | $form_values['height'], |
| 456 | $form_values['show_table'], |
| 457 | $form_values['autoplay'], |
| 458 | $form_values['page_header'], |
| 459 | $form_values['page_header_format'], |
| 460 | $form_values['page_footer'], |
| 461 | $form_values['page_footer_format'], |
| 462 | $form_values['preroll_company'], |
| 463 | $form_values['preroll_site_name'], |
| 464 | $form_values['preroll_site_key'], |
| 465 | $form_values['preroll_url'], |
| 466 | $form_values['username'], |
| 467 | $form_values['password']); |
| 468 | drupal_set_message('Created profile "' . $form_values['name'] . '".'); |
| 469 | twistage_sync_videos($pid); |
| 470 | } |
| 471 | |
| 472 | if ($form_values['type'] == 'page') { |
| 473 | menu_rebuild(); |
| 474 | } |
| 475 | |
| 476 | return 'admin/settings/twistage'; |
| 477 | } |
| 478 | |
| 479 | /** |
| 480 | * Generate the play order form |
| 481 | */ |
| 482 | function twistage_order_admin_form($pid = 0) { |
| 483 | if (!$pid) { |
| 484 | drupal_goto('admin/settings/twistage'); |
| 485 | } |
| 486 | |
| 487 | $profile = twistage_get_profile($pid); |
| 488 | |
| 489 | $form = array(); |
| 490 | |
| 491 | $form['info'] = array( |
| 492 | '#value' => t('Videos not assigned a play order will not be shown in the player.'), |
| 493 | ); |
| 494 | |
| 495 | $form['pid'] = array( |
| 496 | '#type' => 'hidden', |
| 497 | '#value' => $profile->pid, |
| 498 | ); |
| 499 | |
| 500 | $form['header'] = array( |
| 501 | '#type' => 'value', |
| 502 | '#value' => array( |
| 503 | t('Order'), |
| 504 | t('Video title'), |
| 505 | t('Video ID'), |
| 506 | ), |
| 507 | ); |
| 508 | |
| 509 | $result = db_query("SELECT vid, title, play_order, (play_order = 0) AS i FROM {twistage_videos} WHERE site_key='%s' AND pid=%d AND availability='available' ORDER BY i, play_order", $profile->site_key, $profile->pid); |
| 510 | |
| 511 | while ($row = db_fetch_object($result)) { |
| 512 | $elem = "video_" . $row->vid; |
| 513 | $form['data']['play_order'][$elem] = array( |
| 514 | '#type' => 'textfield', |
| 515 | '#size' => 1, |
| 516 | '#default_value' => $row->play_order ? $row->play_order : "", |
| 517 | ); |
| 518 | |
| 519 | $form['data']['title'][$elem] = array( |
| 520 | '#value' => $row->title, |
| 521 | ); |
| 522 | |
| 523 | $form['data']['vid'][$elem] = array( |
| 524 | '#value' => $row->vid, |
| 525 | ); |
| 526 | } |
| 527 | |
| 528 | // Preroll, if applicable |
| 529 | if ($profile->preroll_company && $profile->preroll_site_name && $profile->preroll_site_key) { |
| 530 | $result = db_query("SELECT vid, title, play_order FROM {twistage_videos} WHERE site_key='%s'", $profile->preroll_site_key); |
| 531 | |
| 532 | $prerolls = array(0 => 'None'); |
| 533 | $default = 0; |
| 534 | while ($row = db_fetch_object($result)) { |
| 535 | $prerolls[$row->vid] = $row->title . " (" . $row->vid . ")"; |
| 536 | if ($row->play_order == 1) { |
| 537 | $default = $row->vid; |
| 538 | } |
| 539 | } |
| 540 | |
| 541 | $form['preroll'] = array( |
| 542 | '#type' => 'radios', |
| 543 | '#title' => t('Select pre-roll video'), |
| 544 | '#options' => $prerolls, |
| 545 | '#default_value' => $default, |
| 546 | ); |
| 547 | } |
| 548 | |
| 549 | return system_settings_form($form); |
| 550 | } |
| 551 | |
| 552 | /** |
| 553 | * Theme function for play order form |
| 554 | */ |
| 555 | function theme_twistage_order_admin_form($form) { |
| 556 | drupal_add_css(drupal_get_path('module', 'twistage') . '/twistage.css', 'module', 'all', FALSE); |
| 557 | |
| 558 | $rows = array(); |
| 559 | |
| 560 | foreach (element_children($form['data']['play_order']) as $key) { |
| 561 | $row = array(); |
| 562 | $row['data'][0] = array('data' => drupal_render($form['data']['play_order'][$key]), 'class' => 'twistage-order-td'); |
| 563 | $row['data'][1] = drupal_render($form['data']['title'][$key]); |
| 564 | $row['data'][2] = drupal_render($form['data']['vid'][$key]); |
| 565 | $rows[] = $row; |
| 566 | } |
| 567 | |
| 568 | $output = theme('table', $form['header']['#value'], $rows, array('id' => 'twistage-order-table')); |
| 569 | $output .= drupal_render($form); |
| 570 | |
| 571 | return $output; |
| 572 | } |
| 573 | |
| 574 | /** |
| 575 | * Valid play order form |
| 576 | */ |
| 577 | function twistage_order_admin_form_validate($form_id, $form_values) { |
| 578 | foreach ($form_values as $key => $val) { |
| 579 | if (substr($key, 0, 5) == "video" && $val && !is_numeric($val)) { |
| 580 | form_set_error($key, 'Non-numeric order for video ' . substr($key, 6)); |
| 581 | } |
| 582 | } |
| 583 | } |
| 584 | |
| 585 | /** |
| 586 | * Process play order form |
| 587 | */ |
| 588 | function twistage_order_admin_form_submit($form_id, $form_values) { |
| 589 | $profile = twistage_get_profile($form_values['pid']); |
| 590 | |
| 591 | // Store old play orders to compare with new ones |
| 592 | $orders = array(); |
| 593 | $result = db_query("SELECT vid, play_order FROM {twistage_videos} WHERE pid=%d AND site_key='%s'", $profile->pid, $profile->site_key); |
| 594 | while ($video = db_fetch_object($result)) { |
| 595 | $orders[$video->vid] = $video->play_order; |
| 596 | } |
| 597 | |
| 598 | // First, wipe out all existing play orders |
| 599 | db_query("UPDATE {twistage_videos} SET play_order=0 WHERE pid=%d AND site_key='%s'", $profile->pid, $profile->site_key); |
| 600 | |
| 601 | foreach ($form_values as $key => $val) { |
| 602 | if (substr($key, 0, 5) == "video") { |
| 603 | $vid = substr($key, 6); |
| 604 | if ($val) { |
| 605 | db_query("UPDATE {twistage_videos} SET play_order=%d WHERE vid='%s' AND pid=%d", $val, $vid, $profile->pid); |
| 606 | if (!$orders[$vid]) { |
| 607 | // Video was not previously in the play order, but it is now. Fire a "hook_twistage_order" to let other modules act |
| 608 | foreach (module_implements('twistage_api') as $module) { |
| 609 | $func = $module . '_twistage_api'; |
| 610 | $video = twistage_get_video($vid, $profile->pid); |
| 611 | // TODO reenble when syn is working better |
| 612 | $func('order add', $video); |
| 613 | } |
| 614 | } |
| 615 | } |
| 616 | } |
| 617 | } |
| 618 | |
| 619 | // Reset play order on all prerolls |
| 620 | db_query("UPDATE {twistage_videos} SET play_order=0 WHERE pid=%d AND site_key='%s'", $profile->pid, $profile->preroll_site_key); |
| 621 | |
| 622 | if ($form_values['preroll']) { |
| 623 | // Set 1 on the chosen preroll if we have one |
| 624 | db_query("UPDATE {twistage_videos} SET play_order=1 WHERE vid='%s' AND pid=%d", $form_values['preroll'], $profile->pid); |
| 625 | } |
| 626 | |
| 627 | drupal_set_message('Play order updated successfully.'); |
| 628 | |
| 629 | return 'admin/settings/twistage'; |
| 630 | |
| 631 | } |
| 632 | |
| 633 | function twistage_global_admin_form() { |
| 634 | $form = array(); |
| 635 | |
| 636 | $form['info'] = array( |
| 637 | '#value' => '<p>Because the preroll site is meant to be potentially shared among several profiles, a global hook URL is provided for it.<br /> |
| 638 | Enter a username and password for this hook URL, and it will update preroll videos in all profiles.</p>' |
| 639 | ); |
| 640 | |
| 641 | if (variable_get('twistage_preroll_hook_username', 0) && variable_get('twistage_preroll_hook_password', 0)) { |
| 642 | $form['info2'] = array( |
| 643 | '#value' => '<p>Your existing hook URL is: <i>http://' . $_SERVER['SERVER_NAME'] . '/twistage/preroll/hook/' . variable_get('twistage_preroll_hook_username', 0) . '/' . variable_get('twistage_preroll_hook_password', 0) . '</i>', |
| 644 | ); |
| 645 | } |
| 646 | |
| 647 | $form['username'] = array( |
| 648 | '#type' => 'textfield', |
| 649 | '#title' => t('Username'), |
| 650 | '#default_value' => variable_get('twistage_preroll_hook_username', ''), |
| 651 | ); |
| 652 | |
| 653 | $form['password'] = array( |
| 654 | '#type' => 'textfield', |
| 655 | '#title' => t('Password'), |
| 656 | '#default_value' => variable_get('twistage_preroll_hook_password', ''), |
| 657 | '#description' => t('Will be shown in clear text'), |
| 658 | ); |
| 659 | |
| 660 | return system_settings_form($form); |
| 661 | } |
| 662 | |
| 663 | function twistage_global_admin_form_submit($form_id, $form_values) { |
| 664 | variable_set('twistage_preroll_hook_username', $form_values['username']); |
| 665 | variable_set('twistage_preroll_hook_password', $form_values['password']); |
| 666 | drupal_set_message('Preroll hook configuration saved.'); |
| 667 | return 'admin/settings/twistage'; |
| 668 | } |
| 669 | |
| 670 | |
| 671 | /** |
| 672 | * Generate the settings screen |
| 673 | */ |
| 674 | function twistage_settings_page($pid = 0) { |
| 675 | if ($pid && is_numeric($pid)) { |
| 676 | return drupal_get_form('twistage_profile_admin_form', $pid); |
| 677 | } else { |
| 678 | $result = db_query("SELECT pid, name, type, path FROM {twistage_profiles} WHERE 1"); |
| 679 | if (!db_num_rows($result)) { |
| 680 | $content = '<p>No profiles found. <a href="/admin/settings/twistage/create">Create one now</a>.</p>'; |
| 681 | return $content; |
| 682 | } |
| 683 | |
| 684 | $header = array( |
| 685 | t('Name'), |
| 686 | t('Type'), |
| 687 | t('Path (if page)'), |
| 688 | t('Operations'), |
| 689 | ); |
| 690 | |
| 691 | $rows = array(); |
| 692 | |
| 693 | while ($profile = db_fetch_object($result)) { |
| 694 | $rows[] = array( |
| 695 | $profile->name, |
| 696 | $profile->type, |
| 697 | $profile->path, |
| 698 | '<a href="/admin/settings/twistage/profile/' . $profile->pid . '">edit</a> ' . |
| 699 | '<a href="/admin/settings/twistage/order/' . $profile->pid . '">set play order</a> ' . |
| 700 | (module_exists('twistage_syndicate') ? '<a href="/admin/settings/twistage/syndication/' . $profile->pid . '">syndication</a>' : '') . " " . |
| 701 | (module_exists('twistage_publish') ? '<a href="/admin/settings/twistage/publishing/' . $profile->pid . '">publishing</a>' : ''), |
| 702 | ); |
| 703 | } |
| 704 | |
| 705 | return theme('table', $header, $rows); |
| 706 | } |
| 707 | } |
| 708 | |
| 709 | /** |
| 710 | * Perform a sync of data from Twistage on all the videos associated with a certain profile. |
| 711 | * @param pid |
| 712 | * profile ID to sync |
| 713 | */ |
| 714 | function twistage_sync_videos($pid = 0) { |
| 715 | if (!$pid) { |
| 716 | return; |
| 717 | } |
| 718 | |
| 719 | $profile = twistage_get_profile($pid); |
| 720 | |
| 721 | if (!$profile) { |
| 722 | return; |
| 723 | } |
| 724 | |
| 725 | // Sync videos from the preroll site if one exists |
| 726 | if ($profile->preroll_company && $profile->preroll_site_name && $profile->preroll_site_key) { |
| 727 | $preroll = TRUE; |
| 728 | } |
| 729 | |
| 730 | // Store play orders |
| 731 | $result = db_query("SELECT * FROM {twistage_videos} WHERE pid=%d", $profile->pid); |
| 732 | $order = array(); |
| 733 | while ($video = db_fetch_object($result)) { |
| 734 | $order[$video->vid] = $video->play_order; |
| 735 | $syn[$video->vid] = $video->syndicated; |
| 736 | } |
| 737 | |
| 738 | // Get all videos (non-preroll) |
| 739 | $main = twistage_fetch_videos($pid, false); |
| 740 | // Sleep between API calls to satisfy the 1-req-per-second limit twistage imposes. |
| 741 | usleep(1500000); |
| 742 | // Get prerolls |
| 743 | $prerolls = twistage_fetch_videos($pid, true); |
| 744 | // Smash them together |
| 745 | $videos = array_merge($main, $prerolls); |
| 746 | if ($videos) { |
| 747 | // Delete all existing data. |
| 748 | db_query("DELETE FROM {twistage_videos} WHERE pid=%d", $pid); |
| 749 | } else { |
| 750 | // Bail out, and don't delete anything. |
| 751 | drupal_set_message('Unable to sync. Please check the error log for more details.', 'error'); |
| 752 | drupal_goto('admin/settings/twistage'); |
| 753 | } |
| 754 | |
| 755 | foreach ($videos as $vdata) { |
| 756 | $vdata = (array)$vdata; // To make accessing properties easier. PHP is not happy with object properties with dashes in them. |
| 757 | |
| 758 | $video = new stdClass; |
| 759 | |
| 760 | // Check to see if this video belongs to the main or preroll section |
| 761 | if ($vdata['site-name'] == $profile->site_name) { |
| 762 | $video->site_key = $profile->site_key; |
| 763 | } else if ($preroll & ($vdata['site-name'] == $profile->preroll_site_name)) { |
| 764 | $video->site_key = $profile->preroll_site_key; |
| 765 | } else { |
| 766 | // Skip video if no match on either site name |
| 767 | continue; |
| 768 | } |
| 769 | |
| 770 | $tags = array(); |
| 771 | foreach ($vdata['tags']->tag as $tag) { |
| 772 | $tags[] = strval($tag->name); |
| 773 | } |
| 774 | |
| 775 | $video->pid = $pid; |
| 776 | $video->vid = $vdata['video-id']; |
| 777 | $video->title = $vdata['title']; |
| 778 | $video->description = $vdata['description']; |
| 779 | $video->tags = $tags; |
| 780 | $video->status = $vdata['status']; // different status codes are returned by "Search Videos" and "Video Metadata". For parity we use metadata. |
| 781 | $video->availability = $vdata['availability']; |
| 782 | $video->created = strtotime($vdata['created-at']); |
| 783 | $video->publisher = $vdata['publisher-name']; |
| 784 | |
| 785 | twistage_save_video($video); |
| 786 | |
| 787 | if ($order[$video->vid]) { |
| 788 | db_query("UPDATE {twistage_videos} SET play_order=%d WHERE vid='%s'", $order[$video->vid], $video->vid); |
| 789 | } else { |
| 790 | db_query("UPDATE {twistage_videos} SET play_order=0 WHERE vid='%s'", $video->vid); |
| 791 | } |
| 792 | |
| 793 | if ($syn[$video->vid]) { |
| 794 | db_query("UPDATE {twistage_videos} SET syndicated=%d WHERE vid='%s'", $syn[$video->vid], $video->vid); |
| 795 | } else { |
| 796 | db_query("UPDATE {twistage_videos} SET syndicated=0 WHERE vid='%s'", $video->vid); |
| 797 | } |
| 798 | } |
| 799 | drupal_set_message('Video sync complete.'); |
| 800 | drupal_goto('admin/settings/twistage'); |
| 801 | } |
| 802 | |
| 803 | /** |
| 804 | * Fetch an array of video objects from Twistage that are associated with the given profile. Note that they are returned in no particular order (just as Twistage provides them) |
| 805 | * Calling this function when rendering any Drupal page will add notable latency, since it necessarily involves waiting for a reply from Twistage. |
| 806 | * Therefore, this should only be called when syncing the local video DB with Twistage (i.e., upon installation or user request). |
| 807 | * The form of the data returned is somewhat awkward for PHP (there are dashes in the object property names). For ease of use, when the objects are stored |
| 808 | * locally in the databse, some of the properties are renamed. User-facing functions in this module use these local naming conventions, not what comes out of this function. |
| 809 | * This function is a wrapper for the Twistage "Video Search API", although it returns an array of objects similar to what twistage_fetch_metadata returns, |
| 810 | * since it requests the list of videos with a verbosity level of "high". |
| 811 | * @param pid |
| 812 | * The profile for which to fetch videos |
| 813 | * @param preroll |
| 814 | * Fetch videos associated with the preroll site for this profile, not the main site |
| 815 | * @param start |
| 816 | * Optionally limit the search to videos posted after this timestamp |
| 817 | * @param end |
| 818 | * Optionally limit the search to videos posted after this timestamp |
| 819 | * @param limit |
| 820 | * Return only this many videos |
| 821 | * @return |
| 822 | * array of video objects |
| 823 | */ |
| 824 | function twistage_fetch_videos($pid, $preroll = false, $start = 0, $end = 0, $limit = 0) { |
| 825 | $profile = twistage_get_profile($pid); |
| 826 | |
| 827 | $signature = _twistage_authenticate($profile->site_key); |
| 828 | |
| 829 | if ($preroll) { |
| 830 | $url = "http://service.twistage.com/companies/" . urlencode($profile->preroll_company) . "/sites/" . urlencode($profile->preroll_site_name) . "/videos.xml"; |
| 831 | $url .= "?verbosity=high&signature=" . urlencode($signature); |
| 832 | } else { |
| 833 | $url = "http://service.twistage.com/companies/" . urlencode($profile->company) . "/sites/" . urlencode($profile->site_name) . "/videos.xml"; |
| 834 | $url .= "?verbosity=high&signature=" . urlencode($signature); |
| 835 | } |
| 836 | |
| 837 | if ($start) { |
| 838 | $s = getdate($start); |
| 839 | $str = $s['year'] . '/' . $s['mon'] . '/' . $s['mday']; |
| 840 | $url .= "&from=" . urlencode($str); |
| 841 | } |
| 842 | |
| 843 | if ($end) { |
| 844 | $s = getdate($end); |
| 845 | $str = $s['year'] . '/' . $s['mon'] . '/' . $s['mday']; |
| 846 | $url .= "&until=" . urlencode($str); |
| 847 | } |
| 848 | |
| 849 | if ($limit) { |
| 850 | $url .= "&limit=" . urlencode($limit); |
| 851 | } |
| 852 | |
| 853 | $data = file_get_contents($url); |
| 854 | |
| 855 | if (!$data) { |
| 856 | watchdog('twistage', 'Error obtaining video list from Twistage. Check your account settings.'); |
| 857 | return array(); |
| 858 | } |
| 859 | |
| 860 | $xml = simplexml_load_string($data); |
| 861 | |
| 862 | if ($xml) { |
| 863 | foreach ($xml->video as $video) { |
| 864 | $videos[] = $video; |
| 865 | } |
| 866 | return $videos; |
| 867 | } else { |
| 868 | watchdog('twistage', 'XML parse error in data fetched from Twistage'); |
| 869 | return array(); |
| 870 | } |
| 871 | } |
| 872 | |
| 873 | /** |
| 874 | * Fetch metadata for a video. |
| 875 | * @param vid |
| 876 | * the video ID |
| 877 | * @param pid |
| 878 | * profile ID from which to take authentication credentials |
| 879 | * @return array |
| 880 | * an array of metadata |
| 881 | */ |
| 882 | function twistage_fetch_metadata($vid, $pid) { |
| 883 | $profile = twistage_get_profile($pid); |
| 884 | $signature = _twistage_authenticate($profile->site_key); |
| 885 | $url = "http://console.twistage.com/videos/" . urlencode($vid) . ".xml?signature=" . urlencode($signature); |
| 886 | $data = file_get_contents($url); |
| 887 | if (!$data) { |
| 888 | // No luck with the main site key, so try the preroll site key before failing |
| 889 | $signature = _twistage_authenticate($profile->preroll_site_key); |
| 890 | $url = "http://console.twistage.com/videos/" . urlencode($vid) . ".xml?signature=" . urlencode($signature); |
| 891 | $data = file_get_contents($url); |
| 892 | if (!$data) { |
| 893 | watchdog('twistage', 'Could not fetch metadata for video ID ' . $vid, WATCHDOG_WARNING); |
| 894 | return array(); |
| 895 | } |
| 896 | } |
| 897 | |
| 898 | $xml = simplexml_load_string($data); |
| 899 | return (array)$xml; |
| 900 | } |
| 901 | |
| 902 | |
| 903 | |
| 904 | /** |
| 905 | * Save a Twistage video object in the local database. |
| 906 | * This doesn't work the same way as Drupal nodes, etc. The vid is determined by Twistage and we must use it since it's what must be passed to render a player. |
| 907 | * This function does not touch play order or syndication data. |
| 908 | * In no way does this function save anything to your Twistage account. |
| 909 | * @param video |
| 910 | * Object representing the video to save. Must be a object following Drupal conventions (ie, renamed properties with dashes in them, timestamp instead of string for created time) |
| 911 | */ |
| 912 | function twistage_save_video($video) { |
| 913 | if (!$video->vid || !$video->pid) { |
| 914 | // Bail out if something is amiss. |
| 915 | return; |
| 916 | } |
| 917 | |
| 918 | $result = db_query("SELECT vid FROM {twistage_videos} WHERE vid='%s' AND pid=%d", $video->vid, $video->pid); |
| 919 | if (db_num_rows($result)) { |
| 920 | // Update |
| 921 | db_query("UPDATE {twistage_videos} SET site_key='%s', title='%s', description='%s', tags='%s', status='%s', availability='%s', created=%d, publisher='%s' WHERE vid='%s' AND pid=%d", |
| 922 | $video->site_key, |
| 923 | $video->title, |
| 924 | $video->description, |
| 925 | serialize($video->tags), |
| 926 | $video->status, |
| 927 | $video->availability, |
| 928 | $video->created, |
| 929 | $video->publisher, |
| 930 | $video->vid, |
| 931 | $video->pid); |
| 932 | } else { |
| 933 | db_query("INSERT INTO {twistage_videos} (vid, pid, site_key, title, description, tags, status, availability, created, publisher) VALUES ('%s', %d, '%s', '%s', '%s', '%s', '%s', '%s', %d, '%s')", |
| 934 | $video->vid, |
| 935 | $video->pid, |
| 936 | $video->site_key, |
| 937 | $video->title, |
| 938 | $video->description, |
| 939 | serialize($video->tags), |
| 940 | $video->status, |
| 941 | $video->availability, |
| 942 | $video->created, |
| 943 | $video->publisher); |
| 944 | } |
| 945 | |
| 946 | } |
| 947 | |
| 948 | /** |
| 949 | * Retrieve a Twistage video object from the local database. Retrieves all properties. |
| 950 | * @param vid |
| 951 | * video ID |
| 952 | * @return |
| 953 | * video object |
| 954 | */ |
| 955 | function twistage_get_video($vid, $pid) { |
| 956 | $result = db_query("SELECT * FROM {twistage_videos} WHERE vid='%s' AND pid=%d", $vid, $pid); |
| 957 | $video = db_fetch_object($result); |
| 958 | // This was a particularly nasty bug which messed up a lot of things downstream that depended on $video being null if the vid didn't exist in the db |
| 959 | // setting $video->tags to a blank array registers $video as non-null. |
| 960 | if ($video) { |
| 961 | $video->tags = unserialize($video->tags); |
| 962 | } |
| 963 | return $video; |
| 964 | } |
| 965 | |
| 966 | /** |
| 967 | * Delete a Twistage video. |
| 968 | * @param vid |
| 969 | * video ID |
| 970 | */ |
| 971 | function twistage_delete_video($vid) { |
| 972 | $result = db_query("DELETE FROM {twistage_videos} WHERE vid='%s'", $vid); |
| 973 | } |
| 974 | |
| 975 | /** |
| 976 | * Return a Twistage profile object -- all properties. |
| 977 | * @param pid |
| 978 | * profile ID |
| 979 | * @return |
| 980 | * profile object |
| 981 | */ |
| 982 | function twistage_get_profile($pid) { |
| 983 | return db_fetch_object(db_query("SELECT * FROM {twistage_profiles} WHERE pid=%d", $pid)); |
| 984 | } |
| 985 | |
| 986 | /** |
| 987 | * Receives "pings" from Twistage and provide Drupal module hooks appropriately. |
| 988 | * We expect the user will have entered a "Hook URL" in their Twistage account which includes a username and password as GET parameters. These must be entered in the admin form. |
| 989 | * The actual Twistage hook data is passed as POST parameters. |
| 990 | */ |
| 991 | function twistage_process_hook($profile, $username, $password) { |
| 992 | $profile = db_fetch_object(db_query("SELECT * FROM {twistage_profiles} WHERE name='%s'", $profile)); |
| 993 | |
| 994 | // Check to see if we have a username/password. If not, we do not process the hook at all. |
| 995 | if ($profile->username == '' || $profile->password == '') { |
| 996 | return; |
| 997 | } |
| 998 | |
| 999 | // Next, check to see if the username/password passed match these. |
| 1000 | if ($profile->username != $username || $profile->password != $password) { |
| 1001 | return; |
| 1002 | } |
| 1003 | |
| 1004 | // Now that we've passed those two tests, process the |
| 1005 | switch ($_POST['action']) { |
| 1006 | case 'update': |
| 1007 | case 'create': |
| 1008 | // New video posted. |
| 1009 | $video = twistage_get_video($_POST['vid'], $profile->pid); |
| 1010 | |
| 1011 | if (!$video) { |
| 1012 | $video = new stdClass; |
| 1013 | $video->vid = $_POST['vid']; |
| 1014 | $video->pid = $profile->pid; |
| 1015 | } |
| 1016 | $video->title = $_POST['title']; |
| 1017 | |
| 1018 | $xml = twistage_fetch_metadata($video->vid, $video->pid); |
| 1019 | |
| 1020 | if($xml['site-name'] == $profile->preroll_site_name) { |
| 1021 | $video->site_key = $profile->preroll_site_key; |
| 1022 | } else { |
| 1023 | $video->site_key = $profile->site_key; |
| 1024 | } |
| 1025 | |
| 1026 | $tags = array(); |
| 1027 | foreach ($xml['tags']->tag as $tag) { |
| 1028 | $tags[] = strval($tag->name); |
| 1029 | } |
| 1030 | |
| 1031 | $video->description = $xml['description']; |
| 1032 | $video->tags = $tags; |
| 1033 | $video->status = $xml['status']; |
| 1034 | $video->availability = $xml['availability']; |
| 1035 | $video->created = strtotime($xml['created-at']); |
| 1036 | $video->publisher = $xml['publisher-name']; |
| 1037 | |
| 1038 | // If we got a custom nid data field, include that in the video object so that hook implementations can see it |
| 1039 | if ($_POST['nid']) { |
| 1040 | $video->nid = $_POST['nid']; |
| 1041 | } |
| 1042 | |
| 1043 | twistage_save_video($video); |
| 1044 | |
| 1045 | // hook_twistage_api: Tell other modules about this if they're interested. In order to maintain consistenc, we do not pass the $video object by reference or act on any return value. |
| 1046 | foreach (module_implements('twistage_api') as $module) { |
| 1047 | $func = $module . '_twistage_api'; |
| 1048 | $func($_POST['action'], $video); |
| 1049 | } |
| 1050 | |
| 1051 | break; |
| 1052 | |
| 1053 | case 'delete': |
| 1054 | $video = twistage_get_video($_POST['vid'], $profile->pid); |
| 1055 | foreach (module_implements('twistage_api') as $module) { |
| 1056 | $func = $module . '_twistage_api'; |
| 1057 | $func('delete', $video); |
| 1058 | } |
| 1059 | twistage_delete_video($_POST['vid'], $profile->pid); |
| 1060 | break; |
| 1061 | } |
| 1062 | |
| 1063 | // We don't actually want to render a page here, so stop code execution now. |
| 1064 | die(); |
| 1065 | } |
| 1066 | |
| 1067 | function twistage_preroll_hook($username, $password) { |
| 1068 | // Basic security checks |
| 1069 | if (!variable_get('twistage_preroll_hook_username', 0) || !variable_get('twistage_preroll_hook_password', 0)) { |
| 1070 | return; |
| 1071 | } |
| 1072 | |
| 1073 | if ($username != variable_get('twistage_preroll_hook_username', '') || $password != variable_get('twistage_preroll_hook_password', '')) { |
| 1074 | return; |
| 1075 | } |
| 1076 | |
| 1077 | // Cycle through all profiles and check if the video exists there. |
| 1078 | $result = db_query("SELECT * FROM {twistage_profiles}"); |
| 1079 | while ($profile = db_fetch_object($result)) { |
| 1080 | $video = twistage_get_video($_POST['vid'], $profile->pid); |
| 1081 | if ($video) { |
| 1082 | // We only act if the video is already in the profile; we're not adding videos to profiles that don't already have them. |
| 1083 | $xml = twistage_fetch_metadata($video->vid, $video->pid); |
| 1084 | $tags = array(); |
| 1085 | foreach ($xml['tags']->tag as $tag) { |
| 1086 | $tags[] = strval($tag->name); |
| 1087 | } |
| 1088 | |
| 1089 | $video->description = $xml['description']; |
| 1090 | $video->tags = $tags; |
| 1091 | $video->status = $xml['status']; |
| 1092 | $video->availability = $xml['availability']; |
| 1093 | $video->created = strtotime($xml['created-at']); |
| 1094 | $video->publisher = $xml['publisher-name']; |
| 1095 | |
| 1096 | twistage_save_video($video); |
| 1097 | |
| 1098 | // Fire a hook_twistage_api for each profile/video combo. |
| 1099 | foreach (module_implements('twistage_api') as $module) { |
| 1100 | $func = $module . '_twistage_api'; |
| 1101 | $func($_POST['action'], $video); |
| 1102 | } |
| 1103 | } |
| 1104 | } |
| 1105 | } |
| 1106 | |
| 1107 | function twistage_get_first_video($pid) { |
| 1108 | $profile = twistage_get_profile($pid); |
| 1109 | $video = db_fetch_object(db_query_range("SELECT * FROM {twistage_videos} WHERE pid=%d AND site_key='%s' AND play_order > 0 ORDER BY play_order", $pid, $profile->site_key, 0, 1)); |
| 1110 | if ($video) { |
| 1111 | $video->tags = unserialize($video->tags); |
| 1112 | } |
| 1113 | return $video; |
| 1114 | } |
| 1115 | |
| 1116 | function twistage_get_preroll_video($pid) { |
| 1117 | $profile = twistage_get_profile($pid); |
| 1118 | $video = db_fetch_object(db_query_range("SELECT * FROM {twistage_videos} WHERE pid=%d AND site_key='%s' AND play_order > 0 ORDER BY play_order", $pid, $profile->preroll_site_key, 0, 1)); |
| 1119 | if ($video) { |
| 1120 | $video->tags = unserialize($video->tags); |
| 1121 | } |
| 1122 | return $video; |
| 1123 | } |
| 1124 | |
| 1125 | |
| 1126 | /** |
| 1127 | * Tool function to request a session signature from Twistage using the site license key. |
| 1128 | * @return |
| 1129 | * string containing the session signature |
| 1130 | */ |
| 1131 | function _twistage_authenticate($key, $publishUser = '') { |
| 1132 | if ($publishUser) { |
| 1133 | $url = "http://service.twistage.com/api/publish_key"; |
| 1134 | $url .= "?authKey=" . urlencode($key) . "&userID=" . urlencode($publishUser); |
| 1135 | } else { |
| 1136 | $url = "http://service.twistage.com/api/view_key"; |
| 1137 | $url .= "?authKey=" . urlencode($key); |
| 1138 | } |
| 1139 | |
| 1140 | $fp = fopen($url, "r"); |
| 1141 | if ($fp) { |
| 1142 | $signature = fread($fp, 40); |
| 1143 | fclose($fp); |
| 1144 | } else { |
| 1145 | $signature = ""; |
| 1146 | } |
| 1147 | |
| 1148 | return $signature; |