array( 'name' => t('Album'), 'module' => 'station_catalog_album', 'description' => t("An album in the station's library."), 'has_title' => FALSE, 'title_label' => '', 'has_body' => TRUE, 'body_label' => t('Description'), ) ); } /** * Implementation of hook_perm(). */ function station_catalog_perm() { return array( 'administer station catalog', 'view station album content', 'create station album content', 'edit any station album content', 'delete any station album content', ); } /** * Implementation of hook_access(). */ function station_catalog_album_access($op, $node, $account) { // Admins can do anything. if (user_access('administer station catalog', $account)) { return TRUE; } switch ($op) { case 'view': return user_access('view station album content', $account); case 'create': return user_access('create station album content', $account); case 'update': return user_access('edit any station album content', $account); case 'delete': return user_access('delete any station album content', $account); } } /** * Returns the the next unused album number. * * @return * Integer with the next, unused album number. */ function station_catalog_album_next_number() { return db_result(db_query('SELECT MAX(number) + 1 FROM {station_catalog}')); } /** * Implementation of hook_prepare(). */ function station_catalog_album_prepare(&$node) { if (isset($node->album['artist']) && isset($node->album['album'])) { if ($mb_info = _station_catalog_musicbrainz_album($node->album['artist'], $node->album['album'])) { $fields = array( 'artist' => t('Artist'), 'album' => t('Album'), 'year' => t('Year'), 'mb_release_id' => t('Music Brainz ID'), 'asin' => t('ASIN'), ); $adjusted = array(); foreach ($fields as $field => $name) { if (empty($node->album[$field])) { $adjusted[] = $name; $node->album[$field] = $mb_info[$field]; } } if ($adjusted) { drupal_set_message(t('Values for @fields fields were loaded from the MusicBrainz data.', array('@fields' => station_anded_list($adjusted)))); } } } } /** * Implementation of hook_form(). */ function station_catalog_album_form($node) { $type = node_get_types('type', $node); $form['album'] = array( '#type' => 'fieldset', '#title' => t('Album information'), '#tree' => TRUE, '#weight' => -4, ); $form['album']['number'] = array( '#type' => 'textfield', '#title' => t('Number'), '#default_value' => isset($node->album['number']) ? $node->album['number'] : '', '#description' => t("The album's log number must be numeric and unique."), ); $form['album']['artist'] = array( '#type' => 'textfield', '#title' => t('Artist'), '#default_value' => isset($node->album['artist']) ? $node->album['artist'] : '', '#required' => TRUE, '#maxlength' => 255, ); $form['album']['album'] = array( '#type' => 'textfield', '#title' => t('Album title'), '#default_value' => isset($node->album['album']) ? $node->album['album'] : '', '#required' => TRUE, '#maxlength' => 255, ); $form['album']['year'] = array( '#type' => 'textfield', '#title' => t('Year'), '#default_value' => isset($node->album['year']) ? $node->album['year'] : '', '#required' => TRUE, '#description' => t("The year the album was released."), ); $form['album']['label'] = array( '#type' => 'textfield', '#title' => t('Label'), '#default_value' => isset($node->album['label']) ? $node->album['label'] : '', '#required' => FALSE, '#maxlength' => 255, '#description' => t("Name of the label that released the album."), ); $form['album']['mb_release_id'] = array( '#type' => 'textfield', '#title' => t('Music Brainz Release ID'), '#default_value' => isset($node->album['mb_release_id']) ? $node->album['mb_release_id'] : '', '#required' => FALSE, '#maxlength' => 255, '#description' => t("MusicBrainz ID for this release."), ); $form['album']['asin'] = array( '#type' => 'textfield', '#title' => t('Amazon Standard Identification Number'), '#default_value' => isset($node->album['asin']) ? $node->album['asin'] : '', '#required' => FALSE, '#maxlength' => 255, '#description' => t("Amazon product ID for this album."), ); if ($type->has_body) { $form['body_filter']['body'] = array( '#type' => 'textarea', '#title' => check_plain($type->body_label), '#default_value' => isset($node->body) ? $node->body : '', '#rows' => 10, '#required' => ($type->min_word_count > 0), ); $form['body_filter']['format'] = filter_form($node->format); } $form['#submit'][] = 'station_catalog_album_node_form_submit'; return $form; } /** * Implementation of hook_validate(). */ function station_catalog_album_validate(&$node, &$form) { if ($node->album['number'] != '') { if (!is_numeric($node->album['number'])) { form_set_error('album][number', t('Album number must be a numeric value.')); } elseif ($node->album['number']) { // look for duplicate numbers if ($node->nid) { $query = db_query('SELECT sc.nid, n.title FROM {station_catalog} sc INNER JOIN {node} n ON sc.nid = n.nid WHERE sc.number = %d AND sc.nid <> %d', $node->album['number'], $node->nid); } else { $query = db_query('SELECT sc.nid, n.title FROM {station_catalog} sc INNER JOIN {node} n ON sc.nid = n.nid WHERE sc.number = %d', $node->album['number']); } if ($other_node = db_fetch_object($query)) { form_set_error('album][number', t('Another album %title already has this number.', array('@link' => url('node/'. $other_node->nid), '%title' => $other_node->title)) ); } } } if (!empty($node->album['year']) && !is_numeric($node->album['year'])) { form_set_error('album][year', t('Year must be a numeric value.')); } } /** * Form submit handler to set the node's title(). */ function station_catalog_album_node_form_submit($form, &$form_state) { // Compute the title. $form_state['values']['title'] = $form_state['values']['album']['artist'] .' - '. $form_state['values']['album']['album']; $form_state['values']['album']['number'] = ($form_state['values']['album']['number'] != '') ? $form_state['values']['album']['number'] : station_catalog_album_next_number(); } /** * Implementation of hook_load(). */ function station_catalog_album_load($node) { $result = db_query('SELECT number, artist, album, year, label, mb_release_id, asin FROM {station_catalog} WHERE nid = %d', $node->nid); return array('album' => db_fetch_array($result)); } /** * Implementation of hook_insert(). */ function station_catalog_album_insert($node) { $record = array_merge($node->album, array('nid' => $node->nid)); drupal_write_record('station_catalog', $record); } /** * Implementation of hook_delete(). */ function station_catalog_album_delete($node) { db_query("DELETE FROM {station_catalog} WHERE nid = %d", $node->nid); } /** * Implementation of hook_update(). */ function station_catalog_album_update($node) { db_query("DELETE FROM {station_catalog} WHERE nid = %d", $node->nid); db_query("INSERT INTO {station_catalog} (nid, number, artist, album, year, label, mb_release_id, asin) VALUES (%d, %d, '%s', '%s', %d, '%s', '%s', '%s')", $node->nid, $node->album['number'], $node->album['artist'], $node->album['album'], $node->album['year'], $node->album['label'], $node->album['mb_release_id'], $node->album['asin']); } /** * Implementation of hook_view(). */ function station_catalog_album_view(&$node, $teaser = FALSE, $page = FALSE) { $node = node_prepare($node, $teaser); if ($page) { $breadcrumb = drupal_get_breadcrumb(); $breadcrumb[] = l(t('Station'), 'station'); $breadcrumb[] = l(t('Catalog'), 'station/catalog/search'); drupal_set_breadcrumb($breadcrumb); } $node->content['album'] = array( 'number' => array( '#type' => 'item', '#title' => t('Number'), '#value' => $node->album['number'], '#weight' => -6, ), 'artist' => array( '#type' => 'item', '#title' => t('Artist'), '#value' => $node->album['artist'], '#weight' => -5, ), 'album' => array( '#type' => 'item', '#title' => t('Album'), '#value' => $node->album['album'], '#weight' => -4, ), 'year' => array( '#type' => 'item', '#title' => t('Year'), '#value' => $node->album['year'] ? $node->album['year'] : '', '#weight' => -3, ), 'label' => array( '#type' => 'item', '#title' => t('Label'), '#value' => $node->album['label'], '#weight' => -2, ), ); if (!empty($node->album['mb_release_id'])) { $node->content['album']['mb_release_id'] = array( '#type' => 'item', '#title' => t('MusicBrainz'), '#value' => l($node->album['mb_release_id'], "http://musicbrainz.org/release/{$node->album['mb_release_id']}.html"), '#weight' => 0, ); } if (!empty($node->album['asin'])) { $node->content['album']['asin'] = array( '#type' => 'item', '#title' => t('Amazon'), '#value' => l($node->album['asin'], 'http://www.amazon.com/gp/product/'. $node->album['asin']), '#weight' => 0, ); } return $node; } /** * Implementation of hook_taxonomy(). * * Delete our vocabulary variable if the vocabulary is deleted. */ function station_catalog_taxonomy($op, $type, $object = NULL) { if ($op == 'delete' && $type == 'vocabulary' && $object->vid == _station_catalog_get_vid()) { variable_del('station_catalog_vocabulary'); } } /** * Find or create a station catalog vocabulary ID. * * @return * Vocabulary ID. */ function _station_catalog_get_vid() { $vid = variable_get('station_catalog_vocabulary', ''); if (empty($vid)) { // Check to see if a a vocabulary exists $vid = db_result(db_query("SELECT vid FROM {vocabulary} WHERE module = '%s'", 'station_catalog')); if (!$vid) { $vocabulary = array( 'name' => t('Station album genres'), 'description' => t("Select the appropriate genre's for this album."), 'multiple' => '1', 'required' => '1', 'hierarchy' => '0', 'relations' => '0', 'module' => 'station_catalog', 'nodes' => array('station_album' => 1), ); taxonomy_save_vocabulary($vocabulary); $vid = $vocabulary['vid']; } variable_set('station_catalog_vocabulary', $vid); } return $vid; } function _station_catalog_musicbrainz_album($artist, $title) { $args = array( 'type' => 'xml', 'artist' => $artist, 'title' => $title ); $url = url('http://musicbrainz.org/ws/1/release/', array('query' => drupal_query_string_encode($args))); $ret = array(); $response = drupal_http_request($url); if ($response->code == 200) { $doc = DOMDocument::loadXML($response->data); $xpath = new DOMXPath($doc); // Can't use the default namespace, must explicitly set one... $xpath->registerNameSpace('mb', 'http://musicbrainz.org/ns/mmd-1.0#'); #dvm($doc->saveXML()); // Only return exact matches. $result = $xpath->query('//mb:release-list/mb:release[@ext:score="100"]'); if ($result && $result->length) { foreach ($result as $item) { $release = simplexml_import_dom($result->item(0)); # dvm($release); } $release = simplexml_import_dom($result->item(0)); $ret['mb_release_id'] = (string) $release['id']; $ret['artist'] = (string) $release->artist->name; $ret['album'] = (string) $release->title; $ret['asin'] = (string) $release->asin; // Release year is a bit of a pain, the tag name isn't a valid PHP // identifier and we need to use a regular expression to match the // year portion of the ate. $event = 'release-event-list'; preg_match('/.*US (\d{4}).*/', $release->$event->event['date'], $matches); $ret['year'] = (string) $matches[1]; // Now that we've got the release id, we need to make another call to get the label. # $label = _station_catalog_musicbrainz_label($ret['mb_release_id']); $ret['label'] = ''; } } return $ret; } function _station_catalog_musicbrainz_label($release_id) { $args = array( 'type' => 'xml', 'inc' => 'labels', ); $url = url('http://musicbrainz.org/ws/1/release/'. $release_id, array('query' => drupal_query_string_encode($args))); dvm($url); $ret = array(); $response = drupal_http_request($url); if ($response->code == 200) { $doc = DOMDocument::loadXML($response->data); dvm($doc->savexml()); } return $ret; } /** * Implementation of hook_view_api(). */ function station_catalog_views_api() { return array( 'api' => 2.0, ); }