WordPress.org

Plugin Directory

Changeset 583851 for feedwordpress


Ignore:
Timestamp:
08/10/12 10:02:07 (21 months ago)
Author:
radgeek
Message:

Framework for processing Atom tombstones and framework for post expiration. Commissioned by Ellissa Nagle.

Location:
feedwordpress/trunk
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • feedwordpress/trunk

    • Property svn:ignore set to
      .git
      .gitignore
      *(*conflicted copy*)*

  • feedwordpress/trunk/feeds-page.php

    r532256 r583851  
    112112            'updated_posts_box' => __('Updated Posts'), 
    113113            'custom_settings_box' => __('Custom Feed Settings (for use in templates)'), 
    114             'fetch_settings_box' => __('Settings for Fetching Feeds (Advanced)'), 
     114            'advanced_settings_box' => __('Advanced Settings'), 
    115115        ); 
    116116        if ($this->for_default_settings()) : 
     
    364364    } 
    365365     
    366     function fetch_settings_box ($page, $box = NULL) { 
     366    function advanced_settings_box ($page, $box = NULL) { 
     367        ?> 
     368        <table class="edit-form"> 
     369        <tr> 
     370        <th>Fetch Timeout:</th> 
     371        <td> 
     372        <?php 
    367373        $this->setting_radio_control( 
    368374            'fetch timeout', 'fetch_timeout', 
     
    375381            ) 
    376382        ); 
    377     } /* FeedWordPressFeedsPage::fetch_settings_box () */ 
     383        ?> 
     384        </td> 
     385        </tr> 
     386        <tr> 
     387        <th>Feed Update Type:</th> 
     388        <td><?php 
     389        $this->setting_radio_control('update_incremental', 'update_incremental', 
     390            /*options=*/ array( 
     391                'incremental' => '<strong>Incremental.</strong> When items no longer appear on the feed, keep them in the WordPress posts table.', 
     392                'complete' => '<strong>Complete.</strong> When items no longer appear on the feed, they are obsolete; retire them from the WordPress posts table.', 
     393            ), 
     394            /*params=*/ array( 
     395                'setting-default' => NULL, 
     396                'global-setting-default' => 'incremental', 
     397                'default-input-value' => 'default',  
     398            ) 
     399        ); ?></td> 
     400        </tr> 
     401        <tr> 
     402        <th>Allow Feeds to Delete Posts:</th> 
     403        <td><?php 
     404        $this->setting_radio_control('tombstones', 'tombstones', 
     405            /*options=*/ array( 
     406                'yes' => 'Yes. If a feed indicates that one of its posts has been deleted, delete the local copy syndicated to this website.', 
     407                'no' => 'No. Even if a feed indicates that one of its posts has been deleted, retain the local copy on this website.', 
     408            ), 
     409            /*params=*/ array( 
     410                'setting-default' => NULL, 
     411                'global-setting-default' => 'yes', 
     412                'default-input-value' => 'default', 
     413            ) 
     414        ); ?></td> 
     415        </tr> 
     416        </table> 
     417        <?php 
     418    } /* FeedWordPressFeedsPage::advanced_settings_box () */ 
    378419     
    379420    function display_authentication_credentials_box ($params = array()) { 
     
    11761217            $this->update_setting('fetch timeout', $timeout); 
    11771218        endif; 
     1219         
     1220        if (isset($post['update_incremental'])) : 
     1221            $this->update_setting('update_incremental', $post['update_incremental']); 
     1222        endif; 
     1223 
     1224        if (isset($post['tombstones'])) : 
     1225            $this->update_setting('tombstones', $post['tombstones']); 
     1226        endif; 
    11781227 
    11791228        if (isset($post['update_minimum'])) : 
  • feedwordpress/trunk/feedwordpress.php

    r549672 r583851  
    44Plugin URI: http://feedwordpress.radgeek.com/ 
    55Description: simple and flexible Atom/RSS syndication for WordPress 
    6 Version: 2012.0524 
     6Version: 2012.0810 
    77Author: Charles Johnson 
    88Author URI: http://radgeek.com/ 
     
    1212/** 
    1313 * @package FeedWordPress 
    14  * @version 2012.0524 
     14 * @version 2012.0810 
    1515 */ 
    1616 
     
    3535# -- Don't change these unless you know what you're doing... 
    3636 
    37 define ('FEEDWORDPRESS_VERSION', '2012.0524'); 
     37define ('FEEDWORDPRESS_VERSION', '2012.0810'); 
    3838define ('FEEDWORDPRESS_AUTHOR_CONTACT', 'http://radgeek.com/contact'); 
    3939 
     
    5555endif; 
    5656define ('FEEDWORDPRESS_DEBUG', $feedwordpress_debug); 
     57$feedwordpress_compatibility = true; 
     58define ('FEEDWORDPRESS_COMPATIBILITY', $feedwordpress_compatibility); 
    5759 
    5860define ('FEEDWORDPRESS_CAT_SEPARATOR_PATTERN', '/[:\n]/'); 
     
    12141216        endif; 
    12151217 
     1218        // This is a special post status for hiding posts that have expired 
     1219        register_post_status('fwpretired', array( 
     1220        'label' => _x('Retired', 'post'), 
     1221        'label_count' => _n_noop('Retired <span class="count">(%s)</span>', 'Retired <span class="count">(%s)</span>'), 
     1222        'exclude_from_search' => true, 
     1223        'public' => false, 
     1224        'publicly_queryable' => false, 
     1225        'show_in_admin_all_list' => false, 
     1226        'show_in_admin_status_list' => true, 
     1227        )); 
     1228        add_action( 
     1229            /*hook=*/ 'template_redirect', 
     1230            /*function=*/ array(&$this, 'redirect_retired'), 
     1231            /*priority=*/ -100 
     1232        ); 
     1233 
    12161234        $this->clear_cache_magic_url(); 
    12171235        $this->update_magic_url(); 
    12181236    } /* FeedWordPress::init() */ 
     1237     
     1238    function redirect_retired () { 
     1239        global $wp_query; 
     1240        if (is_singular()) : 
     1241            if ('fwpretired'==$wp_query->post->post_status) : 
     1242                do_action('feedwordpress_redirect_retired', $wp_query->post); 
     1243                 
     1244                if (!($template = get_404_template())) : 
     1245                    $template = get_index_template(); 
     1246                endif; 
     1247                if ($template = apply_filters('template_include', $template)) : 
     1248                    header("HTTP/1.1 410 Gone"); 
     1249                    include($template); 
     1250                endif; 
     1251                exit; 
     1252            endif; 
     1253        endif; 
     1254    } 
    12191255     
    12201256    function dashboard_setup () { 
  • feedwordpress/trunk/syndicatedlink.class.php

    r549640 r583851  
    5858            $this->get_settings_from_notes(); 
    5959        endif; 
     60         
     61        add_filter('feedwordpress_update_complete', array(&$this, 'process_retirements'), 1000, 1); 
    6062    } /* SyndicatedLink::SyndicatedLink () */ 
    6163     
     
    237239            $this->magpie->originals = $posts; 
    238240 
     241            // If this is a complete feed, rather than an incremental feed, we 
     242            // need to prepare to mark everything for presumptive retirement. 
     243            if ($this->is_incremental()) : 
     244                $q = new WP_Query(array( 
     245                'fields' => '_synfrom', 
     246                'post_status__not' => 'fwpretired', 
     247                'ignore_sticky_posts' => true, 
     248                'meta_key' => 'syndication_feed_id', 
     249                'meta_value' => $this->id, 
     250                )); 
     251                foreach ($q->posts as $p) : 
     252                    update_post_meta($p->ID, '_feedwordpress_retire_me_'.$this->id, '1'); 
     253                endforeach; 
     254            endif; 
     255             
    239256            if (is_array($posts)) : 
    240257                foreach ($posts as $key => $item) : 
     
    256273                endforeach; 
    257274            endif; 
     275             
     276            if ('yes'==$this->setting('tombstones', 'tombstones', 'yes')) : 
     277                // Check for use of Atom tombstones. Spec: 
     278                // <http://tools.ietf.org/html/draft-snell-atompub-tombstones-18> 
     279                $tombstones = $this->simplepie->get_feed_tags('http://purl.org/atompub/tombstones/1.0', 'deleted-entry'); 
     280                if (count($tombstones) > 0) : 
     281                    foreach ($tombstones as $tombstone) : 
     282                        $ref = NULL; 
     283                        foreach (array('', 'http://purl.org/atompub/tombstones/1.0') as $ns) : 
     284                            if (isset($tombstone['attribs'][$ns]) 
     285                            and isset($tombstone['attribs'][$ns]['ref'])) : 
     286                                $ref = $tombstone['attribs'][$ns]['ref']; 
     287                            endif; 
     288                        endforeach; 
     289                         
     290                        $q = new WP_Query(array( 
     291                        'ignore_sticky_posts' => true, 
     292                        'guid' => $ref, 
     293                        'meta_key' => 'syndication_feed_id', 
     294                        'meta_value' => $this->id, // Only allow a feed to tombstone its own entries. 
     295                        )); 
     296                         
     297                        foreach ($q->posts as $p) : 
     298                            $old_status = $p->post_status; 
     299                            FeedWordPress::diagnostic('syndicated_posts', 'Retiring existing post # '.$p->ID.' "'.$p->post_title.'" due to Atom tombstone element in feed.'); 
     300                            set_post_field('post_status', 'fwpretired', $p->ID); 
     301                            wp_transition_post_status('fwpretired', $old_status, $p); 
     302                        endforeach; 
     303                         
     304                    endforeach; 
     305                endif; 
     306            endif; 
     307             
    258308            $suffix = ($crashed ? 'crashed' : 'completed'); 
    259309            do_action('update_syndicated_feed_items', $this->id, $this); 
     
    293343    } /* SyndicatedLink::poll() */ 
    294344 
     345    function process_retirements ($delta) { 
     346        global $post; 
     347 
     348        $q = new WP_Query(array( 
     349        'fields' => '_synfrom', 
     350        'post_status__not' => 'fwpretired', 
     351        'ignore_sticky_posts' => true, 
     352        'meta_key' => '_feedwordpress_retire_me_'.$this->id, 
     353        'meta_value' => '1', 
     354        )); 
     355        if ($q->have_posts()) : 
     356            foreach ($q->posts as $p) : 
     357                $old_status = $p->post_status; 
     358                FeedWordPress::diagnostic('syndicated_posts', 'Retiring existing post # '.$p->ID.' "'.$p->post_title.'" due to absence from a non-incremental feed.'); 
     359                set_post_field('post_status', 'fwpretired', $p->ID); 
     360                wp_transition_post_status('fwpretired', $old_status, $p); 
     361                delete_post_meta($p->ID, '_feedwordpress_retire_me_'.$this->id); 
     362            endforeach; 
     363        endif; 
     364        return $delta; 
     365    } 
     366     
    295367    /** 
    296368     * Updates the URL for the feed syndicated by this link. 
     
    616688        endif; 
    617689    } /* SyndicatedLink::update_setting () */ 
     690     
     691    function is_incremental () { 
     692        return ('complete'==$this->setting('update_incremental', 'update_incremental', 'incremental')); 
     693    } /* SyndicatedLink::is_incremental () */ 
    618694     
    619695    function uri ($params = array()) { 
  • feedwordpress/trunk/syndicatedpost.class.php

    r549672 r583851  
    851851        $author = array (); 
    852852         
    853         if (isset($this->item['author_name'])): 
    854             $author['name'] = $this->item['author_name']; 
    855         elseif (isset($this->item['dc']['creator'])): 
    856             $author['name'] = $this->item['dc']['creator']; 
    857         elseif (isset($this->item['dc']['contributor'])): 
    858             $author['name'] = $this->item['dc']['contributor']; 
    859         elseif (isset($this->feed->channel['dc']['creator'])) : 
    860             $author['name'] = $this->feed->channel['dc']['creator']; 
    861         elseif (isset($this->feed->channel['dc']['contributor'])) : 
    862             $author['name'] = $this->feed->channel['dc']['contributor']; 
    863         elseif (isset($this->feed->channel['author_name'])) : 
    864             $author['name'] = $this->feed->channel['author_name']; 
    865         elseif ($this->feed->is_rss() and isset($this->item['author'])) : 
    866             // The author element in RSS is allegedly an 
    867             // e-mail address, but lots of people don't use 
    868             // it that way. So let's make of it what we can. 
    869             $author = parse_email_with_realname($this->item['author']); 
    870              
    871             if (!isset($author['name'])) : 
    872                 if (isset($author['email'])) : 
    873                     $author['name'] = $author['email']; 
    874                 else : 
    875                     $author['name'] = $this->feed->channel['title']; 
     853        $aa = $this->entry->get_authors(); 
     854        if (count($aa) > 0) : 
     855            $a = reset($aa); 
     856 
     857            $author = array( 
     858            'name' => $a->get_name(), 
     859            'email' => $a->get_email(), 
     860            'uri' => $a->get_link(), 
     861            ); 
     862        endif; 
     863 
     864        if (FEEDWORDPRESS_COMPATIBILITY) : 
     865            // Search through the MagpieRSS elements: Atom, Dublin Core, RSS 
     866            if (isset($this->item['author_name'])): 
     867                $author['name'] = $this->item['author_name']; 
     868            elseif (isset($this->item['dc']['creator'])): 
     869                $author['name'] = $this->item['dc']['creator']; 
     870            elseif (isset($this->item['dc']['contributor'])): 
     871                $author['name'] = $this->item['dc']['contributor']; 
     872            elseif (isset($this->feed->channel['dc']['creator'])) : 
     873                $author['name'] = $this->feed->channel['dc']['creator']; 
     874            elseif (isset($this->feed->channel['dc']['contributor'])) : 
     875                $author['name'] = $this->feed->channel['dc']['contributor']; 
     876            elseif (isset($this->feed->channel['author_name'])) : 
     877                $author['name'] = $this->feed->channel['author_name']; 
     878            elseif ($this->feed->is_rss() and isset($this->item['author'])) : 
     879                // The author element in RSS is allegedly an 
     880                // e-mail address, but lots of people don't use 
     881                // it that way. So let's make of it what we can. 
     882                $author = parse_email_with_realname($this->item['author']); 
     883                 
     884                if (!isset($author['name'])) : 
     885                    if (isset($author['email'])) : 
     886                        $author['name'] = $author['email']; 
     887                    else : 
     888                        $author['name'] = $this->feed->channel['title']; 
     889                    endif; 
    876890                endif; 
    877891            endif; 
    878         elseif ($this->link->name()) : 
    879             $author['name'] = $this->link->name(); 
    880         else : 
    881             $url = parse_url($this->link->uri()); 
    882             $author['name'] = $url['host']; 
    883         endif; 
    884          
    885         if (isset($this->item['author_email'])): 
    886             $author['email'] = $this->item['author_email']; 
    887         elseif (isset($this->feed->channel['author_email'])) : 
    888             $author['email'] = $this->feed->channel['author_email']; 
    889         endif; 
    890          
    891         if (isset($this->item['author_uri'])): 
    892             $author['uri'] = $this->item['author_uri']; 
    893         elseif (isset($this->item['author_url'])): 
    894             $author['uri'] = $this->item['author_url']; 
    895         elseif (isset($this->feed->channel['author_uri'])) : 
    896             $author['uri'] = $this->item['author_uri']; 
    897         elseif (isset($this->feed->channel['author_url'])) : 
    898             $author['uri'] = $this->item['author_url']; 
    899         elseif (isset($this->feed->channel['link'])) : 
    900             $author['uri'] = $this->feed->channel['link']; 
    901         endif; 
    902  
     892        endif; 
     893         
     894        if (!isset($author['name']) or is_null($author['name'])) : 
     895            // Nothing found. Try some crappy defaults. 
     896            if ($this->link->name()) : 
     897                $author['name'] = $this->link->name(); 
     898            else : 
     899                $url = parse_url($this->link->uri()); 
     900                $author['name'] = $url['host']; 
     901            endif; 
     902        endif; 
     903         
     904        if (FEEDWORDPRESS_COMPATIBILITY) : 
     905            if (isset($this->item['author_email'])): 
     906                $author['email'] = $this->item['author_email']; 
     907            elseif (isset($this->feed->channel['author_email'])) : 
     908                $author['email'] = $this->feed->channel['author_email']; 
     909            endif; 
     910             
     911            if (isset($this->item['author_uri'])): 
     912                $author['uri'] = $this->item['author_uri']; 
     913            elseif (isset($this->item['author_url'])): 
     914                $author['uri'] = $this->item['author_url']; 
     915            elseif (isset($this->feed->channel['author_uri'])) : 
     916                $author['uri'] = $this->item['author_uri']; 
     917            elseif (isset($this->feed->channel['author_url'])) : 
     918                $author['uri'] = $this->item['author_url']; 
     919            elseif (isset($this->feed->channel['link'])) : 
     920                $author['uri'] = $this->feed->channel['link']; 
     921            endif; 
     922        endif; 
     923         
    903924        return $author; 
    904925    } /* SyndicatedPost::author() */ 
     
    14951516        endif; 
    14961517 
     1518        // If this is a legit, non-filtered post, tag it as found on the feed 
     1519        // regardless of fresh or stale status 
     1520        if (!$this->filtered()) : 
     1521            $key = '_feedwordpress_retire_me_' . $this->link->id; 
     1522            delete_post_meta($this->wp_id(), $key); 
     1523             
     1524            $status = get_post_field('post_status', $this->wp_id()); 
     1525            if ('fwpretired'==$status and $this->link->is_incremental()) : 
     1526                FeedWordPress::diagnostic('syndicated_posts', "Un-retiring previously retired post # ".$this->wp_id()." due to re-appearance on non-incremental feed.");  
     1527                set_post_field('post_status', $this->post['post_status'], $this->wp_id()); 
     1528                wp_transition_post_status($this->post['post_status'], $status, $old_status, $this->post); 
     1529            endif; 
     1530        endif; 
     1531         
    14971532        // Remove add_rss_meta hook 
    14981533        remove_action( 
  • feedwordpress/trunk/syndicationdataqueries.class.php

    r547532 r583851  
    4646        endif; 
    4747         
    48         if ($q->get('fields') == '_synfresh') : 
     48        $ff = $q->get('fields'); 
     49        if ($ff == '_synfresh' or $ff == '_synfrom') : 
    4950            $q->query_vars['cache_results'] = false; // Not suitable. 
    5051        endif; 
     
    6162        return $sql; 
    6263    } 
    63      
     64 
    6465    function posts_search ($search, &$query) { 
    6566        global $wpdb; 
     
    9394            // checks -- for reasons of both performance and correctness. Pitch: 
    9495            $search .= " -- '"; 
     96        elseif ($query->get('fields')=='_synfrom') : 
     97            $search .= " AND ({$wpdb->postmeta}.meta_key = '".$query->get('meta_key')."' AND wp_postmeta.meta_value = '".$query->get('meta_value')."') -- '";  
    9598        endif; 
    9699        return $search; 
     
    98101     
    99102    function posts_where ($where, &$q) { 
     103        global $wpdb; 
     104         
    100105        // Ugly hack to ensure we ONLY check by guid in syndicated freshness 
    101106        // checks -- for reasons of both performance and correctness. Catch: 
     
    104109            $where = $bits[0]; 
    105110        endif; 
     111         
     112        if ($psn = $q->get('post_status__not')) : 
     113            $where .= " AND ({$wpdb->posts}.post_status <> '".$wpdb->escape($psn)."')";  
     114        endif; 
     115         
    106116        return $where; 
    107117    } /* SyndicationDataQueries::post_where () */ 
     
    113123            case '_synfresh' : 
    114124                $fields = "{$wpdb->posts}.ID, {$wpdb->posts}.guid, {$wpdb->posts}.post_modified_gmt"; 
     125                break; 
     126            case '_synfrom' : 
     127                $fields = "{$wpdb->posts}.ID, {$wpdb->posts}.guid, {$wpdb->posts}.post_title, {$wpdb->postmeta}.meta_value"; 
    115128                break; 
    116129            default : 
Note: See TracChangeset for help on using the changeset viewer.