[ Index ]

PHP Cross Reference of Drupal 6 (gatewave)

title

Body

[close]

/sites/all/modules/station/archive/ -> station_archive.module (source)

   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  }


Generated: Thu Mar 24 11:18:33 2011 Cross-referenced by PHPXref 0.7