t('System Path (Alias)'), 'field' => 'f.local_uri', 'sort' => 'asc'),
array('data' => t('FeedBurner'), 'field' => 'f.fb_uri'),
array('data' => t('Verified'), 'field' => 'f.verified'),
array('data' => t('Operations'), 'colspan' => '3'),
);
$sql .= tablesort_sql($header);
$result = pager_query($sql, 50, 0, null, $keys, $keys, $keys);
$rows = array();
while ($data = db_fetch_object($result)) {
$alias = drupal_get_path_alias($data->local_uri);
$rows[] = array(
l($data->local_uri . ($data->local_uri != $alias ? ' ('. $alias .')' : ''), $data->local_uri),
l($data->fb_uri, _feedburner_construct_url($data->fb_uri)),
l($data->verified > 0 ? t('Yes') : t('No'), 'admin/feedburner/verify/'. $data->fb_uri),
l(t('edit'), 'admin/build/feedburner/edit/'. $data->local_uri),
l(t('remove'), 'admin/build/feedburner/remove/'. $data->local_uri),
l(t('source'), $data->local_uri, array(), 'feedburner_redirect=false'),
);
}
if (empty($rows)) {
if (empty($keys)) {
$alias = drupal_get_path_alias('rss.xml');
$rows[] = array(
l('rss.xml'. ('rss.xml' != $alias ? ' ('. $alias .')' : ''), 'rss.xml'),
'None',
'',
l(t('redirect'), 'admin/build/feedburner/add/rss.xml'),
'',
l(t('source'), 'rss.xml'),
);
}
else {
$rows[] = array(array('data' => t('No FeedBurner feeds found.'), 'colspan' => '6'));
}
}
$output .= theme('table', $header, $rows);
$output .= theme('pager', null, 50, 0);
$output .= feedburner_help('feedburner_about');
return $output;
}
/**
* Return a form to filter FeedBurner feeds.
*/
function _feedburner_build_filter_form($keys = '') {
$form['#attributes'] = array(
'class' => 'search-form',
);
$form['basic'] = array(
'#type' => 'fieldset',
'#title' => t('Filter feeds'),
);
$form['basic']['inline'] = array(
'#prefix' => '
',
'#suffix' => '
',
);
$form['basic']['inline']['filter'] = array(
'#type' => 'textfield',
'#title' => '',
'#default_value' => $keys,
'#maxlength' => 64,
'#size' => 25,
);
$form['basic']['inline']['submit'] = array(
'#type' => 'submit',
'#value' => t('Filter'),
);
return $form;
}
/**
* Process filter form submission.
*/
function _feedburner_build_filter_form_submit($form_id, $form_values) {
return 'admin/build/feedburner/list/'. trim($form_values['filter']);
}
function _feedburner_build_edit() {
$path = _feedburner_extract_path_keys();
/*if ($path != drupal_get_normal_path($path)) {
//drupal_goto('admin/build/feedburner/edit/'. drupal_get_normal_path($path));
}*/
$result = _feedburner_load($path, 'local_uri, fb_uri');
if (empty($result)) {
drupal_set_title('Add FeedBurner Redirect');
$output = _feedburner_build_edit_form(array('local_uri' => $path));
}
else {
drupal_set_title('Edit FeedBurner Redirect');
$output = _feedburner_build_edit_form(array('local_uri' => $result->local_uri, 'fb_uri' => $result->fb_uri));
}
return $output;
}
function _feedburner_build_edit_form($edit = '') {
$form['#base'] = '_feedburner_build_edit_form';
$form['local_uri'] = array(
'#type' => 'textfield',
'#title' => t('Local Feed'),
'#default_value' => $edit['local_uri'],
'#maxlength' => 128,
'#size' => 30,
'#description' => t('Specify the existing feed on your site from which to redirect.'),
'#field_prefix' => url(null, null, null, true) . (variable_get('clean_url', 0) ? '' : '?q='),
'#validate' => array('_feedburner_build_edit_validate' => array()),
'#autocomplete_path' => 'admin/feedburner/autocomplete/site',
);
$form['fb_uri'] = array(
'#type' => 'textfield',
'#title' => t('FeedBurner Feed'),
'#default_value' => $edit['fb_uri'],
'#maxlength' => 100,
'#size' => 30,
'#description' => t('Requests to the above feed will be requested to this FeedBurner feed. This URI is case-sensitive and alphanumeric.'),
'#field_prefix' => _feedburner_construct_url(),
'#validate' => array('_feedburner_build_edit_validate' => array()),
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Save redirection'),
);
if (_feedburner_can_api(true, false) == true) {
$form['fb_uri']['#autocomplete_path'] = 'admin/feedburner/autocomplete/feedburner';
}
return $form;
}
function _feedburner_build_edit_validate($form_element) {
$value = $form_element['#value'];
switch ($form_element['#name']) {
case 'local_uri':
if (preg_match('/\\s/', $value)) {
form_set_error($field_name, 'Invalid system path.');
break;
}
$value = strtolower(drupal_get_normal_path($value));
form_set_value($form_element, $value);
break;
case 'fb_uri':
if (!preg_match('/\\A[\\w\\x2D\\x2F]*\\z/i', $value)) {
form_set_error($form_element['#name'], 'Invalid FeedBurner URI.');
}
break;
}
}
function _feedburner_build_edit_form_submit($form_id, $form_values) {
if (_feedburner_save($form_values['local_uri'], $form_values['fb_uri']) == true) {
drupal_set_message(t('The FeedBurner redirect has been saved.'));
_feedburner_verify_feed($form_values['fb_uri'], true);
}
return 'admin/build/feedburner';
}
function _feedburner_build_remove() {
$path = _feedburner_extract_path_keys();
if (!empty($path) && _feedburner_save($path) == true) {
drupal_set_message(t('The FeedBurner redirection for %path has been removed.', array('%path' => $path)));
}
drupal_goto('admin/build/feedburner');
}
function _feedburner_settings_form() {
$form['redirection'] = array(
'#type' => 'fieldset',
'#title' => t('Feed Redirection'),
);
$form['redirection']['feedburner_redirect_status'] = array(
'#type' => 'select',
'#title' => t('Redirect Header Status'),
'#default_value' => variable_get('feedburner_redirect_status', FEEDBURNER_DEFAULT_REDIRECT_STATUS),
'#options' => array(
301 => '301 Moved Permanently',
302 => '302 Found',
307 => '307 Temporary Redirect'),
'#description' => t('Please note that the \'307 Temporary Redirect\' is recommended but if your subscribers are having problems you may want to try a different status code. For detailed descriptions of HTTP redirect status codes, see the Wikipedia article on HTTP status codes.', array('@link' => 'http://en.wikipedia.org/wiki/List_of_HTTP_status_codes#3xx_Redirection')),
'#validate' => array('_feedburner_settings_validate' => array()),
);
$form['redirection']['feedburner_blogs'] = array(
'#type' => 'checkbox',
'#title' => t('Allow users to specify their own blogs\' FeedBurner feed.'),
'#default_value' => variable_get('feedburner_blogs', false),
'#description' => t('If the user has the permission "edit own blog", this option is found in his/her "edit account" page.'),
);
$form['feedflare'] = array(
'#type' => 'fieldset',
'#title' => t('FeedFlare/Standard Stats/Ad Network'),
'#description' => t('See @link for more information.', array('@link' => 'http://www.feedburner.com/fb/a/publishers/feedflare')),
'#collapsible' => false,
);
/*if (!array_key_exists('rss2.xml', _feedburner_get_redirects())) {
$form['feedflare']['notice'] = array(
'#value' => 'FeedFlare is only enabled when you have a FeedBurner feed for your site\'s main feed (rss.xml).
',
);
}*/
$form['feedflare']['feedburner_feedflare_node_types'] = array(
'#type' => 'checkboxes',
//'#type' => 'select',
'#title' => t('Node types'),
'#multiple' => true,
'#default_value' => variable_get('feedburner_feedflare_node_types', array()),
'#options' => node_get_types('names'),
);
$form['array_filter'] = array('#type' => 'value', '#value' => true);
$form['feedflare']['feedburner_feedflare'] = array(
'#type' => 'select',
'#title' => t('FeedFlare in nodes'),
'#default_value' => variable_get('feedburner_feedflare', 0),
'#options' => array(
0 => t('Disabled'),
1 => t('Teaser view'),
2 => t('Full-page view'),
3 => t('Teasers and full-page view')),
'#description' => t('When to display the FeedFlare after the node text.'),
);
if (_feedburner_can_api()) {
$form['account'] = array(
'#type' => 'fieldset',
'#title' => t('FeedBurner Account'),
'#description' => t('To use more advanced features like FeedFlare, e-mail subscriptions, and feed stats, you need to enter your FeedBurner account details. To disable these features, leave your username blank. If you do not currently have a FeedBurner account, you can register at @link.', array('@link' => 'https://www.feedburner.com/fb/a/register')),
'#collapsible' => true,
'#collapsed' => false,
);
$form['account']['feedburner_username'] = array(
'#type' => 'textfield',
'#title' => t('Your FeedBurner username'),
'#default_value' => variable_get('feedburner_username', ''),
'#size' => 25,
'#maxlength' => 30,
'#validate' => array('_feedburner_settings_validate' => array()),
);
$form['account']['feedburner_password'] = array(
'#type' => 'password',
'#title' => t('Your FeedBurner password'),
//'#default_value' => variable_get('feedburner_password', ''),
'#size' => 25,
'#maxlength' => 30,
'#validate' => array('_feedburner_settings_validate' => array()),
);
$form['account']['feedburner_auth'] = array(
'#type' => 'value',
'#value' => variable_get('feedburner_auth', null),
);
$account_status = variable_get('feedburner_auth', null) != null;
$form['account']['status'] = array(
'#type' => 'markup',
'#value' => ''. t('Account status:
@status', array('@status' => ($account_status ? 'Verified' : 'NOT VERIFIED'))) .'
',
);
}
/*_feedburner_include('api');
if (!_feedburner_can_api(false)) {
foreach($form['account'] as &$form_item) {
$form_item['#disabled'] = true;
}
}*/
$form['advanced'] = array(
'#type' => 'fieldset',
'#title' => t('Advanced Settings'),
'#collapsible' => true,
'#collapsed' => true,
);
$form['advanced']['feedburner_useragents'] = array(
'#type' => 'textarea',
'#title' => t('User Agents Allowed Direct Feed Access'),
'#description' => t('Enter a list of user agents (one per line) that are allowed direct access to your site\'s Feeds and will not be redirected to the FeedBurner feeds.'),
'#default_value' => preg_replace('/\\|/', "\n", variable_get('feedburner_useragents', FEEDBURNER_DEFAULT_USERAGENTS)),
'#rows' => 3,
'#validate' => array('_feedburner_settings_validate' => array()),
);
$form['advanced']['feedburner_domain'] = array(
'#type' => 'textfield',
'#title' => t('MyBrand Custom Domain'),
'#description' => t('MyBrand is a premium FeedBurner service that allows you to showcase your feeds by serving them from your own domain (e.g., @domain). You must have access to change your CNAME entry in the DNS records for the domain you wish to change. For more information, see @link.', array('@link' => 'http://www.feedburner.com/fb/a/mybrand', '@domain' => 'feeds.'. $_SERVER['SERVER_NAME'])),
'#default_value' => variable_get('feedburner_domain', FEEDBURNER_DEFAULT_DOMAIN),
'#field_prefix' => 'http://',
'#field_suffix' => '/feedname',
'#size' => 30,
'#maxlength' => 30,
'#validate' => array('_feedburner_settings_validate' => array()),
);
$form['blurb'] = array(
'#type' => 'markup',
'#value' => feedburner_help('feedburner_about'),
'#weight' => 10,
);
return system_settings_form($form);
}
/**
* Validate and correct values for the settings form.
* - Format user agents from a list to a regex-ready string
* - Check custom domain name syntax
*/
function _feedburner_settings_validate($form_element) {
$value = $form_element['#value'];
switch ($form_element['#name']) {
case 'feedburner_redirect_status':
form_set_value($form_element, intval($value));
break;
case 'feedburner_useragents':
// Replace one or more consecutive line breaks or pipes with regex pipes,
// remove any non-word non-pipe characters and also remove any pipes at
// the beginning or end of the string
$value = preg_replace(array('/[\\r\\n\\|]+/', '/[^\\|\\w]|\\A\\|+|\\|+\\z/'), array('|', ''), $value);
form_set_value($form_element, $value);
break;
case 'feedburner_domain':
if ($value != FEEDBURNER_DEFAULT_DOMAIN) {
$request = drupal_http_request('http://'. $value);
if (!isset($request->redirect_url) || $request->redirect_url != 'http://www.feedburner.com/fb/a/home' || !preg_match('/\/fb\/a\/home$/', $request->redirect_url)) {
drupal_set_message(t('The MyBrand domain @domain was not successfully verified. Make sure you have edited the domain\'s CNAME settings before enabling this option.', array('@domain' => $value)), 'error');
}
}
break;
case 'feedburner_username':
case 'feedburner_password':
if (!preg_match('/\\A\\w*\\z/', $value)) {
form_set_error($form_element, t('Invalid '. preg_replace('/feedburner_/', '', $form_element['#name']) .'.'));
}
break;
}
}
function _feedburner_settings_form_validate($form_id, $form_values, $form) {
$account = array(
'user' => $form_values['feedburner_username'],
'password' => $form_values['feedburner_password'],
'auth' => $form_values['feedburner_auth'],
);
if (!empty($account['user']) && !empty($account['password'])) {
_feedburner_include('api');
_feedburner_api_verify_account($account);
if ($account['auth'] == false) {
drupal_set_message(t($account['error']), 'error');
}
}
form_set_value($form['account']['feedburner_auth'], $account['auth']);
}
function _feedburner_settings_form_submit($form_id, $form_values) {
unset($form_values['feedburner_password']);
return system_settings_form_submit($form_id, $form_values);
}
/*
* Extract the remaining part of the query url onward from a specified argument.
* @param pos the position in the query argument, default 5th
* @return the remaining url paramenters (including any backslashes)
*/
function _feedburner_extract_path_keys($pos = 5) {
$path = explode('/', $_GET['q'], $pos);
return count($path) == $pos ? $path[$pos - 1] : '';
}
/**
* Updates or removes a feed in the database.
* @param local_uri The local system feed uri to update.
* @param fb_uri The FeedBurner feed uri (set to null to remove redirection).
* @return true if the redirection is updated or removed, false otherwise.
*/
function _feedburner_save($local_uri, $fb_uri = null) {
if (empty($fb_uri)) {
db_query("DELETE FROM {feedburner_feeds} WHERE local_uri = '%s'", $local_uri);
}
else {
db_query("UPDATE {feedburner_feeds} SET fb_uri = '%s' WHERE local_uri = '%s'", $fb_uri, $local_uri);
if (db_affected_rows() == 0) {
db_query("INSERT INTO {feedburner_feeds} (local_uri, fb_uri) VALUES ('%s', '%s')", $local_uri, $fb_uri);
}
}
return (db_affected_rows() != 0);
}
/**
* Removes a feed's output from the Drupal cache. This is used just to be sure
* that no one is accidentally served the cached version of a feed instead of
* being redirected.
* @param local_uri The local system URI of the feed.
*/
/*function _feedburner_clear_feed_cache($local_uri) {
// TODO: replace base_url with url function calls
// Need to clear the cache for the feed page and also an alias if it is set
// ?? cache_clear_all(url($local_uri), 'cache_page');
global $base_url;
cache_clear_all($base_url .'/'. $local_uri, 'cache_page');
$alias = drupal_get_path_alias($local_uri);
if ($alias != $local_uri) {
cache_clear_all($base_url .'/'. $alias, 'cache_page');
}
}*/
function _feedburner_verify() {
$fb_uri = _feedburner_extract_path_keys(3);
_feedburner_verify_feed($fb_uri, true);
drupal_goto('admin/build/feedburner');
}
/**
* Verifies a FeedBurner feed and its details and features available.
*/
function _feedburner_verify_feed($fb_uri, $output = false) {
$local_uri = db_result(db_query("SELECT local_uri FROM {feedburner_feeds} WHERE fb_uri = '%s'", $fb_uri));
if (!empty($fb_uri)) {
$fb_request = drupal_http_request(_feedburner_construct_url($fb_uri) .'?format=xml');
if ($fb_request->code == 200) {
$feed = array();
// Feed ID (email subscription link) detection
if (preg_match('/(\\d+)<\/feedburner:emailServiceId>/i', $fb_request->data, $regs)) {
$feed['id'] = intval($regs[1]);
$feed['email'] = true;
}
// Awareness API detection
if (preg_match('/\\S+<\/feedburner:awareness>/i', $fb_request->data)) {
$feed['awareness_api'] = true;
}
// FeedFlare detection
if (preg_match('/feedflare/i', $fb_request->data) && preg_match('/~f\/'. preg_quote($fb_uri, '/') .'/i', $fb_request->data)) {
$feed['feedflare'] = true;
}
// Ad Network detection
if (preg_match('/~a\/'. preg_quote($fb_uri, '/') .'/i', $fb_request->data)) {
$feed['ad_network'] = true;
}
// Update database with details
db_query("UPDATE {feedburner_feeds} SET verified = %d, details = '%s' WHERE fb_uri = '%s'", time(), serialize($feed), $fb_uri);
if ($output == true) {
drupal_set_message(t('The FeedBurner feed %path was successfully verified.', array('%path' => $fb_uri)));
}
}
else {
db_query("UPDATE {feedburner_feeds} SET verified = 0, details = null WHERE fb_uri = '%s'", $fb_uri);
if ($output == true) {
drupal_set_message(t('The FeedBurner feed %path could not be verified. Please check that you have set up the feed in your FeedBurner account or you can burn the feed at Feedburner.', array('%path' => $fb_uri, '@fb-account' => 'http://www.feedburner.com/fb/a/myfeeds', '@fb-create' => 'https://www.feedburner.com/fb/a/addfeed?sourceUrl='. url($local_uri, null, null, true) .'&mappedUri='. $fb_uri)), 'error');
}
}
}
if (!empty($local_uri) && $output == true) {
$local_request = drupal_http_request(url($local_uri, 'feedburner_redirect=false', null, true));
if ($local_request->code != 200 || !isset($local_request->headers['Content-Type']) || !preg_match('/xml|rss|atom|rdf/i', $local_request->headers['Content-Type'])) {
drupal_set_message(t('The local feed source %path could not be verified. Please make sure it exists.', array('%path' => $local_uri)), 'error');
}
/*$redirect_request = drupal_http_request(url($local_uri, null, null, true));
if (!isset($redirect_request->redirect_url) || $redirect_request->redirect_url != _feedburner_construct_url($fb_uri) || !isset($redirect_request->code) || $redirect_request->code != variable_get('feedburner_redirect_status', FEEDBURNER_DEFAULT_REDIRECT_STATUS)) {
drupal_set_message(t('Redirection from the local feed %local to the FeedBurner feed %fb could not be confirmed. Please check to make sure it works.', array('%local' => $local_uri, '%fb' => $fb_uri)), 'error');
}*/
}
}
/**
* Pings the FeedBurner service. Called when a redirection has changed.
* @return If the ping request was successful.
*/
function _feedburner_ping() {
$request = drupal_http_request('http://www.feedburner.com/fb/a/ping?bloglink='. urlencode(url(null, null, null, true)));
return ($request->code == 200);
}
/**
* Retrieve a pipe delimited string of autocomplete suggestions for feed uris.
*/
function _feedburner_autocomplete($type) {
$matches = array();
$possibles = array();
$string = _feedburner_extract_path_keys(4);
$string = preg_quote($string, '/');
if (!empty($string)) {
switch ($type){
case 'site':
$possibles = _feedburner_get_site_feeds();
break;
case 'feedburner':
_feedburner_include('api');
$api_request = _feedburner_api_request('FindFeeds');
if (isset($api_request->data->feeds->feed)) {
foreach ($api_request->data->feeds->feed as $api_feed) {
$possibles[] = (string) $api_feed['uri'];
}
}
break;
}
}
//var_export($possibles); die();
foreach ($possibles as $feed) {
if (preg_match('/'. $string .'/i', $feed)) {
$matches[$feed] = check_plain($feed);
}
}
/*if (!empty($string)) {
$result = _feedburner_get_site_feeds();
$string = preg_quote($string, '/');
foreach ($result as $feed) {
if (preg_match('/'. $string .'/i', $feed)) {
$matches[$feed] = check_plain($feed);
}
}
}*/
$matches = array_slice($matches, 0, 10);
echo drupal_to_js($matches);
exit();
}
function _feedburner_get_site_feeds() {
$feeds = array();
$feeds[] = 'rss.xml';
// Comment RSS integration
if (module_exists('commentrss')) {
$feeds[] = 'crss';
}
// View RSS integration
if (module_exists('views') && module_exists('views_rss')) {
$result = db_query("SELECT url FROM {view_view} WHERE page_type = 'views_rss'");
while ($view_feed = db_fetch_object($result)) {
$feeds[] = $view_feed->url;
}
}
// Blog integration
if (module_exists('blog')) {
$feeds[] = 'blog/feed';
// Get each user's blog feed as well
$result = db_query('SELECT uid FROM {users} WHERE status = 1');
while ($user_details = db_fetch_object($result)) {
$feeds[] = 'blog/'. $user_details->uid .'/feed';
}
}
// Taxonomy integration
if (module_exists('taxonomy')) {
$result = db_query('SELECT tid FROM {term_data}');
while ($term_details = db_fetch_object($result)) {
$feeds[] = 'taxonomy/term/'. $term_details->tid .'/0/feed';
}
}
/*$aliases = array();
foreach ($feeds as $feed) {
$alias = drupal_get_path_alias($feed);
if ($feed != $alias) {
$aliases[] = $alias;
}
}
$feeds = array_merge($feeds, $aliases);*/
$feeds = array_map('drupal_get_path_alias', $feeds);
sort($feeds);
return $feeds;
}