[ Index ]

PHP Cross Reference of Drupal 6 (gatewave)

title

Body

[close]

/sites/all/modules/station/playlist/ -> station_playlist.module (source)

   1  <?php
   2  // $Id: station_playlist.module,v 1.27 2010/11/06 21:11:01 timplunkett Exp $
   3  
   4  /**
   5   * Implementation of hook_help().
   6   */
   7  function station_playlist_help($path, $arg) {
   8    switch ($path) {
   9      case 'admin/settings/station/playlist':
  10        return t("These settings allow you to configure the playlist node.");
  11    }
  12  }
  13  
  14  /**
  15   * Implementation of hook_menu().
  16   */
  17  function station_playlist_menu() {
  18    $items['admin/settings/station/playlist'] = array(
  19      'title' => 'Playlist',
  20      'page callback' => 'drupal_get_form',
  21      'page arguments' => array('station_playlist_admin_settings'),
  22      'access arguments' => array('administer site configuration'),
  23      'file' => 'station_playlist.admin.inc',
  24      'type' => MENU_LOCAL_TASK
  25    );
  26  
  27    $items['station/autocomplete/playlist'] = array(
  28      'title' => 'Playlist Autocomplete',
  29      'page callback' => 'station_playlist_autocomplete',
  30      'access arguments' => array('access content'),
  31      'type' => MENU_CALLBACK,
  32    );
  33  
  34    $items['station/ahah/playlist'] = array(
  35      'page callback' => 'station_playlist_ahah',
  36      'page arguments' => array(),
  37      'access arguments' => array('access content'),
  38      'type' => MENU_CALLBACK,
  39    );
  40    return $items;
  41  }
  42  
  43  /**
  44   * Implementation of hook_theme().
  45   */
  46  function station_playlist_theme() {
  47    return array(
  48      'station_playlist_track_form' => array(
  49        'arguments' => array('form' => NULL),
  50      ),
  51    );
  52  }
  53  
  54  /**
  55   * Implementation of hook_node_info().
  56   */
  57  function station_playlist_node_info() {
  58    return array(
  59      'station_playlist' => array(
  60        'name' => t('Program Playlist'),
  61        'module' => 'station_playlist',
  62        'description' => t("A playlist lets your listeners see a list of all the music played during a program. It also allows the music director to easily chart what's being played."),
  63        'has_title' => TRUE,
  64        'title_label' => t('Title'),
  65        'has_body' => TRUE,
  66        'body_label' => t('Description'),
  67      )
  68    );
  69  }
  70  
  71  /**
  72    * Implementation of hook_perm().
  73   */
  74  function station_playlist_perm() {
  75    return array(
  76      'administer station playlists',
  77      'view station playlist content',
  78      'create station playlist content',
  79      'edit any station playlist content',
  80      'edit own station playlist content',
  81      'delete any station playlist content',
  82      'delete own station playlist content',
  83    );
  84  }
  85  
  86  /**
  87   * Implementation of hook_link().
  88   *
  89   * This is implemented so that an edit link is displayed for users who have
  90   * the rights to edit a node.
  91   */
  92  function station_playlist_link($type, $object, $teaser = FALSE) {
  93    if ($type == 'node') {
  94      switch ($object->type) {
  95        case 'station_program':
  96          $links = array();
  97  
  98          $field = content_fields('field_station_program', 'station_playlist');
  99          $db_info = content_database_info($field);
 100          $col = $db_info['columns']['nid']['column'];
 101          $result = db_query(db_rewrite_sql("SELECT COUNT(n.nid) FROM {node} n INNER JOIN {{$db_info['table']}} sp ON n.nid = sp.$col WHERE sp.$col = %d AND n.status = 1"), $object->nid);
 102          if (db_result($result)) {
 103            $links['station_station_playlist_view'] = array(
 104              'title' => t('View all playlists'),
 105              'href' => 'station/playlists/'. $object->nid,
 106            );
 107          }
 108  
 109          if (!$teaser) {
 110            if (node_access('update', $object)) {
 111              $links['station_station_playlist_add'] = array(
 112                'title' => t('Add new playlist'),
 113                'href' => 'node/add/station-playlist/'. $object->nid,
 114              );
 115            }
 116          }
 117          return $links;
 118  
 119        case 'station_playlist':
 120          if (!empty($object->field_station_program[0]['nid'])) {
 121            return array('station_program_program_view' => array(
 122              'title' => t('View program'),
 123               'href' => 'node/'. $object->field_station_program[0]['nid'],
 124            ));
 125          }
 126      }
 127    }
 128    return array();
 129  }
 130  
 131  /**
 132   * Implementation of hook_access().
 133   */
 134  function station_playlist_access($op, $node, $account) {
 135    if (user_access('administer station playlists', $account)) {
 136      return TRUE;
 137    }
 138  
 139    switch ($op) {
 140      case 'view':
 141        return user_access('view station playlist content', $account);
 142  
 143      case 'create':
 144        return user_access('create station playlist content', $account);
 145  
 146      case 'update':
 147        if (user_access('edit own station playlist content', $account) && ($account->uid == $node->uid)) {
 148          return TRUE;
 149        }
 150        return user_access('edit any station playlist content', $account);
 151  
 152      case 'delete':
 153        if (user_access('delete own station playlist content', $account) && ($account->uid == $node->uid)) {
 154          return TRUE;
 155        }
 156        return user_access('delete any station playlist content', $account);
 157    }
 158  }
 159  
 160  /**
 161   * Does this track have all the required fields be saved?
 162   *
 163   * Tracks need to have an artist or title to be saved to the database.
 164   *
 165   * @param $track
 166   *   Array with track information.
 167   * @return
 168   *   The track has some values filled in but is missing an artist or title.
 169   * @see station_playlist_track_is_incomplete()
 170   */
 171  function station_playlist_track_is_saveable($track) {
 172    return ($track['artist'] || $track['title']);
 173  }
 174  
 175  /**
 176   * Does an unsavable track have other values set?
 177   *
 178   * @param $track
 179   *   Array with track information.
 180   * @return
 181   *   The track has some values filled in but is missing an artist or title.
 182   * @see station_playlist_track_is_empty()
 183   */
 184  function station_playlist_track_is_incomplete($track) {
 185    return ($track['album'] || $track['label'] || $track['link']) && !($track['artist'] || $track['title']);
 186  }
 187  
 188  /**
 189   * Helper function to build an empty track row.
 190   */
 191  function station_playlist_get_empty_track() {
 192    static $track;
 193  
 194    if (!isset($track)) {
 195      $track = array(
 196        'artist' => '',
 197        'album' => '',
 198        'title' => '',
 199        'label' => '',
 200        'link' => '',
 201        'weight' => 9999,
 202      );
 203      drupal_alter('station_playlist_empty_track', $track);
 204    }
 205    return $track;
 206  }
 207  
 208  /**
 209   * Implementation of hook_form().
 210   *
 211   * Build a form for playlist nodes.
 212   */
 213  function station_playlist_form(&$node, $form_state) {
 214    // if this is a new node (with no nid) and we've got a numeric argument,
 215    // assume that's the program we should attach to.
 216    if (empty($node->nid) && is_numeric(arg(3))) {
 217      $node->field_station_program[0]['nid'] = (int) arg(3);
 218    }
 219  
 220    // Figure out how many empty rows we have and decide if we need to add some
 221    // more.
 222    if (isset($node->tracks)) {
 223      $num_empty_tracks = 5;
 224      foreach ($node->tracks as $track) {
 225        if (!station_playlist_track_is_saveable($track)) {
 226          $num_empty_tracks--;
 227        }
 228      }
 229    }
 230    else {
 231      // New playlists get 10 blank tracks.
 232      $num_empty_tracks = 10;
 233      $node->tracks = array();
 234    }
 235    $empty_track = station_playlist_get_empty_track();
 236    for ($i = 0; $i < $num_empty_tracks; $i++) {
 237      $node->tracks[] = $empty_track;
 238    }
 239  
 240    $form['body_filter']['body'] = array(
 241      '#type' => 'textarea',
 242      '#title' => t('Description'),
 243      '#default_value' => $node->body,
 244      '#rows' => 5,
 245    );
 246    $form['body_filter']['format'] = filter_form($node->format);
 247  
 248    // Wrapper to hold all the tracks elements.
 249    $form['tracks_wrapper'] = array(
 250      '#value' => '<label>'. t('Tracks') .':</label>',
 251      '#prefix' => '<div class="clear-block form-item" id="station-playlist-tracks-wrapper">',
 252      '#suffix' => '</div>',
 253      '#theme' => 'station_playlist_track_form',
 254      '#description' => t('Enter the tracks played on the show, the artist and title are required. If you provide a link, it needs to begin with <code>http://</code> or you will get a link to a page on this site.'),
 255      '#tree' => FALSE,
 256    );
 257    // Container to display existing tracks.
 258    $form['tracks_wrapper']['tracks'] = array(
 259      '#prefix' => '<div id="station-playlist-tracks">',
 260      '#suffix' => '</div>',
 261      '#tree' => TRUE,
 262    );
 263  
 264    foreach ($node->tracks as $weight => $track) {
 265      $form['tracks_wrapper']['tracks'][$weight]['artist'] = array(
 266        '#type' => 'textfield',
 267        '#size' => 20,
 268        '#maxlength' => 255,
 269        '#default_value' => isset($track['artist']) ? $track['artist'] : '',
 270        '#autocomplete_path' => 'station/autocomplete/playlist/artist',
 271      );
 272      $form['tracks_wrapper']['tracks'][$weight]['album'] = array(
 273        '#type' => 'textfield',
 274        '#size' => 20,
 275        '#maxlength' => 255,
 276        '#default_value' => isset($track['album']) ? $track['album'] : '',
 277        '#autocomplete_path' => 'station/autocomplete/playlist/album',
 278      );
 279      $form['tracks_wrapper']['tracks'][$weight]['title'] = array(
 280        '#type' => 'textfield',
 281        '#size' => 20,
 282        '#maxlength' => 255,
 283        '#default_value' => isset($track['title']) ? $track['title'] : '',
 284      );
 285      $form['tracks_wrapper']['tracks'][$weight]['label'] = array(
 286        '#type' => 'textfield',
 287        '#size' => 20,
 288        '#maxlength' => 255,
 289        '#default_value' => isset($track['label']) ? $track['label'] : '',
 290        '#autocomplete_path' => 'station/autocomplete/playlist/label',
 291      );
 292      $form['tracks_wrapper']['tracks'][$weight]['link'] = array(
 293        '#type' => 'textfield',
 294        '#size' => 20,
 295        '#maxlength' => 255,
 296        '#default_value' => isset($track['link']) ? $track['link'] : '',
 297      );
 298      $form['tracks_wrapper']['tracks'][$weight]['weight'] = array(
 299        '#type' => 'weight',
 300        '#default_value' => $weight,
 301        '#delta' => 100,
 302      );
 303      // Remove button.
 304      $form['tracks_wrapper']['tracks'][$weight]['remove'] = array(
 305        '#type' => 'submit',
 306        '#name' => 'remove_' . $weight,
 307        '#value' => t('Remove'),
 308        '#submit' => array('station_playlist_form_ahah_track_submit'),
 309        '#ahah' => array(
 310          'path' => 'station/ahah/playlist',
 311          'wrapper' => 'station-playlist-tracks-wrapper',
 312          'method' => 'replace',
 313          'effect' => 'fade',
 314        ),
 315      );
 316    }
 317  
 318    // We name our button 'add_more' to avoid conflicts with other modules using
 319    // AHAH-enabled buttons with the id 'more'.
 320    $form['tracks_wrapper']['add_more'] = array(
 321      '#type' => 'submit',
 322      '#value' => t('Add more'),
 323      '#weight' => 1,
 324      '#submit' => array('station_playlist_form_ahah_track_submit'),
 325      '#ahah' => array(
 326        'path' => 'station/ahah/playlist',
 327        'wrapper' => 'station-playlist-tracks-wrapper',
 328        'method' => 'replace',
 329        'effect' => 'fade',
 330      ),
 331    );
 332    $form['#validate'][] = 'station_playlist_node_form_validate';
 333    $form['#submit'][] = 'station_playlist_node_form_submit';
 334    return $form;
 335  }
 336  
 337  /**
 338   * A do nothing submit function to prevent the form from saving.
 339   */
 340  function station_playlist_form_ahah_track_submit($form, &$form_state) {
 341    // Set the form to rebuild and run submit handlers.
 342    node_form_submit_build_node($form, $form_state);
 343  }
 344  
 345  function theme_station_playlist_track_form($form) {
 346    // To have the drag and drop not totally wack out the formatting we need
 347    // the first column in the table with no form element.
 348    $header = array('', t('Artist'), t('Title'), t('Album'), t('Label'), t('Link'), t('Weight'), '');
 349  
 350    $rows = array();
 351    foreach (element_children($form['tracks']) as $key) {
 352      $form['tracks'][$key]['weight']['#attributes']['class'] = 'track-weight';
 353      $row = array(
 354        '',
 355        drupal_render($form['tracks'][$key]['artist']),
 356        drupal_render($form['tracks'][$key]['title']),
 357        drupal_render($form['tracks'][$key]['album']),
 358        drupal_render($form['tracks'][$key]['label']),
 359        drupal_render($form['tracks'][$key]['link']),
 360        drupal_render($form['tracks'][$key]['weight']),
 361        drupal_render($form['tracks'][$key]['remove']),
 362      );
 363      $rows[] = array('data' => $row, 'class' => 'draggable');
 364    }
 365  
 366    $output = '';
 367    if (count($rows)) {
 368      drupal_add_tabledrag('station-playlist-tracks-table', 'order', 'sibling', 'track-weight');
 369      $output .= theme('table', $header, $rows, array('id' => 'station-playlist-tracks-table'));
 370    }
 371  
 372    return $output . drupal_render($form);
 373  }
 374  
 375  function station_playlist_node_form_validate($form, &$form_state) {
 376    $tracks = $form_state['values']['tracks'];
 377  
 378    // Check if a track should be removed.
 379    if (isset($form_state['clicked_button']['#parents'][2]) && $form_state['clicked_button']['#parents'][2] == 'remove') {
 380      $delta = $form_state['clicked_button']['#parents'][1];
 381      unset($tracks[$delta]);
 382    }
 383  
 384    // Sort the table by weight (which might have changed with a tablesort)
 385    // then reset the keys.
 386    usort($tracks, '_station_playlist_sort_tracks');
 387    $tracks = array_values($tracks);
 388    // Now strip the previous weights which may not be adjacent and update the
 389    // track's weights.
 390    foreach ($tracks as $key => $track) {
 391      $track['weight'] = $key;
 392    }
 393  
 394    // Check if they've requested a new track.
 395    if (isset($form_state['clicked_button']['#parents'][0]) && $form_state['clicked_button']['#parents'][0] == 'add_more') {
 396      // Add the new row to the tracks list.
 397      $track = station_playlist_get_empty_track();
 398      for ($i = 0; $i < 5; $i++) {
 399        $tracks[] = $track;
 400      }
 401    }
 402  
 403    form_set_value($form['tracks_wrapper']['tracks'], $tracks, $form_state);
 404  }
 405  
 406  /**
 407   * Helper function to sort tracks by weight.
 408   */
 409  function _station_playlist_sort_tracks($a, $b) {
 410    if ((int) $a['weight'] == (int) $b['weight']) {
 411      return 0;
 412    }
 413    return ((int) $a['weight'] < (int) $b['weight']) ? -1 : 1;
 414  }
 415  
 416  /**
 417   * Implementation of hook_validate().
 418   *
 419   * Use this hook to convert form elements to node values.
 420   */
 421  function station_playlist_validate(&$node, &$form) {
 422    // Check for missing track information.
 423    foreach ($node->tracks as $track) {
 424      if (station_playlist_track_is_incomplete($track)) {
 425        form_set_error('tracks]['. $track['weight'] .'][artist', t("You must provide either an artist or a title."));
 426        form_set_error('tracks]['. $track['weight'] .'][title', ' ');
 427      }
 428    }
 429  }
 430  
 431  function station_playlist_ahah() {
 432    // The form is generated in an include file which we need to include manually.
 433    include_once  'modules/node/node.pages.inc';
 434  
 435    $form = station_ajax_form_handler();
 436  
 437    // Render the new output.
 438    $sub_form = $form['tracks_wrapper'];
 439    // Prevent duplicate wrappers.
 440    unset($sub_form['#prefix'], $sub_form['#suffix']);
 441  
 442    $output = theme('status_messages') . drupal_render($sub_form);
 443  
 444    // AHAH is not being nice to us and doesn't know about the "Remove" button.
 445    // This causes it not to attach AHAH behaviours to it after modifying the form.
 446    // So we need to tell it first.
 447    $javascript = drupal_add_js(NULL, NULL);
 448    if (isset($javascript['setting'])) {
 449      $output .= '<script type="text/javascript">jQuery.extend(Drupal.settings, '. drupal_to_js(call_user_func_array('array_merge_recursive', $javascript['setting'])) .');</script>';
 450    }
 451  
 452    // Final rendering callback.
 453    drupal_json(array('status' => TRUE, 'data' => $output));
 454  }
 455  
 456  /**
 457   * Form submit handler to set the node's title().
 458   */
 459  function station_playlist_node_form_submit($form, &$form_state) {
 460    // Compute the title.
 461    $form_state['values']['title'] = t('!program-title playlist for !date', array(
 462      '!program-title' => _nodereference_titles($form_state['values']['field_station_program'][0]['nid']),
 463      '!date' => format_date($form_state['values']['field_station_playlist_date'][0]['value'], 'custom', variable_get('station_playlist_title_dateformat', 'm/d/Y')),
 464    ));
 465  }
 466  
 467  
 468  /**
 469   * Implementation of hook_load().
 470   */
 471  function station_playlist_load($node) {
 472    // Tracks
 473    $extras = new stdClass();
 474    $extras->tracks = array();
 475    $result = db_query('SELECT * FROM {station_playlist_track} WHERE nid = %d ORDER BY weight', $node->nid);
 476    while ($track = db_fetch_array($result)) {
 477      $extras->tracks[] = $track;
 478    }
 479  
 480    return $extras;
 481  }
 482  
 483  /**
 484   * Insert a new playlist
 485   */
 486  function station_playlist_insert($node) {
 487    foreach ($node->tracks as $track) {
 488      if (station_playlist_track_is_saveable($track)) {
 489        $record = array_merge($track, array('nid' => $node->nid, 'vid' => $node->vid));
 490        drupal_write_record('station_playlist_track', $record);
 491      }
 492    }
 493  }
 494  
 495  /**
 496   * Delete a playlist.
 497   */
 498  function station_playlist_delete($node) {
 499    db_query('DELETE FROM {station_playlist_track} WHERE nid = %d', $node->nid);
 500  }
 501  
 502  /**
 503   * Update a playlist.
 504   */
 505  function station_playlist_update($node) {
 506    // delete and re-add tracks
 507    db_query('DELETE FROM {station_playlist_track} WHERE nid = %d', $node->nid);
 508    foreach ($node->tracks as $track) {
 509      if (station_playlist_track_is_saveable($track)) {
 510        $record = array_merge($track, array('nid' => $node->nid, 'vid' => $node->vid));
 511        drupal_write_record('station_playlist_track', $record);
 512      }
 513    }
 514  }
 515  
 516  /**
 517   * Get a playlist ready for viewing.
 518   */
 519  function station_playlist_view(&$node, $teaser = false, $page = false) {
 520    $node = node_prepare($node, $teaser);
 521  
 522    if ($page) {
 523      $program_nid = $node->field_station_program[0]['nid'];
 524      $breadcrumb = drupal_get_breadcrumb();
 525      $breadcrumb[] = l(t('Station'), 'station');
 526      $breadcrumb[] = l(t('Programs'), 'station/programs');
 527      $breadcrumb[] = l(_nodereference_titles($program_nid), 'node/'. $program_nid);
 528      drupal_set_breadcrumb($breadcrumb);
 529    }
 530  
 531    if (!$teaser && isset($node->nid)) {
 532      if ($view = views_get_view('station_playlist_tracks')) {
 533        $display_id = 'default';
 534        if ($view->access($display_id)) {
 535          if ($output = $view->preview($display_id, array($node->nid))) {
 536            $node->content['tracks'] = array(
 537              '#value' => $output,
 538              '#title' => 'Tracks',
 539              '#weight' => 0,
 540            );
 541          }
 542        }
 543        $view->destroy();
 544      }
 545    }
 546    return $node;
 547  }
 548  
 549  /**
 550   * Implementation of hook_nodeapi().
 551   *
 552   * We inject our past and future playlists onto program nodes here.
 553   */
 554  function station_playlist_nodeapi(&$node, $op, $teaser, $page) {
 555    if ($node->type == 'station_program' && $op == 'view') {
 556      $block_content_mapping = array(
 557        'block_1' => 'playlists_future',
 558        'block_2' => 'playlists_past',
 559      );
 560      foreach ($block_content_mapping as $display_id => $content_key) {
 561        if ($view = views_get_view('station_program_playlists')) {
 562          if ($view->access($display_id)) {
 563            $block = $view->execute_display($display_id);
 564            if (isset($block)) {
 565              $node->content[$content_key]['#type'] = 'item';
 566              $node->content[$content_key]['#title'] = $block['subject'];
 567              $node->content[$content_key]['#value'] = $block['content'];
 568            }
 569          }
 570          $view->destroy();
 571        }
 572      }
 573    }
 574  }
 575  
 576  /**
 577   * Retrieve a list of autocomplete suggestions for playlist items.
 578   *
 579   * @param $field
 580   *   The name of the field to match: 'artist', 'album', 'label'
 581   * @param $string
 582   *   The value to search for.
 583   */
 584  function station_playlist_autocomplete($field = '', $string = '') {
 585    $matches = array();
 586    if (in_array($field, array('artist', 'album', 'label'))) {
 587      $sql = NULL;
 588      $catalog_sql  = 'SELECT DISTINCT %s AS val FROM {station_catalog}        WHERE LOWER(%s) LIKE LOWER("%s%%")';
 589      $playlist_sql = 'SELECT DISTINCT %s AS val FROM {station_playlist_track} WHERE LOWER(%s) LIKE LOWER("%s%%")';
 590      $args = array($field, $field, $string);
 591      switch (variable_get('station_playlist_track_autocomplete_source', 'playlists')) {
 592        case 'playlists':
 593          $sql = $playlist_sql;
 594          break;
 595  
 596        case 'catalog':
 597          $sql = $catalog_sql;
 598          break;
 599  
 600        case 'both':
 601          $sql = $catalog_sql . ' UNION ' . $playlist_sql;
 602          $args = array_merge($args, $args);
 603          break;
 604      }
 605  
 606      if ($sql) {
 607        $result = db_query_range($sql . ' ORDER BY val', $args, 0, 10);
 608        while ($item = db_fetch_object($result)) {
 609          $matches[$item->val] = check_plain($item->val);
 610        }
 611      }
 612    }
 613  
 614    print drupal_to_js($matches);
 615    exit();
 616  }
 617  
 618  /**
 619   * Implementation of hook_content_extra_fields.
 620   *
 621   * Let CCK know about the playlist stuff we're putting on nodes.
 622   */
 623  function station_playlist_content_extra_fields($type_name) {
 624    switch ($type_name) {
 625      case 'station_playlist':
 626        return array(
 627          'tracks' => array(
 628            'label' => t('Tracks'),
 629            'description' => t('Station Playlist module form.'),
 630            'weight' => 0,
 631          ),
 632        );
 633  
 634      case 'station_program':
 635        return array(
 636          'playlists_future' => array(
 637            'label' => t('Upcoming shows'),
 638            'description' => t('Station Playlist module form.'),
 639            'weight' => 1,
 640          ),
 641          'playlists_past' => array(
 642            'label' => t('Previous shows'),
 643            'description' => t('Station Playlist module form.'),
 644            'weight' => 2,
 645          ),
 646        );
 647    }
 648  }
 649  
 650  /**
 651   * Implementation of hook_view_api().
 652   */
 653  function station_playlist_views_api() {
 654    return array(
 655      'api' => 2.0,
 656      'path' => drupal_get_path('module', 'station_playlist'),
 657    );
 658  }


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