Index: audio_itunes.info
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/audio/contrib/itunes/audio_itunes.info,v
retrieving revision 1.4
diff -u -p -r1.4 audio_itunes.info
--- audio_itunes.info	2 Oct 2008 07:12:35 -0000	1.4
+++ audio_itunes.info	24 Nov 2008 21:04:25 -0000
@@ -2,6 +2,8 @@
 name = Audio iTunes
 description = An iTunes specific RSS plugin for views feeds.
 package = Audio
-;WAITING ON UPDATE: core = 6.x
+; DOESN'T WORK WITHOUT VIEWS2 PATCH AT http://drupal.org/node/338632
+; core = 6.x
+dependencies[] = audio
 dependencies[] = views
 dependencies[] = views_ui
Index: audio_itunes.install
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/audio/contrib/itunes/audio_itunes.install,v
retrieving revision 1.2
diff -u -p -r1.2 audio_itunes.install
--- audio_itunes.install	25 May 2008 17:21:27 -0000	1.2
+++ audio_itunes.install	24 Nov 2008 21:04:25 -0000
@@ -6,7 +6,6 @@
  */
 function audio_itunes_install() {
   drupal_install_schema('audio_itunes');
-  _audio_add_default_perms();
 }
 
 /**
@@ -20,71 +19,6 @@ function audio_itunes_uninstall() {
  * Implementation of hook_schema().
  */
 function audio_itunes_schema() {
-  $schema['audio_itunes_channel'] = array(
-    'description' => t('Audio iTunes channel.'),
-    'fields' => array(
-      'view_id' => array(
-        'type' => 'int',
-        'size' => 'medium',
-        'not null' => 'true',
-        'default' => 0,
-      ),
-      'subtitle' => array(
-        'type' => 'varchar',
-        'length' => 255,
-        'not null' => 'true',
-        'default' => '',
-      ),
-      'summary' => array(
-        'type' => 'text',
-        'size' => 'medium',
-        'not null' => 'true',
-      ),
-      'author' => array(
-        'type' => 'varchar',
-        'length' => 255,
-        'not null' => 'true',
-        'default' => '',
-      ),
-      'copyright' => array(
-        'type' => 'varchar',
-        'length' => 255,
-        'not null' => 'true',
-        'default' => '',
-      ),
-      'owner_name' => array(
-        'type' => 'varchar',
-        'length' => 255,
-        'not null' => 'true',
-        'default' => '',
-      ),
-      'owner_email' => array(
-        'type' => 'varchar',
-        'length' => 255,
-        'not null' => 'true',
-        'default' => '',
-      ),
-      'image_url' => array(
-        'type' => 'varchar',
-        'length' => 255,
-        'not null' => 'true',
-        'default' => '',
-      ),
-      'block' => array(
-        'type' => 'int',
-        'size' => 'tiny',
-        'not null' => 'true',
-        'default' => 0,
-      ),
-      'explicit' => array(
-        'type' => 'int',
-        'size' => 'tiny',
-        'not null' => 'true',
-        'default' => 0,
-      ),
-    ),
-    'primary key' => array('view_id'),
-  );
   $schema['audio_itunes_item'] = array(
     'description' => t('Audio iTunes item.'),
     'fields' => array(
@@ -128,3 +62,16 @@ function audio_itunes_schema() {
   );
   return $schema;
 }
+
+/**
+ * Update to remove the unused {audio_itunes_channel} table.
+ */
+// FIXME: Commented out until I can figure out some way to pass the data out
+// to admins so they can copy/paste into their views.
+function _audio_itunes_update_6000() {
+  $ret = array();
+
+  db_drop_table($ret, 'audio_itunes_channel');
+
+  return $ret;
+}
\ No newline at end of file
Index: audio_itunes.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/audio/contrib/itunes/audio_itunes.module,v
retrieving revision 1.8
diff -u -p -r1.8 audio_itunes.module
--- audio_itunes.module	22 Oct 2008 18:49:51 -0000	1.8
+++ audio_itunes.module	24 Nov 2008 21:04:26 -0000
@@ -4,32 +4,13 @@
 define('AUDIO_ITUNES_EXPLICIT_YES', 1);
 define('AUDIO_ITUNES_EXPLICIT_CLEAN', 2);
 
-function audio_itunes_menu() {
-  $items = array();
-
-  /* FIXME: Get this into an access callback
-    // insert a iTunes tab on views our argument handler
-    if (user_access('administer views') &&
-        arg(0) == 'admin' &&  arg(1) == 'build' && arg(2) == 'views') {
-      if ($view = views_load_view(arg(3))) {
-        foreach ($view->argument as $index => $argument) {
-          if ($argument['type'] == 'audio_itunes_feed') {
-            break;
-          }
-        }
-      }
-    }
-  }
-   */
-
-  $items['admin/build/views/%view/itunes'] = array(
-    'title' => 'iTunes',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('audio_itunes_channel_form', 1),
-    'type' => MENU_LOCAL_TASK,
+/**
+ * Implementation of hook_views_api().
+ */
+function audio_itunes_views_api() {
+  return array(
+    'api' => 2,
   );
-
-  return $items;
 }
 
 /**
@@ -144,369 +125,3 @@ function audio_itunes_explicit($value) {
   }
   return 'no';
 }
-
-
-/**
- * Load an iTunes channel as an array.
- */
-function audio_itunes_channel_load($view_id) {
-  $channel = db_fetch_array(db_query("SELECT * FROM {audio_itunes_channel} WHERE view_id=%d", $view_id));
-  if (!$channel) {
-    $channel = array();
-  }
-  return $channel;
-}
-
-/**
- * For for editing the view's channel specific information.
- */
-function audio_itunes_channel_form($view_id) {
-  $form = array();
-
-  $form['view_id'] = array(
-    '#type' => 'value',
-    '#value' => $view_id,
-  );
-
-  $channel = audio_itunes_channel_load($view_id);
-
-  $form['subtitle'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Subtitle'),
-    '#default_value' => $channel['subtitle'],
-    '#maxlength' => 255,
-    '#description' => t("The contents of this tag are shown in the Description column in iTunes. The subtitle displays best if it is only a few words long."),
-  );
-  $form['summary'] = array(
-    '#type' => 'textarea',
-    '#title' => t('Summary'),
-    '#default_value' => $channel['summary'],
-    '#maxlength' => 4000,
-    '#rows' => 5,
-    '#description' => t('The contents of this tag are shown in a separate window that appears when the "circled i" in the Description column is clicked. It also appears on the iTunes page for your podcast.'),
-  );
-  $form['author'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Author'),
-    '#default_value' => $channel['author'],
-    '#maxlength' => 255,
-    '#description' => t("This is shown in the Artist column in iTunes."),
-  );
-  $form['copyright'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Copyright'),
-    '#default_value' => $channel['copyright'],
-    '#maxlength' => 255,
-    '#description' => t('i.e. "&#xA9; 2005 John Doe"'),
-  );
-  $form['image_url'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Image URL'),
-    '#default_value' => $channel['image_url'],
-    '#maxlength' => 255,
-    '#description' => t('This specifies the artwork for your podcast. iTunes prefers square .jpg images that are at least 300 x 300 pixels, which is different than what is specified for the standard RSS image tag. iTunes supports images in JPEG and PNG formats. The URL must end in ".jpg" or ".png". If you change your podcast’s image, also change the file’s name. iTunes may not change the image if it checks your feed and the image URL is the same.'),
-  );
-  $form['explicit'] = array(
-    '#type' => 'select', '#title' => t('Explicit'),
-    '#options' => array(0 => 'Unspecified', AUDIO_ITUNES_EXPLICIT_YES => 'Yes', AUDIO_ITUNES_EXPLICIT_CLEAN => 'Clean'),
-    '#default_value' => $channel['explicit'],
-    '#description' => t('If select "yes", an "explicit" parental advisory graphic will appear next to your podcast artwork on the iTunes Music Store, and in the Name column in iTunes. If you select "clean", the parental advisory type is considered Clean, meaning that no explicit language or adult content is included anywhere in the episode, and a "clean" graphic will appear.'),
-  );
-  $form['block'] = array(
-    '#type' => 'checkbox', '#title' => t('Hide'),
-    '#default_value' => $channel['block'],
-    '#description' => t('Check this to prevent the entire podcast from appearing in the iTunes Podcast directory.'),
-  );
-  $form['owner'] = array(
-    '#type' => 'fieldset',
-    '#title' => t('Owner'),
-    '#collapsible' => FALSE,
-    '#tree' => FALSE,
-    '#description' => t("Apple uses this information to contact the owner of the podcast for communication specifically about their podcast. It will not be publicly displayed but it may be picked up by spammers."),
-  );
-  $form['owner']['owner_name'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Name'),
-    '#default_value' => $channel['owner_name'],
-    '#maxlength' => 255,
-  );
-  $form['owner']['owner_email'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Email'),
-    '#default_value' => $channel['owner_email'],
-    '#maxlength' => 255,
-  );
-  $form['buttons']['submit'] = array(
-    '#type' => 'submit',
-    '#value' => t('Save'),
-  );
-  return $form;
-}
-
-function audio_itunes_channel_form_validate($form, &$form_state) {
-  if (!empty($form_state['values']['image_url'])) {
-    if (!valid_url($form_state['values']['image_url'])) {
-      form_set_error('image_url', t('The image URL must be a valid URL.'));
-    }
-    else {
-      $url = parse_url($form_state['values']['image_url']);
-      $ext = strtolower(pathinfo($url['path'], PATHINFO_EXTENSION));
-      if (!isset($url['path']) || ($ext != 'jpg' && $ext != 'png')) {
-        form_set_error('image_url', t('The URL must specify a file ending with <code>.jpg</code> or <code>.png</code>.'));
-      }
-    }
-  }
-  if (!empty($form_state['values']['owner_email']) && !valid_email_address($form_state['values']['owner_email'])) {
-    form_set_error('owner_email', t('The owner email must be a valid email address.'));
-  }
-}
-
-function audio_itunes_channel_form_submit($form, &$form_state) {
-  if ($form_state['values']['view_id']) {
-    // delete and insert rather than updating in case the node doesn't have an existing record
-    db_query("DELETE FROM {audio_itunes_channel} WHERE view_id = %d", $form_state['values']['view_id']);
-    db_query("INSERT INTO {audio_itunes_channel} (view_id, subtitle, summary, author, copyright, owner_name, owner_email, image_url, block, explicit) VALUES (%d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d)",
-      $form_state['values']['view_id'], $form_state['values']['subtitle'], $form_state['values']['summary'], $form_state['values']['author'], $form_state['values']['copyright'], $form_state['values']['owner_name'], $form_state['values']['owner_email'], $form_state['values']['image_url'], $form_state['values']['block'], $form_state['values']['explicit']);
-  }
-}
-
-function audio_itunes_feed_channel_arguments($view) {
-  $itunes = audio_itunes_channel_load($view->vid);
-
-  $ret = array();
-  if ($itunes['author']) {
-    $ret['itunes:author'] = $itunes['author'];
-  }
-  if ($itunes['image_url']) {
-    $ret[] = array('key' => 'itunes:image', 'attributes' => array('href' => $itunes['image_url']));
-  }
-  if ($itunes['subtitle']) {
-    $ret['itunes:subtitle'] = $itunes['subtitle'];
-  }
-  if ($itunes['summary']) {
-    $ret['itunes:summary'] = $itunes['summary'];
-  }
-  if ($itunes['block']) {
-    $ret['itunes:block'] = 'yes';
-  }
-  if ($itunes['owner_name'] && $itunes['owner_email']) {
-    $ret['itunes:owner']['itunes:name'] = $itunes['owner_name'];
-    $ret['itunes:owner']['itunes:email'] = $itunes['owner_email'];
-  }
-
-  $ret['itunes:explicit'] = audio_itunes_explicit($itunes['explicit']);
-
-  // FIXME: add keywords
-  // FIXME: add categories
-
-  return $ret;
-}
-
-
-/**
- * Provide views plugins for the feed types we support.
- */
-function audio_itunes_views_style_plugins() {
-  return array(
-    'audio_itunes' => array(
-      'name' => t('Views RSS: iTunes RSS feed'),
-      'theme' => 'audio_itunes_feed',
-      'needs_table_header' => TRUE,
-      'needs_fields' => TRUE,
-      'even_empty' => TRUE,
-    ),
-  );
-}
-
-/**
- * While we support the global selector, some might want to allow
- * ONLY RSS feeds so we support a stingy selector too
- */
-function audio_itunes_views_arguments() {
-  $arguments = array(
-    'audio_itunes_feed' => array(
-      'name' => t('iTunes RSS: RSS Feed Selector'),
-      'handler' => 'audio_itunes_arg_handler',
-      'option' => 'string',
-      'help' => t('This argument specifies a specific RSS feed selector; it will only select RSS feeds, unlike the built-in selector which can select pluggable feeds. You may enter the title the feed will advertise in the title field here, and the description of the feed in the option field here.'),
-    ),
-  );
-  return $arguments;
-}
-
-/**
- * handler for our own RSS argument; mimics the feed selector
- */
-function audio_itunes_arg_handler($op, &$query, $argtype, $arg = '') {
-  switch ($op) {
-    case 'summary':
-    case 'sort':
-    case 'link':
-    case 'title':
-      break;
-    case 'filter':
-      // This is a clone of the default selector, but it just invokes ours
-      // rather than calling all of them.
-      audio_itunes_views_feed_argument('argument', $GLOBALS['current_view'], $arg, $argtype);
-  }
-}
-
-/**
- * post view for our own op -- mimics the feed selector
- */
-function audio_itunes_views_post_view($view, $items, $output) {
-  foreach ($view->argument as $id => $argument) {
-    if ($argument['type'] == 'audio_itunes_feed') {
-      $feed = $id;
-      break;
-    }
-  }
-
-  if ($feed !== NULL) {
-    return audio_itunes_views_feed_argument('post_view', $view, 'audio_itunes_feed');
-  }
-}
-
-/**
- * feed argument hook that will convert us to RSS or display an icon.
- * the 4th argument isn't part of the hook, but we use it to differentiate
- * when called as a hook or when called manually from audio_itunes_views_post_view
- */
-function audio_itunes_views_feed_argument($op, &$view, $arg, $argdata = NULL) {
-  if ($op == 'argument' && $arg == 'feed') {
-    $view->page_type = 'audio_itunes';
-
-    if ($argdata['options']) {
-      $view->description = $argdata['options'];
-    }
-
-    // reset the 'real url' to the URL without the feed argument.
-    $view_args = array();
-    $max = count($view->args);
-    foreach ($view->args as $id => $view_arg) {
-      ++$count;
-      if ($view_arg == $arg && $view->argument[$id]['id'] == $argdata['id']) {
-        if ($count != $max) {
-          $view_args[] = $argdata['wildcard'];
-        }
-      }
-      else {
-        $view_args[] = $view_arg;
-      }
-    }
-    $view->feed_url = views_get_url($view, $view_args);
-  }
-  else if ($op == 'post_view' && $view->build_type != 'block') {
-    $args = views_post_view_make_args($view, $arg, 'feed');
-    $url = views_get_url($view, $args);
-    $title = views_get_title($view, 'page', $args);
-
-    if ($view->used_filters) {
-      $filters = drupal_query_string_encode($view->used_filters);
-    }
-
-    drupal_add_feed(url($url, $filters), $title);
-  }
-}
-
-/**
- * Implementation of hook_theme
- */
-function audio_itunes_theme() {
-  return array(
-    'audio_itunes_feed' => array(
-      'arguments' => array('view', 'nodes', 'type'),
-    ),
-  );
-}
-
-/**
- * Plugin that actually displays an RSS feed
- */
-function theme_audio_itunes_feed($view, $nodes, $type) {
-  if ($type == 'block') {
-    return;
-  }
-  global $base_url;
-
-
-  $channel = array(
-    // a check_plain isn't required on these because format_rss_channel
-    // already does this.
-    'title'       => views_get_title($view, 'page'),
-    'link'        => url($view->feed_url ? $view->feed_url : $view->real_url, array('absolute' => true)),
-    'description' => $view->description,
-  );
-
-  $item_length = variable_get('feed_item_length', 'teaser');
-  $namespaces = array('xmlns:dc="http://purl.org/dc/elements/1.1/"');
-
-  // Except for the original being a while and this being a foreach, this is
-  // completely cut & pasted from node.module.
-  foreach ($nodes as $node) {
-    // Load the specified node:
-    $item = node_load($node->nid);
-    $link = url("node/$node->nid", array('absolute' => TRUE));
-
-    if ($item_length != 'title') {
-      $teaser = ($item_length == 'teaser') ? TRUE : FALSE;
-
-      // Filter and prepare node teaser
-      if (node_hook($item, 'view')) {
-        node_invoke($item, 'view', $teaser, FALSE);
-      }
-      else {
-        $item = node_prepare($item, $teaser);
-      }
-
-      // Allow modules to change $node->teaser before viewing.
-      node_invoke_nodeapi($item, 'view', $teaser, FALSE);
-    }
-
-    // Allow modules to add additional item fields
-    $extra = node_invoke_nodeapi($item, 'rss item');
-    $extra = array_merge($extra, array(array('key' => 'pubDate', 'value' =>  date('r', $item->created)), array('key' => 'dc:creator', 'value' => $item->name), array('key' => 'guid', 'value' => $item->nid .' at '. $base_url, 'attributes' => array('isPermaLink' => 'false'))));
-    foreach ($extra as $element) {
-      if ($element['namespace']) {
-        $namespaces = array_merge($namespaces, $element['namespace']);
-      }
-    }
-
-    // Prepare the item description
-    switch ($item_length) {
-      case 'fulltext':
-        $item_text = $item->body;
-        break;
-      case 'teaser':
-        $item_text = $item->teaser;
-        if ($item->readmore) {
-          $item_text .= '<p>'. l(t('read more'), 'node/'. $item->nid, array('html' => TRUE)) .'</p>';
-        }
-        break;
-      case 'title':
-        $item_text = '';
-        break;
-    }
-
-    $items .= format_rss_item($item->title, $link, $item_text, $extra);
-  }
-
-  $channel_defaults = array(
-    'version'     => '2.0',
-    'title'       => variable_get('site_name', 'drupal') .' - '. variable_get('site_slogan', ''),
-    'link'        => $base_url,
-    'description' => variable_get('site_mission', ''),
-    'language'    => $GLOBALS['locale'],
-  );
-  $channel = array_merge($channel_defaults, $channel);
-
-  $output = '<?xml version="1.0" encoding="utf-8"?>'."\n";
-  $output .= '<rss version="'. $channel["version"] .'" xml:base="'. $base_url .'" '. implode(' ', $namespaces) .">\n";
-  $output .= format_rss_channel($channel['title'], $channel['link'], $channel['description'], $items, $channel['language'], audio_itunes_feed_channel_arguments($view));
-  $output .= "</rss>\n";
-
-  drupal_set_header('Content-Type: text/xml; charset=utf-8');
-  print $output;
-  module_invoke_all('exit');
-  exit;
-}
Index: audio_itunes.views.inc
===================================================================
RCS file: audio_itunes.views.inc
diff -N audio_itunes.views.inc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ audio_itunes.views.inc	24 Nov 2008 21:04:26 -0000
@@ -0,0 +1,22 @@
+<?php
+
+/**
+ * Implementation of hook_views_plugins
+ */
+function audio_itunes_views_plugins() {
+  return array(
+    'module' => 'audio_itunes', // This just tells our themes are elsewhere.
+    'style' => array(
+      'itunes_rss' => array(
+        'title' => t('iTunes RSS Feed'),
+        'help' => t('Generates an RSS feed from a view with extra iTunes specific attributes.'),
+        'handler' => 'audio_itunes_plugin_style_rss',
+        'theme' => 'views_view_rss',
+        'parent' => 'rss',
+        'uses row plugin' => TRUE,
+        'uses options' => TRUE,
+        'type' => 'feed',
+      ),
+    ),
+  );
+}
\ No newline at end of file
Index: audio_itunes_plugin_style_rss.inc
===================================================================
RCS file: audio_itunes_plugin_style_rss.inc
diff -N audio_itunes_plugin_style_rss.inc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ audio_itunes_plugin_style_rss.inc	24 Nov 2008 21:04:26 -0000
@@ -0,0 +1,171 @@
+<?php
+// $Id: views_plugin_style_rss.inc,v 1.1 2008/09/03 19:21:30 merlinofchaos Exp $
+
+/**
+ * @file
+ * Contains the RSS style plugin.
+ */
+
+/**
+ * iTunes specific style plugin to render an RSS feed.
+ *
+ * @ingroup views_style_plugins
+ */
+class audio_itunes_plugin_style_rss extends views_plugin_style_rss {
+  function option_definition() {
+    $options = parent::option_definition();
+
+    $options['subtitle'] = array('default' => '', 'translatable' => TRUE);
+    $options['summary'] = array('default' => '', 'translatable' => TRUE);
+    $options['author'] = array('default' => '', 'translatable' => TRUE);
+    $options['copyright'] = array('default' => '', 'translatable' => TRUE);
+    $options['image_url'] = array('default' => '', 'translatable' => FALSE);
+    $options['explicit'] = array('default' => '', 'translatable' => FALSE);
+    $options['block'] = array('default' => '', 'translatable' => FALSE);
+    $options['owner_name'] = array('default' => '', 'translatable' => FALSE);
+    $options['owner_email'] = array('default' => '', 'translatable' => FALSE);
+
+    return $options;
+  }
+
+  function options_form(&$form, &$form_state) {
+    $form['subtitle'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Subtitle'),
+      '#default_value' => $this->options['subtitle'],
+      '#maxlength' => 255,
+      '#description' => t("The contents of this tag are shown in the Description column in iTunes. The subtitle displays best if it is only a few words long."),
+    );
+    $form['summary'] = array(
+      '#type' => 'textarea',
+      '#title' => t('Summary'),
+      '#default_value' => $this->options['summary'],
+      '#maxlength' => 4000,
+      '#rows' => 5,
+      '#description' => t('The contents of this tag are shown in a separate window that appears when the "circled i" in the Description column is clicked. It also appears on the iTunes page for your podcast.'),
+    );
+    $form['author'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Author'),
+      '#default_value' => $this->options['author'],
+      '#maxlength' => 255,
+      '#description' => t("This is shown in the Artist column in iTunes."),
+    );
+    $form['copyright'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Copyright'),
+      '#default_value' => $this->options['copyright'],
+      '#maxlength' => 255,
+      '#description' => t('i.e. "&#xA9; 2005 John Doe"'),
+    );
+    $form['image_url'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Image URL'),
+      '#default_value' => $this->options['image_url'],
+      '#maxlength' => 255,
+      '#description' => t('This specifies the artwork for your podcast. iTunes prefers square .jpg images that are at least 300 x 300 pixels, which is different than what is specified for the standard RSS image tag. iTunes supports images in JPEG and PNG formats. The URL must end in ".jpg" or ".png". If you change your podcast’s image, also change the file’s name. iTunes may not change the image if it checks your feed and the image URL is the same.'),
+    );
+    $form['explicit'] = array(
+      '#type' => 'select', '#title' => t('Explicit'),
+      '#options' => array(0 => 'Unspecified', AUDIO_ITUNES_EXPLICIT_YES => 'Yes', AUDIO_ITUNES_EXPLICIT_CLEAN => 'Clean'),
+      '#default_value' => $this->options['explicit'],
+      '#description' => t('If select "yes", an "explicit" parental advisory graphic will appear next to your podcast artwork on the iTunes Music Store, and in the Name column in iTunes. If you select "clean", the parental advisory type is considered Clean, meaning that no explicit language or adult content is included anywhere in the episode, and a "clean" graphic will appear.'),
+    );
+    $form['block'] = array(
+      '#type' => 'checkbox', '#title' => t('Hide'),
+      '#default_value' => $this->options['block'],
+      '#description' => t('Check this to prevent the entire podcast from appearing in the iTunes Podcast directory.'),
+    );
+    $form['owner_name'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Name'),
+      '#default_value' => $this->options['owner_name'],
+      '#maxlength' => 255,
+      '#description' => t("Apple uses this information to contact the owner of the podcast for communication specifically about their podcast. It will not be publicly displayed but it may be picked up by spammers."),
+    );
+    $form['owner_email'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Email'),
+      '#default_value' => $this->options['owner_email'],
+      '#maxlength' => 255,
+    );
+  }
+
+  function options_validate(&$form, &$form_state) {
+    if (!empty($form_state['values']['style_options']['image_url'])) {
+      if (!valid_url($form_state['values']['style_options']['image_url'])) {
+        form_set_error('image_url', t('The image URL must be a valid URL.'));
+      }
+      else {
+        $url = parse_url($form_state['values']['style_options']['image_url']);
+        $ext = strtolower(pathinfo($url['path'], PATHINFO_EXTENSION));
+        if (!isset($url['path']) || ($ext != 'jpg' && $ext != 'png')) {
+          form_set_error('image_url', t('The URL must specify a file ending with <code>.jpg</code> or <code>.png</code>.'));
+        }
+      }
+    }
+    if (!empty($form_state['values']['style_options']['owner_email']) && !valid_email_address($form_state['values']['style_options']['owner_email'])) {
+      form_set_error('owner_email', t('The owner email must be a valid email address.'));
+    }
+  }
+
+  function get_channel_elements() {
+    $extra = parent::get_channel_elements();
+
+    // Specify the namespace in this element because it is always included so
+    // we can omit it from subsequent elements.
+    $extra[] = array(
+      'namespace' => array('xmlns:itunes' => 'http://www.itunes.com/dtds/podcast-1.0.dtd'),
+      'key' => 'itunes:explicit',
+      'value' => audio_itunes_explicit($this->options['explicit']),
+    );
+    if ($this->options['author']) {
+      $extra[] = array(
+        'key' => 'itunes:author',
+        'value' => $this->options['author'],
+      );
+    }
+    if ($this->options['image_url']) {
+      $extra[] = array(
+        'key' => 'itunes:image',
+        'attributes' => array('href' => $this->options['image_url']),
+      );
+    }
+    if ($this->options['subtitle']) {
+      $extra[] = array(
+        'key' => 'itunes:subtitle',
+        'value' => $this->options['subtitle'],
+      );
+    }
+    if ($this->options['summary']) {
+      $extra[] = array(
+        'key' => 'itunes:summary',
+        'value' => $this->options['summary'],
+      );
+    }
+    if ($this->options['block']) {
+      $extra[] = array(
+        'key' => 'itunes:block',
+        'value' => 'yes',
+      );
+    }
+    if ($this->options['owner_name'] && $this->options['owner_email']) {
+      $extra[] = array(
+        'key' => 'itunes:name',
+        'value' => $this->options['owner_name'],
+      );
+      $extra[] = array(
+        'key' => 'itunes:email',
+        'value' => $this->options['owner_email'],
+      );
+    }
+
+    return $extra;
+  }
+
+/*  function render() {
+    dvm($this->theme_functions());
+//    parent::render();
+  }
+*/
+}
\ No newline at end of file
