| [ Index ] |
PHP Cross Reference of Drupal 6 (gatewave) |
[Summary view] [Print] [Text view]
1 <?php 2 // $Id: station_archive.module,v 1.51 2010/09/13 18:54:05 timplunkett Exp $ 3 4 /** 5 * Implementation of hook_help(). 6 */ 7 function station_archive_help($section = '') { 8 switch ($section) { 9 case 'admin/settings/station/archive': 10 return t("These settings let you configure the way the station's webstream is archived into audio nodes. Audio is imported into the archive as part of Drupal's cron task. You'll need to ensure that that is properly configured."); 11 } 12 } 13 14 /** 15 * Implementation of hook_menu(). 16 */ 17 function station_archive_menu() { 18 // Legacy menu items. This functionality is handled by Views now. 19 $items['last'] = array( 20 'title' => 'Show archive', 21 'page callback' => 'station_archive_view_html', 22 'access arguments' => array('access content'), 23 'file' => 'station_archive.legacy_pages.inc', 24 'type' => MENU_CALLBACK, 25 ); 26 $items['last/hours'] = array( 27 'page callback' => 'station_archive_view_hours_html', 28 'access arguments' => array('access content'), 29 'file' => 'station_archive.legacy_pages.inc', 30 'type' => MENU_CALLBACK, 31 ); 32 $items['rss'] = array( 33 'title' => 'RSS show archive', 34 'page callback' => 'station_archive_view_rss', 35 'access arguments' => array('access content'), 36 'file' => 'station_archive.legacy_pages.inc', 37 'type' => MENU_CALLBACK, 38 ); 39 $items['rss/hours'] = array( 40 'page callback' => 'station_archive_view_hours_rss', 41 'access arguments' => array('access content'), 42 'file' => 'station_archive.legacy_pages.inc', 43 'type' => MENU_CALLBACK, 44 ); 45 // end legacy menu items 46 47 $items['admin/settings/station/archive'] = array( 48 'title' => 'Archive', 49 'page callback' => 'drupal_get_form', 50 'page arguments' => array('station_archive_admin_settings'), 51 'access arguments' => array('administer site configuration'), 52 'file' => 'station_archive.admin.inc', 53 'type' => MENU_LOCAL_TASK, 54 ); 55 return $items; 56 } 57 58 /** 59 * Implementation of hook_perm(). 60 */ 61 function station_archive_perm() { 62 return array( 63 'administer station archive', 64 ); 65 } 66 67 /** 68 * Implementation of hook_block(). 69 */ 70 function station_archive_block($op = 'list', $delta = 0, $edit = array()) { 71 switch ($op) { 72 case 'view': 73 if (user_access('access content')) { 74 switch ($delta) { 75 case 1: 76 $block['subject'] = t('Browse by day'); 77 $block['content'] = _station_archive_browse_block(); 78 break; 79 } 80 return $block; 81 } 82 break; 83 84 case 'list': 85 $blocks[1]['info'] = t('Station Archive: Browse by taxonomy'); 86 return $blocks; 87 } 88 } 89 90 /** 91 * Return HTML for browsing the taxonomy. 92 */ 93 function _station_archive_browse_block() { 94 $vid = _station_archive_get_vid(); 95 $tree = taxonomy_get_tree($vid); 96 if ($tree) { 97 foreach ($tree as $term) { 98 if ($term->depth == 0) { 99 $items[] = l($term->name, 'taxonomy/term/'. $term->tid); 100 } 101 } 102 return theme('item_list', $items); 103 } 104 } 105 106 /** 107 * Implementation of hook_nodeapi(). 108 */ 109 function station_archive_nodeapi(&$node, $op, $teaser, $page) { 110 if ($node->type == 'audio') { 111 switch ($op) { 112 case 'update': 113 if (isset($node->station_archive) && user_access('administer station archive')) { 114 // Remove any existing records. 115 db_query("DELETE FROM {station_archive_item} WHERE audio_nid = %d", $node->nid); 116 // If this should be in the archive, create a new record. 117 if ($node->station_archive['archived']) { 118 if (empty($node->station_archive['aired'])) { 119 $node->station_archive['aired'] = (integer) $node->created; 120 } 121 if (empty($node->station_archive['imported'])) { 122 $node->station_archive['imported'] = time(); 123 } 124 $record = array_merge($node->station_archive, array('audio_nid' => $node->nid)); 125 drupal_write_record('station_archive_item', $record); 126 } 127 } 128 break; 129 130 case 'delete': 131 // remove our tracking records when the audio node is deleted. we only 132 // assume that audio node are on this machine, the program nodes could 133 // be on a remote server. 134 db_query('DELETE FROM {station_archive_item} WHERE audio_nid = %d', $node->nid); 135 break; 136 137 case 'load': 138 // Sneak the '1 AS archived' in so we've got a value to indicate that 139 // this node is in the archive. 140 $row = db_fetch_array(db_query("SELECT 1 AS archived, sa.program_nid, sa.aired, sap.title AS program_title, sa.imported, sa.permanent FROM {station_archive_item} sa LEFT OUTER JOIN {station_archive_program} sap ON sa.program_nid = sap.program_nid WHERE sa.audio_nid = %d", $node->nid)); 141 if ($row) { 142 return array('station_archive' => $row); 143 } 144 break; 145 146 case 'view': 147 // If it's in the archives, set the menu appropriately 148 if ($page && !$teaser && isset($node->station_archive)) { 149 $breadcrumb = array( 150 l(t('Home'), NULL), 151 l(t('Station'), 'station'), 152 l(t('Archives'), 'station/archives'), 153 l($node->station_archive['program_title'], 'station/archives/'. $node->station_archive['program_nid']), 154 ); 155 drupal_set_breadcrumb($breadcrumb); 156 157 // Provide information to admins on the import and deletion dates. 158 if (user_access('administer station archive')) { 159 $node->content['station_archive'] = array( 160 '#type' => 'fieldset', 161 '#title' => t('Station Archive Admin Info'), 162 '#collapsible' => TRUE, 163 '#collapsed' => TRUE, 164 station_archive_node_info_form($node), 165 ); 166 } 167 } 168 169 break; 170 } 171 } 172 } 173 174 /** 175 * Get an array containing information about programs. 176 * 177 * @return 178 * An array keyed by program ID, with each program stored as an object. 179 */ 180 function station_archive_get_programs() { 181 $programs = array(); 182 $result = db_query('SELECT sap.program_nid AS nid, sap.title FROM {station_archive_program} sap ORDER BY sap.title'); 183 while ($obj = db_fetch_object($result)) { 184 $programs[$obj->nid] = $obj; 185 } 186 return $programs; 187 } 188 189 190 /** 191 * Implementation of hook_form_alter(). 192 */ 193 function station_archive_form_alter(&$form, $form_state, $form_id) { 194 // We only alter audio node edit forms 195 if ($form_id == 'audio_node_form') { 196 $node = $form['#node']; 197 198 if (isset($node->station_archive) || user_access('administer station archive')) { 199 $form['station_archive'] = array( 200 '#type' => 'fieldset', 201 '#title' => t('Station Archive'), 202 '#collapsible' => TRUE, 203 '#collapsed' => (empty($node->station_archive['archived']) || !isset($node->audio_file)), 204 '#weight' => -5, 205 '#tree' => TRUE, 206 station_archive_node_info_form($node), 207 ); 208 if (user_access('administer station archive')) { 209 $program_options = array(); 210 foreach (station_archive_get_programs() as $nid => $program) { 211 $program_options[$nid] = $program->title; 212 } 213 $form['station_archive']['archived'] = array( 214 '#type' => 'checkbox', 215 '#title' => t('In Station Archive'), 216 '#default_value' => empty($node->station_archive['archived']) ? FALSE : TRUE, 217 '#description' => t("If this is checked, this then the station archive module will associate this with a program."), 218 '#weight' => -1, 219 ); 220 $form['station_archive']['program_nid'] = array( 221 '#type' => 'select', 222 '#title' => t('Recording of'), 223 '#options' => $program_options, 224 '#default_value' => empty($node->station_archive['program_nid']) ? NULL : $node->station_archive['program_nid'], 225 '#description' => t('Select the program that this audio is a recording of.') 226 ); 227 $form['station_archive']['refresh'] = array( 228 '#type' => 'fieldset', 229 '#title' => t('Reload program information'), 230 '#description' => t("This lets you refresh the information about which program was playing at this time. This can be useful when the program information was incorrectly retreived or retreived before changes were made to the schedule."), 231 ); 232 // put a reload button on the form so the admin can refresh program 233 // information that was retreived incorrectly or before changes were 234 // made to the schedule. this is processed in station_archive_nodeapi() 235 // under the $op == 'prepare'. 236 $form['station_archive']['refresh']['reload'] = array( 237 '#type' => 'button', 238 '#value' => t('Reload Program'), 239 ); 240 $form['station_archive']['permanent'] = array( 241 '#type' => 'checkbox', 242 '#title' => t('In permanent archive'), 243 '#default_value' => empty($node->station_archive['permanent']) ? FALSE : TRUE, 244 '#description' => t("If this is checked, this recording will not be deleted during the Station Archive's clean up of old recordings."), 245 ); 246 $form['#validate'][] = 'station_archive_node_form_validate'; 247 } 248 } 249 } 250 } 251 252 function station_archive_node_form_validate(&$form, &$form_state) { 253 // If they clicked the button, reload the program information 254 if (isset($form_state['clicked_button']['#value']) && t('Reload Program') == $form_state['clicked_button']['#value']) { 255 $gmt_timestamp = isset($form_state['values']['station_archive']['aired']) ? $form_state['values']['station_archive']['aired'] : time(); 256 // get a timestamp that's correct for the timezone 257 $local_timestamp = station_local_ts($gmt_timestamp); 258 $prettydate = date('ga \o\n M jS, Y', $local_timestamp); 259 260 // connect to the station module and find program info based on timestamp 261 $schedule = station_default_schedule(); 262 $program = station_get_program_at($gmt_timestamp, $schedule['nid']); 263 if ($program === FALSE) { 264 // couldn't get the program info, configuation error? 265 drupal_set_error(t("Couldn't load the program metadata from the schedule.")); 266 break; 267 } 268 elseif ($program === NULL) { 269 // nothing is scheduled... 270 // if we've got no program use the default metadata 271 $program_nid = 0; 272 $audio_tags['title'] = variable_get('station_archive_unscheduled_title', t('DJ Auto mix')); 273 } 274 else { 275 // we've got program information 276 $djs = array(); 277 if (!empty($program->field_station_program_dj)) { 278 foreach ($program->field_station_program_dj as $entry) { 279 $user = user_load($entry); 280 $djs[] = $user->name; 281 } 282 } 283 $program_nid = $program->nid; 284 $audio_tags['title'] = $program->title; 285 $audio_tags['artist'] = station_anded_list($djs); 286 $audio_tags['genre'] = isset($program->field_station_program_genre[0]['value']) ? $program->field_station_program_genre[0]['value'] : ''; 287 $audio_tags['url_source'] = $program->node_url; 288 } 289 $audio_tags['year'] = date('Y', $local_timestamp); 290 $audio_tags['comment'] = t('Recorded at @date', array('@date' => $prettydate)); 291 292 // audio metadata tags 293 $form_state['values']['audio_tags'] = $audio_tags; 294 // archive program nid (this won't work if there isn't already a copy 295 // of the program in station_archive_program). 296 $form_state['values']['station_archive']['program_nid'] = $program_nid; 297 // taxonomy 298 $vid = _station_archive_get_vid(); 299 $form_state['values']['taxonomy'][$vid] = _station_archive_get_taxonomy($local_timestamp); 300 // promotion 301 $form_state['values']['promote'] = (int) ($program && variable_get('station_archive_promote_scheduled', 1)); 302 303 drupal_set_message(t("The program information has been reloaded from the schedule. Verify that it is correct and save the changes.")); 304 } 305 } 306 307 /** 308 * Create form elements to display the station archive information for an audio 309 * node. 310 * 311 * @param $node 312 * Audio node object. 313 * @return 314 * Array of form information. 315 */ 316 function station_archive_node_info_form($node) { 317 $form = array(); 318 if (isset($node->station_archive)) { 319 $form['station_archive']['aired'] = array( 320 '#type' => 'item', 321 '#title' => t('Air date'), 322 '#value' => format_date($node->station_archive['aired'], 'large'), 323 '#description' => t("The date the program first aired."), 324 '#weight' => -1, 325 ); 326 $form['station_archive']['imported'] = array( 327 '#type' => 'item', 328 '#title' => t('Imported on'), 329 '#value' => format_date($node->station_archive['imported'], 'large'), 330 '#description' => t('This is the date the audio was actually imported to the archive.'), 331 '#weight' => 0, 332 ); 333 if (variable_get('station_archive_cleanup_old', 1)) { 334 if ($node->station_archive['permanent']) { 335 $form['station_archive']['deletion'] = array( 336 '#type' => 'item', 337 '#title' => t('Deletion not scheduled'), 338 '#description' => t("This audio is currently in the permanent archive and will not be removed as part of the normal cleanup process."), 339 '#weight' => 1, 340 ); 341 } 342 else { 343 $max_age = variable_get('station_archive_max_age', 604800); 344 $delete = $node->station_archive['imported'] + $max_age; 345 $form['station_archive']['deletion'] = array( 346 '#type' => 'item', 347 '#title' => t('Deletion scheduled for'), 348 '#value' => format_date($delete, 'large'), 349 '#description' => t("The administrator has specified that archived recordings will be removed after being posted for %interval.", array('%interval' => format_interval($max_age))), 350 '#weight' => 1, 351 ); 352 } 353 } 354 } 355 return $form; 356 } 357 358 /** 359 * Implementation of hook_cron(). 360 * 361 * Remove old files, import new ones. 362 */ 363 function station_archive_cron() { 364 // HACK: we overwrite the user so that the cron user can get around the 365 // permissions check and delete old audio nodes. 366 global $user; 367 $olduser = $user; 368 $user = user_load(array('uid' => 1)); 369 370 if (variable_get('station_archive_cleanup_old', 1) == 1) { 371 _station_archive_delete_old_nodes(); 372 } 373 if (variable_get('station_archive_import_new', 1) == 1) { 374 _station_archive_import_files(); 375 } 376 377 _station_archive_update_program_list(); 378 379 // restore the old user so we don't screw something else up in the cron run 380 $user = $olduser; 381 } 382 383 /** 384 * Find and delete old archived audio nodes. 385 * 386 * We need to make sure we only delete nodes created by this module. So, we 387 * search look at nodes included in our taxonomy. 388 */ 389 function _station_archive_delete_old_nodes() { 390 $cutoff = time() - variable_get('station_archive_max_age', 604800); 391 $result = db_query('SELECT n.nid, n.title FROM {node} n INNER JOIN {station_archive_item} sa ON n.nid = sa.audio_nid WHERE sa.permanent = 0 AND sa.imported < %d', $cutoff); 392 while ($node = db_fetch_object($result)) { 393 watchdog('stationarchive', 'Removing %title from the archive.', array('%title' => $node->title), WATCHDOG_NOTICE); 394 node_delete($node->nid); 395 } 396 } 397 398 /** 399 * Scan the import directory looking for MP3s to import. 400 */ 401 function _station_archive_import_files() { 402 // locate new mp3s in the import directory 403 if ($dirpath = variable_get('station_archive_import_dir', drupal_get_path('module', 'station_archive') .'/import')) { 404 $files = file_scan_directory($dirpath, '[0-9]+\.(mp3|ogg)$'); 405 foreach ($files as $file) { 406 // try to avoid php's script timeout with a bunch of large files or 407 // a slow machine 408 set_time_limit(0); 409 410 $cuefile = dirname($file->filename) .'/'. $file->name .'.cue'; 411 // if there's a .cue file, it's still being downloaded, we'll get it on 412 // the next cron call. 413 if (!file_exists($cuefile)) { 414 watchdog('stationarchive', 'Attempting to import %filename into the archive.', array('%filename' => $file->filename), WATCHDOG_NOTICE); 415 $status = _station_archive_add_file($file); 416 // if there was a problem stop the import 417 if (!$status) { 418 return; 419 } 420 } 421 } 422 } 423 } 424 425 /** 426 * Update the entries in the {station_archive_program} table. 427 * 428 * Views uses the {station_archive_program} to group audio nodes to what may be 429 * remote programs. This function keeps it up to date. 430 */ 431 function _station_archive_update_program_list() { 432 // Use the local schedule if one is available. 433 if (module_exists('station_schedule')) { 434 $programs = station_schedule_get_program_list(); 435 } 436 else { 437 // Try to connect to a remote schedule via XMLRPC for program information. 438 // If they haven't provided a url we can't retreive any data. 439 if (!$url = variable_get('station_remote_schedule_url', '')) { 440 return FALSE; 441 } 442 $programs = xmlrpc(check_url($url .'/xmlrpc.php'), 'station.program.get.list'); 443 if (xmlrpc_errno()) { 444 watchdog('station_archive', 'Failed to load program listing remotely. Error %code : %message', array('%code' => xmlrpc_errno(), '%message' => xmlrpc_error_msg()), WATCHDOG_ERROR); 445 return FALSE; 446 } 447 } 448 449 // Insert a program for unschedule times. 450 $programs[0] = array( 451 'nid' => 0, 452 'title' => variable_get('station_archive_unscheduled_title', t('DJ Auto mix')), 453 ); 454 455 foreach ($programs as $program) { 456 $program['program_nid'] = $program['nid']; 457 db_query("DELETE FROM {station_archive_program} WHERE program_nid = %d", $program['program_nid']); 458 drupal_write_record('station_archive_program', $program); 459 } 460 } 461 462 /** 463 * Add a file to the archive. 464 * 465 * Create an audio node for an mp3 or ogg file that is named with an hour's 466 * timestamp. Use the timestamp to load the program information. 467 * 468 * @param $file 469 * Drupal file object. 470 * @return 471 * Boolean indicating success. 472 */ 473 function _station_archive_add_file($file) { 474 // extract the timestamp from the filename (should be simply timestamp.mp3) 475 $basename = explode('.', $file->basename); 476 $gmt_timestamp = (int) $basename[0]; 477 $file_format = $basename[1]; 478 // get a timestamp that's correct for the timezone 479 $local_timestamp = station_local_ts($gmt_timestamp); 480 $prettydate = date('ga \o\n M jS, Y', $local_timestamp); 481 482 // connect to the station module and find program info based on timestamp 483 $schedule = station_default_schedule(); 484 $program = station_get_program_at($gmt_timestamp, $schedule['nid']); 485 if ($program === FALSE) { 486 // couldn't get the program info, configuation error? 487 watchdog('stationarchive', "Couldn't load the program metadata. We'll retry the import on the next cron run.", array(), WATCHDOG_WARNING); 488 return FALSE; 489 } 490 elseif ($program == NULL) { 491 // nothing is scheduled... 492 // ...check if they've elected to delete unscheduled programs, do so. 493 if (variable_get('station_archive_delete_unscheduled', 0)) { 494 file_delete($file->filename); 495 watchdog('stationarchive', 'Deleted audio that was recorded during unscheduled time. Filename %filename', array('%filename' => $file->filename), WATCHDOG_NOTICE); 496 return TRUE; 497 } 498 // if we've got no program use the default metadata 499 $program_nid = 0; 500 $program_title = variable_get('station_archive_unscheduled_title', t('DJ Auto mix')); 501 } 502 elseif (!$program->may_archive) { 503 // The program scheduled at this time is marked as non-archivable. We'll 504 // delete the file and log it. 505 file_delete($file->filename); 506 watchdog('stationarchive', 'Deleted %program-title, it was marked as non-archivable.', array('%program-title' => $program->title), WATCHDOG_NOTICE); 507 return TRUE; 508 } 509 else { 510 // we've got program information 511 $program_nid = (int) $program->nid; 512 $program_title = $program->title; 513 $djs = array(); 514 if (!empty($program->field_station_program_dj)) { 515 foreach ($program->field_station_program_dj as $entry) { 516 $user = user_load($entry); 517 $djs[] = $user->name; 518 } 519 } 520 $audio_tags['title'] = $program->title; 521 $audio_tags['artist'] = station_anded_list($djs); 522 $audio_tags['genre'] = isset($program->field_station_program_genre[0]['value']) ? $program->field_station_program_genre[0]['value'] : ''; 523 $audio_tags['url_source'] = $program->node_url; 524 } 525 $audio_tags['title'] = $program_title; 526 $audio_tags['year'] = date('Y', $local_timestamp); 527 $audio_tags['comment'] = t('Recorded at @date', array('@date' => $prettydate)); 528 529 // find/create the proper taxonomic terms based on day and hour 530 $taxonomy = _station_archive_get_taxonomy($local_timestamp); 531 // then create a new audio node with it 532 $title_format = variable_get('station_archive_title_format', '[audio-tag-title-raw]'); 533 $node = audio_api_insert($file->filename, $title_format, '', $audio_tags, $taxonomy); 534 535 // make any other changes to the node... 536 $node->station_archive = array( 537 'archived' => 1, 538 'program_nid' => $program_nid, 539 'aired' => $gmt_timestamp, 540 'imported' => time(), 541 'permanent' => 0, 542 ); 543 $node->audio_file['downloadable'] = 1; 544 $node->created = $gmt_timestamp; 545 // don't bother to check for promotion if there's no metadata 546 $node->promote = (int) ($program && variable_get('station_archive_promote_scheduled', 1)); 547 // keep the timestamp as the filename so we can re-import again if needed but 548 // store a more readable filename for the user. 549 $node->audio_file['file_name'] = str_replace(' ', '_', $audio_tags['title'] ." ($prettydate).$file_format"); 550 551 // ... and save it 552 $node = node_submit($node); 553 node_save($node); 554 555 watchdog('stationarchive', 'Added %title to the archive.', array('%title' => $program_title), WATCHDOG_NOTICE, l(t('view'), 'node/'. $node->nid)); 556 557 return TRUE; 558 } 559 560 /** 561 * Find/create the term ids for a day and hour based on a timestamp. 562 * 563 * @param $local_timestamp 564 * A timestamp that's been adjusted for the local timezone 565 * @return 566 * Array with day and hour term ids. 567 * 568 * @see station_local_ts() 569 */ 570 function _station_archive_get_taxonomy($local_timestamp) { 571 $vid = _station_archive_get_vid(); 572 $day = date('w', $local_timestamp); 573 $hour = date('G', $local_timestamp); 574 $minute = station_minute_from_day_hour($day, $hour); 575 $time = station_time_from_minute($minute); 576 577 $dayterm = _station_archive_get_day_term($vid, $day); 578 if (!$dayterm) { 579 $dayterm = array( 580 'vid' => $vid, 581 'name' => $time['w'], 582 'weight' => $day - 7, 583 ); 584 taxonomy_save_term($dayterm); 585 } 586 587 $hourterm = _station_archive_get_hour_term($dayterm, $hour); 588 if (!$hourterm) { 589 $hourterm = array( 590 'vid' => $dayterm['vid'], 591 'parent' => $dayterm['tid'], 592 'name' => $time['time'] . $time['a'], 593 'weight' => $hour, 594 ); 595 taxonomy_save_term($hourterm); 596 } 597 598 return array($dayterm['tid'], $hourterm['tid']); 599 } 600 601 /** 602 * Find or create a Station Archive vocabulary ID. 603 * 604 * @return 605 * Vocabulary ID. 606 */ 607 function _station_archive_get_vid() { 608 $vid = variable_get('station_archive_vid', ''); 609 if (empty($vid)) { 610 // Check to see if a stationarchive vocabulary exists 611 $vid = db_result(db_query("SELECT vid FROM {vocabulary} WHERE module = '%s'", 'station_archive')); 612 if (!$vid) { 613 $vocab = array( 614 'name' => 'Station Archive', 615 'description' => t("This vocabulary is used by the Station Archive module to track the audio nodes it has added."), 616 'help' => t("Do not add nodes to this vocabulary unless you want the station archive module to delete them when they're older than the maximum archive age."), 617 'multiple' => 1, 618 'required' => 0, 619 'hierarchy' => 1, 620 'relations' => 0, 621 'module' => 'station_archive', 622 'nodes' => array('audio' => 1), 623 ); 624 taxonomy_save_vocabulary($vocab); 625 $vid = $vocab['vid']; 626 } 627 variable_set('station_archive_vid', $vid); 628 } 629 return $vid; 630 } 631 632 /** 633 * Implementation of hook_taxonomy(). 634 * 635 * Delete our vocabulary variable if the vocabulary is deleted. 636 */ 637 function station_archive_taxonomy($op, $type, $object = NULL) { 638 if ($op == 'delete' && $type == 'vocabulary' && $object->vid == _station_archive_get_vid()) { 639 variable_del('station_archive_vid'); 640 } 641 } 642 643 /** 644 * Give a string with hours return an array of vocabulary term ids for the 645 * given hours. 646 * 647 * @param $vid 648 * integer vocabulary id 649 * @param $hour_string 650 * string with hours values, integers from 1 to 168 separated by spaces 651 */ 652 function _station_archive_get_hour_tids($vid, $hour_string = '') { 653 $ids = array(); 654 foreach (explode(' ', $hour_string) as $id) { 655 $id = (integer) $id; 656 if ($id > 0 && $id <= 24*7) { 657 $ids[] = $id; 658 } 659 } 660 sort($ids); 661 662 $tids = array(); 663 foreach ($ids as $id) { 664 $day = (integer) (($id - 1) / 24); 665 $hour = ($id - 1) % 24; 666 667 if ($dayterm = _station_archive_get_day_term($vid, $day)) { 668 if ($hourterm = _station_archive_get_hour_term($dayterm, $hour)) { 669 $tids[] = $hourterm['tid']; 670 } 671 } 672 } 673 674 return $tids; 675 } 676 677 /** 678 * Find the taxonomy term for a day. 679 * 680 * @param $vid 681 * Our vocabulary ID. 682 * @param $day 683 * Integer day between 0 and 6. 684 * @return 685 * Array with a day's taxonomy term, FALSE if it doesn't exist. 686 */ 687 function _station_archive_get_day_term($vid, $day) { 688 $dayname = station_day_name($day); 689 $result = db_query(db_rewrite_sql("SELECT t.tid, t.* FROM {term_data} t WHERE t.vid = %d AND LOWER('%s') LIKE LOWER(name)", 't', 'tid'), array($vid, trim($dayname))); 690 return db_fetch_array($result); 691 } 692 693 /** 694 * Find or create taxonomy term for a day. 695 * 696 * @param $dayterm 697 * Array day taxonomy term. 698 * @param $hour 699 * Integer hour between 0 and 23. 700 * @return 701 * Array with an hour's taxonomy term, false if it doesn't exist. 702 */ 703 function _station_archive_get_hour_term($dayterm, $hour) { 704 $minute = station_minute_from_day_hour(0, $hour); 705 $time = station_time_from_minute($minute); 706 $hourname = $time['time'] . $time['a']; 707 $result = db_query(db_rewrite_sql("SELECT d.tid, d.* FROM {term_data} d INNER JOIN {term_hierarchy} h ON d.tid = h.tid WHERE d.vid = %d AND h.parent = %d AND LOWER('%s') LIKE LOWER(name)", 't', 'tid'), array($dayterm['vid'], $dayterm['tid'], trim($hourname))); 708 return db_fetch_array($result); 709 } 710 711 /** 712 * Implementation of hook_views_api(). 713 */ 714 function station_archive_views_api() { 715 return array( 716 'api' => 2.0, 717 'path' => drupal_get_path('module', 'station_archive') . '/views', 718 ); 719 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated: Thu Mar 24 11:18:33 2011 | Cross-referenced by PHPXref 0.7 |