WordPress.org

Plugin Directory

Changeset 1749912 for feedwordpress


Ignore:
Timestamp:
10/20/17 13:50:35 (4 weeks ago)
Author:
radgeek
Message:

2017.1020: Significant new feature -- Boilerplate / Credits setting panel brought into off-the-shelf FeedWordPress feature set. Smaller bugfixes, PHP 7.1+ compatibility tweaks, etc.

Location:
feedwordpress/trunk
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • feedwordpress/trunk/feedwordpress.php

    r1740884 r1749912  
    44Plugin URI: http://feedwordpress.radgeek.com/ 
    55Description: simple and flexible Atom/RSS syndication for WordPress 
    6 Version: 2017.1004 
    7 Author: Charles Johnson 
    8 Author URI: http://radgeek.com/ 
     6Version: 2017.1020 
     7Author: C. Johnson 
     8Author URI: https://feedwordpress.radgeek.com/contact/ 
    99License: GPL 
    1010*/ 
     
    1212/** 
    1313 * @package FeedWordPress 
    14  * @version 2017.1004 
     14 * @version 2017.1020 
    1515 */ 
    1616 
     
    3333# -- Don't change these unless you know what you're doing... 
    3434 
    35 define ('FEEDWORDPRESS_VERSION', '2017.1004'); 
    36 define ('FEEDWORDPRESS_AUTHOR_CONTACT', 'http://radgeek.com/contact'); 
     35define ('FEEDWORDPRESS_VERSION', '2017.1020'); 
     36define ('FEEDWORDPRESS_AUTHOR_CONTACT', 'http://feedwordpress.radgeek.com/contact'); 
    3737 
    3838if (!defined('FEEDWORDPRESS_BLEG')) : 
    3939    define ('FEEDWORDPRESS_BLEG', true); 
    4040endif; 
    41 define('FEEDWORDPRESS_BLEG_BTC', '1FN3Q4VSR4jV7unRjaknVQVe5ky88ktPHS'); 
     41define('FEEDWORDPRESS_BLEG_BTC', '15EsQ9QMZtLytsaVYZUaUCmrkSMaxZBTso'); 
     42define('FEEDWORDPRESS_BLEG_PAYPAL', '22PAJZZCK5Z3W'); 
     43 
     44define('FEEDWORDPRESS_BOILERPLATE_DEFAULT_HOOK_ORDER', 11000); // at the tail end of the filtering process 
    4245 
    4346// Defaults 
     
    203206    remove_filter('pre_link_rss', 'wp_filter_kses'); 
    204207    remove_filter('pre_link_url', 'wp_filter_kses'); 
     208 
     209    # Boilerplate functionality: hook in to title, excerpt, and content to add boilerplate text 
     210    $hookOrder = get_option('feedwordpress_boilerplate_hook_order', FEEDWORDPRESS_BOILERPLATE_DEFAULT_HOOK_ORDER); 
     211    add_filter( 
     212    /*hook=*/ 'the_title', 
     213    /*function=*/ 'add_boilerplate_title', 
     214    /*priority=*/ $hookOrder, 
     215    /*arguments=*/ 2 
     216    ); 
     217    add_filter( 
     218    /*hook=*/ 'get_the_excerpt', 
     219    /*function=*/ 'add_boilerplate_excerpt', 
     220    /*priority=*/ $hookOrder, 
     221    /*arguments=*/ 1 
     222    ); 
     223    add_filter( 
     224    /*hook=*/ 'the_content', 
     225    /*function=*/ 'add_boilerplate_content', 
     226    /*priority=*/ $hookOrder, 
     227    /*arguments=*/ 1 
     228    ); 
     229    add_filter( 
     230    /*hook=*/ 'the_content_rss', 
     231    /*function=*/ 'add_boilerplate_content', 
     232    /*priority=*/ $hookOrder, 
     233    /*arguments=*/ 1 
     234    ); 
    205235 
    206236    # Admin menu 
     
    927957        return $ret; 
    928958    } // function feedwordpress_save_edit_controls 
     959 
     960################################################################################ 
     961## class FeedWordPressBoilerplateReformatter ################################### 
     962################################################################################ 
     963 
     964class FeedWordPressBoilerplateReformatter { 
     965    var $id, $element; 
     966 
     967    public function __construct ($id = NULL, $element = 'post') { 
     968        $this->id = $id; 
     969        $this->element = $element; 
     970    } 
     971 
     972    function shortcode_methods () { 
     973        return array( 
     974            'source' => 'source_link', 
     975            'source-name' => 'source_name', 
     976            'source-url' => 'source_url', 
     977            'original-link' => 'original_link', 
     978            'original-url' => 'original_url', 
     979            'author' => 'source_author_link', 
     980            'author-name' => 'source_author', 
     981            'feed-setting' => 'source_setting', 
     982        ); 
     983    } 
     984    function do_shortcode ($template) { 
     985        $codes = $this->shortcode_methods(); 
     986 
     987        // Register shortcodes relative to this object/post ID/element. 
     988        foreach ($codes as $code => $method) : 
     989            add_shortcode($code, array($this, $method)); 
     990        endforeach; 
     991 
     992        $template = do_shortcode($template); 
     993         
     994        // Unregister shortcodes. 
     995        foreach ($codes as $code => $method) : 
     996            remove_shortcode($code); 
     997        endforeach; 
     998         
     999        return $template; 
     1000    } 
     1001     
     1002    function source_name ($atts) { 
     1003        $param = shortcode_atts(array( 
     1004        'original' => NULL, 
     1005        ), $atts); 
     1006        return get_syndication_source($param['original'], $this->id); 
     1007    } 
     1008    function source_url ($atts) { 
     1009        $param = shortcode_atts(array( 
     1010        'original' => NULL, 
     1011        ), $atts); 
     1012        return get_syndication_source_link($param['original'], $this->id); 
     1013    } 
     1014    function source_link ($atts) { 
     1015        switch (strtolower($atts[0])) : 
     1016        case '-name' : 
     1017            $ret = $this->source_name($atts); 
     1018            break; 
     1019        case '-url' : 
     1020            $ret = $this->source_url($atts); 
     1021            break; 
     1022        default : 
     1023            $param = shortcode_atts(array( 
     1024            'original' => NULL, 
     1025            ), $atts); 
     1026            if ('title' == $this->element) : 
     1027                $ret = $this->source_name($atts); 
     1028            else : 
     1029                $ret = '<a href="'.htmlspecialchars($this->source_url($atts)).'">'.htmlspecialchars($this->source_name($atts)).'</a>'; 
     1030            endif; 
     1031        endswitch; 
     1032        return $ret; 
     1033    } 
     1034    function source_setting ($atts) { 
     1035        $param = shortcode_atts(array( 
     1036        'key' => NULL, 
     1037        ), $atts); 
     1038        return get_feed_meta($param['key'], $this->id); 
     1039    } 
     1040    function original_link ($atts, $text) { 
     1041        $url = $this->original_url($atts); 
     1042        return '<a href="'.esc_url($url).'">'.do_shortcode($text).'</a>'; 
     1043    } 
     1044    function original_url ($atts) { 
     1045        return get_syndication_permalink($this->id); 
     1046    } 
     1047    function source_author ($atts) { 
     1048        return get_the_author(); 
     1049    } 
     1050    function source_author_link ($atts) { 
     1051        switch (strtolower($atts[0])) : 
     1052        case '-name' : 
     1053            $ret = $this->source_author($atts); 
     1054            break; 
     1055        default : 
     1056            global $authordata; // Janky. 
     1057            if ('title' == $this->element) : 
     1058                $ret = $this->source_author($atts); 
     1059            else : 
     1060                $ret = get_the_author(); 
     1061                $url = get_author_posts_url((int) $authordata->ID, (int) $authordata->user_nicename); 
     1062                if ($url) : 
     1063                    $ret = '<a href="'.$url.'" ' 
     1064                        .'title="Read other posts by '.esc_html($authordata->display_name).'">' 
     1065                        .$ret 
     1066                        .'</a>'; 
     1067                endif;           
     1068            endif; 
     1069        endswitch; 
     1070        return $ret; 
     1071    } 
     1072} 
     1073 
     1074function add_boilerplate_reformat ($template, $element, $id = NULL) { 
     1075    if ('post' == $element and !preg_match('/< (p|div) ( \s [^>]+ )? >/xi', $template)) : 
     1076        $template = '<p class="syndicated-attribution">'.$template.'</p>'; 
     1077    endif; 
     1078 
     1079    $ref = new FeedWordPressBoilerplateReformatter($id, $element); 
     1080    return $ref->do_shortcode($template); 
     1081} 
     1082 
     1083function add_boilerplate_simple ($element, $title, $id = NULL) { 
     1084    if (is_syndicated($id)) : 
     1085        $meta = get_feed_meta('boilerplate rules', $id); 
     1086        if ($meta and !is_array($meta)) : $meta = unserialize($meta); endif; 
     1087 
     1088        if (!is_array($meta) or empty($meta)) : 
     1089            $meta = get_option('feedwordpress_boilerplate'); 
     1090        endif; 
     1091 
     1092        if (is_array($meta) and !empty($meta)) : 
     1093            foreach ($meta as $rule) : 
     1094                if ($element==$rule['element']) : 
     1095                    $rule['template'] = add_boilerplate_reformat($rule['template'], $element, $id); 
     1096 
     1097                    if ('before'==$rule['placement']) : 
     1098                        $title = $rule['template'] . ' ' . $title; 
     1099                    else : 
     1100                        $title = $title . ' ' . $rule['template']; 
     1101                    endif; 
     1102                endif; 
     1103            endforeach; 
     1104        endif; 
     1105    endif; 
     1106    return $title; 
     1107} 
     1108function add_boilerplate_title ($title, $id = NULL) { 
     1109    return add_boilerplate_simple('title', $title, $id); 
     1110} 
     1111function add_boilerplate_excerpt ($title, $id = NULL) { 
     1112    return add_boilerplate_simple('excerpt', $title, $id); 
     1113} 
     1114function add_boilerplate_content ($content) { 
     1115    if (is_syndicated()) : 
     1116        $meta = get_feed_meta('boilerplate rules'); 
     1117        if ($meta and !is_array($meta)) : $meta = unserialize($meta); endif; 
     1118 
     1119        if (!is_array($meta) or empty($meta)) : 
     1120            $meta = get_option('feedwordpress_boilerplate'); 
     1121        endif; 
     1122 
     1123        if (is_array($meta) and !empty($meta)) : 
     1124            foreach ($meta as $rule) : 
     1125                if ('post'==$rule['element']) : 
     1126                    $rule['template'] = add_boilerplate_reformat($rule['template'], 'post'); 
     1127 
     1128                    if ('before'==$rule['placement']) : 
     1129                        $content = $rule['template'] . "\n" . $content; 
     1130                    else : 
     1131                        $content = $content . "\n" . $rule['template']; 
     1132                    endif; 
     1133                endif; 
     1134            endforeach; 
     1135        endif; 
     1136    endif; 
     1137    return $content;     
     1138} 
    9291139 
    9301140################################################################################ 
  • feedwordpress/trunk/feedwordpresssyndicationpage.class.php

    r1729270 r1749912  
    737737<div style="display: inline-block; vertical-align: bottom"> 
    738738<input type="image" name="submit" src="<?php print esc_url(plugins_url('/' . FeedWordPress::path('paypal-donation-64px.png' ) ) ); ?>" alt="Donate through PayPal" /> 
    739 <input type="hidden" name="business" value="distro.to.feedback@radgeek.com"  /> 
     739<input type="hidden" name="business" value="<?php print esc_attr(FEEDWORDPRESS_BLEG_PAYPAL); ?>"  /> 
    740740<input type="hidden" name="cmd" value="_xclick"  /> 
    741741<input type="hidden" name="item_name" value="FeedWordPress donation"  /> 
  • feedwordpress/trunk/posts-page.php

    r1553712 r1749912  
    120120            endif; 
    121121        endif; 
     122 
     123        if (isset($post['save']) or isset($post['submit'])) : 
     124            if (isset($post['boilerplate'])) : 
     125                foreach ($post['boilerplate'] as $index => $line) : 
     126                    if (0 == strlen(trim($line['template']))) : 
     127                        unset($post['boilerplate'][$index]); 
     128                    endif; 
     129                endforeach; 
     130 
     131                // Convert indexes to 0..(N-1) to avoid possible collisions 
     132                $post['boilerplate'] = array_values($post['boilerplate']); 
     133 
     134                if ($this->for_feed_settings()) : 
     135                    $this->link->settings['boilerplate rules'] = serialize($post['boilerplate']); 
     136                    $this->link->save_settings(/*reload=*/ true); 
     137                else : 
     138                    update_option('feedwordpress_boilerplate', $post['boilerplate']); 
     139                endif; 
     140            endif; 
     141         
     142            if (isset($post['boilerplate_hook_order'])) : 
     143                $this->update_setting('boilerplate hook order', intval($post['boilerplate_hook_order'])); 
     144            endif; 
     145        endif; 
     146 
    122147        parent::save_settings($post); 
    123148    } 
    124149 
    125150    /** 
    126      * Outputs "Publication" settings box. 
     151     * publication_box: Outputs "Publication" settings box. 
    127152     * 
    128153     * @since 2009.0713 
     
    499524    } /* FeedWordPressPostsPage::custom_post_types_box() */ 
    500525     
     526    public function boilerplate_box ($page, $box = NULL) { 
     527        if ($page->for_feed_settings()) : 
     528            $attrib = unserialize($page->link->settings['boilerplate rules']); 
     529            $syndicatedPosts = 'this feed\'s posts'; 
     530        else : 
     531            $attrib = get_option('feedwordpress_boilerplate'); 
     532            $syndicatedPosts = 'syndicated posts'; 
     533        endif; 
     534        $hookOrder = intval($page->setting('boilerplate hook order', FEEDWORDPRESS_BOILERPLATE_DEFAULT_HOOK_ORDER)); 
     535?> 
     536    <style type="text/css">  
     537    .boilerplate-help-box { 
     538        float: right; 
     539        width: 300px; 
     540        border: 1px dotted #777; 
     541        margin: 3px; 
     542        padding: 5px; 
     543        background-color: #f7f7f7; 
     544    } 
     545    .boilerplate-help-box dt { 
     546        font-weight: bold; 
     547        font-size: 85%; 
     548    } 
     549    .boilerplate-help-box dd { 
     550        font-size: 80%; line-height: 100%; font-style: italic; 
     551        padding-left: 1.5em; 
     552    } 
     553    .boilerplate-help-box code { 
     554        font-size: inherit; 
     555        font-style: normal; 
     556        background-color: inherit; 
     557    } 
     558 
     559    .boilerplate-li { 
     560        padding-bottom: 5px; 
     561        margin-bottom: 5px; 
     562        border-bottom: 1px dotted black; 
     563    } 
     564     
     565    </style> 
     566 
     567    <div class="boilerplate-help-box"> 
     568    <p style="border-bottom: 1px dotted #777;">To remove boilerplate, just blank out the text box and leave it empty.</p> 
     569 
     570    <p>Use shortcodes to include information about your source:</p> 
     571    <dl> 
     572    <dt><code>[source]</code></dt> 
     573    <dd>A link to the source you syndicated the post from</dd> 
     574 
     575    <dt><code>[source-name]</code></dt> 
     576    <dd>Name of the source you syndicated the post from</dd> 
     577 
     578    <dt><code>[source-url]</code></dt> 
     579    <dd>URL of the source you syndicated the post from</dd> 
     580 
     581    <dt><code>[original-link]text[/original-link]</code></dt> 
     582    <dd>A link to the <em>original post</em> back on the source website, 
     583    using <code>text</code> as the link text.</dd> 
     584     
     585    <dt><code>[original-url]</code></dt> 
     586    <dd>URL of the <em>original post</em> back on the source website</dd> 
     587 
     588    <dt><code>[author]</code></dt> 
     589    <dd>A link with the name of the author who wrote the post, linking to other posts by the same author</dd> 
     590 
     591    <dt><code>[author-name]</code></dt> 
     592    <dd>Name of the author who wrote the post</dd> 
     593     
     594    <dt><code>[feed-setting key="setting-name"]</code></dt> 
     595    <dd>Value of a custom feed setting (named <code>setting-name</code>) for the feed</dd> 
     596    </dl> 
     597    </div> 
     598 
     599<?php 
     600        print "<ul>\n"; 
     601        if (!is_array($attrib)) : $attrib = array(); endif; 
     602 
     603        print '<input type="hidden" id="next-boilerplate-rule-index" name="next_boilerplate_rule_index" value="'.count($attrib).'" />'; 
     604 
     605        // In AJAX environment, this is a dummy rule that stays hidden. In a 
     606        // non-AJAX environment, this provides a blank rule that we can fill in. 
     607        $attrib['new'] = array( 
     608        'class' => array('hide-if-js'), 
     609        'placement' => 'before', 
     610        'element' => 'post', 
     611        'template' => '', 
     612        ); 
     613 
     614        foreach ($attrib as $index => $line) : 
     615            if (isset($line['template'])) : 
     616                $selected['before'] = (($line['placement']=='before') ? ' selected="selected"' : ''); 
     617                $selected['after'] = (($line['placement']=='after') ? ' selected="selected"' : ''); 
     618                $selected['title'] = (($line['element']=='title') ? ' selected="selected"' : ''); 
     619                $selected['post'] = (($line['element']=='post') ? ' selected="selected"' : ''); 
     620                $selected['excerpt'] = (($line['element']=='excerpt') ? ' selected="selected"' : ''); 
     621 
     622                if (!isset($line['class'])) : $line['class'] = array(); endif; 
     623                $line['class'][] = 'boilerplate-li'; 
     624?> 
     625 
     626<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"> 
     627<option value="before"<?php print $selected['before']; ?>>before</option> 
     628<option value="after"<?php print $selected['after']; ?>>after</option> 
     629</select> the <select style="width: 8.0em" id="boilerplate-<?php print $index; ?>-element" name="boilerplate[<?php print $index; ?>][element]"> 
     630<option value="title"<?php print $selected['title']; ?>>title</option> 
     631<option value="post"<?php print $selected['post']; ?>>content</option> 
     632<option value="excerpt"<?php print $selected['excerpt']; ?>>excerpt</option> 
     633</select> of  
     634<?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> 
     635<?php 
     636            endif; 
     637        endforeach; 
     638?> 
     639    </ul> 
     640    <br style="clear: both" /> 
     641 
     642    <script type="text/javascript"> 
     643        jQuery(document).ready( function($) { 
     644            $('.boilerplate-template').blur( function() { 
     645                if (this.value.length == 0) { 
     646                    var theLi = $('li:has(#'+this.id+")"); 
     647                    theLi.hide('normal') 
     648                } 
     649            } ); 
     650 
     651            var addRuleLi = document.createElement('li'); 
     652            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> ….'; 
     653            $('#boilerplate-new-li').after(addRuleLi); 
     654 
     655            $('#add-new-boilerplate-rule').click( function() { 
     656                // Get index counter 
     657                var nextIndex = parseInt($('#next-boilerplate-rule-index').val()); 
     658 
     659                var newIdPrefix = 'boilerplate-'+nextIndex; 
     660                var newNamePrefix = 'boilerplate['+nextIndex+']'; 
     661 
     662                var dummy = {}; 
     663                dummy['li'] = {'el': $('#boilerplate-new-li') } 
     664                dummy['placement'] = {'el': $('#boilerplate-new-placement') }; 
     665                dummy['element'] = {'el': $('#boilerplate-new-element') }; 
     666                dummy['template'] = {'el': $('#boilerplate-new-template') }; 
     667 
     668                for (var element in dummy) { 
     669                    dummy[element]['save'] = { 
     670                        'id': dummy[element]['el'].attr('id'), 
     671                        'name': dummy[element]['el'].attr('name') 
     672                    }; 
     673                    dummy[element]['el'].attr('id', newIdPrefix+'-'+element); 
     674                    dummy[element]['el'].attr('name', newNamePrefix+'['+element+']'); 
     675                } 
     676     
     677                var newLi = $('#'+newIdPrefix+'-li').clone(/*events=*/ true); 
     678                //newLi.attr('id', null); 
     679                newLi.removeClass('hide-if-js'); 
     680                newLi.addClass('boilerplate-li'); 
     681                newLi.css('display', 'none'); 
     682 
     683                // Switch back 
     684                for (var element in dummy) { 
     685                    dummy[element]['el'].attr('id', dummy[element]['save']['id']); 
     686                    dummy[element]['el'].attr('name', dummy[element]['save']['name']); 
     687                } 
     688 
     689                $('#boilerplate-new-li').before(newLi); 
     690                newLi.show('normal'); 
     691 
     692                $('#next-boilerplate-rule-index').val(nextIndex+1); 
     693 
     694                return false; 
     695            } ) 
     696        } ); 
     697    </script> 
     698<?php 
     699        if ($page->for_default_settings()) : 
     700?> 
     701    <h3>Advanced Settings</h3> 
     702    <table class="edit-form narrow"> 
     703    <tbody> 
     704    <tr><th scope="row"><?php _e("Hook Order:") ?></th> 
     705    <td><input type="number" name="boilerplate_hook_order" value="<?php print esc_attr($hookOrder); ?>" /></td></tr> 
     706    </tbody> 
     707    </table> 
     708<?php 
     709        endif; 
     710    } /* FeedWordPressPostsPage::boilerplate_box() */ 
     711 
    501712    function display () { 
    502713        $this->boxes_by_methods = array( 
     
    504715        'links_box' => __('Links'), 
    505716        'formatting_box' => __('Formatting'), 
     717        'boilerplate_box' => ('Boilerplate / Credits'), 
    506718        'comments_and_pings_box' => __('Comments & Pings'), 
    507719        'custom_post_settings_box' => __('Custom Post Settings (to apply to each syndicated post)'), 
     
    511723        parent::display(); 
    512724     } /* FeedWordPressPostsPage::display () */ 
     725 
     726 
    513727} 
    514728 
  • feedwordpress/trunk/readme.txt

    r1740884 r1749912  
    11=== FeedWordPress === 
    2 Contributors: Charles Johnson 
     2Contributors: C. Johnson 
    33Donate link: http://feedwordpress.radgeek.com/ 
    44Tags: syndication, aggregation, feed, atom, rss 
    55Requires at least: 4.5 
    66Tested up to: 4.8.2 
    7 Stable tag: 2017.1004 
     7Stable tag: 2017.1020 
    88 
    99FeedWordPress syndicates content from feeds you choose into your WordPress weblog.  
     
    1111== Description == 
    1212 
    13 * Author: [Charles Johnson](http://radgeek.com/contact) 
     13* Author: [C. Johnson](http://feedback.radgeek.com/contact) 
    1414* Project URI: <http://feedwordpress.radgeek.com/> 
    1515* License: GPL 2. See License below for copyright jots and tittles. 
    1616 
    17 FeedWordPress is an Atom/RSS aggregator for WordPress. It syndicates content 
    18 from feeds that you choose into your WordPress weblog; the content it syndicates 
    19 appears as a series of special posts in your WordPress posts database. If you 
    20 syndicate several feeds then you can use WordPress's posts database and 
    21 templating engine as the back-end of an aggregation ("planet") website. It was 
    22 developed, originally, because I needed a more flexible replacement for 
    23 [Planet][] to use at Feminist Blogs, an aggregator site that I used to administer. 
     17FeedWordPress is an Atom/RSS aggregator for WordPress. It syndicates content from feeds that you choose into your WordPress weblog, and then the content it syndicates appears as a series of special posts in your WordPress posts database. If you syndicate several feeds then you can use WordPress's posts database and templating engine as the back-end of an aggregation ("planet") website. It was developed, originally, as a utility/hobby project, because I needed a more flexible replacement for [Planet][] for aggregator sites that I administered. 
    2418 
    2519[Planet]: http://www.planetplanet.org/ 
    2620 
    27 FeedWordPress is designed with flexibility, ease of use, and ease of 
    28 configuration in mind. You'll need a working installation of WordPress (version 
    29 [3.0] or later), and also FTP or SFTP access to your web host. The ability to 
    30 create cron jobs on your web host is helpful but not required. You *don't* need 
    31 to tweak any plain-text configuration files and you *don't* need shell access 
    32 to your web host to make it work. (Although, I should point out, web hosts that 
    33 *don't* offer shell access are *bad web hosts*.) 
     21FeedWordPress is designed with flexibility, ease of use, and ease of configuration in mind. You'll need a working installation of WordPress (version [4.5][] or later), and it helps to have SFTP or FTP access to your web host. The ability to create cron jobs on your web host is helpful but not required. 
    3422 
    3523  [WordPress]: http://wordpress.org/ 
    3624  [WordPress MU]: http://mu.wordpress.org/ 
    37   [3.0]: http://codex.wordpress.org/Version_3.0 
     25  [4.5]: http://codex.wordpress.org/Version_4.5 
    3826 
    3927== Installation == 
     
    4129To use FeedWordPress, you will need: 
    4230 
    43 *   an installed and configured copy of [WordPress][] or [WordPress MU][] 
    44     (version 3.0 or later). 
    45  
    46 *   FTP, SFTP or shell access to your web host 
     31*   an installed and configured copy of [WordPress][] (version 4.5 or later). 
     32 
     33*   the ability to install new plugins on your site using either WordPress's Plugins Repository, SFTP, FTP or shell access to your web host 
    4734 
    4835= New Installations = 
    4936 
    50 1.  Download the FeedWordPress installation package and extract the files on 
    51     your computer.  
    52  
    53 2.  Create a new directory named `feedwordpress` in the `wp-content/plugins` 
    54     directory of your WordPress installation. Use an FTP or SFTP client to 
    55     upload the contents of your FeedWordPress archive to the new directory 
    56     that you just created on your web host. 
     371.  Download the FeedWordPress installation package and extract the files on your computer.  
     38 
     392.  Create a new directory named `feedwordpress` in the `wp-content/plugins` directory of your WordPress installation. Use an FTP or SFTP client to upload the contents of your FeedWordPress archive to the new directory that you just created on your web host. 
    5740 
    58413.  Log in to the WordPress Dashboard and activate the FeedWordPress plugin. 
    5942 
    60 4.  Once the plugin is activated, a new **Syndication** section should 
    61     appear in your WordPress admin menu. Click here to add new syndicated 
    62     feeds, set up configuration options, and determine how FeedWordPress 
    63     will check for updates. For help, see the [FeedWordPress Quick Start][] 
    64     page. 
     434.  Once the plugin is activated, a new **Syndication** section should appear in your WordPress admin menu. Click here to add new syndicated feeds, set up configuration options, and determine how FeedWordPress will check for updates. For help, see the [FeedWordPress Quick Start][] page. 
    6544     
    6645[FeedWordPress Quick Start]: http://feedwordpress.radgeek.com/wiki/quick-start 
     
    6847= Upgrades = 
    6948 
    70 To *upgrade* an existing installation of FeedWordPress to the most recent 
    71 release: 
    72  
    73 1.  Download the FeedWordPress installation package and extract the files on 
    74     your computer.  
    75  
    76 2.  Upload the new PHP files to `wp-content/plugins/feedwordpress`, 
    77     overwriting any existing FeedWordPress files that are there. 
    78      
    79 3.  Log in to your WordPress administrative interface immediately in order 
    80     to see whether there are any further tasks that you need to perform 
    81     to complete the upgrade. 
     49To *upgrade* an existing installation of FeedWordPress to the most recent release: 
     50 
     511.  Download the FeedWordPress installation package and extract the files on your computer.  
     52 
     532.  Upload the new PHP files to `wp-content/plugins/feedwordpress`, overwriting any existing FeedWordPress files that are there. 
     54     
     553.  Log in to your WordPress administrative interface immediately in order to see whether there are any further tasks that you need to perform to complete the upgrade. 
    8256 
    83574.  Enjoy your newer and hotter installation of FeedWordPress 
     
    8559== Using and Customizing FeedWordPress == 
    8660 
    87 FeedWordPress has many options which can be accessed through the WordPress 
    88 Dashboard, and a lot of functionality accessible programmatically through 
    89 WordPress templates or plugins. For further documentation of the ins and 
    90 outs, see the documentation at the [FeedWordPress project homepage][]. 
     61FeedWordPress has many options which can be accessed through the WordPress Dashboard, and a lot of functionality accessible programmatically through WordPress templates or plugins. For further documentation of the ins and outs, see the documentation at the [FeedWordPress project homepage][]. 
    9162 
    9263  [FeedWordPress project homepage]: http://feedwordpress.radgeek.com/ 
     
    9465== Changelog == 
    9566 
     67= 2017.1020 = 
     68 
     69*   ADD BOILERPLATE / CREDITS FEATURE AVAILABLE IN POSTS & LINKS SETTINGS PANEL. I have added a new settings panel to the off-the-shelf features of FeedWordPress, under Syndication > Posts & Links (or under the Posts settings page for any individual feed), which allows you to define boilerplate text that should appear in connection with every syndicated post, or with every post syndicated from a particular feed. So, for example, if you want each syndicated post to include a byline reading "This is a syndicated post, reprinted from (LINK TO ORIGINAL SOURCE WEBSITE).", you could set up this byline from within the FeedWordPress settings interface, by going to the Boilerplate / Credits panel, and adding a line to appear BEFORE the CONTENT of each syndicated post, using the text and shortcode "This is a syndicated post, reprinted from [source]." For those of you who have corresponded with me about this feature before, you may be familiar with it from the long-standing "experimental" add-on, FWP+: Add Attribution; I've decided that it's been enough years, and I've had enough requests, that the Add Attribution feature may as well be included in the main FeedWordPress code. 
     70 
     71    Back when FeedWordPress was first created, the assumption was that a well-behaved aggregator would include boilerplate text to indicate the source of syndicated posts, but that the best way to do this was to provide a set of syndication-specific template tags so that the administrator setting up the site could edit their Theme template files with constructs like: 
     72 
     73        <?php if (is_syndicated()) : ?> 
     74        <p class="byline">This post by <?php the_author(); ?> originally 
     75        appeared at <a href="<?php the_syndication_source_link(); ?>"><?php 
     76        the_syndication_source(); ?></a>.</p> 
     77        <?php else : ?> 
     78        <p class="byline">By <?php the_author(); ?>.</p> 
     79        <?php endif; ?> 
     80 
     81    You can still do this, of course, and for maximum expressive power and flexibility, it is certainly the best way to do it. Template Tags are documented here: <http://feedwordpress.radgeek.com/wiki/templates/> However, (1) it requires writing PHP code, which not everyone is comfortable doing; and (2) it requires altering template files within your Theme, which is not always possible, especially given the increasing role that prepackaged commercial themes have come to play in the WordPress ecosystem. So, now, you can get some basic features for adding boilerplate text and attribution credits even without touching your template files, and without having to add custom add-ons for FeedWordPress. Enjoy! 
     82 
     83*   MINOR CODE MODERNIZATION, PHP 7.1 COMPATIBILITY AND BUG FIXES. This project is now 12+ years old (good lord), and there are still some places where code was written at a time when PHP was a very different language from what it is now. Props to @david-robinson-practiceweb for pointing out and sending a pull request to fix some instances where obsolete PHP reference notation (`&$q` on parameters and so on) created a compatibility problem for PHP 7.1. Props to an email correspondent for pointing out a place in SyndicatedPost where excerpts should be generated from post content using encoding-aware mb_substr(), instead of naively running them through substr(). I've begun making some efforts throughout to begin auditing some of the creakiest old code in the project, to update what needs updating and improve documentation throughout. 
     84 
    9685= 2017.0913 = 
    9786 
    98 *   PARTIAL FIX FOR 2X DUPLICATE POSTS APPEARING ON DUAL HTTP/HTTPS SITES: Some 
    99     users reported an issue in which their FeedWordPress sites, which are over 
    100     both insecure HTTP and over HTTPS, would pick up exactly 2 copies of every 
    101     post or almost every post from certain feeds, and where the guids for each 
    102     of the pair of duplicate posts would look exactly alike, except for a 
    103     difference in the protocol, for example: 
     87*   PARTIAL FIX FOR 2X DUPLICATE POSTS APPEARING ON DUAL HTTP/HTTPS SITES: Some users reported an issue in which their FeedWordPress sites, which are over both insecure HTTP and over HTTPS, would pick up exactly 2 copies of every post or almost every post from certain feeds, and where the guids for each of the pair of duplicate posts would look exactly alike, except for a difference in the protocol, for example: 
    10488 
    10589        http://www.example.com/?guid=c1cd28da39e8d7babcf6499983aca545  
    10690        https://www.example.com/?guid=c1cd28da39e8d7babcf6499983aca545 
    10791 
    108     ... where www.example.com is the server that your own copy of FeedWordPress 
    109     is installed. This release of FeedWordPress normalizes post guid prefixes 
    110     so as to avoid or limit the scope of this problem. 
    111  
    112 *   PHP 7 Compatibility: eliminate remaining sources of PHP 7 compatibility-check 
    113     failures -- remove the use of depreciated mysql_error() function, and make 
    114     sure all classes make use of __construct() convention for constructors. 
    115  
    116 *   AVOID "PHP Warning: shell_exec() has been disabled for security reasons in 
    117     [...]/feedwordpress/feeds-page.php on line 197": FeedWordPress uses the PHP 
    118     shell_exec() function in a very narrowly limited way for information gathering, 
    119     trying to find the real path to curl or wget on your system, so that it can 
    120     give as realistic as possible a recommendation for the sample crontab line 
    121     displayed in Syndication > Feeds & Updates. Some web hosting environments 
    122     disable shell_exec for security reasons (since it could in theory be used to 
    123     do a lot more stuff than the very limited information gathering FWP uses it 
    124     for); in which case, this part of the code in FeedWordPress could spit out 
    125     a nasty-looking and potentially worrisome-looking error message. So, now this 
    126     code is fenced with checks to make sure that shell_exec is available, before 
    127     FWP attempts to make use of it. 
     92    ... where www.example.com is the server that your own copy of FeedWordPress is installed. This release of FeedWordPress normalizes post guid prefixes so as to avoid or limit the scope of this problem. 
     93 
     94*   PHP 7 Compatibility: eliminate remaining sources of PHP 7 compatibility-check failures -- remove the use of depreciated mysql_error() function, and make sure all classes make use of __construct() convention for constructors. 
     95 
     96*   AVOID "PHP Warning: shell_exec() has been disabled for security reasons in [...]/feedwordpress/feeds-page.php on line 197": FeedWordPress uses the PHP shell_exec() function in a very narrowly limited way for information gathering, trying to find the real path to curl or wget on your system, so that it can give as realistic as possible a recommendation for the sample crontab line displayed in Syndication > Feeds & Updates. Some web hosting environments disable shell_exec for security reasons (since it could in theory be used to do a lot more stuff than the very limited information gathering FWP uses it for); in which case, this part of the code in FeedWordPress could spit out a nasty-looking and potentially worrisome-looking error message. So, now this code is fenced with checks to make sure that shell_exec is available, before FWP attempts to make use of it. 
    12897 
    12998= 2016.1213 = 
    13099 
    131 *   WORDPRESS BACKWARD COMPATIBILITY FOR VERSIONS [4.5, 4.7]: This change fixes 
    132     a fatal PHP error (on some web server configurations you'd see the message 
    133     "Fatal error: require_once(): Failed opening required '[...]/wp-includes/class-wp-feed-cache.php'" 
    134     on others, you might just see an HTTP 500 Internal Server Error or a blank 
    135     page) when using FeedWordPress with versions of WordPress before 4.7. A 
    136     change that I introduced to avoid a code module that had been deprecated in 
    137     version 4.7 ended up relying on code modules that were only introduced as 
    138     of version 4.7; so now, instead, FeedWordPress attempts to detect which 
    139     modules the current version of the WordPress core makes available, and load 
    140     the right modules depending on your WordPress version. 
    141  
    142     In theory, up to this point, FeedWordPress supported any version of 
    143     WordPress from version 3.0 onward. In practice, version 3.0 was released 
    144     over 6 years ago, and I can realistically commit only to testing out new 
    145     releases of FeedWordPress with a few prior versions of WordPress; so I've 
    146     updated the "Requires at least" field to version 4.5, the first major 
    147     release issued in 2016. If you've really got to use FeedWordPress with 
    148     older versions of WordPress, it will probably still work with any moderately 
    149     modern release of WordPress, but I won't promise to keep it working with 
    150     releases of WordPress that are more than about a year old. 
     100*   WORDPRESS BACKWARD COMPATIBILITY FOR VERSIONS [4.5, 4.7]: This change fixes a fatal PHP error (on some web server configurations you'd see the message "Fatal error: require_once(): Failed opening required '[...]/wp-includes/class-wp-feed-cache.php'" on others, you might just see an HTTP 500 Internal Server Error or a blank page) when using FeedWordPress with versions of WordPress before 4.7. A    change that I introduced to avoid a code module that had been deprecated in version 4.7 ended up relying on code modules that were only introduced as of version 4.7; so now, instead, FeedWordPress attempts to detect which modules the current version of the WordPress core makes available, and load the right modules depending on your WordPress version. 
     101 
     102    In theory, up to this point, FeedWordPress supported any version of WordPress from version 3.0 onward. In practice, version 3.0 was released over 6 years ago, and I can realistically commit only to testing out new   releases of FeedWordPress with a few prior versions of WordPress; so I've updated the "Requires at least" field to version 4.5, the first major release issued in 2016. If you've really got to use FeedWordPress with older versions of WordPress, it will probably still work with any moderately modern release of WordPress, but I won't promise to keep it working with releases of WordPress that are more than about a year old. 
    151103     
    152104= 2016.1211 = 
     
    154106*   WORDPRESS COMPATIBILITY: Tested with new versions of WordPress up to 4.7. 
    155107 
    156 *   PHP WARNINGS UNDER WP 4.7: Eliminated cause of a PHP warning under WP 4.7 
    157     "Parameter 1 to FeedWordPressHTTPAuthenticator::set_auth_options expected to be reference" 
    158     Warnings were due to a change in how http_api_curl hook is sometimes called 
    159     in WP 4.7; so I changed the signature of the event handling method to avoid 
    160     the notice. Props to @cogdog, @froomkin, @gwynethllewelyn et al. for flagging 
    161     the issue and @garymarkfuller for suggesting a preliminary fix to the issue 
    162     that was fairly similar to the solution I ended up adopting. 
    163  
    164 *   PHP 7 and PHP Strict Standards compatibility changes: @alexiskulash @daidais 
    165     and @zoul0813 all sent pull requests through Github to fix some issues from 
    166     a very old code base that has made its way from PHP 3.x through 5.x to the 
    167     roll-out of PHP 7. Class methods should now fare better under modern versions 
    168     of PHP and generate fewer "Deprecated" notices. 
    169  
    170 *   IMPROVEMENTS TO SCHEDULED AND AUTOMATIC UPDATES:  use wp_loaded hook to check 
    171     for magic URL parameters and to execute updates, to do pageload-based automatic 
    172     updates, etc. Ensures that anything plugins or themes need to do in init to set 
    173     up custom post types, taxonomies, etc. will be done before the update_feedwordpress 
    174     updates are attempted. If you saw posts not getting put into the correct custom 
    175     post type or custom taxonomies or similar problems when performing scheduled updates, 
    176     but the problem seemed to go away when you manually performed updates through the 
    177     wp-admin interface, then you might be able to solve those problems with this update. 
     108*   PHP WARNINGS UNDER WP 4.7: Eliminated cause of a PHP warning under WP 4.7 "Parameter 1 to FeedWordPressHTTPAuthenticator::set_auth_options expected to be reference" Warnings were due to a change in how http_api_curl hook is sometimes called in WP 4.7; so I changed the signature of the event handling method to avoid the notice. Props to @cogdog, @froomkin, @gwynethllewelyn et al. for flagging the issue and @garymarkfuller for suggesting a preliminary fix to the issue that was fairly similar to the solution I ended up adopting. 
     109 
     110*   PHP 7 and PHP Strict Standards compatibility changes: @alexiskulash @daidais and @zoul0813 all sent pull requests through Github to fix some issues from a very old code base that has made its way from PHP 3.x through 5.x to the roll-out of PHP 7. Class methods should now fare better under modern versions of PHP and generate fewer "Deprecated" notices. 
     111 
     112*   IMPROVEMENTS TO SCHEDULED AND AUTOMATIC UPDATES:  use wp_loaded hook to check for magic URL parameters and to execute updates, to do pageload-based automatic updates, etc. Ensures that anything plugins or themes need to do in init to set up custom post types, taxonomies, etc. will be done before the update_feedwordpress updates are attempted. If you saw posts not getting put into the correct custom post type or custom taxonomies or similar problems when performing scheduled updates, but the problem seemed to go away when you manually performed updates through the wp-admin interface, then you might be able to solve those problems with this update. 
    178113 
    179114= 2016.0420 = 
     
    181116*   WORDPRESS COMPATIBILITY: Tested with new versions of WordPress up to 4.5. 
    182117 
    183 *   FILTERS AND ADD-ONS: Allow filters and add-ons to filter terms and taxonomy 
    184     (categories, tags, custom taxonomies, etc.) more thoroughly and more 
    185     fine-grainedly using syndicated_post_terms_match, syndicated_post_terms_match_{taxonomy}, 
    186     syndicated_post_terms_unfamiliar, syndicated_post_terms_mapping, 
    187     syndicated_item_feed_terms, and syndicated_item_preset_terms filters. 
    188  
    189 *   FILTERS AND ADD-ONS: Globals $fwp_channel and $fwp_feedmeta REMOVED. 
    190     These global variables, originally introduced to allow filters access to 
    191     information about the source feed in `syndicated_item` filters were 
    192     deprecated 6+ years ago. If you have any filters or add-ons which still 
    193     depend on these global variables, you've been using obsolete techniques 
    194     and you should see about fixing them to access data about the source feed 
    195     using the SyndicatedPost::link element instead. For documentation, see 
    196     the FeedWordPress documentation wiki at 
    197     <http://feedwordpress.radgeek.com/wiki/syndicatedpost> and 
    198     <http://feedwordpress.radgeek.com/wiki/syndicatedlink>. 
    199  
    200 *   BUGFIX: Syndication > Diagnostics HTTP diagnostic test widget was broken due to 
    201     a dumb error on my part. Now fixed. 
    202      
    203 *   SMALL CODING CHANGES: Lots of small changes to code organization, incorporation 
    204     of some PHP 5.x coding conventions, etc. 
     118*   FILTERS AND ADD-ONS: Allow filters and add-ons to filter terms and taxonomy (categories, tags, custom taxonomies, etc.) more thoroughly and more fine-grainedly using syndicated_post_terms_match, syndicated_post_terms_match_{taxonomy},  syndicated_post_terms_unfamiliar, syndicated_post_terms_mapping, syndicated_item_feed_terms, and syndicated_item_preset_terms filters. 
     119 
     120*   FILTERS AND ADD-ONS: Globals $fwp_channel and $fwp_feedmeta REMOVED. These global variables, originally introduced to allow filters access to information about the source feed in `syndicated_item` filters were deprecated 6+ years ago. If you have any filters or add-ons which still depend on these global variables, you've been using obsolete techniques and you should see about fixing them to access data about the source feed using the SyndicatedPost::link element instead. For documentation, see  the FeedWordPress documentation wiki at <http://feedwordpress.radgeek.com/wiki/syndicatedpost> and <http://feedwordpress.radgeek.com/wiki/syndicatedlink>. 
     121 
     122*   BUGFIX: Syndication > Diagnostics HTTP diagnostic test widget was broken due to a dumb error on my part. Now fixed. 
     123     
     124*   SMALL CODING CHANGES: Lots of small changes to code organization, incorporation of some PHP 5.x coding conventions, etc. 
    205125 
    206126= 2015.0514 = 
    207127 
    208 *   IMPORTANT SECURITY UPDATE: This version includes two important fixes for 
    209     potential security vulnerabilities reported to me through support channels. 
    210      
    211     The first is a common problem across several plugins due to an ambiguity in 
    212     the WordPress documentation and a change in the behavior of WordPress's 
    213     built-in add_query_arg() and remove_query_arg() functions 
    214     which could, under certain low-probability conditions, allow for potential 
    215     XSS attack vectors. This fixes issue # 39 
    216     reported at <https://github.com/radgeek/feedwordpress/issues/39> 
    217     Thanks to github.com/quassy 
    218      
    219     The second is a security vulnerability fixes a security vulnerability that 
    220     was reported to me privately (thanks to Adrián M. F.) which, under other 
    221     low-probability conditions, could allow for SQL insertion attacks by 
    222     a malicious user with access to login credentials, which would compromise 
    223     data security. 
    224  
    225     It is *IMPORTANT* and worth your while to upgrade FeedWordPress as soon as 
    226     possible in order to eliminate these vulnerabilities. If you have any 
    227     questions or if there is something blocking you from making the upgrade 
    228     which you need my help with, don't hesitate to get in touch. 
    229  
    230 *   ADMIN UI BUGFIX: "Update Now" button in feeds setting pages should now work 
    231     once again instead of causing a PHP fatal error. See 
    232     <https://github.com/radgeek/feedwordpress/issues/46> 
    233      
    234 *   SEVERAL OTHER SMALL BUG FIXES. See <https://github.com/radgeek/feedwordpress/issues/32> 
    235     <https://github.com/radgeek/feedwordpress/issues/30> 
    236     <https://github.com/radgeek/feedwordpress/issues/29> 
    237     etc. 
     128*   IMPORTANT SECURITY UPDATE: This version includes two important fixes for potential security vulnerabilities reported to me through support channels. 
     129     
     130    The first is a common problem across several plugins due to an ambiguity in the WordPress documentation and a change in the behavior of WordPress's built-in add_query_arg() and remove_query_arg() functions which could, under certain low-probability conditions, allow for potential XSS attack vectors. This fixes issue # 39 reported at <https://github.com/radgeek/feedwordpress/issues/39> Thanks to github.com/quassy 
     131     
     132    The second is a security vulnerability fixes a security vulnerability that was reported to me privately (thanks to Adrián M. F.) which, under other low-probability conditions, could allow for SQL insertion attacks by a malicious user with access to login credentials, which would compromise data security. 
     133 
     134    It is *IMPORTANT* and worth your while to upgrade FeedWordPress as soon as possible in order to eliminate these vulnerabilities. If you have any questions or if there is something blocking you from making the upgrade which you need my help with, don't hesitate to get in touch. 
     135 
     136*   ADMIN UI BUGFIX: "Update Now" button in feeds setting pages should now work once again instead of causing a PHP fatal error. See <https://github.com/radgeek/feedwordpress/issues/46> 
     137     
     138*   SEVERAL OTHER SMALL BUG FIXES. See <https://github.com/radgeek/feedwordpress/issues/32> <https://github.com/radgeek/feedwordpress/issues/30> <https://github.com/radgeek/feedwordpress/issues/29> etc. 
    238139 
    239140= 2014.0805 = 
    240141 
    241 *   FILTERS AND ADD-ONS: A number of new hooks for filters and add-ons to 
    242     further customize the behavior of FWP have been added. 
    243  
    244 *   COMPATIBILITY/BUGFIX: Many users saw odd characters, especially "n," 
    245     appearing in posts in versions of WordPress from 3.6 on, due to a change 
    246     in when the API expects HTML data for posts to be slashed and when it 
    247     does not. This has been fixed, so that the junk characters should no 
    248     longer appear, regardless of your version of WordPress. 
    249  
    250 *   BUGFIX: A bug preventing FWP from saving categories assigned under 
    251     Syndication > Categories & Tags has been fixed. 
    252      
    253 *   BUGFIX: Post-editing related metaboxes should now show up when you edit 
    254     items of any post type, including custom types, not only normal WordPress 
    255     posts. 
    256      
    257 *   BUGFIX: A bug in the admin UI that caused the "Alternative Feeds" / 
    258     "Find Feeds" box to throw a permissions error has been fixed. 
    259      
    260 *   BUGFIX: A bug preventing proper mapping of categories and other terms in 
    261     2013.0504 has been fixed. 
    262      
    263 *   BUGFIX: A number of small fixes contributed through Github by Flynsarmy 
    264     should eliminate PHP warnings for many users on several methods that are 
    265     called as static methods within FeedWordPress. 
     142*   FILTERS AND ADD-ONS: A number of new hooks for filters and add-ons to further customize the behavior of FWP have been added. 
     143 
     144*   COMPATIBILITY/BUGFIX: Many users saw odd characters, especially "n," appearing in posts in versions of WordPress from 3.6 on, due to a change in when the API expects HTML data for posts to be slashed and when it does not. This has been fixed, so that the junk characters should no longer appear, regardless of your version of WordPress. 
     145 
     146*   BUGFIX: A bug preventing FWP from saving categories assigned under Syndication > Categories & Tags has been fixed. 
     147     
     148*   BUGFIX: Post-editing related metaboxes should now show up when you edit items of any post type, including custom types, not only normal WordPress   posts. 
     149     
     150*   BUGFIX: A bug in the admin UI that caused the "Alternative Feeds" / "Find Feeds" box to throw a permissions error has been fixed. 
     151     
     152*   BUGFIX: A bug preventing proper mapping of categories and other terms in 2013.0504 has been fixed. 
     153     
     154*   BUGFIX: A number of small fixes contributed through Github by Flynsarmy should eliminate PHP warnings for many users on several methods that are    called as static methods within FeedWordPress. 
    266155 
    267156= 2013.0504 = 
    268157     
    269 *   BUGFIX: PHP 5.4 compatibility -- includes some more extensive fixes to 
    270     compatibility issues with PHP 5.4's handling of global variables 
    271  
    272 *   DIAGNOSTICS: New diagnostics settings added to help track behavior of 
    273     terms (categories, post tags, etc.) for syndicated posts. 
     158*   BUGFIX: PHP 5.4 compatibility -- includes some more extensive fixes to compatibility issues with PHP 5.4's handling of global variables 
     159 
     160*   DIAGNOSTICS: New diagnostics settings added to help track behavior of terms (categories, post tags, etc.) for syndicated posts. 
    274161 
    275162= 2012.0504 = 
    276163 
    277 *   MODULE REORGANIZATION: Should ensure that all needed submodules will be 
    278     properly included regardless of whether you are installing from github, 
    279     from SVN, or from the WordPress plugins page. If you've been getting 
    280     fatal errors about required modules not being found, this release should 
    281     hopefully resolve the issue. 
     164*   MODULE REORGANIZATION: Should ensure that all needed submodules will be properly included regardless of whether you are installing from github, from SVN, or from the WordPress plugins page. If you've been getting fatal errors about required modules not being found, this release should hopefully resolve the issue. 
    282165 
    283166= 2012.0503 = 
    284167 
    285 *   BUGFIX: Works properly again with WordPress installations that use a 
    286     MySQL table name prefix other than the default `wp_` prefix. 
    287      
    288 *   BUGFIX: Includes a couple of significant PHP 5.4 compatibility fixes. 
    289     Now that PHP 5.4 is more widely deployed, Diagnostics will now also 
    290     show PHP version and some other potentially useful troubleshooting 
    291     information. 
    292  
    293 *   ADMIN UI: Better indicates your options when deleting a syndicated post 
    294     so as to let you know whether it will be Trashed (and thus not 
    295     resyndicated) or Erased (and thus potentially resyndicated) 
    296      
    297 *   ADMIN UI: Adds an AJAXy Test Expression button to allow live testing of 
    298     sample results from expressions in Custom Post Settings. 
     168*   BUGFIX: Works properly again with WordPress installations that use a MySQL table name prefix other than the default `wp_` prefix. 
     169     
     170*   BUGFIX: Includes a couple of significant PHP 5.4 compatibility fixes. Now that PHP 5.4 is more widely deployed, Diagnostics will now also show PHP version and some other potentially useful troubleshooting    information. 
     171 
     172*   ADMIN UI: Better indicates your options when deleting a syndicated post so as to let you know whether it will be Trashed (and thus not resyndicated) or Erased (and thus potentially resyndicated) 
     173     
     174*   ADMIN UI: Adds an AJAXy Test Expression button to allow live testing of sample results from expressions in Custom Post Settings. 
    299175 
    300176= 2012.1218 = 
    301177 
    302 *   WORDPRESS VISUAL EDITOR FIXED. There was an unlisted change in the 
    303     2012.1212 release which had the effect of disabling the WordPress Visual 
    304     Editor for all posts syndicated by FeedWordPress. Many users reported 
    305     this as a bug. It was actually a deliberate decision -- a crappy way to 
    306     try to deal with a crappy situation. (Many users had previously reported 
    307     a "bug" in which all the paragraph or line breaks seemed to be stripped 
    308     out of their syndicated posts; the issue turned out to be that the 
    309     Visual Editor was stripping out `<p>` and `<br/>` tags on the assumption 
    310     that the resulting post would be sent through standard WordPress 
    311     formatting filters. But under default settings, posts syndicated by FWP 
    312     deliberately bypass WordPress formatting filters.) In any case, this 
    313     version adopts a more flexible compromise. *If* FeedWordPress is set up 
    314     to bypass WordPress formatting filters (as it is by default), *then* 
    315     the Visual Editor will be disabled for syndicated posts (since using it 
    316     would produce incorrect results). If on the other hand FeedWordPress is 
    317     set up to expose syndicated posts to WordPress formatting filters (as it 
    318     usually is for those using the Visual Editor to manually edit posts), 
    319     then the Visual Editor tab will be re-enabled for syndicated posts. 
     178*   WORDPRESS VISUAL EDITOR FIXED. There was an unlisted change in the 2012.1212 release which had the effect of disabling the WordPress Visual Editor for all posts syndicated by FeedWordPress. Many users reported this as a bug. It was actually a deliberate decision -- a crappy way to try to deal with a crappy situation. (Many users had previously reported a "bug" in which all the paragraph or line breaks seemed to be stripped out of their syndicated posts; the issue turned out to be that the Visual Editor was stripping out `<p>` and `<br/>` tags on the assumption that the resulting post would be sent through standard WordPress formatting filters. But under default settings, posts syndicated by FWP deliberately bypass WordPress formatting filters.) In any case, this version adopts a more flexible compromise. *If* FeedWordPress is set up to bypass WordPress formatting filters (as it is by default), *then* the Visual Editor will be disabled for syndicated posts (since using it would produce incorrect results). If on the other hand FeedWordPress is set up to expose syndicated posts to WordPress formatting filters (as it usually is for those using the Visual Editor to manually edit posts), then the Visual Editor tab will be re-enabled for syndicated posts. 
    320179     
    321180*   BUG FIX: PERMALINKS REWRITTEN FOR CUSTOM POST TYPES AS WELL AS NORMAL 
     
    20261885= From 0.91 to 0.95 = 
    20271886 
    2028 *   BUG FIX: Fixed an obscure bug in the handling of categories: 
    2029     categories with trailing whitespace could cause categories with 
    2030     duplicate names to be created. This no longer happens. While I was 
    2031     at it I tightened up the operation of 
    2032     FeedWordPress::lookup_categories() a bit in general. 
    2033  
    2034 *   FEATURE DEPRECATED: the feed setting `hardcode categories` is now 
    2035     deprecated in favor of `unknown categories` (see below), which 
    2036     allows you to strip off any syndication categories not already in 
    2037     your database using `unknown categories: default` or `unknown 
    2038     categories: filter`. If you have `hardcode categories: yes` set on a 
    2039     feed, this will be treated as `unknown categories: default` (i.e., 
    2040     no new categories will be added, but if a post doesn't match any of 
    2041     the categories it will be added in the default category--usually 
    2042     "Uncategorized" or "General"). 
    2043  
    2044 *   FEATURE: You can now set global defaults as to whether or not 
    2045     FeedWordPress will update the Link Name and Link Description 
    2046     settings for feeds automatically from the feed title and feed 
    2047     tagline. (By default, it does, as it has in past versions.) Whether 
    2048     this behavior is turned on or off, you can still override the 
    2049     default behavior using feed settings of `hardcode name: yes`, 
    2050     `hardcode name: no`, `hardcode description: yes`, or `hardcode 
    2051     description: no`. 
    2052  
    2053 *   FEATURE: Users can now provide one or several "aliases" for an 
    2054     author, just as they can for a category. For example, to make 
    2055     FeedWordPress treat posts by "Joseph Cardinal Ratzinger" and "Pope 
    2056     Benedict XVI" as by the same author, edit the user profile for Pope 
    2057     Benedict XVI and add a line like this to the "User profile" field: 
     1887*   BUG FIX: Fixed an obscure bug in the handling of categories: categories with trailing whitespace could cause categories with duplicate names to be created. This no longer happens. While I was at it I tightened up the operation of FeedWordPress::lookup_categories() a bit in general. 
     1888 
     1889*   FEATURE DEPRECATED: the feed setting `hardcode categories` is now deprecated in favor of `unknown categories` (see below), which allows you to strip off any syndication categories not already in your database using `unknown categories: default` or `unknown categories: filter`. If you have `hardcode categories: yes` set on a feed, this will be treated as `unknown categories: default` (i.e., no new categories will be added, but if a post doesn't match any of the categories it will be added in the default category--usually "Uncategorized" or "General"). 
     1890 
     1891*   FEATURE: You can now set global defaults as to whether or not FeedWordPress will update the Link Name and Link Description settings for feeds automatically from the feed title and feed tagline. (By default, it does, as it has in past versions.) Whether this behavior is turned on or off, you can still override the default behavior using feed settings of `hardcode name: yes`, `hardcode name: no`, `hardcode description: yes`, or `hardcode description: no`. 
     1892 
     1893*   FEATURE: Users can now provide one or several "aliases" for an author, just as they can for a category. For example, to make FeedWordPress treat posts by "Joseph Cardinal Ratzinger" and "Pope Benedict XVI" as by the same author, edit the user profile for Pope Benedict XVI and add a line like this to the "User profile" field: 
    20581894     
    20591895        a.k.a.: Joseph Cardinal Ratzinger 
    20601896     
    2061     You can add several aliases, each on a line by itself. You can also 
    2062     add any other text you like to the Profile without interfering with 
    2063     the aliases. 
    2064      
    2065 *   FEATURE: Users can now choose how to handle syndicated posts that 
    2066     are in unfamiliar categories or by unfamiliar authors (i.e., 
    2067     categories or authors whose names are not yet in the WordPress 
    2068     database). By default, FeedWordPress will (as before) create a new 
    2069     category (or new author) and use it for the current post and any 
    2070     future posts. This behavior can be changed, either for all feeds or 
    2071     for one or another particular feed. 
    2072      
    2073     There are now three different options for an unfamiliar author: (1) 
    2074     FeedWordPress can create a new author account and attribute the 
    2075     syndicated post to the new account; (2) FeedWordPress can attribute 
    2076     the post to an author if the author's name is familiar, and to a 
    2077     default author (currently, this means the Site Administrator 
    2078     account) if it is not; (3) FeedWordPress can drop posts by 
    2079     unfamiliar authors and syndicate only posts by authors who are 
    2080     already in the database. 
    2081      
    2082     There are, similarly, two different options for an unfamiliar 
    2083     category: (1) FeedWordPress can create new categories and place the 
    2084     syndicated post in them; (2) FeedWordPress can drop the unfamiliar 
    2085     categories and place syndicated posts only in categories that it is 
    2086     already familiar with. In addition, FeedWordPress 0.95 lets you 
    2087     choose whether posts that are in *no* familiar categories should be 
    2088     syndicated (and placed in the default category for the blog) or 
    2089     simply dropped. 
    2090      
    2091     You can set the default behavior for both authors and categories 
    2092     using the settings in Options --> Syndication. You can also set 
    2093     different behavior for specific feeds by adding the `unfamiliar 
    2094     author` and / or `unfamiliar categories` settings to the Link Notes 
    2095     section of a feed: 
     1897    You can add several aliases, each on a line by itself. You can also add any other text you like to the Profile without interfering with the aliases. 
     1898     
     1899*   FEATURE: Users can now choose how to handle syndicated posts that are in unfamiliar categories or by unfamiliar authors (i.e., categories or authors whose names are not yet in the WordPress database). By default, FeedWordPress will (as before) create a new category (or new author) and use it for the current post and any future posts. This behavior can be changed, either for all feeds or for one or another particular feed. 
     1900     
     1901    There are now three different options for an unfamiliar author: (1) FeedWordPress can create a new author account and attribute the syndicated post to the new account; (2) FeedWordPress can attribute the post to an author if the author's name is familiar, and to a    default author (currently, this means the Site Administrator account) if it is not; (3) FeedWordPress can drop posts by unfamiliar authors and syndicate only posts by authors who are already in the database. 
     1902     
     1903    There are, similarly, two different options for an unfamiliar category: (1) FeedWordPress can create new categories and place the syndicated post in them; (2) FeedWordPress can drop the unfamiliar categories and place syndicated posts only in categories that it is already familiar with. In addition, FeedWordPress 0.95 lets you choose whether posts that are in *no* familiar categories should be syndicated (and placed in the default category for the blog) or simply dropped. 
     1904     
     1905    You can set the default behavior for both authors and categories using the settings in Options --> Syndication. You can also set different behavior for specific feeds by adding the `unfamiliar author` and / or `unfamiliar categories` settings to the Link Notes section of a feed: 
    20961906     
    20971907        unfamiliar author: (create|default|filter) 
    20981908        unfamiliar categories: (create|default|filter) 
    20991909     
    2100     A setting of `unfamiliar author: create` will make FeedWordPress 
    2101     create new authors to match unfamiliar author names *for this feed 
    2102     alone*. A setting of `unfamiliar author: default` will make it 
    2103     assign posts from unfamiliar authors to the default user account. A 
    2104     setting of `unfamiliar author: filter` will cause all posts (from 
    2105     this feed alone) to be dropped unless they are by an author already 
    2106     listed in the database. Similiarly, `unfamiliar categories: create` 
    2107     will make FeedWordPress create new categories to match unfamiliar 
    2108     category names *for this feed alone*; `unfamiliar categories: 
    2109     default` will cause it to drop any unfamiliar category names; and 
    2110     `unfamiliar categories: filter` will cause it to *both* drop any 
    2111     unfamiliar category names *and* to only syndicate posts that are 
    2112     placed in one or more familiar categories. 
    2113      
    2114     These two new features allow users to do some coarse-grained 
    2115     filtering without having to write a PHP filter. Specifically, they 
    2116     offer an easy way for you to filter feeds by category or by author. 
    2117     Suppose, for example, that you only wanted to syndicate posts that 
    2118     your contributors place in the "Llamas" category. You could do so by 
    2119     setting up your installation of WordPress so that the only category 
    2120     in the database is "Llamas," and then use Options --> Syndication to 
    2121     set "Unfamiliar categories" to "don't create new categories and 
    2122     don't syndicate posts unless they match at least one familiar 
    2123     category". Now, when you update, only posts in the "Llamas" category 
    2124     will be syndicated by FeedWordPress. 
    2125      
    2126     Similarly, if you wanted to filter one particular feed so that only 
    2127     posts by (for example) the author "Earl J. Llama" were syndicated to 
    2128     your site, you could do so by creating a user account for Earl J. 
    2129     Llama, then adding the following line to the settings for the feed 
    2130     in Link Notes: 
     1910    A setting of `unfamiliar author: create` will make FeedWordPress create new authors to match unfamiliar author names *for this feed alone*. A setting of `unfamiliar author: default` will make it assign posts from unfamiliar authors to the default user account. A setting of `unfamiliar author: filter` will cause all posts (from this feed alone) to be dropped unless they are by an author already listed in the database. Similiarly, `unfamiliar categories: create` will make FeedWordPress create new categories to match unfamiliar category names *for this feed alone*; `unfamiliar categories:    default` will cause it to drop any unfamiliar category names; and `unfamiliar categories: filter` will cause it to *both* drop any unfamiliar category names *and* to only syndicate posts that are placed in one or more familiar categories. 
     1911     
     1912    These two new features allow users to do some coarse-grained filtering without having to write a PHP filter. Specifically, they offer an easy way for you to filter feeds by category or by author. Suppose, for example, that you only wanted to syndicate posts that your contributors place in the "Llamas" category. You could do so by setting up your installation of WordPress so that the only category in the database is "Llamas," and then use Options --> Syndication to set "Unfamiliar categories" to "don't create new categories and don't syndicate posts unless they match at least one familiar category". Now, when you update, only posts in the "Llamas" category will be syndicated by FeedWordPress. 
     1913     
     1914    Similarly, if you wanted to filter one particular feed so that only posts by (for example) the author "Earl J. Llama" were syndicated to your site, you could do so by creating a user account for Earl J. Llama, then adding the following line to the settings for the feed in Link Notes: 
    21311915     
    21321916        unfamiliar author: filter 
    21331917     
    2134     This will cause any posts from this feed that are not authored by 
    2135     Earl J. Llama to be discarded, and only the posts by Earl J. Llama 
    2136     will be syndicated. (If the setting is used on one specific feed, it 
    2137     will not affect how posts from other feeds are syndicated.) 
     1918    This will cause any posts from this feed that are not authored by Earl J. Llama to be discarded, and only the posts by Earl J. Llama will be syndicated. (If the setting is used on one specific feed, it will not affect how posts from other feeds are syndicated.) 
    21381919     
    21391920== License == 
    21401921 
    2141 The FeedWordPress plugin is copyright © 2005-2010 by Charles Johnson. It uses 
     1922The FeedWordPress plugin is copyright © 2005-2017 by Charles Johnson. It uses 
    21421923code derived or translated from: 
    21431924 
  • feedwordpress/trunk/syndicatedpost.class.php

    r1740884 r1749912  
    1313 * who make use of feed data in PHP add-ons and filters. 
    1414 * 
    15  * @version 2017.1004 
     15 * @version 2017.1018 
    1616 */ 
    1717class SyndicatedPost { 
     
    4444     * @param SyndicatedLink $source The feed it was syndicated from. 
    4545     */ 
    46     function __construct ($item, &$source) { 
     46    public function __construct ($item, $source) { 
    4747        global $wpdb; 
    4848 
    49         if ( empty($item) && empty($source) ) 
     49        if ( empty($item) and empty($source) ) 
    5050            return; 
    5151 
     
    6969        endif; 
    7070 
    71         $this->link =& $source; 
     71        $this->link = $source; 
    7272        $this->feed = $source->magpie; 
    7373        $this->feedmeta = $source->settings; 
     
    291291     * elements or attributes 
    292292     */ 
    293      function query ($path) { 
     293     public function query ($path) { 
    294294        $xq = new SyndicatedPostXPathQuery(array("path" => $path)); 
    295295 
     
    343343    } /* SyndicatedPost::get_feed_channel_elements() */ 
    344344 
    345     function get_categories ($params = array()) { 
     345    public function get_categories ($params = array()) { 
    346346        return $this->entry->get_categories(); 
    347347    } 
    348348     
    349     function title ($params = array()) { 
     349    public function title ($params = array()) { 
    350350        return $this->entry->get_title(); 
    351351    } /* SyndicatedPost::title () */ 
    352352     
    353     function content ($params = array()) { 
     353    public function content ($params = array()) { 
    354354 
    355355        $params = wp_parse_args($params, array( 
     
    403403    } /* SyndicatedPost::content() */ 
    404404 
    405     function excerpt () { 
     405    public function excerpt () { 
    406406        # Identify and sanitize excerpt: atom:summary, or rss:description 
    407407        $excerpt = $this->entry->get_description(); 
     
    434434    } /* SyndicatedPost::excerpt() */ 
    435435 
    436     function permalink () { 
     436    /** 
     437     * SyndicatedPost::permalink: returns the permalink for the post, as provided by the 
     438     * source feed. 
     439     * 
     440     * @return string The URL of the original permalink for this syndicated post 
     441     */ 
     442    public function permalink () { 
    437443        // Handles explicit <link> elements and also RSS 2.0 cases with 
    438444        // <guid isPermaLink="true">, etc. Hooray! 
    439445        $permalink = $this->entry->get_link(); 
    440446        return $permalink; 
    441     } 
    442  
    443     function created ($params = array()) { 
     447    } /* SyndicatedPost::permalink () */ 
     448 
     449    public function created ($params = array()) { 
    444450        $unfiltered = false; $default = NULL; 
    445451        extract($params); 
     
    462468    } /* SyndicatedPost::created() */ 
    463469 
    464     function published ($params = array(), $default = NULL) { 
     470    public function published ($params = array(), $default = NULL) { 
    465471        $fallback = true; $unfiltered = false; 
    466472        if (!is_array($params)) : // Old style 
     
    511517    } /* SyndicatedPost::published() */ 
    512518 
    513     function updated ($params = array(), $default = -1) { 
     519    public function updated ($params = array(), $default = -1) { 
    514520        $fallback = true; $unfiltered = false; 
    515521        if (!is_array($params)) : // Old style 
     
    637643    } /* SyndicatedPost::normalize_guid() */ 
    638644 
    639     function guid () { 
     645    public function guid () { 
    640646        $guid = null; 
    641647        if (isset($this->item['id'])):                      // Atom 0.3 / 1.0 
     
    696702    } /* SyndicatedPost::guid() */ 
    697703 
    698     function author () { 
     704    public function author () { 
    699705        $author = array (); 
    700706 
Note: See TracChangeset for help on using the changeset viewer.