Commit cde470d0 authored by shammash's avatar shammash Committed by lechuck
Browse files

updated feedwordpress to 2011.0721

parent 1b5f06a1
......@@ -746,38 +746,68 @@ function fwp_option_box_closer () {
}
function fwp_tags_box ($tags, $object, $params = array()) {
$params = wp_parse_args($params, array( // Default values
'taxonomy' => 'post_tag',
'textarea_name' => NULL,
'textarea_id' => NULL,
'input_id' => NULL,
'input_name' => NULL,
'id' => NULL,
'box_title' => __('Post Tags'),
));
if (!is_array($tags)) : $tags = array(); endif;
$tax_name = (isset($params['taxonomy']) ? $params['taxonomy'] : 'post_tag');
$tax_name = $params['taxonomy'];
$taxonomy = get_taxonomy($params['taxonomy']);
$disabled = (!current_user_can($taxonomy->cap->assign_terms) ? 'disabled="disabled"' : '');
$desc = "<p style=\"font-size:smaller;font-style:bold;margin:0\">Tag $object as...</p>";
if (isset($params['textarea_name'])) :
$textAreaName = $params['textarea_name'];
else :
$textAreaName = "tax_input[$tax_name]";
if (is_null($params['textarea_name'])) :
$params['textarea_name'] = "tax_input[$tax_name]";
endif;
if (is_null($params['textarea_id'])) :
$params['textarea_id'] = "tax-input-${tax_name}";
endif;
if (is_null($params['input_id'])) :
$params['input_id'] = "new-tag-${tax_name}";
endif;
if (is_null($params['input_name'])) :
$params['input_name'] = "newtag[$tax_name]";
endif;
if (is_null($params['id'])) :
$params['id'] = $tax_name;
endif;
print $desc;
$helps = __('Separate tags with commas.');
$box['title'] = __('Tags');
?>
<div class="tagsdiv" id="<?php echo $tax_name; ?>">
<div class="jaxtag">
<div class="nojs-tags hide-if-js">
<p><?php _e('Add or remove tags'); ?></p>
<textarea name="<?php echo esc_html($textAreaName); ?>" class="the-tags" id="tax-input[<?php echo $tax_name; ?>]"><?php echo esc_attr(implode(",", $tags)); ?></textarea></div>
<div class="tagsdiv" id="<?php echo $params['id']; ?>">
<div class="jaxtag">
<div class="nojs-tags hide-if-js">
<p><?php echo $taxonomy->labels->add_or_remove_items; ?></p>
<textarea name="<?php echo $params['textarea_name']; ?>" class="the-tags" id="<?php echo $params['textarea_id']; ?>"><?php echo esc_attr(implode(",", $tags)); ?></textarea></div>
<div class="ajaxtag hide-if-no-js">
<label class="screen-reader-text" for="new-tag-<?php echo $tax_name; ?>"><?php echo $box['title']; ?></label>
<div class="taghint"><?php _e('Add new tag'); ?></div>
<p>
<input type="text" id="new-tag-<?php echo $tax_name; ?>" name="newtag[<?php echo $tax_name; ?>]" class="newtag form-input-tip" size="16" autocomplete="off" value="" />
<input type="button" class="button tagadd" value="<?php esc_attr_e('Add'); ?>" tabindex="3" />
</p>
</div></div>
<p class="howto"><?php echo $helps; ?></p>
<div class="tagchecklist"></div>
</div>
<p class="hide-if-no-js"><a href="#titlediv" class="tagcloud-link" id="link-<?php echo $tax_name; ?>"><?php printf( __('Choose from the most used tags in %s'), $box['title'] ); ?></a></p>
<?php
<?php if ( current_user_can($taxonomy->cap->assign_terms) ) :?>
<div class="ajaxtag hide-if-no-js">
<label class="screen-reader-text" for="<?php echo $params['input_id']; ?>"><?php echo $params['box_title']; ?></label>
<div class="taghint"><?php echo $taxonomy->labels->add_new_item; ?></div>
<p><input type="text" id="<?php print $params['input_id']; ?>" name="<?php print $params['input_name']; ?>" class="newtag form-input-tip" size="16" autocomplete="off" value="" />
<input type="button" class="button tagadd" value="<?php esc_attr_e('Add'); ?>" tabindex="3" /></p>
</div>
<p class="howto"><?php echo esc_attr( $taxonomy->labels->separate_items_with_commas ); ?></p>
<?php endif; ?>
</div>
<div class="tagchecklist"></div>
</div>
<?php if ( current_user_can($taxonomy->cap->assign_terms) ) : ?>
<p class="hide-if-no-js"><a href="#titlediv" class="tagcloud-link" id="link-<?php echo $tax_name; ?>"><?php echo $taxonomy->labels->choose_from_most_used; ?></a></p>
<?php endif;
}
function fwp_category_box ($checked, $object, $tags = array(), $params = array()) {
......@@ -946,6 +976,12 @@ class FeedWordPressSettingsUI {
background-position:0 top;
background-repeat:repeat-x;
}
.update-results {
max-width: 100%;
overflow: auto;
}
</style>
<?php
} /* FeedWordPressSettingsUI::admin_styles () */
......@@ -1076,7 +1112,7 @@ function fwp_syndication_manage_page_links_table_rows ($links, $page, $visible =
// Prep: Get last updated timestamp
$sLink = new SyndicatedLink($link->link_id);
if (!is_null($sLink->setting('update/last'))) :
$lastUpdated = fwp_time_elapsed($sLink->setting('update/last'));
$lastUpdated = 'Last checked '. fwp_time_elapsed($sLink->setting('update/last'));
else :
$lastUpdated = __('None yet');
endif;
......@@ -1101,19 +1137,41 @@ function fwp_syndication_manage_page_links_table_rows ($links, $page, $visible =
."</div>\n";
endif;
$nextUpdate = "<div style='font-style:italic;size:0.9em'>Ready for next update ";
if (isset($sLink->settings['update/ttl']) and is_numeric($sLink->settings['update/ttl'])) :
if (isset($sLink->settings['update/timed']) and $sLink->settings['update/timed']=='automatically') :
$next = $sLink->settings['update/last'] + ((int) $sLink->settings['update/ttl'] * 60);
$nextUpdate = "<div style='max-width: 30.0em; font-size: 0.9em;'><div style='font-style:italic;'>";
$ttl = $sLink->setting('update/ttl');
if (is_numeric($ttl)) :
$next = $sLink->setting('update/last') + $sLink->setting('update/fudge') + ((int) $ttl * 60);
if ('automatically'==$sLink->setting('update/timed')) :
if ($next < time()) :
$nextUpdate .= 'Ready and waiting to be updated since ';
else :
$nextUpdate .= 'Scheduled for next update ';
endif;
$nextUpdate .= fwp_time_elapsed($next);
if (FEEDWORDPRESS_DEBUG) : $nextUpdate .= " [".(($next-time())/60)." minutes]"; endif;
else :
$nextUpdate .= "every ".$sLink->settings['update/ttl']." minute".(($sLink->settings['update/ttl']!=1)?"s":"");
$lastUpdated .= " &middot; Next ";
if ($next < time()) :
$lastUpdated .= 'ASAP';
elseif ($next - time() < 60) :
$lastUpdated .= fwp_time_elapsed($next);
elseif ($next - time() < 60*60*24) :
$lastUpdated .= gmdate('g:ia', $next + (get_option('gmt_offset') * 3600));
else :
$lastUpdated .= gmdate('F j', $next + (get_option('gmt_offset') * 3600));
endif;
$nextUpdate .= "Scheduled to be checked for updates every ".$ttl." minute".(($ttl!=1)?"s":"")."</div><div style='size:0.9em; margin-top: 0.5em'> This update schedule was requested by the feed provider";
if ($sLink->setting('update/xml')) :
$nextUpdate .= " using a standard <code style=\"font-size: inherit; padding: 0; background: transparent\">&lt;".$sLink->setting('update/xml')."&gt;</code> element";
endif;
$nextUpdate .= ".";
endif;
else:
$nextUpdate .= "as soon as possible";
$nextUpdate .= "Scheduled for update as soon as possible";
endif;
$nextUpdate .= "</div>";
$nextUpdate .= "</div></div>";
unset($sLink);
......
......@@ -24,6 +24,9 @@ class FeedWordPressAuthorsPage extends FeedWordPressAdminPage {
function refresh_author_list () {
$this->authorlist = fwp_author_list();
// Case-insensitive "natural" alphanumeric sort. Preserves key/value associations.
if (function_exists('natcasesort')) : natcasesort($this->authorlist); endif;
}
/*static*/ function syndicated_authors_box ($page, $box = NULL) {
......@@ -45,6 +48,26 @@ class FeedWordPressAuthorsPage extends FeedWordPressAdminPage {
?>
<table class="form-table">
<?php
if ($page->for_default_settings()) :
?>
<tr><th>Unmatched authors</th>
<td><span>Authors who haven&#8217;t been syndicated before</span>
<select style="max-width: 27.0em" id="unfamiliar-author" name="unfamiliar_author" onchange="contextual_appearance('unfamiliar-author', 'unfamiliar-author-newuser', 'unfamiliar-author-default', 'newuser', 'inline');">
<option value="create"<?php print $unfamiliar['create']; ?>>will have a new author account created for them</option>
<?php foreach ($page->authorlist as $author_id => $author_name) : ?>
<option value="<?php echo $author_id; ?>"<?php print (isset($unfamiliar[$author_id]) ? $unfamiliar[$author_id] : ''); ?>>will have their posts attributed to <?php echo $author_name; ?></option>
<?php endforeach; ?>
<option value="newuser">will have their posts attributed to a new user...</option>
<option value="filter"<?php print $unfamiliar['filter'] ?>>get filtered out</option>
</select>
<span id="unfamiliar-author-newuser">named <input type="text" name="unfamiliar_author_newuser" value="" /></span></p>
</td>
</tr>
<?php
endif;
if ($page->for_feed_settings()) :
$map = $this->link->setting('map authors', NULL, array());
?>
......@@ -55,8 +78,10 @@ authors?</p>
<li><p><input type="radio" name="author_rules_name[all]" value="*"
<?php if (isset($map['name']['*'])) : $author_action = $map['name']['*']; ?>
checked="checked"
<?php else : $author_action = NULL; ?>
<?php endif; ?>
<?php
else :
$author_action = NULL;
endif; ?>
/> All posts syndicated
from this feed <select class="author-rules" id="author-rules-all"
name="author_rules_action[all]" onchange="contextual_appearance('author-rules-all', 'author-rules-all-newuser', 'author-rules-all-default', 'newuser', 'inline');">
......
......@@ -70,6 +70,7 @@ class FeedWordPressDiagnosticsPage extends FeedWordPressAdminPage {
if (isset($post['submit'])
or isset($post['save'])) :
update_option('feedwordpress_debug', $post['feedwordpress_debug']);
update_option('feedwordpress_secret_key', $post['feedwordpress_secret_key']);
if (!isset($post['diagnostics_output'])
or !is_array($post['diagnostics_output'])) :
......@@ -106,8 +107,9 @@ class FeedWordPressDiagnosticsPage extends FeedWordPressAdminPage {
} /* FeedWordPressDiagnosticsPage::accept_POST () */
function info_box ($page, $box = NULL) {
$link_category_id = FeedWordPress::link_category_id();
?>
global $feedwordpress;
$link_category_id = FeedWordPress::link_category_id();
?>
<table class="edit-form narrow">
<thead style="display: none">
<th scope="col">Topic</th>
......@@ -146,6 +148,14 @@ class FeedWordPressDiagnosticsPage extends FeedWordPressAdminPage {
</table>
<?php endif; ?></td>
</tr>
<tr>
<th scope="row"><?php _e('Secret Key:'); ?></th>
<td><input type="text" name="feedwordpress_secret_key" value="<?php print esc_attr($feedwordpress->secret_key()); ?>" />
<p class="setting-description">This is used to control access to some diagnostic testing functions. You can change it to any string you want,
but only tell it to people you trust to help you troubleshoot your
FeedWordPress installation. Keep it secret&#8212;keep it safe.</p></td>
</tr>
</table>
<?php
......@@ -228,7 +238,8 @@ testing but absolutely inappropriate for a production server.</p>
$hours = get_option('feedwordpress_diagnostics_persistent_errors_hours', 2);
$fields = apply_filters('feedwordpress_diagnostics', array(
'Update Diagnostics' => array(
'updated_feeds' => 'as each feed checked for updates',
'update_schedule:check' => 'whenever a FeedWordPress checks in on the update schedule',
'updated_feeds' => 'as each feed is checked for updates',
'updated_feeds:errors:persistent' => 'when attempts to update a feed have resulted in errors</label> <label>for at least <input type="number" min="1" max="360" step="1" name="diagnostics_persistent_error_hours" value="'.$hours.'" /> hours',
'updated_feeds:errors' => 'any time FeedWordPress encounters any errors while checking a feed for updates',
'syndicated_posts' => 'as each syndicated post is added to the database',
......@@ -236,8 +247,14 @@ testing but absolutely inappropriate for a production server.</p>
'memory_usage' => 'indicating how much memory was used',
),
'Syndicated Post Details' => array(
'feed_items:freshness' => 'as FeedWordPress decides whether to treat an item as a new post, an update, or a duplicate of an existing post',
'feed_items:rejected' => 'when FeedWordPress rejects a post without syndicating it',
'syndicated_posts:meta_data' => 'as syndication meta-data is added on the post',
),
'Advanced Diagnostics' => array(
'feed_items:freshness:sql' => 'when FeedWordPress issues the SQL query it uses to decide whether to treat items as new, updates, or duplicates',
'syndicated_posts:static_meta_data' => 'providing meta-data about syndicated posts in the Edit Posts interface',
),
), $page);
foreach ($fields as $section => $items) :
......
......@@ -175,7 +175,8 @@ class FeedWordPressFeedsPage extends FeedWordPressAdminPage {
} /* FeedWordPressFeedsPage::updated_posts_box() */
/*static*/ function global_feeds_box ($page, $box = NULL) {
$automatic_updates = get_option('feedwordpress_automatic_updates');
global $feedwordpress;
$automatic_updates = $feedwordpress->automatic_update_hook(array('setting only' => true));
$update_time_limit = (int) get_option('feedwordpress_update_time_limit');
// Hey, ho, let's go...
......@@ -263,6 +264,30 @@ class FeedWordPressFeedsPage extends FeedWordPressAdminPage {
?></td>
</tr>
<tr>
<th scope="row"><?php print __('Minimum Interval:'); ?></th>
<td><p style="margin-top:0px">Some feeds include standard elements that
request a specific update schedule. If the interval requested by the
feed provider is <em>longer</em> than FeedWordPress's normal scheduling,
FeedWordPress will always respect their request to slow down. But what
should it do if the update interval is <em>shorter</em> than the schedule set above?</p>
<?php
$this->setting_radio_control(
'update/minimum', 'update_minimum',
/*options=*/ array(
'no' => 'Speed up and accept the interval from the feed provider',
'yes' => 'Keep pace and use the longer scheduling from FeedWordPress',
),
/*params=*/ array(
'setting-default' => NULL,
'global-setting-default' => 'no',
'default-input-value' => 'default',
)
);
?>
</td>
</tr>
<?php if ($this->for_default_settings()) : ?>
<tr>
......@@ -905,7 +930,7 @@ class FeedWordPressFeedsPage extends FeedWordPressAdminPage {
update_option('feedwordpress_cat_id', $post['syndication_category']);
if (!isset($post['automatic_updates']) or !in_array($post['automatic_updates'], array('init', 'shutdown'))) :
$automatic_updates = false;
$automatic_updates = NULL;
else :
$automatic_updates = $post['automatic_updates'];
endif;
......@@ -939,6 +964,10 @@ class FeedWordPressFeedsPage extends FeedWordPressAdminPage {
endif;
$this->update_setting('fetch timeout', $timeout);
endif;
if (isset($post['update_minimum'])) :
$this->update_setting('update/minimum', $post['update_minimum']);
endif;
$this->updatedPosts->accept_POST($post);
parent::save_settings($post);
......
......@@ -11,7 +11,7 @@ class FeedTime {
$this->set($time);
} /* FeedTime constructor */
function set ($time) {
function set ($time, $recurse = false) {
$this->rep = $time;
$this->ts = NULL;
if (is_numeric($time)) : // Presumably a Unix-epoch timestamp
......@@ -23,7 +23,7 @@ class FeedTime {
if ($this->failed()) :
// In some versions of PHP, strtotime() does not support
// the UT timezone. Since UT is by definition within 1
// second of UTC, we'll just convert it here to avoid
// second of UTC, we'll just convert it preemptively to avoid
// problems.
$time = preg_replace(
'/(\s)UT$/',
......@@ -31,6 +31,12 @@ class FeedTime {
$time
);
$this->ts = strtotime($time);
if ($this->failed()
and preg_match('/^(.*)([+\-][0-9]+|\s+[A-Za-z]{1,3})$/', $time, $matches)) :
// Try dropping the time zone and recurse
$this->set($matches[1], /*recurse=*/ true);
endif;
endif;
endif;
} /* FeedTime::set() */
......
......@@ -62,7 +62,7 @@ fwpList = {
if ( !s ) { return false; }
if ( !e.is("[class^=add:" + list.id + ":]") ) { return !fwpList.add.call( list, e, s ); }
if ( !e.is('[class^="add:' + list.id + ':"]') ) { return !fwpList.add.call( list, e, s ); }
if ( !s.element ) { return true; }
......@@ -91,6 +91,7 @@ fwpList = {
if ( true === res ) { return true; }
jQuery.each( res.responses, function() {
// FIXME: Causes ownerDocument is undefined breakage in WP3.2
fwpList.add.call( list, this.data, $.extend( {}, s, { // this.firstChild.nodevalue
pos: this.position || 0,
id: this.id || 0,
......@@ -321,11 +322,11 @@ fwpList = {
process: function(el) {
var list = this;
$("[class^=add:" + list.id + ":]", el || null)
$('[class^="add:' + list.id + ':"]', el || null)
.filter('form').submit( function() { return list.fwpList.add(this); } ).end()
.not('form').click( function() { return list.fwpList.add(this); } );
$("[class^=delete:" + list.id + ":]", el || null).click( function() { return list.fwpList.del(this); } );
$("[class^=dim:" + list.id + ":]", el || null).click( function() { return list.fwpList.dim(this); } );
$('[class^="delete:' + list.id + ':"]', el || null).click( function() { return list.fwpList.del(this); } );
$('[class^="dim:' + list.id + ':"]', el || null).click( function() { return list.fwpList.dim(this); } );
},
recolor: function() {
......
<?php
class FeedWordPress_File extends WP_SimplePie_File {
function FeedWordPress_File ($url, $timeout = 10, $redirects = 5, $headers = null, $useragent = null, $force_fsockopen = false) {
self::__construct($url, $timeout, $redirects, $headers, $useragent, $force_fsockopen);
}
function __construct ($url, $timeout = 10, $redirects = 5, $headers = null, $useragent = null, $force_fsockopen = false) {
if (is_callable(array('WP_SimplePie_File', 'WP_SimplePie_File'))) : // PHP 4 idiom
WP_SimplePie_File::WP_SimplePie_File($url, $timeout, $redirects, $headers, $useragent, $force_fsockopen);
else : // PHP 5+
parent::__construct($url, $timeout, $redirects, $headers, $useragent, $force_fsockopen);
endif;
// SimplePie makes a strongly typed check against integers with
// this, but WordPress puts a string in. Which causes caching
// to break and fall on its ass when SimplePie is getting a 304,
// but doesn't realize it because this member is "304" instead.
$this->status_code = (int) $this->status_code;
}
} /* class FeedWordPress_File () */
<?php
class FeedWordPress_Parser extends SimplePie_Parser {
function parse (&$data, $encoding) {
// Use UTF-8 if we get passed US-ASCII, as every US-ASCII character is a UTF-8 character
if (strtoupper($encoding) === 'US-ASCII')
{
$this->encoding = 'UTF-8';
}
else
{
$this->encoding = $encoding;
}
// Strip BOM:
// UTF-32 Big Endian BOM
if (substr($data, 0, 4) === "\x00\x00\xFE\xFF")
{
$data = substr($data, 4);
}
// UTF-32 Little Endian BOM
elseif (substr($data, 0, 4) === "\xFF\xFE\x00\x00")
{
$data = substr($data, 4);
}
// UTF-16 Big Endian BOM
elseif (substr($data, 0, 2) === "\xFE\xFF")
{
$data = substr($data, 2);
}
// UTF-16 Little Endian BOM
elseif (substr($data, 0, 2) === "\xFF\xFE")
{
$data = substr($data, 2);
}
// UTF-8 BOM
elseif (substr($data, 0, 3) === "\xEF\xBB\xBF")
{
$data = substr($data, 3);
}
if (substr($data, 0, 5) === '<?xml' && strspn(substr($data, 5, 1), "\x09\x0A\x0D\x20") && ($pos = strpos($data, '?>')) !== false)
{
$declaration =& new SimplePie_XML_Declaration_Parser(substr($data, 5, $pos - 5));
if ($declaration->parse())
{
$data = substr($data, $pos + 2);
$data = '<?xml version="' . $declaration->version . '" encoding="' . $encoding . '" standalone="' . (($declaration->standalone) ? 'yes' : 'no') . '"?>' . $data;
}
else
{
$this->error_string = 'SimplePie bug! Please report this!';
return false;
}
}
$return = true;
static $xml_is_sane = null;
if ($xml_is_sane === null)
{
$parser_check = xml_parser_create();
xml_parse_into_struct($parser_check, '<foo>&amp;</foo>', $values);
xml_parser_free($parser_check);
$xml_is_sane = isset($values[0]['value']);
}
// Create the parser
if ($xml_is_sane)
{
$xml = xml_parser_create_ns($this->encoding, $this->separator);
xml_parser_set_option($xml, XML_OPTION_SKIP_WHITE, 1);
xml_parser_set_option($xml, XML_OPTION_CASE_FOLDING, 0);
xml_set_object($xml, $this);
xml_set_character_data_handler($xml, 'cdata');
xml_set_element_handler($xml, 'tag_open', 'tag_close');
xml_set_start_namespace_decl_handler($xml, 'start_xmlns');
// Parse!
if (!xml_parse($xml, $data, true))
{
$this->error_code = xml_get_error_code($xml);
$this->error_string = xml_error_string($this->error_code);
$return = false;
}
$this->current_line = xml_get_current_line_number($xml);
$this->current_column = xml_get_current_column_number($xml);
$this->current_byte = xml_get_current_byte_index($xml);
xml_parser_free($xml);
return $return;
}
else
{
libxml_clear_errors();
$xml =& new XMLReader();
$xml->xml($data);
while (@$xml->read())
{
switch ($xml->nodeType)
{
case constant('XMLReader::END_ELEMENT'):
if ($xml->namespaceURI !== '')
{
$tagName = "{$xml->namespaceURI}{$this->separator}{$xml->localName}";
}
else
{
$tagName = $xml->localName;
}
$this->tag_close(null, $tagName);
break;
case constant('XMLReader::ELEMENT'):
$empty = $xml->isEmptyElement;
if ($xml->namespaceURI !== '')
{
$tagName = "{$xml->namespaceURI}{$this->separator}{$xml->localName}";
}
else
{
$tagName = $xml->localName;
}
$attributes = array();
while ($xml->moveToNextAttribute())
{
if ($xml->namespaceURI !== '')
{
$attrName = "{$xml->namespaceURI}{$this->separator}{$xml->localName}";
}
else
{
$attrName = $xml->localName;
}
$attributes[$attrName] = $xml->value;
}
foreach ($attributes as $attr => $value) :
list($ns, $local) = $this->split_ns($attr);
if ($ns=='http://www.w3.org/2000/xmlns/') :
if ('xmlns' == $local) : $local = false; endif;
$this->start_xmlns(null, $local, $value);
endif;
endforeach;
$this->tag_open(null, $tagName, $attributes);
if ($empty)
{
$this->tag_close(null, $tagName);
}
break;
case constant('XMLReader::TEXT'):
case constant('XMLReader::CDATA'):
$this->cdata(null, $xml->value);
break;
}
}
if ($error = libxml_get_last_error())
{