Commit 26cdb06b authored by lucha's avatar lucha

[auto] plugin: feedwordpress 2017.1020

parent 775baaf3
......@@ -3,15 +3,15 @@
Plugin Name: FeedWordPress
Plugin URI: http://feedwordpress.radgeek.com/
Description: simple and flexible Atom/RSS syndication for WordPress
Version: 2017.1004
Author: Charles Johnson
Author URI: http://radgeek.com/
Version: 2017.1020
Author: C. Johnson
Author URI: https://feedwordpress.radgeek.com/contact/
License: GPL
*/
/**
* @package FeedWordPress
* @version 2017.1004
* @version 2017.1020
*/
# This uses code derived from:
......@@ -32,13 +32,16 @@ License: GPL
# -- Don't change these unless you know what you're doing...
define ('FEEDWORDPRESS_VERSION', '2017.1004');
define ('FEEDWORDPRESS_AUTHOR_CONTACT', 'http://radgeek.com/contact');
define ('FEEDWORDPRESS_VERSION', '2017.1020');
define ('FEEDWORDPRESS_AUTHOR_CONTACT', 'http://feedwordpress.radgeek.com/contact');
if (!defined('FEEDWORDPRESS_BLEG')) :
define ('FEEDWORDPRESS_BLEG', true);
endif;
define('FEEDWORDPRESS_BLEG_BTC', '1FN3Q4VSR4jV7unRjaknVQVe5ky88ktPHS');
define('FEEDWORDPRESS_BLEG_BTC', '15EsQ9QMZtLytsaVYZUaUCmrkSMaxZBTso');
define('FEEDWORDPRESS_BLEG_PAYPAL', '22PAJZZCK5Z3W');
define('FEEDWORDPRESS_BOILERPLATE_DEFAULT_HOOK_ORDER', 11000); // at the tail end of the filtering process
// Defaults
define ('DEFAULT_SYNDICATION_CATEGORY', 'Contributors');
......@@ -203,6 +206,33 @@ if (!$feedwordpress->needs_upgrade()) : // only work if the conditions are safe!
remove_filter('pre_link_rss', 'wp_filter_kses');
remove_filter('pre_link_url', 'wp_filter_kses');
# Boilerplate functionality: hook in to title, excerpt, and content to add boilerplate text
$hookOrder = get_option('feedwordpress_boilerplate_hook_order', FEEDWORDPRESS_BOILERPLATE_DEFAULT_HOOK_ORDER);
add_filter(
/*hook=*/ 'the_title',
/*function=*/ 'add_boilerplate_title',
/*priority=*/ $hookOrder,
/*arguments=*/ 2
);
add_filter(
/*hook=*/ 'get_the_excerpt',
/*function=*/ 'add_boilerplate_excerpt',
/*priority=*/ $hookOrder,
/*arguments=*/ 1
);
add_filter(
/*hook=*/ 'the_content',
/*function=*/ 'add_boilerplate_content',
/*priority=*/ $hookOrder,
/*arguments=*/ 1
);
add_filter(
/*hook=*/ 'the_content_rss',
/*function=*/ 'add_boilerplate_content',
/*priority=*/ $hookOrder,
/*arguments=*/ 1
);
# Admin menu
add_action('admin_init', array($feedwordpress, 'admin_init'));
add_action('admin_menu', 'fwp_add_pages');
......@@ -927,6 +957,186 @@ function fwp_publish_post_hook ($post_id) {
return $ret;
} // function feedwordpress_save_edit_controls
################################################################################
## class FeedWordPressBoilerplateReformatter ###################################
################################################################################
class FeedWordPressBoilerplateReformatter {
var $id, $element;
public function __construct ($id = NULL, $element = 'post') {
$this->id = $id;
$this->element = $element;
}
function shortcode_methods () {
return array(
'source' => 'source_link',
'source-name' => 'source_name',
'source-url' => 'source_url',
'original-link' => 'original_link',
'original-url' => 'original_url',
'author' => 'source_author_link',
'author-name' => 'source_author',
'feed-setting' => 'source_setting',
);
}
function do_shortcode ($template) {
$codes = $this->shortcode_methods();
// Register shortcodes relative to this object/post ID/element.
foreach ($codes as $code => $method) :
add_shortcode($code, array($this, $method));
endforeach;
$template = do_shortcode($template);
// Unregister shortcodes.
foreach ($codes as $code => $method) :
remove_shortcode($code);
endforeach;
return $template;
}
function source_name ($atts) {
$param = shortcode_atts(array(
'original' => NULL,
), $atts);
return get_syndication_source($param['original'], $this->id);
}
function source_url ($atts) {
$param = shortcode_atts(array(
'original' => NULL,
), $atts);
return get_syndication_source_link($param['original'], $this->id);
}
function source_link ($atts) {
switch (strtolower($atts[0])) :
case '-name' :
$ret = $this->source_name($atts);
break;
case '-url' :
$ret = $this->source_url($atts);
break;
default :
$param = shortcode_atts(array(
'original' => NULL,
), $atts);
if ('title' == $this->element) :
$ret = $this->source_name($atts);
else :
$ret = '<a href="'.htmlspecialchars($this->source_url($atts)).'">'.htmlspecialchars($this->source_name($atts)).'</a>';
endif;
endswitch;
return $ret;
}
function source_setting ($atts) {
$param = shortcode_atts(array(
'key' => NULL,
), $atts);
return get_feed_meta($param['key'], $this->id);
}
function original_link ($atts, $text) {
$url = $this->original_url($atts);
return '<a href="'.esc_url($url).'">'.do_shortcode($text).'</a>';
}
function original_url ($atts) {
return get_syndication_permalink($this->id);
}
function source_author ($atts) {
return get_the_author();
}
function source_author_link ($atts) {
switch (strtolower($atts[0])) :
case '-name' :
$ret = $this->source_author($atts);
break;
default :
global $authordata; // Janky.
if ('title' == $this->element) :
$ret = $this->source_author($atts);
else :
$ret = get_the_author();
$url = get_author_posts_url((int) $authordata->ID, (int) $authordata->user_nicename);
if ($url) :
$ret = '<a href="'.$url.'" '
.'title="Read other posts by '.esc_html($authordata->display_name).'">'
.$ret
.'</a>';
endif;
endif;
endswitch;
return $ret;
}
}
function add_boilerplate_reformat ($template, $element, $id = NULL) {
if ('post' == $element and !preg_match('/< (p|div) ( \s [^>]+ )? >/xi', $template)) :
$template = '<p class="syndicated-attribution">'.$template.'</p>';
endif;
$ref = new FeedWordPressBoilerplateReformatter($id, $element);
return $ref->do_shortcode($template);
}
function add_boilerplate_simple ($element, $title, $id = NULL) {
if (is_syndicated($id)) :
$meta = get_feed_meta('boilerplate rules', $id);
if ($meta and !is_array($meta)) : $meta = unserialize($meta); endif;
if (!is_array($meta) or empty($meta)) :
$meta = get_option('feedwordpress_boilerplate');
endif;
if (is_array($meta) and !empty($meta)) :
foreach ($meta as $rule) :
if ($element==$rule['element']) :
$rule['template'] = add_boilerplate_reformat($rule['template'], $element, $id);
if ('before'==$rule['placement']) :
$title = $rule['template'] . ' ' . $title;
else :
$title = $title . ' ' . $rule['template'];
endif;
endif;
endforeach;
endif;
endif;
return $title;
}
function add_boilerplate_title ($title, $id = NULL) {
return add_boilerplate_simple('title', $title, $id);
}
function add_boilerplate_excerpt ($title, $id = NULL) {
return add_boilerplate_simple('excerpt', $title, $id);
}
function add_boilerplate_content ($content) {
if (is_syndicated()) :
$meta = get_feed_meta('boilerplate rules');
if ($meta and !is_array($meta)) : $meta = unserialize($meta); endif;
if (!is_array($meta) or empty($meta)) :
$meta = get_option('feedwordpress_boilerplate');
endif;
if (is_array($meta) and !empty($meta)) :
foreach ($meta as $rule) :
if ('post'==$rule['element']) :
$rule['template'] = add_boilerplate_reformat($rule['template'], 'post');
if ('before'==$rule['placement']) :
$content = $rule['template'] . "\n" . $content;
else :
$content = $content . "\n" . $rule['template'];
endif;
endif;
endforeach;
endif;
endif;
return $content;
}
################################################################################
## class FeedWordPress #########################################################
################################################################################
......
......@@ -736,7 +736,7 @@ support, and documentation.</p>
<div style="display: inline-block; vertical-align: bottom">
<input type="image" name="submit" src="<?php print esc_url(plugins_url('/' . FeedWordPress::path('paypal-donation-64px.png' ) ) ); ?>" alt="Donate through PayPal" />
<input type="hidden" name="business" value="distro.to.feedback@radgeek.com" />
<input type="hidden" name="business" value="<?php print esc_attr(FEEDWORDPRESS_BLEG_PAYPAL); ?>" />
<input type="hidden" name="cmd" value="_xclick" />
<input type="hidden" name="item_name" value="FeedWordPress donation" />
<input type="hidden" name="no_shipping" value="1" />
......
......@@ -119,11 +119,36 @@ class FeedWordPressPostsPage extends FeedWordPressAdminPage {
update_option('feedwordpress_syndicated_post_type', $post['syndicated_post_type']);
endif;
endif;
if (isset($post['save']) or isset($post['submit'])) :
if (isset($post['boilerplate'])) :
foreach ($post['boilerplate'] as $index => $line) :
if (0 == strlen(trim($line['template']))) :
unset($post['boilerplate'][$index]);
endif;
endforeach;
// Convert indexes to 0..(N-1) to avoid possible collisions
$post['boilerplate'] = array_values($post['boilerplate']);
if ($this->for_feed_settings()) :
$this->link->settings['boilerplate rules'] = serialize($post['boilerplate']);
$this->link->save_settings(/*reload=*/ true);
else :
update_option('feedwordpress_boilerplate', $post['boilerplate']);
endif;
endif;
if (isset($post['boilerplate_hook_order'])) :
$this->update_setting('boilerplate hook order', intval($post['boilerplate_hook_order']));
endif;
endif;
parent::save_settings($post);
}
/**
* Outputs "Publication" settings box.
* publication_box: Outputs "Publication" settings box.
*
* @since 2009.0713
* @param object $page of class FeedWordPressPostsPage tells us whether this is
......@@ -498,11 +523,198 @@ class FeedWordPressPostsPage extends FeedWordPressAdminPage {
<?php
} /* FeedWordPressPostsPage::custom_post_types_box() */
public function boilerplate_box ($page, $box = NULL) {
if ($page->for_feed_settings()) :
$attrib = unserialize($page->link->settings['boilerplate rules']);
$syndicatedPosts = 'this feed\'s posts';
else :
$attrib = get_option('feedwordpress_boilerplate');
$syndicatedPosts = 'syndicated posts';
endif;
$hookOrder = intval($page->setting('boilerplate hook order', FEEDWORDPRESS_BOILERPLATE_DEFAULT_HOOK_ORDER));
?>
<style type="text/css">
.boilerplate-help-box {
float: right;
width: 300px;
border: 1px dotted #777;
margin: 3px;
padding: 5px;
background-color: #f7f7f7;
}
.boilerplate-help-box dt {
font-weight: bold;
font-size: 85%;
}
.boilerplate-help-box dd {
font-size: 80%; line-height: 100%; font-style: italic;
padding-left: 1.5em;
}
.boilerplate-help-box code {
font-size: inherit;
font-style: normal;
background-color: inherit;
}
.boilerplate-li {
padding-bottom: 5px;
margin-bottom: 5px;
border-bottom: 1px dotted black;
}
</style>
<div class="boilerplate-help-box">
<p style="border-bottom: 1px dotted #777;">To remove boilerplate, just blank out the text box and leave it empty.</p>
<p>Use shortcodes to include information about your source:</p>
<dl>
<dt><code>[source]</code></dt>
<dd>A link to the source you syndicated the post from</dd>
<dt><code>[source-name]</code></dt>
<dd>Name of the source you syndicated the post from</dd>
<dt><code>[source-url]</code></dt>
<dd>URL of the source you syndicated the post from</dd>
<dt><code>[original-link]text[/original-link]</code></dt>
<dd>A link to the <em>original post</em> back on the source website,
using <code>text</code> as the link text.</dd>
<dt><code>[original-url]</code></dt>
<dd>URL of the <em>original post</em> back on the source website</dd>
<dt><code>[author]</code></dt>
<dd>A link with the name of the author who wrote the post, linking to other posts by the same author</dd>
<dt><code>[author-name]</code></dt>
<dd>Name of the author who wrote the post</dd>
<dt><code>[feed-setting key="setting-name"]</code></dt>
<dd>Value of a custom feed setting (named <code>setting-name</code>) for the feed</dd>
</dl>
</div>
<?php
print "<ul>\n";
if (!is_array($attrib)) : $attrib = array(); endif;
print '<input type="hidden" id="next-boilerplate-rule-index" name="next_boilerplate_rule_index" value="'.count($attrib).'" />';
// In AJAX environment, this is a dummy rule that stays hidden. In a
// non-AJAX environment, this provides a blank rule that we can fill in.
$attrib['new'] = array(
'class' => array('hide-if-js'),
'placement' => 'before',
'element' => 'post',
'template' => '',
);
foreach ($attrib as $index => $line) :
if (isset($line['template'])) :
$selected['before'] = (($line['placement']=='before') ? ' selected="selected"' : '');
$selected['after'] = (($line['placement']=='after') ? ' selected="selected"' : '');
$selected['title'] = (($line['element']=='title') ? ' selected="selected"' : '');
$selected['post'] = (($line['element']=='post') ? ' selected="selected"' : '');
$selected['excerpt'] = (($line['element']=='excerpt') ? ' selected="selected"' : '');
if (!isset($line['class'])) : $line['class'] = array(); endif;
$line['class'][] = 'boilerplate-li';
?>
<li id="boilerplate-<?php print $index; ?>-li" class="<?php print implode(' ', $line['class']); ?>">&raquo; <strong>Add</strong> <select id="boilerplate-<?php print $index; ?>-placement" name="boilerplate[<?php print $index; ?>][placement]" style="width: 8.0em">
<option value="before"<?php print $selected['before']; ?>>before</option>
<option value="after"<?php print $selected['after']; ?>>after</option>
</select> the <select style="width: 8.0em" id="boilerplate-<?php print $index; ?>-element" name="boilerplate[<?php print $index; ?>][element]">
<option value="title"<?php print $selected['title']; ?>>title</option>
<option value="post"<?php print $selected['post']; ?>>content</option>
<option value="excerpt"<?php print $selected['excerpt']; ?>>excerpt</option>
</select> of
<?php print $syndicatedPosts; ?>: <textarea style="vertical-align: top; width: 40%;" rows="2" cols="30" class="boilerplate-template" id="boilerplate-<?php print $index; ?>-template" name="boilerplate[<?php print $index; ?>][template]"><?php print htmlspecialchars($line['template']); ?></textarea></li>
<?php
endif;
endforeach;
?>
</ul>
<br style="clear: both" />
<script type="text/javascript">
jQuery(document).ready( function($) {
$('.boilerplate-template').blur( function() {
if (this.value.length == 0) {
var theLi = $('li:has(#'+this.id+")");
theLi.hide('normal')
}
} );
var addRuleLi = document.createElement('li');
addRuleLi.innerHTML = '<strong style="vertical-align: middle; font-size: 110%">[+]</strong> <a style="font-variant: small-caps" id="add-new-boilerplate-rule" href="#">Add new boilerplate</a> ….';
$('#boilerplate-new-li').after(addRuleLi);
$('#add-new-boilerplate-rule').click( function() {
// Get index counter
var nextIndex = parseInt($('#next-boilerplate-rule-index').val());
var newIdPrefix = 'boilerplate-'+nextIndex;
var newNamePrefix = 'boilerplate['+nextIndex+']';
var dummy = {};
dummy['li'] = {'el': $('#boilerplate-new-li') }
dummy['placement'] = {'el': $('#boilerplate-new-placement') };
dummy['element'] = {'el': $('#boilerplate-new-element') };
dummy['template'] = {'el': $('#boilerplate-new-template') };
for (var element in dummy) {
dummy[element]['save'] = {
'id': dummy[element]['el'].attr('id'),
'name': dummy[element]['el'].attr('name')
};
dummy[element]['el'].attr('id', newIdPrefix+'-'+element);
dummy[element]['el'].attr('name', newNamePrefix+'['+element+']');
}
var newLi = $('#'+newIdPrefix+'-li').clone(/*events=*/ true);
//newLi.attr('id', null);
newLi.removeClass('hide-if-js');
newLi.addClass('boilerplate-li');
newLi.css('display', 'none');
// Switch back
for (var element in dummy) {
dummy[element]['el'].attr('id', dummy[element]['save']['id']);
dummy[element]['el'].attr('name', dummy[element]['save']['name']);
}
$('#boilerplate-new-li').before(newLi);
newLi.show('normal');
$('#next-boilerplate-rule-index').val(nextIndex+1);
return false;
} )
} );
</script>
<?php
if ($page->for_default_settings()) :
?>
<h3>Advanced Settings</h3>
<table class="edit-form narrow">
<tbody>
<tr><th scope="row"><?php _e("Hook Order:") ?></th>
<td><input type="number" name="boilerplate_hook_order" value="<?php print esc_attr($hookOrder); ?>" /></td></tr>
</tbody>
</table>
<?php
endif;
} /* FeedWordPressPostsPage::boilerplate_box() */
function display () {
$this->boxes_by_methods = array(
'publication_box' => __('Syndicated Posts'),
'links_box' => __('Links'),
'formatting_box' => __('Formatting'),
'boilerplate_box' => ('Boilerplate / Credits'),
'comments_and_pings_box' => __('Comments & Pings'),
'custom_post_settings_box' => __('Custom Post Settings (to apply to each syndicated post)'),
'custom_post_types_box' => ('Custom Post Types (advanced database settings)'),
......@@ -510,6 +722,8 @@ class FeedWordPressPostsPage extends FeedWordPressAdminPage {
parent::display();
} /* FeedWordPressPostsPage::display () */
}
$postsPage = new FeedWordPressPostsPage;
......
This diff is collapsed.
......@@ -12,7 +12,7 @@ require_once(dirname(__FILE__).'/syndicatedpostxpathquery.class.php');
* different feed formats, which may be useful to FeedWordPress users
* who make use of feed data in PHP add-ons and filters.
*
* @version 2017.1004
* @version 2017.1018
*/
class SyndicatedPost {
var $item = null; // MagpieRSS representation
......@@ -43,10 +43,10 @@ class SyndicatedPost {
* @param array $item The item syndicated from the feed.
* @param SyndicatedLink $source The feed it was syndicated from.
*/
function __construct ($item, &$source) {
public function __construct ($item, $source) {
global $wpdb;
if ( empty($item) && empty($source) )
if ( empty($item) and empty($source) )
return;
if (is_array($item)
......@@ -68,7 +68,7 @@ class SyndicatedPost {
$this->item = $item;
endif;
$this->link =& $source;
$this->link = $source;
$this->feed = $source->magpie;
$this->feedmeta = $source->settings;
......@@ -290,7 +290,7 @@ class SyndicatedPost {
* @returns array of string values representing contents of matching
* elements or attributes
*/
function query ($path) {
public function query ($path) {
$xq = new SyndicatedPostXPathQuery(array("path" => $path));
$feedChannel = array_merge(
......@@ -342,15 +342,15 @@ class SyndicatedPost {
return $matches;
} /* SyndicatedPost::get_feed_channel_elements() */
function get_categories ($params = array()) {
public function get_categories ($params = array()) {
return $this->entry->get_categories();
}
function title ($params = array()) {
public function title ($params = array()) {
return $this->entry->get_title();
} /* SyndicatedPost::title () */
function content ($params = array()) {
public function content ($params = array()) {
$params = wp_parse_args($params, array(
"full only" => false,
......@@ -402,7 +402,7 @@ class SyndicatedPost {
return $content;
} /* SyndicatedPost::content() */
function excerpt () {
public function excerpt () {
# Identify and sanitize excerpt: atom:summary, or rss:description
$excerpt = $this->entry->get_description();
......@@ -433,14 +433,20 @@ class SyndicatedPost {
return $excerpt;
} /* SyndicatedPost::excerpt() */
function permalink () {
/**
* SyndicatedPost::permalink: returns the permalink for the post, as provided by the
* source feed.
*
* @return string The URL of the original permalink for this syndicated post
*/
public function permalink () {
// Handles explicit <link> elements and also RSS 2.0 cases with