| 1 |
<?php
|
| 2 |
// $Id: itunes_plugin_style_rss.inc,v 1.4 2009/07/31 22:55:10 drewish Exp $
|
| 3 |
|
| 4 |
/**
|
| 5 |
* @file
|
| 6 |
* Contains the RSS style plugin.
|
| 7 |
*/
|
| 8 |
|
| 9 |
/**
|
| 10 |
* iTunes specific style plugin to render an RSS feed.
|
| 11 |
*
|
| 12 |
* @ingroup views_style_plugins
|
| 13 |
*/
|
| 14 |
class itunes_plugin_style_rss extends views_plugin_style_rss {
|
| 15 |
function option_definition() {
|
| 16 |
$options = parent::option_definition();
|
| 17 |
|
| 18 |
$options['subtitle'] = array('default' => '', 'translatable' => TRUE);
|
| 19 |
$options['summary'] = array('default' => '', 'translatable' => TRUE);
|
| 20 |
$options['author'] = array('default' => '', 'translatable' => TRUE);
|
| 21 |
$options['copyright'] = array('default' => '', 'translatable' => TRUE);
|
| 22 |
$options['image_url'] = array('default' => '', 'translatable' => FALSE);
|
| 23 |
$options['explicit'] = array('default' => 0, 'translatable' => FALSE);
|
| 24 |
$options['block'] = array('default' => 0, 'translatable' => FALSE);
|
| 25 |
$options['owner_name'] = array('default' => '', 'translatable' => FALSE);
|
| 26 |
$options['owner_email'] = array('default' => '', 'translatable' => FALSE);
|
| 27 |
$options['categories'] = array('default' => array('', '', ''), 'translatable' => FALSE);
|
| 28 |
$options['keywords'] = array('default' => '', 'translatable' => TRUE);
|
| 29 |
|
| 30 |
return $options;
|
| 31 |
}
|
| 32 |
|
| 33 |
function options_form(&$form, &$form_state) {
|
| 34 |
$form['subtitle'] = array(
|
| 35 |
'#type' => 'textfield',
|
| 36 |
'#title' => t('Subtitle'),
|
| 37 |
'#default_value' => $this->options['subtitle'],
|
| 38 |
'#maxlength' => 255,
|
| 39 |
'#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."),
|
| 40 |
);
|
| 41 |
$form['summary'] = array(
|
| 42 |
'#type' => 'textarea',
|
| 43 |
'#title' => t('Summary'),
|
| 44 |
'#default_value' => $this->options['summary'],
|
| 45 |
'#maxlength' => 4000,
|
| 46 |
'#rows' => 5,
|
| 47 |
'#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.'),
|
| 48 |
);
|
| 49 |
$form['author'] = array(
|
| 50 |
'#type' => 'textfield',
|
| 51 |
'#title' => t('Author'),
|
| 52 |
'#default_value' => $this->options['author'],
|
| 53 |
'#maxlength' => 255,
|
| 54 |
'#description' => t("This is shown in the Artist column in iTunes."),
|
| 55 |
);
|
| 56 |
$form['copyright'] = array(
|
| 57 |
'#type' => 'textfield',
|
| 58 |
'#title' => t('Copyright'),
|
| 59 |
'#default_value' => $this->options['copyright'],
|
| 60 |
'#maxlength' => 255,
|
| 61 |
'#description' => t('i.e. "© 2005 John Doe"'),
|
| 62 |
);
|
| 63 |
$form['image_url'] = array(
|
| 64 |
'#type' => 'textfield',
|
| 65 |
'#title' => t('Image URL'),
|
| 66 |
'#default_value' => $this->options['image_url'],
|
| 67 |
'#maxlength' => 255,
|
| 68 |
'#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.'),
|
| 69 |
);
|
| 70 |
$form['explicit'] = array(
|
| 71 |
'#type' => 'select', '#title' => t('Explicit'),
|
| 72 |
'#options' => array(0 => 'Unspecified', ITUNES_EXPLICIT_YES => 'Yes', ITUNES_EXPLICIT_CLEAN => 'Clean'),
|
| 73 |
'#default_value' => $this->options['explicit'],
|
| 74 |
'#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.'),
|
| 75 |
);
|
| 76 |
$form['block'] = array(
|
| 77 |
'#type' => 'checkbox', '#title' => t('Hide'),
|
| 78 |
'#default_value' => $this->options['block'],
|
| 79 |
'#description' => t('Check this to prevent the entire podcast from appearing in the iTunes Podcast directory.'),
|
| 80 |
);
|
| 81 |
$form['owner_name'] = array(
|
| 82 |
'#type' => 'textfield',
|
| 83 |
'#title' => t('Name'),
|
| 84 |
'#default_value' => $this->options['owner_name'],
|
| 85 |
'#maxlength' => 255,
|
| 86 |
'#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."),
|
| 87 |
);
|
| 88 |
$form['owner_email'] = array(
|
| 89 |
'#type' => 'textfield',
|
| 90 |
'#title' => t('Email'),
|
| 91 |
'#default_value' => $this->options['owner_email'],
|
| 92 |
'#maxlength' => 255,
|
| 93 |
);
|
| 94 |
$category_options = array('' => t('- None selected -'));
|
| 95 |
foreach (itunes_categories() as $top_level => $children) {
|
| 96 |
$category_options[] = (object) array(
|
| 97 |
'option' => array($top_level => $top_level)
|
| 98 |
);
|
| 99 |
foreach ($children as $second_level) {
|
| 100 |
$category_options[] = (object) array(
|
| 101 |
'option' => array($top_level . '|' . $second_level => ' - ' . $second_level)
|
| 102 |
);
|
| 103 |
}
|
| 104 |
}
|
| 105 |
$form['categories'] = array(
|
| 106 |
'#type' => 'fieldset',
|
| 107 |
'#title' => t('Categories'),
|
| 108 |
'#collapsible' => TRUE,
|
| 109 |
'#description' => '<p>'. t('There are two ways to browse podcast subject categories on iTunes: click Browse in the Quick Links box or click a selection in the Category box. The former method leads to a text-based table, while the latter leads to pages that include the podcast art.') .'</p>'
|
| 110 |
.'<p>'. t('For placement within the older, text-based browse system, podcast feeds may list up to 3 category/subcategory pairs. (For example, "Music" counts as 1, as does "Business > Careers.") For placement within the newer browse system based on Category links, however, and for placement within the Top Podcasts lists that appear in the right column of most podcast pages, only the first category listed in the feed is used.') .'</p>',
|
| 111 |
);
|
| 112 |
$form['categories'][0] = array(
|
| 113 |
'#type' => 'select',
|
| 114 |
'#title' => t('First Category'),
|
| 115 |
'#default_value' => $this->options['categories'][0],
|
| 116 |
'#options' => $category_options,
|
| 117 |
);
|
| 118 |
$form['categories'][1] = array(
|
| 119 |
'#type' => 'select',
|
| 120 |
'#title' => t('Second Category'),
|
| 121 |
'#default_value' => $this->options['categories'][1],
|
| 122 |
'#options' => $category_options,
|
| 123 |
);
|
| 124 |
$form['categories'][2] = array(
|
| 125 |
'#type' => 'select',
|
| 126 |
'#title' => t('Third Category'),
|
| 127 |
'#default_value' => $this->options['categories'][2],
|
| 128 |
'#options' => $category_options,
|
| 129 |
);
|
| 130 |
$form['keywords'] = array(
|
| 131 |
'#type' => 'textfield',
|
| 132 |
'#title' => t('Keywords'),
|
| 133 |
'#default_value' => $this->options['keywords'],
|
| 134 |
'#maxlength' => 4000,
|
| 135 |
'#description' => t('This tag allows users to search on a maximum of 12 text keywords. Use commas to separate keywords.'),
|
| 136 |
);
|
| 137 |
}
|
| 138 |
|
| 139 |
function options_validate(&$form, &$form_state) {
|
| 140 |
if (!empty($form_state['values']['style_options']['image_url'])) {
|
| 141 |
if (!valid_url($form_state['values']['style_options']['image_url'])) {
|
| 142 |
form_set_error('image_url', t('The image URL must be a valid URL.'));
|
| 143 |
}
|
| 144 |
else {
|
| 145 |
$url = parse_url($form_state['values']['style_options']['image_url']);
|
| 146 |
$ext = drupal_strtolower(pathinfo($url['path'], PATHINFO_EXTENSION));
|
| 147 |
if (!isset($url['path']) || ($ext != 'jpg' && $ext != 'png')) {
|
| 148 |
form_set_error('image_url', t('The URL must specify a file ending with <code>.jpg</code> or <code>.png</code>.'));
|
| 149 |
}
|
| 150 |
}
|
| 151 |
}
|
| 152 |
if (!empty($form_state['values']['style_options']['owner_email'])) {
|
| 153 |
if (!valid_email_address($form_state['values']['style_options']['owner_email'])) {
|
| 154 |
form_set_error('owner_email', t('The owner email must be a valid email address.'));
|
| 155 |
}
|
| 156 |
}
|
| 157 |
if (!empty($form_state['values']['style_options']['keywords'])) {
|
| 158 |
if (substr_count($form_state['values']['style_options']['keywords'], ',') > 11) {
|
| 159 |
form_set_error('keywords', t('Only 12 keywords are allowed.'));
|
| 160 |
}
|
| 161 |
}
|
| 162 |
}
|
| 163 |
|
| 164 |
function get_channel_elements() {
|
| 165 |
$extra = parent::get_channel_elements();
|
| 166 |
|
| 167 |
// Specify the namespace in this element because it is always included so
|
| 168 |
// we can omit it from subsequent elements.
|
| 169 |
$extra[] = array(
|
| 170 |
'namespace' => array('xmlns:itunes' => 'http://www.itunes.com/dtds/podcast-1.0.dtd'),
|
| 171 |
'key' => 'itunes:explicit',
|
| 172 |
'value' => itunes_explicit($this->options['explicit']),
|
| 173 |
);
|
| 174 |
if ($this->options['copyright']) {
|
| 175 |
$extra[] = array(
|
| 176 |
'key' => 'copyright',
|
| 177 |
'value' => $this->options['copyright'],
|
| 178 |
);
|
| 179 |
}
|
| 180 |
if ($this->options['author']) {
|
| 181 |
$extra[] = array(
|
| 182 |
'key' => 'itunes:author',
|
| 183 |
'value' => $this->options['author'],
|
| 184 |
);
|
| 185 |
}
|
| 186 |
if ($this->options['image_url']) {
|
| 187 |
$extra[] = array(
|
| 188 |
'key' => 'itunes:image',
|
| 189 |
'attributes' => array('href' => $this->options['image_url']),
|
| 190 |
'value' => NULL,
|
| 191 |
);
|
| 192 |
}
|
| 193 |
if ($this->options['subtitle']) {
|
| 194 |
$extra[] = array(
|
| 195 |
'key' => 'itunes:subtitle',
|
| 196 |
'value' => $this->options['subtitle'],
|
| 197 |
);
|
| 198 |
}
|
| 199 |
if ($this->options['summary']) {
|
| 200 |
$extra[] = array(
|
| 201 |
'key' => 'itunes:summary',
|
| 202 |
'value' => $this->options['summary'],
|
| 203 |
);
|
| 204 |
}
|
| 205 |
if ($this->options['block']) {
|
| 206 |
$extra[] = array(
|
| 207 |
'key' => 'itunes:block',
|
| 208 |
'value' => 'yes',
|
| 209 |
);
|
| 210 |
}
|
| 211 |
if ($this->options['owner_name'] && $this->options['owner_email']) {
|
| 212 |
$extra[] = array(
|
| 213 |
'key' => 'itunes:owner',
|
| 214 |
'value' => array(
|
| 215 |
array(
|
| 216 |
'key' => 'itunes:name',
|
| 217 |
'value' => $this->options['owner_name'],
|
| 218 |
),
|
| 219 |
array(
|
| 220 |
'key' => 'itunes:email',
|
| 221 |
'value' => $this->options['owner_email'],
|
| 222 |
),
|
| 223 |
),
|
| 224 |
);
|
| 225 |
}
|
| 226 |
// We've got up to three categories which can consist of a parent and
|
| 227 |
// child stored as "Parent" or "Parent|Child". We need to split them up and
|
| 228 |
// create nested elements.
|
| 229 |
foreach ($this->options['categories'] as $category) {
|
| 230 |
if ($category) {
|
| 231 |
$parts = explode('|', $category);
|
| 232 |
$element = array(
|
| 233 |
'key' => 'itunes:category',
|
| 234 |
'attributes' => array('text' => $parts[0]),
|
| 235 |
'value' => NULL,
|
| 236 |
);
|
| 237 |
if (isset($parts[1])) {
|
| 238 |
$element['value'][] = array(
|
| 239 |
'key' => 'itunes:category',
|
| 240 |
'attributes' => array('text' => $parts[1]),
|
| 241 |
'value' => NULL,
|
| 242 |
);
|
| 243 |
}
|
| 244 |
$extra[] = $element;
|
| 245 |
}
|
| 246 |
}
|
| 247 |
if ($this->options['keywords']) {
|
| 248 |
$extra[] = array(
|
| 249 |
'key' => 'itunes:keywords',
|
| 250 |
'value' => $this->options['keywords'],
|
| 251 |
);
|
| 252 |
}
|
| 253 |
|
| 254 |
return $extra;
|
| 255 |
}
|
| 256 |
}
|