PluginProbe
FeedWordPress / 2011.0211.2
FeedWordPress v2011.0211.2
trunk 0.8 0.9 0.91 0.95 0.96 0.97 0.98 0.981 0.99 0.991 0.992 0.993 2008.1030 2008.1101 2008.1105 2008.1214 2009.0612 2009.0613 2009.0618 2009.0707 2009.1111 2009.1112 2010.0127 2010.0528 All 65 releases
← All changes | feedwordpress.php +1350 -1661 trunk2011.0211.2 View file →
@@ -1,266 +1,504 @@
1 1 <?php
2 2 /*
3 3 Plugin Name: FeedWordPress
4 -Plugin URI: https://fwpplugin.com/
4 +Plugin URI: http://feedwordpress.radgeek.com/
5 5 Description: simple and flexible Atom/RSS syndication for WordPress
6 -Version: 2026.0517
7 -Author: C. Johnson
8 -Author URI: https://fwpplugin.com/contact/
6 +Version: 2011.0211.2
7 +Author: Charles Johnson
8 +Author URI: http://radgeek.com/
9 9 License: GPL
10 10 */
11 11
12 12 /**
13 13 * @package FeedWordPress
14 - * @version 2026.0517
14 + * @version 2011.0211.2
15 15 */
16 16
17 -# This plugin uses code derived from:
17 +# This uses code derived from:
18 18 # - wp-rss-aggregate.php by Kellan Elliot-McCrea <kellan@protest.net>
19 -# - SimplePie feed parser by Ryan Parman, Geoffrey Sneddon, Ryan McCue, et al.
20 -# - MagpieRSS feed parser by Kellan Elliot-McCrea <kellan@protest.net>
19 +# - MagpieRSS by Kellan Elliot-McCrea <kellan@protest.net>
21 20 # - Ultra-Liberal Feed Finder by Mark Pilgrim <mark@diveintomark.org>
22 21 # - WordPress Blog Tool and Publishing Platform <http://wordpress.org/>
23 -# - Github contributors @Flynsarmy, @BandonRandon, @david-robinson-practiceweb,
24 -# @daidais, @thegreatmichael, @stedaniels, @alexiskulash, @quassy, @zoul0813,
25 -# @timmmmyboy, @vobornik, @inanimatt, @tristanleboss, @martinburchell,
26 -# @bigalownz, @oppiansteve, @GwynethLlewelyn, and @glg222
27 22 # according to the terms of the GNU General Public License.
23 +#
24 +# INSTALLATION: see readme.txt or <http://projects.radgeek.com/install>
25 +#
26 +# USAGE: once FeedWordPress is installed, you manage just about everything from
27 +# the WordPress Dashboard, under the Syndication menu. To ensure that fresh
28 +# content is added as it becomes available, you can convince your contributors
29 +# to put your XML-RPC URI (if WordPress is installed at
30 +# <http://www.zyx.com/blog>, XML-RPC requests should be sent to
31 +# <http://www.zyx.com/blog/xmlrpc.php>), or update manually under the
32 +# Syndication menu, or set up automatic updates under Syndication --> Settings,
33 +# or use a cron job.
28 34
29 -####################################################################################
30 -## CONSTANTS & DEFAULTS ############################################################
31 -####################################################################################
35 +# -- Don't change these unless you know what you're doing...
32 36
33 -define ('FEEDWORDPRESS_VERSION', '2026.0517');
34 -define ('FEEDWORDPRESS_AUTHOR_CONTACT', 'https://fwpplugin.com/contact' );
37 +define ('FEEDWORDPRESS_VERSION', '2011.0211.2');
38 +define ('FEEDWORDPRESS_AUTHOR_CONTACT', 'http://radgeek.com/contact');
35 39
36 -if ( ! defined( 'FEEDWORDPRESS_BLEG' ) ) :
37 - define ( 'FEEDWORDPRESS_BLEG', true );
40 +if (!defined('FEEDWORDPRESS_BLEG')) :
41 + define ('FEEDWORDPRESS_BLEG', true);
38 42 endif;
39 43
40 -define( 'FEEDWORDPRESS_BLEG_BTC_pre_2020', '15EsQ9QMZtLytsaVYZUaUCmrkSMaxZBTso' );
41 -define( 'FEEDWORDPRESS_BLEG_BTC_2020', '1NB1ebYVb68Har4WijmE8gKnZ47NptCqtB' ); // 2020.0201
42 -define( 'FEEDWORDPRESS_BLEG_BTC', '1HCDdeGcR66EPxkPT2rbdTd1ezh27pmjPR' ); // 2021.0713
43 -define( 'FEEDWORDPRESS_BLEG_PAYPAL', '22PAJZZCK5Z3W' );
44 -
45 44 // Defaults
46 -define( 'DEFAULT_SYNDICATION_CATEGORY', 'Contributors' );
47 -define( 'DEFAULT_UPDATE_PERIOD', 60 ); // value in minutes
48 -define( 'FEEDWORDPRESS_DEFAULT_CHECKIN_INTERVAL', DEFAULT_UPDATE_PERIOD / 10 );
45 +define ('DEFAULT_SYNDICATION_CATEGORY', 'Contributors');
46 +define ('DEFAULT_UPDATE_PERIOD', 60); // value in minutes
49 47
50 -// Dependencies: modules packaged with FeedWordPress plugin.
51 -/** @var string Path to parent directory */
52 -$dir = dirname( __FILE__ );
53 -require_once "{$dir}/externals/myphp/myphp.class.php";
54 -
55 -/** @var bool|string Set to either true or 'yes' if debugging is set. */
56 -$feedwordpress_debug = FeedWordPress::param( 'feedwordpress_debug', get_option( 'feedwordpress_debug' ) );
57 -
58 -if ( is_string( $feedwordpress_debug ) ) :
59 - $feedwordpress_debug = ( $feedwordpress_debug == 'yes' );
48 +if (isset($_REQUEST['feedwordpress_debug'])) :
49 + $feedwordpress_debug = $_REQUEST['feedwordpress_debug'];
50 +else :
51 + $feedwordpress_debug = get_option('feedwordpress_debug');
52 + if (is_string($feedwordpress_debug)) :
53 + $feedwordpress_debug = ($feedwordpress_debug == 'yes');
54 + endif;
60 55 endif;
56 +define ('FEEDWORDPRESS_DEBUG', $feedwordpress_debug);
61 57
62 -define ( 'FEEDWORDPRESS_DEBUG', $feedwordpress_debug );
63 -$feedwordpress_compatibility = true;
64 -define ( 'FEEDWORDPRESS_COMPATIBILITY', $feedwordpress_compatibility );
58 +define ('FEEDWORDPRESS_CAT_SEPARATOR_PATTERN', '/[:\n]/');
59 +define ('FEEDWORDPRESS_CAT_SEPARATOR', "\n");
65 60
66 -define ( 'FEEDWORDPRESS_CAT_SEPARATOR_PATTERN', '/[:\n]/' );
67 -define ( 'FEEDWORDPRESS_CAT_SEPARATOR', "\n" );
61 +define ('FEEDVALIDATOR_URI', 'http://feedvalidator.org/check.cgi');
68 62
69 -// define ('FEEDVALIDATOR_URI', 'http://feedvalidator.org/check.cgi'); // Link dead (gwyneth 20210617)
70 -define ( 'FEEDVALIDATOR_URI', 'https://validator.w3.org/feed/check.cgi' ); // Falling back to the W3C validator link
63 +define ('FEEDWORDPRESS_FRESHNESS_INTERVAL', 10*60); // Every ten minutes
71 64
72 -define ( 'FEEDWORDPRESS_FRESHNESS_INTERVAL', 10 * 60 ); // Every ten minutes
65 +define ('FWP_SCHEMA_HAS_USERMETA', 2966);
66 +define ('FWP_SCHEMA_USES_ARGS_TAXONOMY', 12694); // Revision # for using $args['taxonomy'] to get link categories
67 +define ('FWP_SCHEMA_20', 3308); // Database schema # for WP 2.0
68 +define ('FWP_SCHEMA_21', 4772); // Database schema # for WP 2.1
69 +define ('FWP_SCHEMA_23', 5495); // Database schema # for WP 2.3
70 +define ('FWP_SCHEMA_25', 7558); // Database schema # for WP 2.5
71 +define ('FWP_SCHEMA_26', 8201); // Database schema # for WP 2.6
72 +define ('FWP_SCHEMA_27', 9872); // Database schema # for WP 2.7
73 +define ('FWP_SCHEMA_28', 11548); // Database schema # for WP 2.8
74 +define ('FWP_SCHEMA_29', 12329); // Database schema # for WP 2.9
75 +define ('FWP_SCHEMA_30', 12694); // Database schema # for WP 3.0
73 76
74 -define( 'FEEDWORDPRESS_BOILERPLATE_DEFAULT_HOOK_ORDER', 11000 ); // at the tail end of the filtering process
75 -
76 -if ( FEEDWORDPRESS_DEBUG ) :
77 +if (FEEDWORDPRESS_DEBUG) :
77 78 // Help us to pick out errors, if any.
78 - ini_set( 'error_reporting', E_ALL & ~E_NOTICE );
79 - ini_set( 'display_errors', true );
80 -
79 + ini_set('error_reporting', E_ALL & ~E_NOTICE);
80 + ini_set('display_errors', true);
81 +
81 82 // When testing we don't want cache issues to interfere. But this is
82 - // a VERY BAD SETTING for a production server. Webmasters will eat your
83 + // a VERY BAD SETTING for a production server. Webmasters will eat your
83 84 // face for breakfast if you use it, and the baby Jesus will cry. So
84 85 // make sure FEEDWORDPRESS_DEBUG is FALSE for any site that will be
85 86 // used for more than testing purposes!
86 - define( 'FEEDWORDPRESS_CACHE_AGE', 1 );
87 - define( 'FEEDWORDPRESS_CACHE_LIFETIME', 1 );
88 - define( 'FEEDWORDPRESS_FETCH_TIMEOUT_DEFAULT', 60 );
87 + define('FEEDWORDPRESS_CACHE_AGE', 1);
88 + define('FEEDWORDPRESS_CACHE_LIFETIME', 1);
89 + define('FEEDWORDPRESS_FETCH_TIMEOUT_DEFAULT', 60);
89 90 else :
90 91 // Hold onto data all day for conditional GET purposes,
91 92 // but consider it stale after 1 min (requiring a conditional GET)
92 - define( 'FEEDWORDPRESS_CACHE_LIFETIME', 24 * 60 * 60 ); // aka one day.
93 - define( 'FEEDWORDPRESS_CACHE_AGE', 1 * 60 );
94 - define( 'FEEDWORDPRESS_FETCH_TIMEOUT_DEFAULT', 20 );
93 + define('FEEDWORDPRESS_CACHE_LIFETIME', 24*60*60);
94 + define('FEEDWORDPRESS_CACHE_AGE', 1*60);
95 + define('FEEDWORDPRESS_FETCH_TIMEOUT_DEFAULT', 20);
95 96 endif;
96 97
97 -####################################################################################
98 -## CORE DEPENDENCIES & PLUGIN MODULES ##############################################
99 -####################################################################################
98 +// Use our the cache settings that we want.
99 +add_filter('wp_feed_cache_transient_lifetime', array('FeedWordPress', 'cache_lifetime'));
100 100
101 -/** @var array<string> Dependencies: modules packaged with WordPress core */
102 -$wpCoreDependencies = array(
103 - "class:SimplePie" => "class-simplepie",
104 - "class:WP_SimplePie_File" => "class-wp-simplepie-file",
105 - "class:WP_SimplePie_Sanitize_KSES" => "class-wp-simplepie-sanitize-kses",
106 - "function:wp_insert_user" => "registration",
107 -);
101 +// Ensure that we have SimplePie loaded up and ready to go.
102 +// We no longer need a MagpieRSS upgrade module. Hallelujah!
103 +if (!class_exists('SimplePie')) :
104 + require_once(ABSPATH . WPINC . '/class-simplepie.php');
105 +endif;
106 +require_once(ABSPATH . WPINC . '/class-feed.php');
108 107
109 -// Ensure that we have SimplePie loaded up and ready to go
110 -// along with the WordPress auxiliary classes.
111 -$unmetCoreDependencies = array();
112 -foreach ( $wpCoreDependencies as $unit => $fileSlug ) :
113 - list( $unitType, $unitName ) = explode( ":", $unit, 2 );
108 +if (!function_exists('wp_insert_user')) :
109 + require_once (ABSPATH . WPINC . '/registration.php'); // for wp_insert_user
110 +endif;
114 111
115 - $dependencyMet = ( ('class' == $unitType ) ? class_exists( $unitName ) : function_exists( $unitName ) );
116 - if ( ! $dependencyMet ) :
117 - $phpFileName = ABSPATH . WPINC . "/{$fileSlug}.php";
118 - if ( file_exists( $phpFileName ) ) :
119 - require_once $phpFileName;
120 - else :
121 - $unmetCoreDependencies[] = $unitName;
122 - endif;
112 +require_once(dirname(__FILE__) . '/admin-ui.php');
113 +require_once(dirname(__FILE__) . '/feedwordpresssyndicationpage.class.php');
114 +require_once(dirname(__FILE__) . '/compatability.php'); // LEGACY API: Replicate or mock up functions for legacy support purposes
115 +
116 +require_once(dirname(__FILE__) . '/syndicatedpost.class.php');
117 +require_once(dirname(__FILE__) . '/syndicatedlink.class.php');
118 +require_once(dirname(__FILE__) . '/feedwordpresshtml.class.php');
119 +require_once(dirname(__FILE__) . '/feedwordpress-content-type-sniffer.class.php');
120 +
121 +// Magic quotes are just about the stupidest thing ever.
122 +if (is_array($_POST)) :
123 + $fwp_post = $_POST;
124 + if (get_magic_quotes_gpc()) :
125 + $fwp_post = stripslashes_deep($fwp_post);
123 126 endif;
124 -endforeach;
125 -
126 -// Fallback garbage-pail module used in WP < 4.7 which may meet our dependencies
127 -if ( count( $unmetCoreDependencies ) > 0 ) :
128 - require_once ABSPATH . WPINC . "/class-feed.php";
129 127 endif;
130 128
131 -// Dependencies: modules packaged with FeedWordPress plugin
132 -$dir = dirname( __FILE__ );
133 -require_once "{$dir}/feedwordpressadminpage.class.php";
134 -require_once "{$dir}/feedwordpresssettingsui.class.php";
135 -require_once "{$dir}/feedwordpressdiagnostic.class.php";
136 -require_once "{$dir}/admin-ui.php";
137 -require_once "{$dir}/template-functions.php";
138 -require_once "{$dir}/feedwordpresssyndicationpage.class.php";
139 -require_once "{$dir}/compatability.php"; // Legacy API
140 -require_once "{$dir}/syndicatedpost.class.php";
141 -require_once "{$dir}/syndicatedlink.class.php";
142 -require_once "{$dir}/feedwordpresshtml.class.php";
143 -require_once "{$dir}/inspectpostmeta.class.php";
144 -require_once "{$dir}/syndicationdataqueries.class.php";
145 -require_once "{$dir}/extend/SimplePie/feedwordpie.class.php";
146 -require_once "{$dir}/extend/SimplePie/feedwordpie_cache.class.php";
147 -require_once "{$dir}/extend/SimplePie/feedwordpie_item.class.php";
148 -require_once "{$dir}/extend/SimplePie/feedwordpie_file.class.php";
149 -require_once "{$dir}/extend/SimplePie/feedwordpie_parser.class.php";
150 -require_once "{$dir}/extend/SimplePie/feedwordpie_content_type_sniffer.class.php";
151 -require_once "{$dir}/feedwordpressrpc.class.php";
152 -require_once "{$dir}/feedwordpresshttpauthenticator.class.php";
153 -require_once "{$dir}/feedwordpresslocalpost.class.php";
154 -
155 -####################################################################################
156 -## GLOBAL PARAMETERS ###############################################################
157 -####################################################################################
158 -
159 129 // Get the path relative to the plugins directory in which FWP is stored
160 130 preg_match (
161 - '|'.preg_quote( WP_PLUGIN_DIR ) . '/(.+)$|',
162 - dirname( __FILE__ ),
131 + '|'.preg_quote(WP_PLUGIN_DIR).'/(.+)$|',
132 + dirname(__FILE__),
163 133 $ref
164 134 );
165 135
166 -if ( isset( $ref[1] ) ) :
136 +if (isset($ref[1])) :
167 137 $fwp_path = $ref[1];
168 138 else : // Something went wrong. Let's just guess.
169 139 $fwp_path = 'feedwordpress';
170 140 endif;
171 141
172 -####################################################################################
173 -## FEEDWORDPRESS: INITIALIZE OBJECT AND FILTERS ####################################
174 -####################################################################################
142 +// If this is a FeedWordPress admin page, queue up scripts for AJAX functions that FWP uses
143 +// If it is a display page or a non-FeedWordPress admin page, don't.
144 +wp_register_style('feedwordpress-elements', WP_PLUGIN_URL.'/'.$fwp_path.'/feedwordpress-elements.css');
145 +if (FeedWordPressSettingsUI::is_admin()) :
146 + // For JavaScript that needs to be generated dynamically
147 + add_action('admin_print_scripts', array('FeedWordPressSettingsUI', 'admin_scripts'));
175 148
176 -$feedwordpress = new FeedWordPress;
177 -if ( ! $feedwordpress->needs_upgrade() ) : // only work if the conditions are safe!
178 - $feedwordpress->add_filters();
149 + // For CSS that needs to be generated dynamically.
150 + add_action('admin_print_styles', array('FeedWordPressSettingsUI', 'admin_styles'));
179 151
152 + wp_enqueue_style('dashboard');
153 + wp_enqueue_style('feedwordpress-elements');
154 +
155 + if (function_exists('wp_admin_css')) :
156 + wp_admin_css('css/dashboard');
157 + endif;
158 +endif;
159 +
160 +if (!FeedWordPress::needs_upgrade()) : // only work if the conditions are safe!
161 +
162 + # Syndicated items are generally received in output-ready (X)HTML and
163 + # should not be folded, crumpled, mutilated, or spindled by WordPress
164 + # formatting filters. But we don't want to interfere with filters for
165 + # any locally-authored posts, either.
166 + #
167 + # What WordPress should really have is a way for upstream filters to
168 + # stop downstream filters from running at all. Since it doesn't, and
169 + # since a downstream filter can't access the original copy of the text
170 + # that is being filtered, what we will do here is (1) save a copy of the
171 + # original text upstream, before any other filters run, and then (2)
172 + # retrieve that copy downstream, after all the other filters run, *if*
173 + # this is a syndicated post
174 +
175 + add_filter('the_content', 'feedwordpress_preserve_syndicated_content', -10000);
176 + add_filter('the_content', 'feedwordpress_restore_syndicated_content', 10000);
177 +
178 + add_action('atom_entry', 'feedwordpress_item_feed_data');
179 +
180 + # Filter in original permalinks if the user wants that
181 + add_filter('post_link', 'syndication_permalink', /*priority=*/ 1, /*arguments=*/ 3);
182 +
183 + # When foreign URLs are used for permalinks in feeds or display
184 + # contexts, they need to be escaped properly.
185 + add_filter('the_permalink', 'syndication_permalink_escaped');
186 + add_filter('the_permalink_rss', 'syndication_permalink_escaped');
187 +
188 + add_filter('post_comments_feed_link', 'syndication_comments_feed_link');
189 +
190 + # WTF? By default, wp_insert_link runs incoming link_url and link_rss
191 + # URIs through default filters that include `wp_kses()`. But `wp_kses()`
192 + # just happens to escape any occurrence of & to &amp; -- which just
193 + # happens to fuck up any URI with a & to separate GET parameters.
194 + remove_filter('pre_link_rss', 'wp_filter_kses');
195 + remove_filter('pre_link_url', 'wp_filter_kses');
196 +
197 + # Admin menu
198 + add_action('admin_menu', 'fwp_add_pages');
199 + add_action('admin_notices', 'fwp_check_debug');
200 +
201 + add_action('admin_menu', 'feedwordpress_add_post_edit_controls');
202 + add_action('save_post', 'feedwordpress_save_post_edit_controls');
203 +
204 + add_action('admin_footer', array('FeedWordPress', 'admin_footer'));
205 +
180 206 # Inbound XML-RPC update methods
181 207 $feedwordpressRPC = new FeedWordPressRPC;
182 208
183 209 # Outbound XML-RPC ping reform
184 - remove_action( 'publish_post', 'generic_ping' ); // WP 1.5.x
185 - remove_action( 'do_pings', 'do_all_pings', 10, 1 ); // WP 2.1, 2.2
186 - remove_action( 'publish_post', '_publish_post_hook', 5, 1 ); // WP 2.3
210 + remove_action('publish_post', 'generic_ping'); // WP 1.5.x
211 + remove_action('do_pings', 'do_all_pings', 10, 1); // WP 2.1, 2.2
212 + remove_action('publish_post', '_publish_post_hook', 5, 1); // WP 2.3
187 213
188 - add_action( 'publish_post', 'fwp_publish_post_hook', 5, 1 );
189 - add_action( 'do_pings', 'fwp_do_pings', 10, 1 );
190 - add_action( 'feedwordpress_update', 'fwp_hold_pings' );
191 - add_action( 'feedwordpress_update_complete', 'fwp_release_pings' );
214 + add_action('publish_post', 'fwp_publish_post_hook', 5, 1);
215 + add_action('do_pings', 'fwp_do_pings', 10, 1);
216 + add_action('feedwordpress_update', 'fwp_hold_pings');
217 + add_action('feedwordpress_update_complete', 'fwp_release_pings');
192 218
219 + add_action('syndicated_feed_error', array('FeedWordPressDiagnostic', 'feed_error'), 100, 3);
220 +
221 + add_action('wp_footer', 'debug_out_feedwordpress_footer', -100);
222 + add_action('admin_footer', 'debug_out_feedwordpress_footer', -100);
223 +
224 + $feedwordpress = new FeedWordPress;
225 +
226 + # Cron-less auto-update. Hooray!
227 + $autoUpdateHook = get_option('feedwordpress_automatic_updates');
228 + if ($autoUpdateHook != 'init') :
229 + $autoUpdateHook = 'shutdown';
230 + endif;
231 + add_action($autoUpdateHook, array(&$feedwordpress, 'auto_update'));
232 + add_action('init', array(&$feedwordpress, 'init'));
233 + add_action('shutdown', array(&$feedwordpress, 'email_diagnostic_log'));
234 + add_action('wp_dashboard_setup', array(&$feedwordpress, 'dashboard_setup'));
235 +
236 + # Default sanitizers
237 + add_filter('syndicated_item_content', array('SyndicatedPost', 'resolve_relative_uris'), 0, 2);
238 + add_filter('syndicated_item_content', array('SyndicatedPost', 'sanitize_content'), 0, 2);
239 +
193 240 else :
194 241 # Hook in the menus, which will just point to the upgrade interface
195 - add_action( 'admin_menu', array( $feedwordpress, 'add_pages' ) );
196 -endif; // if ( !FeedWordPress::needs_upgrade())
242 + add_action('admin_menu', 'fwp_add_pages');
243 +endif; // if (!FeedWordPress::needs_upgrade())
197 244
198 -register_deactivation_hook( __FILE__, 'feedwordpress_deactivate' );
199 -
200 -/**
201 - * Hook to deactivate FeedWordPress.
202 - *
203 - * @return int|false @see wp_clear_scheduled_hook()
204 - */
205 -function feedwordpress_deactivate() {
206 - wp_clear_scheduled_hook( 'fwp_scheduled_update_checkin' );
207 -} /* feedwordpress_deactivate () */
208 -
209 245 ################################################################################
210 246 ## LOGGING FUNCTIONS: log status updates to error_log if you want it ###########
211 247 ################################################################################
212 248
213 -/**
214 - * Divides bytes into units of higher magnitude (e.g KB, MB, etc).
215 - *
216 - * @param int|string $quantity Quantity in bytes to be displayed. Can be a string that only includes numeric digits.
217 - *
218 - * @return string Formatted string with quantity and unit.
219 - *
220 - * @deprecated use the WordPress built-in `size_format()` function instead! (gwyneth 20230918)
221 - */
222 -function debug_out_human_readable_bytes( $quantity ) {
223 - if ( ! is_numeric( $quantity ) ) :
224 - return __( "(wrong quantity)" );
225 - endif;
226 - $quantity = intval( $quantity );
249 +class FeedWordPressDiagnostic {
250 + function feed_error ($error, $old, $link) {
251 + $wpError = $error['object'];
252 + $url = $link->uri();
253 +
254 + $mesgs = $wpError->get_error_messages();
255 + foreach ($mesgs as $mesg) :
256 + $mesg = esc_html($mesg);
257 + FeedWordPress::diagnostic(
258 + 'updated_feeds:errors',
259 + "Feed Error: [${url}] update returned error: $mesg"
260 + );
261 +
262 + $hours = get_option('feedwordpress_diagnostics_persistent_errors_hours', 2);
263 + $span = ($error['ts'] - $error['since']);
264 +
265 + if ($span >= ($hours * 60 * 60)) :
266 + $since = date('r', $error['since']);
267 + $mostRecent = date('r', $error['ts']);
268 + FeedWordPress::diagnostic(
269 + 'updated_feeds:errors:persistent',
270 + "Feed Update Error: [${url}] returning errors"
271 + ." since ${since}:<br/><code>$mesg</code>",
272 + $url, $error['since'], $error['ts']
273 + );
274 + endif;
275 + endforeach;
276 + }
277 +
278 + function admin_emails ($id = '') {
279 + $users = get_users_of_blog($id);
280 + $recipients = array();
281 + foreach ($users as $user) :
282 + $user_id = (isset($user->user_id) ? $user->user_id : $user->ID);
283 + $dude = new WP_User($user_id);
284 + if ($dude->has_cap('administrator')) :
285 + if ($dude->user_email) :
286 + $recipients[] = $dude->user_email;
287 + endif;
288 + endif;
289 + endforeach;
290 + return $recipients;
291 + }
292 +} /* class FeedWordPressDiagnostic */
293 +
294 +function debug_out_human_readable_bytes ($quantity) {
295 + $quantity = (int) $quantity;
227 296 $magnitude = 'B';
228 - /** @var array Two-letter abbreviations of the units in increasing magnitude. */
229 - $orders = array( 'KB', 'MB', 'GB', 'TB' );
230 - while ( ( $quantity > ( 1024 * 100 ) ) and ( count( $orders ) > 0 ) ) :
231 - $quantity = floor( $quantity / 1024 );
232 - $magnitude = array_shift( $orders );
297 + $orders = array('KB', 'MB', 'GB', 'TB');
298 + while (($quantity > (1024*100)) and (count($orders) > 0)) :
299 + $quantity = floor($quantity / 1024);
300 + $magnitude = array_shift($orders);
233 301 endwhile;
234 - return "{$quantity} {$magnitude}";
302 + return "${quantity} ${magnitude}";
235 303 }
236 304
237 -function debug_out_feedwordpress_footer() {
238 - if ( FeedWordPressDiagnostic::is_on('memory_usage') ) :
239 - if ( function_exists('memory_get_usage') ) :
240 - FeedWordPress::diagnostic( 'memory_usage', "Memory: Current usage: " . size_format( memory_get_usage() ) );
305 +function debug_out_feedwordpress_footer () {
306 + if (FeedWordPress::diagnostic_on('memory_usage')) :
307 + if (function_exists('memory_get_usage')) :
308 + FeedWordPress::diagnostic ('memory_usage', "Memory: Current usage: ".debug_out_human_readable_bytes(memory_get_usage()));
241 309 endif;
242 - if ( function_exists('memory_get_peak_usage') ) :
243 - FeedWordPress::diagnostic('memory_usage', "Memory: Peak usage: " . size_format( memory_get_peak_usage() ) );
310 + if (function_exists('memory_get_peak_usage')) :
311 + FeedWordPress::diagnostic ('memory_usage', "Memory: Peak usage: ".debug_out_human_readable_bytes(memory_get_peak_usage()));
244 312 endif;
245 313 endif;
246 314 } /* debug_out_feedwordpress_footer() */
247 315
248 316 ################################################################################
317 +## TEMPLATE API: functions to make your templates syndication-aware ############
318 +################################################################################
319 +
320 +/**
321 + * is_syndicated: Tests whether the current post in a Loop context, or a post
322 + * given by ID number, was syndicated by FeedWordPress. Useful for templates
323 + * to determine whether or not to retrieve syndication-related meta-data in
324 + * displaying a post.
325 + *
326 + * @param int $id The post to check for syndicated status. Defaults to the current post in a Loop context.
327 + * @return bool TRUE if the post's meta-data indicates it was syndicated; FALSE otherwise
328 + */
329 +function is_syndicated ($id = NULL) {
330 + return (strlen(get_syndication_feed_id($id)) > 0);
331 +} /* function is_syndicated() */
332 +
333 +function feedwordpress_display_url ($url, $before = 60, $after = 0) {
334 + $bits = parse_url($url);
335 +
336 + // Strip out crufty subdomains
337 + if (isset($bits['host'])) :
338 + $bits['host'] = preg_replace('/^www[0-9]*\./i', '', $bits['host']);
339 + endif;
340 +
341 + // Reassemble bit-by-bit with minimum of crufty elements
342 + $url = (isset($bits['user'])?$bits['user'].'@':'')
343 + .(isset($bits['host'])?$bits['host']:'')
344 + .(isset($bits['path'])?$bits['path']:'')
345 + .(isset($uri_bits['port'])?':'.$uri_bits['port']:'')
346 + .(isset($bits['query'])?'?'.$bits['query']:'');
347 +
348 + if (strlen($url) > ($before+$after)) :
349 + $url = substr($url, 0, $before).'…'.substr($url, 0 - $after, $after);
350 + endif;
351 +
352 + return $url;
353 +} /* feedwordpress_display_url () */
354 +
355 +function get_syndication_source_property ($original, $id, $local, $remote = NULL) {
356 + $ret = NULL;
357 + if (is_null($original)) :
358 + $original = FeedWordPress::use_aggregator_source_data();
359 + endif;
360 +
361 + if (is_null($remote)) :
362 + $remote = $local . '_original';
363 + endif;
364 +
365 + $vals = ($original ? get_post_custom_values($remote, $id) : array());
366 + if (count($vals) < 1) :
367 + $vals = get_post_custom_values($local, $id);
368 + endif;
369 +
370 + if (count($vals) > 0) :
371 + $ret = $vals[0];
372 + endif;
373 + return $ret;
374 +} /* function get_syndication_source_property () */
375 +
376 +function the_syndication_source_link ($original = NULL, $id = NULL) { echo get_syndication_source_link($original, $id); }
377 +function get_syndication_source_link ($original = NULL, $id = NULL) {
378 + return get_syndication_source_property($original, $id, 'syndication_source_uri');
379 +} /* function get_syndication_source_link() */
380 +
381 +function the_syndication_source ($original = NULL, $id = NULL) { echo get_syndication_source($original, $id); }
382 +function get_syndication_source ($original = NULL, $id = NULL) {
383 + $ret = get_syndication_source_property($original, $id, 'syndication_source');
384 + if (is_null($ret) or strlen(trim($ret)) == 0) : // Fall back to URL of blog
385 + $ret = feedwordpress_display_url(get_syndication_source_link());
386 + endif;
387 + return $ret;
388 +} /* function get_syndication_source() */
389 +
390 +function the_syndication_feed ($original = NULL, $id = NULL) { echo get_syndication_feed($original, $id); }
391 +function get_syndication_feed ($original = NULL, $id = NULL) {
392 + return get_syndication_source_property($original, $id, 'syndication_feed');
393 +} /* function get_syndication_feed() */
394 +
395 +function the_syndication_feed_guid ($original = NULL, $id = NULL) { echo get_syndication_feed_guid($original, $id); }
396 +function get_syndication_feed_guid ($original = NULL, $id = NULL) {
397 + $ret = get_syndication_source_property($original, $id, 'syndication_source_id');
398 + if (is_null($ret) or strlen(trim($ret))==0) : // Fall back to URL of feed
399 + $ret = get_syndication_feed();
400 + endif;
401 + return $ret;
402 +} /* function get_syndication_feed_guid () */
403 +
404 +function get_syndication_feed_id ($id = NULL) { list($u) = get_post_custom_values('syndication_feed_id', $id); return $u; }
405 +function the_syndication_feed_id ($id = NULL) { echo get_syndication_feed_id($id); }
406 +
407 +$feedwordpress_linkcache = array (); // only load links from database once
408 +function get_syndication_feed_object ($id = NULL) {
409 + global $feedwordpress_linkcache;
410 +
411 + $link = NULL;
412 +
413 + $feed_id = get_syndication_feed_id($id);
414 + if (strlen($feed_id) > 0):
415 + if (isset($feedwordpress_linkcache[$feed_id])) :
416 + $link = $feedwordpress_linkcache[$feed_id];
417 + else :
418 + $link = new SyndicatedLink($feed_id);
419 + $feedwordpress_linkcache[$feed_id] = $link;
420 + endif;
421 + endif;
422 + return $link;
423 +}
424 +
425 +function get_feed_meta ($key, $id = NULL) {
426 + $ret = NULL;
427 +
428 + $link = get_syndication_feed_object($id);
429 + if (is_object($link) and isset($link->settings[$key])) :
430 + $ret = $link->settings[$key];
431 + endif;
432 + return $ret;
433 +} /* get_feed_meta() */
434 +
435 +function get_syndication_permalink ($id = NULL) {
436 + list($u) = get_post_custom_values('syndication_permalink', $id); return $u;
437 +}
438 +function the_syndication_permalink ($id = NULL) {
439 + echo get_syndication_permalink($id);
440 +}
441 +
442 +/**
443 + * get_local_permalink: returns a string containing the internal permalink
444 + * for a post (whether syndicated or not) on your local WordPress installation.
445 + * This may be useful if you want permalinks to point to the original source of
446 + * an article for most purposes, but want to retrieve a URL for the local
447 + * representation of the post for one or two limited purposes (for example,
448 + * linking to a comments page on your local aggregator site).
449 + *
450 + * @param $id The numerical ID of the post to get the permalink for. If empty,
451 + * defaults to the current post in a Loop context.
452 + * @return string The URL of the local permalink for this post.
453 + *
454 + * @uses get_permalink()
455 + * @global $feedwordpress_the_original_permalink
456 + *
457 + * @since 2010.0217
458 + */
459 +function get_local_permalink ($id = NULL) {
460 + global $feedwordpress_the_original_permalink;
461 +
462 + // get permalink, and thus activate filter and force global to be filled
463 + // with original URL.
464 + $url = get_permalink($id);
465 + return $feedwordpress_the_original_permalink;
466 +} /* get_local_permalink() */
467 +
468 +/**
469 + * the_original_permalink: displays the contents of get_original_permalink()
470 + *
471 + * @param $id The numerical ID of the post to get the permalink for. If empty,
472 + * defaults to the current post in a Loop context.
473 + *
474 + * @uses get_local_permalinks()
475 + * @uses apply_filters
476 + *
477 + * @since 2010.0217
478 + */
479 +function the_local_permalink ($id = NULL) {
480 + print apply_filters('the_permalink', get_local_permalink($id));
481 +} /* function the_local_permalink() */
482 +
483 +################################################################################
249 484 ## FILTERS: syndication-aware handling of post data for templates and feeds ####
250 485 ################################################################################
251 486
252 -$feedwordpress_the_syndicated_content = null;
253 -$feedwordpress_the_original_permalink = null;
487 +$feedwordpress_the_syndicated_content = NULL;
488 +$feedwordpress_the_original_permalink = NULL;
254 489
255 490 function feedwordpress_preserve_syndicated_content ($text) {
256 491 global $feedwordpress_the_syndicated_content;
257 492
258 - $p = new FeedWordPressLocalPost;
259 - if ( ! $p->is_exposed_to_formatting_filters()) :
493 + $globalExpose = (get_option('feedwordpress_formatting_filters') == 'yes');
494 + $localExpose = get_post_custom_values('_feedwordpress_formatting_filters');
495 + $expose = ($globalExpose or ((count($localExpose) > 0) and $localExpose[0]));
496 +
497 + if ( is_syndicated() and !$expose ) :
260 498 $feedwordpress_the_syndicated_content = $text;
261 499 else :
262 - $feedwordpress_the_syndicated_content = null;
500 + $feedwordpress_the_syndicated_content = NULL;
263 501 endif;
264 502 return $text;
265 503 }
266 504
@@ -265,9 +503,9 @@
265 503 }
266 504
267 505 function feedwordpress_restore_syndicated_content ($text) {
268 506 global $feedwordpress_the_syndicated_content;
269 -
507 +
270 508 if ( !is_null($feedwordpress_the_syndicated_content) ) :
271 509 $text = $feedwordpress_the_syndicated_content;
272 510 endif;
273 511
@@ -278,21 +516,21 @@
278 516 // In a post context....
279 517 if (is_syndicated()) :
280 518 ?>
281 519 <source>
282 - <title><?php print esc_html( get_syndication_source() ); ?></title>
283 - <link rel="alternate" type="text/html" href="<?php print esc_url( get_syndication_source_link() ); ?>" />
284 - <link rel="self" href="<?php print esc_url( get_syndication_feed() ); ?>" />
520 + <title><?php print htmlspecialchars(get_syndication_source()); ?></title>
521 + <link rel="alternate" type="text/html" href="<?php print htmlspecialchars(get_syndication_source_link()); ?>" />
522 + <link rel="self" href="<?php print htmlspecialchars(get_syndication_feed()); ?>" />
285 523 <?php
286 524 $id = get_syndication_feed_guid();
287 - if ( strlen( $id ) > 0 ) :
525 + if (strlen($id) > 0) :
288 526 ?>
289 - <id><?php print esc_xml( $id ); ?></id>
527 + <id><?php print htmlspecialchars($id); ?></id>
290 528 <?php
291 529 endif;
292 530 $updated = get_feed_meta('feed/updated');
293 - if ( strlen( $updated ) > 0 ) : ?>
294 - <updated><?php print esc_xml( $updated ); ?></updated>
531 + if (strlen($updated) > 0) : ?>
532 + <updated><?php print $updated; ?></updated>
295 533 <?php
296 534 endif;
297 535 ?>
298 536 </source>
@@ -306,11 +544,8 @@
306 544 * Syndication => Posts & Links. Saves the old internal permalink in a global
307 545 * variable for later use.
308 546 *
309 547 * @param string $permalink The internal permalink
310 - * @param mixed|null $post Post object
311 - * @param bool $leavename Unused
312 - * @param bool $sample Unused
313 548 * @return string The new permalink. Same as the old if the post is not
314 549 * syndicated, or if FWP is set to use internal permalinks, or if the post
315 550 * was syndicated, but didn't have a proper permalink recorded.
316 551 *
@@ -320,12 +555,12 @@
320 555 * @uses url_to_postid()
321 556 * @global $id
322 557 * @global $feedwordpress_the_original_permalink
323 558 */
324 -function syndication_permalink($permalink = '', $post = null, $leavename = false, $sample = false ) {
559 +function syndication_permalink ($permalink = '', $post = null, $leavename = false) {
325 560 global $id;
326 561 global $feedwordpress_the_original_permalink;
327 -
562 +
328 563 // Save the local permalink in case we need to retrieve it later.
329 564 $feedwordpress_the_original_permalink = $permalink;
330 565
331 566 if (is_object($post) and isset($post->ID) and !empty($post->ID)) :
@@ -373,13 +608,13 @@
373 608 // it here.
374 609 $permalink = esc_html($permalink);
375 610 endif;
376 611 return $permalink;
377 -} /* function syndication_permalink_escaped() */
612 +} /* function syndication_permalink_escaped() */
378 613
379 614 /**
380 615 * syndication_comments_feed_link: Escape XML special characters in comments
381 - * feed links
616 + * feed links
382 617 *
383 618 * @param string $link
384 619 * @return string
385 620 *
@@ -386,9 +621,9 @@
386 621 * @uses is_syndicated()
387 622 * @uses FeedWordPress::munge_permalinks()
388 623 */
389 624 function syndication_comments_feed_link ($link) {
390 - global $feedwordpress_the_original_permalink;
625 + global $feedwordpress_the_original_permalink, $id;
391 626
392 627 if (is_syndicated() and FeedWordPress::munge_permalinks()) :
393 628 // If the source post provided a comment feed URL using
394 629 // wfw:commentRss or atom:link/@rel="replies" we can make use of
@@ -393,11 +628,10 @@
393 628 // If the source post provided a comment feed URL using
394 629 // wfw:commentRss or atom:link/@rel="replies" we can make use of
395 630 // that value here.
396 631 $source = get_syndication_feed_object();
397 - $replacement = null;
398 -
399 - if (is_object($source) && $source->setting('munge comments feed links', 'munge_comments_feed_links', 'yes') != 'no') :
632 + $replacement = NULL;
633 + if ($source->setting('munge comments feed links', 'munge_comments_feed_links', 'yes') != 'no') :
400 634 $commentFeeds = get_post_custom_values('wfw:commentRSS');
401 635 if (
402 636 is_array($commentFeeds)
403 637 and (count($commentFeeds) > 0)
@@ -403,9 +637,9 @@
403 637 and (count($commentFeeds) > 0)
404 638 and (strlen($commentFeeds[0]) > 0)
405 639 ) :
406 640 $replacement = $commentFeeds[0];
407 -
641 +
408 642 // This is a foreign link; WordPress can't vouch for its not
409 643 // having any entities that need to be &-escaped. So we'll do it
410 644 // here.
411 645 $replacement = esc_html($replacement);
@@ -410,9 +644,9 @@
410 644 // here.
411 645 $replacement = esc_html($replacement);
412 646 endif;
413 647 endif;
414 -
648 +
415 649 if (is_null($replacement)) :
416 650 // Q: How can we get the proper feed format, since the
417 651 // format is, stupidly, not passed to the filter?
418 652 // A: Kludge kludge kludge kludge!
@@ -434,25 +668,206 @@
434 668 // generate the comment feed URL, so the
435 669 // comments feed link is never munged by FWP.
436 670 endif;
437 671 endif;
438 -
439 - if ( !is_null($replacement)) : $link = $replacement; endif;
672 +
673 + if (!is_null($replacement)) : $link = $replacement; endif;
440 674 endif;
441 675 return $link;
442 676 } /* function syndication_comments_feed_link() */
443 677
444 - require_once("{$dir}/feedwordpress.pings.functions.php");
678 +################################################################################
679 +## ADMIN MENU ADD-ONS: register Dashboard management pages #####################
680 +################################################################################
445 681
446 - require_once("{$dir}/feedwordpress.wp-admin.post-edit.functions.php");
682 +function fwp_add_pages () {
683 + $menu_cap = FeedWordPress::menu_cap();
684 + $settings_cap = FeedWordPress::menu_cap(/*sub=*/ true);
685 + $syndicationMenu = FeedWordPress::path('syndication.php');
686 +
687 + add_menu_page(
688 + 'Syndicated Sites', 'Syndication',
689 + $menu_cap,
690 + $syndicationMenu,
691 + NULL,
692 + WP_PLUGIN_URL.'/'.FeedWordPress::path('feedwordpress-tiny.png')
693 + );
447 694
695 + do_action('feedwordpress_admin_menu_pre_feeds', $menu_cap, $settings_cap);
696 + add_submenu_page(
697 + $syndicationMenu, 'Syndicated Feeds & Updates', 'Feeds & Updates',
698 + $settings_cap, FeedWordPress::path('feeds-page.php')
699 + );
700 +
701 + do_action('feedwordpress_admin_menu_pre_posts', $menu_cap, $settings_cap);
702 + add_submenu_page(
703 + $syndicationMenu, 'Syndicated Posts & Links', 'Posts & Links',
704 + $settings_cap, FeedWordPress::path('posts-page.php')
705 + );
706 +
707 + do_action('feedwordpress_admin_menu_pre_authors', $menu_cap, $settings_cap);
708 + add_submenu_page(
709 + $syndicationMenu, 'Syndicated Authors', 'Authors',
710 + $settings_cap, FeedWordPress::path('authors-page.php')
711 + );
712 +
713 + do_action('feedwordpress_admin_menu_pre_categories', $menu_cap, $settings_cap);
714 + add_submenu_page(
715 + $syndicationMenu, 'Categories'.FEEDWORDPRESS_AND_TAGS, 'Categories'.FEEDWORDPRESS_AND_TAGS,
716 + $settings_cap, FeedWordPress::path('categories-page.php')
717 + );
718 +
719 + do_action('feedwordpress_admin_menu_pre_performance', $menu_cap, $settings_cap);
720 + add_submenu_page(
721 + $syndicationMenu, 'FeedWordPress Performance', 'Performance',
722 + $settings_cap, FeedWordPress::path('performance-page.php')
723 + );
724 +
725 + do_action('feedwordpress_admin_menu_pre_diagnostics', $menu_cap, $settings_cap);
726 + add_submenu_page(
727 + $syndicationMenu, 'FeedWordPress Diagnostics', 'Diagnostics',
728 + $settings_cap, FeedWordPress::path('diagnostics-page.php')
729 + );
730 +} /* function fwp_add_pages () */
731 +
732 +function fwp_check_debug () {
733 + // This is a horrible fucking kludge that I have to do because the
734 + // admin notice code is triggered before the code that updates the
735 + // setting.
736 + if (isset($_POST['feedwordpress_debug'])) :
737 + $feedwordpress_debug = $_POST['feedwordpress_debug'];
738 + else :
739 + $feedwordpress_debug = get_option('feedwordpress_debug');
740 + endif;
741 + if ($feedwordpress_debug==='yes') :
742 +?>
743 + <div class="error">
744 +<p><strong>FeedWordPress warning.</strong> Debugging mode is <strong>ON</strong>.
745 +While it remains on, FeedWordPress displays many diagnostic error messages,
746 +warnings, and notices that are ordinarily suppressed, and also turns off all
747 +caching of feeds. Use with caution: this setting is absolutely inappropriate
748 +for a production server.</p>
749 + </div>
750 +<?php
751 + endif;
752 +} /* function fwp_check_debug () */
753 +
448 754 ################################################################################
449 -## class FeedWordPressBoilerplateReformatter ###################################
755 +## fwp_hold_pings() and fwp_release_pings(): Outbound XML-RPC ping reform ####
756 +## ... 'coz it's rude to send 500 pings the first time your aggregator runs ####
450 757 ################################################################################
451 758
452 -require_once("{$dir}/feedwordpressboilerplatereformatter.class.php");
453 -require_once("{$dir}/feedwordpressboilerplatereformatter.shortcode.functions.php");
759 +$fwp_held_ping = NULL; // NULL: not holding pings yet
454 760
761 +function fwp_hold_pings () {
762 + global $fwp_held_ping;
763 + if (is_null($fwp_held_ping)):
764 + $fwp_held_ping = 0; // 0: ready to hold pings; none yet received
765 + endif;
766 +}
767 +
768 +function fwp_release_pings () {
769 + global $fwp_held_ping;
770 + if ($fwp_held_ping):
771 + if (function_exists('wp_schedule_single_event')) :
772 + wp_schedule_single_event(time(), 'do_pings');
773 + else :
774 + generic_ping($fwp_held_ping);
775 + endif;
776 + endif;
777 + $fwp_held_ping = NULL; // NULL: not holding pings anymore
778 +}
779 +
780 +function fwp_do_pings () {
781 + if (!is_null($fwp_held_ping) and $post_id) : // Defer until we're done updating
782 + $fwp_held_ping = $post_id;
783 + elseif (function_exists('do_all_pings')) :
784 + do_all_pings();
785 + else :
786 + generic_ping($fwp_held_ping);
787 + endif;
788 +}
789 +
790 +function fwp_publish_post_hook ($post_id) {
791 + global $fwp_held_ping;
792 +
793 + if (!is_null($fwp_held_ping)) : // Syndicated post. Don't mark with _pingme
794 + if ( defined('XMLRPC_REQUEST') )
795 + do_action('xmlrpc_publish_post', $post_id);
796 + if ( defined('APP_REQUEST') )
797 + do_action('app_publish_post', $post_id);
798 +
799 + if ( defined('WP_IMPORTING') )
800 + return;
801 +
802 + // Defer sending out pings until we finish updating
803 + $fwp_held_ping = $post_id;
804 + else :
805 + if (function_exists('_publish_post_hook')) : // WordPress 2.3
806 + _publish_post_hook($post_id);
807 + endif;
808 + endif;
809 +}
810 +
811 + function feedwordpress_add_post_edit_controls () {
812 + add_meta_box('feedwordpress-post-controls', __('Syndication'), 'feedwordpress_post_edit_controls', 'post', 'side', 'high');
813 + } // function FeedWordPress::postEditControls
814 +
815 + function feedwordpress_post_edit_controls () {
816 + global $post;
817 +
818 + $frozen_values = get_post_custom_values('_syndication_freeze_updates', $post->ID);
819 + $frozen_post = (count($frozen_values) > 0 and 'yes' == $frozen_values[0]);
820 +
821 + if (is_syndicated($post->ID)) :
822 + ?>
823 + <p>This is a syndicated post, which originally appeared at
824 + <cite><?php print esc_html(get_syndication_source(NULL, $post->ID)); ?></cite>.
825 + <a href="<?php print esc_html(get_syndication_permalink($post->ID)); ?>">View original post</a>.</p>
826 +
827 + <p><input type="hidden" name="feedwordpress_noncename" id="feedwordpress_noncename" value="<?php print wp_create_nonce(plugin_basename(__FILE__)); ?>" />
828 + <label><input type="checkbox" name="freeze_updates" value="yes" <?php if ($frozen_post) : ?>checked="checked"<?php endif; ?> /> <strong>Manual editing.</strong>
829 + If set, FeedWordPress will not overwrite the changes you make manually
830 + to this post, if the syndicated content is updated on the
831 + feed.</label></p>
832 + <?php
833 + else :
834 + ?>
835 + <p>This post was created locally at this website.</p>
836 + <?php
837 + endif;
838 + } // function feedwordpress_post_edit_controls () */
839 +
840 + function feedwordpress_save_post_edit_controls ( $post_id ) {
841 + global $post;
842 +
843 + if (!isset($_POST['feedwordpress_noncename']) or !wp_verify_nonce($_POST['feedwordpress_noncename'], plugin_basename(__FILE__))) :
844 + return $post_id;
845 + endif;
846 +
847 + // Verify if this is an auto save routine. If it is our form has
848 + // not been submitted, so we don't want to do anything.
849 + if ( defined('DOING_AUTOSAVE') and DOING_AUTOSAVE ) :
850 + return $post_id;
851 + endif;
852 +
853 + // Check permissions
854 + if ( !current_user_can( 'edit_'.$_POST['post_type'], $post_id) ) :
855 + return $post_id;
856 + endif;
857 +
858 + // OK, we're golden. Now let's save some data.
859 + if (isset($_POST['freeze_updates'])) :
860 + update_post_meta($post_id, '_syndication_freeze_updates', $_POST['freeze_updates']);
861 + $ret = $_POST['freeze_updates'];
862 + else :
863 + delete_post_meta($post_id, '_syndication_freeze_updates');
864 + $ret = NULL;
865 + endif;
866 +
867 + return $ret;
868 + } // function feedwordpress_save_edit_controls
869 +
455 870 ################################################################################
456 871 ## class FeedWordPress #########################################################
457 872 ################################################################################
458 873
@@ -489,570 +904,152 @@
489 904 array('q', 'cite'),
490 905 array('script', 'src')
491 906 );
492 907
493 - var $feeds = null;
494 - var $feedurls = null;
495 - var $httpauth = null;
908 + var $feeds = NULL;
496 909
497 - /**
498 - * FeedWordPress::__construct (): Construct FeedWordPress singleton object
499 - * and retrieves a list of feeds for later reference.
500 - *
501 - * @uses FeedWordPressHTTPAuthenticator
502 - */
503 - public function __construct () {
910 + # function FeedWordPress (): Contructor; retrieve a list of feeds
911 + function FeedWordPress () {
504 912 $this->feeds = array ();
505 - $this->feedurls = array();
506 913 $links = FeedWordPress::syndicated_links();
507 -
508 914 if ($links): foreach ($links as $link):
509 - $id = intval($link->link_id);
510 - $url = $link->link_rss;
511 -
512 - // Store for later reference.
513 - $this->feeds[$id] = $id;
514 - if (strlen($url) > 0) :
515 - $this->feedurls[$url] = $id;
516 - endif;
915 + $this->feeds[] = new SyndicatedLink($link);
517 916 endforeach; endif;
917 + } // FeedWordPress::FeedWordPress ()
518 918
519 - // System-related event hooks
520 - add_filter('cron_schedules', array($this, 'cron_schedules'), 10, 1);
521 -
522 - // FeedWordPress-related event hooks
523 - add_filter('feedwordpress_update_complete', array($this, 'process_retirements'), 1000, 1);
524 -
525 - $this->httpauth = new FeedWordPressHTTPAuthenticator;
526 - } /* FeedWordPress::__construct () */
527 -
528 - /**
529 - * FeedWordPress::add_filters() connects FeedWordPress to WordPress lifecycle
530 - * events by setting up action and filter hooks.
531 - *
532 - * @uses get_option()
533 - * @uses add_filter()
534 - * @uses add_action()
535 - * @uses remove_filter()
536 - */
537 - public function add_filters () {
538 - # Syndicated items are generally received in output-ready (X)HTML and
539 - # should not be folded, crumpled, mutilated, or spindled by WordPress
540 - # formatting filters. But we don't want to interfere with filters for
541 - # any locally-authored posts, either.
542 - #
543 - # What WordPress should really have is a way for upstream filters to
544 - # stop downstream filters from running at all. Since it doesn't, and
545 - # since a downstream filter can't access the original copy of the text
546 - # that is being filtered, what we will do here is (1) save a copy of the
547 - # original text upstream, before any other filters run, and then (2)
548 - # retrieve that copy downstream, after all the other filters run, *if*
549 - # this is a syndicated post
550 -
551 - add_filter('the_content', 'feedwordpress_preserve_syndicated_content', -10000);
552 - add_filter('the_content', 'feedwordpress_restore_syndicated_content', 10000);
553 -
554 - add_action('atom_entry', 'feedwordpress_item_feed_data');
555 -
556 - # Filter in original permalinks if the user wants that
557 - add_filter('post_link', 'syndication_permalink', /*priority=*/ 1, /*arguments=*/ 3);
558 - add_filter('post_type_link', 'syndication_permalink', /*priority=*/ 1, /*arguments=*/ 4);
559 -
560 - # When foreign URLs are used for permalinks in feeds or display
561 - # contexts, they need to be escaped properly.
562 - add_filter('the_permalink', 'syndication_permalink_escaped');
563 - add_filter('the_permalink_rss', 'syndication_permalink_escaped');
564 -
565 - add_filter('post_comments_feed_link', 'syndication_comments_feed_link');
566 -
567 - # WTF? By default, wp_insert_link runs incoming link_url and link_rss
568 - # URIs through default filters that include `wp_kses()`. But `wp_kses()`
569 - # just happens to escape any occurrence of & to &amp; -- which just
570 - # happens to fuck up any URI with a & to separate GET parameters.
571 - remove_filter('pre_link_rss', 'wp_filter_kses');
572 - remove_filter('pre_link_url', 'wp_filter_kses');
573 -
574 - # Boilerplate functionality: hook in to title, excerpt, and content to add boilerplate text
575 - $hookOrder = get_option('feedwordpress_boilerplate_hook_order', FEEDWORDPRESS_BOILERPLATE_DEFAULT_HOOK_ORDER);
576 - add_filter(
577 - /*hook=*/ 'the_title',
578 - /*function=*/ 'add_boilerplate_title',
579 - /*priority=*/ $hookOrder,
580 - /*arguments=*/ 2
581 - );
582 - add_filter(
583 - /*hook=*/ 'get_the_excerpt',
584 - /*function=*/ 'add_boilerplate_excerpt',
585 - /*priority=*/ $hookOrder,
586 - /*arguments=*/ 1
587 - );
588 - add_filter(
589 - /*hook=*/ 'the_content',
590 - /*function=*/ 'add_boilerplate_content',
591 - /*priority=*/ $hookOrder,
592 - /*arguments=*/ 1
593 - );
594 - add_filter(
595 - /*hook=*/ 'the_content_rss',
596 - /*function=*/ 'add_boilerplate_content',
597 - /*priority=*/ $hookOrder,
598 - /*arguments=*/ 1
599 - );
600 -
601 - # Admin menu
602 - add_action('admin_init', array($this, 'admin_init'));
603 - add_action('admin_menu', array($this, 'add_pages'));
604 - add_action('admin_notices', array($this, 'check_debug'));
605 -
606 - add_action('admin_menu', 'feedwordpress_add_post_edit_controls');
607 - add_action('save_post', 'feedwordpress_save_post_edit_controls');
608 -
609 - add_action('admin_footer', array($this, 'admin_footer'));
610 -
611 - add_action('syndicated_feed_error', array('FeedWordPressDiagnostic', 'feed_error'), 100, 3);
612 -
613 - add_action('wp_footer', 'debug_out_feedwordpress_footer', -100);
614 - add_action('admin_footer', 'debug_out_feedwordpress_footer', -100);
615 -
616 - # Cron-less auto-update. Hooray!
617 - $autoUpdateHook = $this->automatic_update_hook();
618 - if ( !is_null($autoUpdateHook)) :
619 - add_action($autoUpdateHook, array($this, 'auto_update'));
620 - endif;
621 -
622 - add_action('init', array($this, 'init'));
623 - add_action('wp_loaded', array($this, 'wp_loaded'));
624 -
625 - add_action('shutdown', array($this, 'email_diagnostic_log'));
626 - add_action('shutdown', array($this, 'feedwordpress_cleanup'));
627 - add_action('wp_dashboard_setup', array($this, 'dashboard_setup'));
628 -
629 - # Default sanitizers
630 - add_filter('syndicated_item_content', array('SyndicatedPost', 'resolve_relative_uris'), 0, 2);
631 - add_filter('syndicated_item_content', array('SyndicatedPost', 'sanitize_content'), 0, 2);
632 -
633 - add_action('plugins_loaded', array($this, 'admin_api'));
634 - add_action('all_admin_notices', array($this, 'all_admin_notices'));
635 -
636 - // Use the cache settings that we want, from a static method
637 - add_filter('wp_feed_cache_transient_lifetime', array(get_class($this), 'cache_lifetime'));
638 -
639 - } /* FeedWordPress::add_filters () */
640 -
641 - ################################################################################
642 - ## ADMIN MENU ADD-ONS: register Dashboard management pages #####################
643 - ################################################################################
644 -
645 - /**
646 - * FeedWordPress::add_pages(): set up WordPress admin interface pages thru
647 - * hooking in Syndication menu and submenus
648 - *
649 - * @uses FeedWordPress::menu_cap()
650 - * @uses FeedWordPress::path()
651 - * @uses add_menu_page()
652 - * @uses add_submenu_page()
653 - * @uses do_action()
654 - * @uses add_filter()
655 - */
656 - public function add_pages()
657 - {
658 - $menu_cap = FeedWordPress::menu_cap();
659 - $settings_cap = FeedWordPress::menu_cap( /*sub=*/ true );
660 - $syndicationMenu = FeedWordPress::path( 'syndication.php' );
661 -
662 - add_menu_page(
663 - /* page_title */ 'Syndicated Sites',
664 - /* menu_title */ 'Syndication',
665 - /* capability */ $menu_cap,
666 - /* menu_slug */ $syndicationMenu,
667 - /* function */ NULL,
668 - /* icon_url */ $this->plugin_dir_url( /* 'assets/images/feedwordpress-tiny.png' */ 'assets/images/icon.svg' )
669 - /* position */
670 - );
671 -
672 - do_action( 'feedwordpress_admin_menu_pre_feeds', $menu_cap, $settings_cap );
673 - add_submenu_page(
674 - /* parent_slug */ $syndicationMenu,
675 - /* page_title */ 'Syndicated Sites',
676 - /* menu_title */ 'Syndicated Sites',
677 - /* capability */ $settings_cap,
678 - /* menu_slug */ $syndicationMenu,
679 - /* function */
680 - );
681 -
682 - do_action('feedwordpress_admin_menu_pre_feeds', $menu_cap, $settings_cap);
683 - add_submenu_page(
684 - $syndicationMenu, 'Syndicated Feeds & Updates', 'Feeds & Updates',
685 - $settings_cap, FeedWordPress::path('feeds-page.php')
686 - );
687 -
688 - do_action('feedwordpress_admin_menu_pre_posts', $menu_cap, $settings_cap);
689 - add_submenu_page(
690 - $syndicationMenu, 'Syndicated Posts & Links', 'Posts & Links',
691 - $settings_cap, FeedWordPress::path('posts-page.php')
692 - );
693 -
694 - do_action('feedwordpress_admin_menu_pre_authors', $menu_cap, $settings_cap);
695 - add_submenu_page(
696 - $syndicationMenu, 'Syndicated Authors', 'Authors',
697 - $settings_cap, FeedWordPress::path('authors-page.php')
698 - );
699 -
700 - do_action('feedwordpress_admin_menu_pre_categories', $menu_cap, $settings_cap);
701 - add_submenu_page(
702 - $syndicationMenu, 'Categories & Tags', 'Categories & Tags',
703 - $settings_cap, FeedWordPress::path('categories-page.php')
704 - );
705 -
706 - do_action('feedwordpress_admin_menu_pre_performance', $menu_cap, $settings_cap);
707 - add_submenu_page(
708 - $syndicationMenu, 'FeedWordPress Performance', 'Performance',
709 - $settings_cap, FeedWordPress::path('performance-page.php')
710 - );
711 -
712 - do_action('feedwordpress_admin_menu_pre_diagnostics', $menu_cap, $settings_cap);
713 - add_submenu_page(
714 - $syndicationMenu, 'FeedWordPress Diagnostics', 'Diagnostics',
715 - $settings_cap, FeedWordPress::path('diagnostics-page.php')
716 - );
717 -
718 - add_filter('page_row_actions', array($this, 'row_actions'), 10, 2);
719 - add_filter('post_row_actions', array($this, 'row_actions'), 10, 2);
720 - } /* function FeedWordPress::add_pages () */
721 -
722 - public function check_debug() {
723 - // This is a horrible fucking kludge that I have to do because the
724 - // admin notice code is triggered before the code that updates the
725 - // setting.
726 - $feedwordpress_debug = FeedWordPress::param( 'feedwordpress_debug', get_option( 'feedwordpress_debug' ) );
727 -
728 - FeedWordPressSettingsUI::get_template_part( 'notice-debug-mode', $feedwordpress_debug, 'html' );
729 - } /* function FeedWordPress::check_debug () */
730 -
731 - /**
732 - * FeedWordPress::subscribed (): Check whether a feed is currently in the
733 - * subscription list for FeedWordPress.
734 - *
735 - * @param mixed $id Numeric ID of a WordPress link object or URL of a feed
736 - * @return bool TRUE if currently subscribed; FALSE otherwise.
737 - */
738 - public function subscribed ($id) {
739 - return (isset($this->feedurls[$id]) or isset($this->feeds[$id]));
740 - } /* FeedWordPress::subscribed () */
741 -
742 - /**
743 - * FeedWordPress::subscription (): Get the SyndicatedLink object for a
744 - * given URL or numeric ID, if we have either an active subscription to
745 - * it; or a de-activated subscription.
746 - *
747 - * @param mixed $which Numeric ID for a WordPress link object or string URL for a feed
748 - * @return mixed SyndicatedLink object if subscription is found; null if not
749 - */
750 - public function subscription ($which) {
751 - $sub = null;
752 -
753 - if (is_string($which) and isset($this->feedurls[$which])) :
754 - $which = $this->feedurls[$which];
755 - endif;
756 -
757 - if (isset($this->feeds[$which])) :
758 - $sub = $this->feeds[$which];
759 - endif;
760 -
761 - // If it's not in the in-memory cache already, try to load it from DB.
762 - // This is necessary to fill requests for subscriptions that we don't
763 - // cache in memory, e.g. for deactivated feeds.
764 - if (is_null($sub)) :
765 - $sub = get_bookmark($which);
766 - endif;
767 -
768 - // Load 'er up if you haven't already.
769 - if ( !is_null($sub) and !($sub InstanceOf SyndicatedLink)) :
770 - $link = new SyndicatedLink($sub);
771 - $this->feeds[$which] = $link;
772 - $sub = $link;
773 - endif;
774 -
775 - return $sub;
776 - } /* FeedWordPress::subscription () */
777 -
778 - /** function update (): polls for updates on one or more Contributor feeds
779 -
780 - @desc
919 + # function update (): polls for updates on one or more Contributor feeds
920 + #
781 921 # Arguments:
782 -
783 - - $uri (string): Either the URI of the feed to poll, the URI of the
784 - (human-readable) website whose feed you want to poll, or null.
785 -
786 - If $uri is null, then FeedWordPress will poll any feeds that are
787 - ready for polling. It will not poll feeds that are marked as
788 - "Invisible" Links (signifying that the subscription has been
789 - de-activated), or feeds that are not yet stale according to their
790 - TTL setting (which is either set in the feed, or else set
791 - randomly within a window of 30 minutes - 2 hours).
792 -
922 + # ----------
923 + # * $uri (string): either the URI of the feed to poll, the URI of the
924 + # (human-readable) website whose feed you want to poll, or NULL.
925 + #
926 + # If $uri is NULL, then FeedWordPress will poll any feeds that are
927 + # ready for polling. It will not poll feeds that are marked as
928 + # "Invisible" Links (signifying that the subscription has been
929 + # de-activated), or feeds that are not yet stale according to their
930 + # TTL setting (which is either set in the feed, or else set
931 + # randomly within a window of 30 minutes - 2 hours).
932 + #
793 933 # Returns:
794 -
795 - - Normally returns an associative array, with 'new' => the number
796 - of new posts added during the update, and 'updated' => the number
797 - of old posts that were updated during the update. If both numbers
798 - are zero, there was no change since the last poll on that URI.
799 -
800 - - Returns null if URI it was passed was not a URI that this
801 - installation of FeedWordPress syndicates.
802 -
934 + # --------
935 + # * Normally returns an associative array, with 'new' => the number
936 + # of new posts added during the update, and 'updated' => the number
937 + # of old posts that were updated during the update. If both numbers
938 + # are zero, there was no change since the last poll on that URI.
939 + #
940 + # * Returns NULL if URI it was passed was not a URI that this
941 + # installation of FeedWordPress syndicates.
942 + #
803 943 # Effects:
944 + # --------
945 + # * One or more feeds are polled for updates
946 + #
947 + # * If the feed Link does not have a hardcoded name set, its Link
948 + # Name is synchronized with the feed's title element
949 + #
950 + # * If the feed Link does not have a hardcoded URI set, its Link URI
951 + # is synchronized with the feed's human-readable link element
952 + #
953 + # * If the feed Link does not have a hardcoded description set, its
954 + # Link Description is synchronized with the feed's description,
955 + # tagline, or subtitle element.
956 + #
957 + # * The time of polling is recorded in the feed's settings, and the
958 + # TTL (time until the feed is next available for polling) is set
959 + # either from the feed (if it is supplied in the ttl or syndication
960 + # module elements) or else from a randomly-generated time window
961 + # (between 30 minutes and 2 hours).
962 + #
963 + # * New posts from the polled feed are added to the WordPress store.
964 + #
965 + # * Updates to existing posts since the last poll are mirrored in the
966 + # WordPress store.
967 + #
968 + function update ($uri = null, $crash_ts = null) {
969 + global $wpdb;
804 970
805 - - One or more feeds are polled for updates
806 -
807 - - If the feed Link does not have a hardcoded name set, its Link
808 - Name is synchronized with the feed's title element
809 -
810 - - If the feed Link does not have a hardcoded URI set, its Link URI
811 - is synchronized with the feed's human-readable link element
812 -
813 - - If the feed Link does not have a hardcoded description set, its
814 - Link Description is synchronized with the feed's description,
815 - tagline, or subtitle element.
816 -
817 - - The time of polling is recorded in the feed's settings, and the
818 - TTL (time until the feed is next available for polling) is set
819 - either from the feed (if it is supplied in the ttl or syndication
820 - module elements) or else from a randomly-generated time window
821 - (between 30 minutes and 2 hours).
822 -
823 - - New posts from the polled feed are added to the WordPress store.
824 -
825 - - Updates to existing posts since the last poll are mirrored in the
826 - WordPress store.
827 -
828 - @param string|null $uri Either the URI of the feed to poll, the URI of the (human-readable) website whose feed you want to poll, or null.
829 - @param mixed|null $crash_ts Unknown purpose.
830 - @return array|null Associative array, with 'new' => # of new posts added during update, and 'updated' => # of old posts that were updated. If both are zero, there was no change since çast update.
831 - */
832 - public function update( $uri = null, $crash_ts = null ) {
833 - if ( FeedWordPress::needs_upgrade() ) : // Will make duplicate posts if we don't hold off
834 - return null;
971 + if (FeedWordPress::needs_upgrade()) : // Will make duplicate posts if we don't hold off
972 + return NULL;
835 973 endif;
836 -
837 - if ( ! is_null( $uri ) and $uri != '*' ) :
838 - $uri = trim( $uri );
974 +
975 + if (!is_null($uri) and $uri != '*') :
976 + $uri = trim($uri);
839 977 else : // Update all
840 - if ( $this->update_hooked ) :
841 - $diag = $this->update_hooked;
842 - else :
843 - $diag = 'Initiating a MANUAL check-in on the update schedule at ' . date( 'r', time() );
844 - endif;
845 - $this->diagnostic( 'update_schedule:check', $diag );
846 -
847 - update_option( 'feedwordpress_last_update_all', time() );
978 + update_option('feedwordpress_last_update_all', time());
848 979 endif;
849 980
850 - do_action( 'feedwordpress_update', $uri );
981 + do_action('feedwordpress_update', $uri);
851 982
852 - if ( is_null( $crash_ts ) ) :
983 + if (is_null($crash_ts)) :
853 984 $crash_ts = $this->crash_ts();
854 985 endif;
855 986
856 987 // Randomize order for load balancing purposes
857 - $feed_set = array_keys( $this->feeds );
858 - shuffle( $feed_set );
988 + $feed_set = $this->feeds;
989 + shuffle($feed_set);
859 990
860 - $updateWindow = (int) get_option( 'feedwordpress_update_window', DEFAULT_UPDATE_PERIOD ) * 60 /* sec/min */;
861 - $interval = (int) get_option( 'feedwordpress_freshness', FEEDWORDPRESS_FRESHNESS_INTERVAL );
862 - $portion = max(
863 - (int) ceil( count( $feed_set ) / ( $updateWindow / $interval ) ),
864 - 10
865 - );
991 + $feed_set = apply_filters('feedwordpress_update_feeds', $feed_set, $uri);
866 992
867 - $max_polls = apply_filters(
868 - 'feedwordpress_polls_per_update',
869 - get_option(
870 - 'feedwordpress_polls_per_update', $portion
871 - ),
872 - $uri
873 - );
874 -
875 - $feed_set = apply_filters( 'feedwordpress_update_feeds', $feed_set, $uri );
876 -
877 993 // Loop through and check for new posts
878 - $delta = null;
879 - $remaining = $max_polls;
880 - foreach ( $feed_set as $feed_id) :
881 -
882 - $feed = $this->subscription( $feed_id );
883 - // Try to catch a very unusual condition where the $feed comes as NULL (gwyneth 20230919)
884 - if ( ! empty( $feed ) ) :
885 - $this->diagnostic( 'update_schedule', "Feed " . $feed_id . " returned an empty feed" );
886 - endif;
887 -
888 - // Has this process overstayed its welcome?
889 - if (
890 - // Over time limit?
891 - ( ! is_null( $crash_ts ) and ( time() > $crash_ts ) )
892 -
893 - // Over feed count?
894 - or ( 0 == $remaining )
895 - ) :
994 + $delta = NULL;
995 + foreach ($feed_set as $feed) :
996 + if (!is_null($crash_ts) and (time() > $crash_ts)) : // Check whether we've exceeded the time limit
896 997 break;
897 998 endif;
898 999
899 - $pinged_that = ( is_null( $uri ) or ( $uri == '*' ) or in_array( $uri, array( $feed->uri(), $feed->homepage() ) ) );
1000 + $pinged_that = (is_null($uri) or ($uri=='*') or in_array($uri, array($feed->uri(), $feed->homepage())));
900 1001
901 - if ( ! is_null( $uri ) ) : // A site-specific ping always updates
1002 + if (!is_null($uri)) : // A site-specific ping always updates
902 1003 $timely = true;
903 1004 else :
904 1005 $timely = $feed->stale();
905 1006 endif;
906 1007
907 - // If at least one feed was hit for updating...
908 - if ( $pinged_that and is_null( $delta ) ) :
909 - // ... don't return error condition
910 - $delta = array( 'new' => 0, 'updated' => 0, 'stored' => 0 );
1008 + if ($pinged_that and is_null($delta)) : // If at least one feed was hit for updating...
1009 + $delta = array('new' => 0, 'updated' => 0); // ... don't return error condition
911 1010 endif;
912 1011
913 - if ( $pinged_that and $timely ) :
914 - $remaining = $remaining - 1;
915 -
916 - do_action( 'feedwordpress_check_feed', $feed->settings );
1012 + if ($pinged_that and $timely) :
1013 + do_action('feedwordpress_check_feed', $feed->settings);
917 1014 $start_ts = time();
918 - $added = $feed->poll( $crash_ts );
919 - do_action( 'feedwordpress_check_feed_complete', $feed->settings, $added, time() - $start_ts );
1015 + $added = $feed->poll($crash_ts);
1016 + do_action('feedwordpress_check_feed_complete', $feed->settings, $added, time() - $start_ts);
920 1017
921 - if ( is_array( $added ) ) : // Success
922 - foreach ( $added as $key => $count ) :
923 - $delta[ $key ] += $added[ $key ];
924 - endforeach;
1018 + if (is_array($added)) : // Success
1019 + if (isset($added['new'])) : $delta['new'] += $added['new']; endif;
1020 + if (isset($added['updated'])) : $delta['updated'] += $added['updated']; endif;
925 1021 endif;
926 1022 endif;
927 1023 endforeach;
928 1024
929 - do_action( 'feedwordpress_update_complete', $delta );
1025 + do_action('feedwordpress_update_complete', $delta);
1026 +
930 1027 return $delta;
931 - } /* FeedWordPress::update () */
1028 + }
932 1029
933 - /**
934 - * Checks if we're over the update time limit.
935 - *
936 - * @todo is returning null advisable? (gwyneth 20230916)
937 - *
938 - * @param int|null $default Default value, called when the corresponding FWP option is not set.
939 - *
940 - * @return int|null
941 - */
942 - public function crash_ts( $default = null ) {
943 - $crash_dt = (int) get_option( 'feedwordpress_update_time_limit', 0 );
944 - if ( $crash_dt > 0 ) :
1030 + function crash_ts ($default = NULL) {
1031 + $crash_dt = (int) get_option('feedwordpress_update_time_limit', 0);
1032 + if ($crash_dt > 0) :
945 1033 $crash_ts = time() + $crash_dt;
946 1034 else :
947 1035 $crash_ts = $default;
948 1036 endif;
949 1037 return $crash_ts;
950 - } /* FeedWordPress::crash_ts () */
951 -
952 -
953 - /**
954 - * Checks if we have a secret key set in the options; if not, generate one.
955 - *
956 - * @return string Secret key, either from options or auto-generated.
957 - *
958 - * @todo Only 6 characters? That is rather easy to guess... Also, uniqid() can return 13 or 23
959 - * characters, what's the point of using MD5 in this case? (gwyneth 20230916)
960 - */
961 - public function secret_key() {
962 - $secret = get_option( 'feedwordpress_secret_key', false );
963 - if ( ! $secret) : // Generate random key.
964 - $secret = substr( md5( uniqid( microtime() ) ), 0, 6 );
965 - update_option( 'feedwordpress_secret_key', $secret );
966 - endif;
967 - return $secret;
968 - } /* FeedWordPress::secret_key () */
969 -
970 - /**
971 - * Returns true if we have set a secret FWP key.
972 - *
973 - * @return bool True if we have a secret key, false otherwise
974 - *
975 - * @uses MyPHP::request()
976 - */
977 - public function has_secret() {
978 - return ( MyPHP::request( 'feedwordpress_key' ) == $this->secret_key() );
979 - } /* FeedWordPress::has_secret () */
980 -
981 - var $update_hooked = null;
982 -
983 - /**
984 - * Activates the hook for automatic plugin updates, if requested.
985 - *
986 - * @param Array $params Parameters to send to the hook.
987 - *
988 - * @return string Represents the hook's name. There is a slight chance that this is null, though. (gwyneth 20230916)
989 - *
990 - * @uses wp_parse_args()
991 - * @uses MyPHP::request()
992 - */
993 - public function automatic_update_hook( $params = array() ) {
994 - $params = wp_parse_args( $params, array( // Defaults
995 - 'setting only' => false,
996 - ));
997 - $hook = get_option( 'feedwordpress_automatic_updates', null );
998 - $method = 'FeedWordPress option';
999 -
1000 - // Allow for forced behavior in testing.
1001 - if (
1002 - ! $params['setting only']
1003 - and $this->has_secret()
1004 - and MyPHP::request( 'automatic_update' )
1005 - ) :
1006 - $hook = MyPHP::request( 'automatic_update') ;
1007 - $method = 'URL parameter';
1008 - endif;
1009 -
1010 - $exact = $hook; // Before munging
1011 -
1012 - if ( !! $hook) :
1013 - if ( $hook == 'init' or $hook == 'wp_loaded' ) : // Re-map init to wp_loaded
1014 - $hook = ( $params['setting only'] ? 'init' : 'wp_loaded' );
1015 -
1016 - // Constrain possible values. If it's not an init or wp_loaded, it's a shutdown
1017 - else :
1018 - $hook = 'shutdown';
1019 - endif;
1020 - endif;
1021 -
1022 - if ( $hook ) :
1023 - $this->update_hooked = "Initiating an AUTOMATIC CHECK FOR UPDATES ON PAGE LOAD " . $hook . " due to " . $method . " = " . trim( $this->val( $exact ) );
1024 - endif;
1025 -
1026 - return $hook;
1027 - } /* FeedWordPress::automatic_update_hook () */
1028 -
1029 - public function last_update_all () {
1030 - $last = get_option('feedwordpress_last_update_all');
1031 - if ( $this->has_secret() and FeedWordPress::param('automatic_update') ) :
1032 - $last = 1; // A long, long time ago.
1033 - elseif ( $this->has_secret() and FeedWordPress::param('last_update_all') ) :
1034 - $last = FeedWordPress::param( 'last_update_all' );
1035 - endif;
1036 - return $last;
1037 - } /* FeedWordPress::last_update_all () */
1038 -
1039 - public function force_update_all () {
1040 - return ($this->has_secret() and FeedWordPress::param( 'force_update_feeds' ));
1041 - } /* FeedWordPress::force_update_all () */
1042 -
1043 - public function stale () {
1044 - if ( !is_null($this->automatic_update_hook())) :
1038 + }
1039 +
1040 + function stale () {
1041 + if (get_option('feedwordpress_automatic_updates')) :
1045 1042 // Do our best to avoid possible simultaneous
1046 1043 // updates by getting up-to-the-minute settings.
1047 -
1048 - $last = $this->last_update_all();
1049 -
1044 +
1045 + $last = get_option('feedwordpress_last_update_all');
1046 +
1050 1047 // If we haven't updated all yet, give it a time window
1051 1048 if (false === $last) :
1052 1049 $ret = false;
1053 1050 update_option('feedwordpress_last_update_all', time());
1054 -
1051 +
1055 1052 // Otherwise, check against freshness interval
1056 1053 elseif (is_numeric($last)) : // Expect a timestamp
1057 1054 $freshness = get_option('feedwordpress_freshness');
1058 1055 if (false === $freshness) : // Use default
@@ -1057,13 +1054,13 @@
1057 1054 $freshness = get_option('feedwordpress_freshness');
1058 1055 if (false === $freshness) : // Use default
1059 1056 $freshness = FEEDWORDPRESS_FRESHNESS_INTERVAL;
1060 1057 endif;
1061 - $ret = ( (time() - $last) > $freshness );
1058 + $ret = ( (time() - $last) > $freshness);
1062 1059
1063 - // This should never happen.
1060 + // This should never happen.
1064 1061 else :
1065 - FeedWordPressDiagnostic::critical_bug('FeedWordPress::stale::last', $last, __LINE__, __FILE__);
1062 + FeedWordPress::critical_bug('FeedWordPress::stale::last', $last, __LINE__);
1066 1063 endif;
1067 1064
1068 1065 else :
1069 1066 $ret = false;
@@ -1068,494 +1065,27 @@
1068 1065 else :
1069 1066 $ret = false;
1070 1067 endif;
1071 1068 return $ret;
1072 - } /* FeedWordPress::stale() */
1069 + } // FeedWordPress::stale()
1073 1070
1074 - static function admin_init () {
1075 - // WordPress 3.5+ compat: the WP devs are in the midst of removing Links from the WordPress core. Eventually we'll have to deal
1076 - // with the possible disappearance of the wp_links table as a whole; but in the meantime, we just need to turn on the interface
1077 - // element to avoid problems with user capabilities that presume the presence of the Links Manager in the admin UI.
1078 - global $post_type;
1079 -
1080 - if ( !intval(get_option('link_manager_enabled', false))) :
1081 - update_option('link_manager_enabled', true);
1082 - endif;
1083 -
1084 - if (defined('FEEDWORDPRESS_PREPARE_TO_ZAP') and FEEDWORDPRESS_PREPARE_TO_ZAP) :
1085 - $post_id = FEEDWORDPRESS_PREPARE_TO_ZAP;
1086 - $sendback = wp_get_referer();
1087 - if (
1088 - ! $sendback
1089 - or strpos( $sendback, 'post.php' ) !== false
1090 - or strpos( $sendback, 'post-new.php' ) !== false
1091 - ) :
1092 - if ( 'attachment' == $post_type ) : // where does this come from?? I put it as a global...(gwyneth 20230916)
1093 - $sendback = admin_url( 'upload.php' );
1094 - else :
1095 - $sendback = admin_url( 'edit.php' );
1096 - $sendback .= ( ! empty( $post_type ) ) ? '?post_type=' . $post_type : '';
1097 - endif;
1098 - else :
1099 - $sendback = esc_url( remove_query_arg( array('trashed', 'untrashed', 'deleted', 'zapped', 'unzapped', 'ids'), $sendback ) );
1100 - endif;
1101 -
1102 - // Make sure we have a post corresponding to this ID.
1103 - $post = $post_type = $post_type_object = null; // whatever $post_type_object might be, it's not being used! (gwyneth 20230920)
1104 - if ( $post_id ) :
1105 - $post = get_post( $post_id );
1106 - endif;
1107 -
1108 - if ( $post ) :
1109 - $post_type = $post->post_type;
1110 - endif;
1111 - $p = get_post( $post_id );
1112 -
1113 - if ( ! $post ) :
1114 - wp_die( esc_html__( 'The item you are trying to zap no longer exists.' ) );
1115 - endif;
1116 -
1117 - if ( ! current_user_can( 'delete_post', $post_id ) ) :
1118 - wp_die( esc_html__( 'You are not allowed to zap this item.' ) );
1119 - endif;
1120 -
1121 - if ( $user_id = wp_check_post_lock( $post_id ) ) :
1122 - if ( is_numeric( $user_id ) and function_exists( 'get_userdata' ) ) :
1123 - $user = get_userdata( (int) $user_id );
1124 - wp_die( esc_html( sprintf( __( 'You cannot retire this item. %s is currently editing.' ), $user->display_name ) ) );
1125 - else :
1126 - wp_die( esc_html__( 'You cannot retire this item. Someone is currently editing.' ) );
1127 - endif;
1128 - endif;
1129 -
1130 - if (FeedWordPress::param( 'fwp_post_delete' ) == 'zap') :
1131 - FeedWordPress::diagnostic('syndicated_posts', 'Zapping existing post # '.$p->ID.' "'.$p->post_title.'" due to user request.');
1132 -
1133 - $old_status = $post->post_status;
1134 -
1135 - set_post_field('post_status', 'fwpzapped', $post_id);
1136 - wp_transition_post_status('fwpzapped', $old_status, $post);
1137 -
1138 - # Set up the post to have its content blanked on
1139 - # next update if you do not undo the zapping.
1140 - add_post_meta($post_id, '_feedwordpress_zapped_blank_me', 1, /*unique=*/ true);
1141 - add_post_meta($post_id, '_feedwordpress_zapped_blank_old_status', $old_status, /*unique=*/ true);
1142 -
1143 - wp_redirect( esc_url_raw( add_query_arg( array('zapped' => 1, 'ids' => $post_id), $sendback ) ) );
1144 -
1145 - else :
1146 - $old_status = get_post_meta($post_id, '_feedwordpress_zapped_blank_old_status', /*single=*/ true);
1147 -
1148 - set_post_field('post_status', $old_status, $post_id);
1149 - wp_transition_post_status($old_status, 'fwpzapped', $post);
1150 -
1151 - # O.K., make sure this post does not get blanked
1152 - delete_post_meta($post_id, '_feedwordpress_zapped_blank_me');
1153 - delete_post_meta($post_id, '_feedwordpress_zapped_blank_old_status');
1154 -
1155 - wp_redirect( esc_url_raw( add_query_arg( array('unzapped' => 1, 'ids' => $post_id), $sendback ) ) );
1156 -
1157 - endif;
1158 -
1159 - // Intercept, don't pass on.
1160 - exit;
1161 - endif;
1162 - } /* FeedWordPress::admin_init() */
1163 -
1164 - public function admin_api () {
1165 - // This sucks, but WordPress doesn't give us any other way to
1166 - // easily invoke a permanent-delete from a plugged in post
1167 - // actions link. So we create a magic parameter, and when this
1168 - // magic parameter is activated, the WordPress trashcan is
1169 - // temporarily de-activated.
1170 -
1171 - if (FeedWordPress::param( 'fwp_post_delete' ) == 'nuke') :
1172 - // Get post ID #
1173 - $post_id = FeedWordPress::param( 'post' );
1174 - if ( ! $post_id) :
1175 - $post_id = FeedWordPress::param( 'post_ID' );
1176 - endif;
1177 -
1178 - // Make sure we've got the right nonce and all that.
1179 - check_admin_referer('delete-post_' . $post_id);
1180 -
1181 - // If so, disable the trashcan.
1182 - define('EMPTY_TRASH_DAYS', 0);
1183 - elseif ( FeedWordPress::param( 'fwp_post_delete' ) == 'zap' || FeedWordPress::param( 'fwp_post_delete' ) == 'unzap' ) :
1184 - // Get post ID #
1185 - $post_id = FeedWordPress::param( 'post' );
1186 - if ( ! $post_id) :
1187 - $post_id = FeedWordPress::param( 'post_ID' );
1188 - endif;
1189 -
1190 - // Make sure we've got the right nonce and all that
1191 - check_admin_referer('delete-post_' . $post_id);
1192 -
1193 - // If so, get ready to intercept the call a little
1194 - // further down the line.
1195 - define('FEEDWORDPRESS_PREPARE_TO_ZAP', $post_id);
1196 -
1197 - endif;
1198 -
1199 - } /* FeedWordPress::admin_api () */
1200 -
1201 - public function all_admin_notices () {
1202 - if (FeedWordPress::param( 'zapped' )) :
1203 - $n = intval( FeedWordPress::param( 'zapped' ) );
1204 -?>
1205 -<div id="message" class="updated"><p><?php print esc_html( $n ); ?> syndicated item<?php print esc_html( $n != 1 ? 's' : '' ); ?> zapped. <strong>These items will not be re-syndicated.</strong> If this was a mistake, you must <strong>immediately</strong> Un-Zap them in the Zapped items section to avoid losing the data.</p></div>
1206 -<?php
1207 - endif;
1208 - if ( FeedWordPress::param( 'unzapped' ) ) :
1209 - $n = intval( FeedWordPress::param( 'unzapped' ) );
1210 -?>
1211 -<div id="message" class="updated"><p><?php print esc_html( $n ); ?> syndicated item<?php print esc_html( $n != 1 ? 's' : '' ) ?> un-zapped and restored to normal.</p></div>
1212 -<?php
1213 - endif;
1214 - } /* FeedWordPress::all_admin_notices () */
1215 -
1216 - public function process_retirements ($delta) {
1217 - update_option('feedwordpress_process_zaps', 1);
1218 -
1219 - return $delta;
1220 - }
1221 -
1222 - public function feedwordpress_cleanup () {
1223 - if (get_option('feedwordpress_process_zaps', null)) :
1224 - $q = new WP_Query(array(
1225 - 'fields' => '_synfrom',
1226 - 'post_status' => 'fwpzapped',
1227 - 'ignore_sticky_posts' => true,
1228 - 'meta_key' => '_feedwordpress_zapped_blank_me',
1229 - 'meta_value' => 1,
1230 - ));
1231 -
1232 - if ($q->have_posts()) :
1233 - foreach ($q->posts as $p) :
1234 -
1235 - $post_id = $p->ID;
1236 - $revisions = wp_get_post_revisions($post_id, array("check_enabled" => false));
1237 -
1238 - # Now nuke the content of the post & its revisions
1239 - set_post_field('post_content', '', $post_id);
1240 - set_post_field('post_excerpt', '', $post_id);
1241 -
1242 - foreach ($revisions as $rev) :
1243 - set_post_field('post_content', '', $rev->ID);
1244 - set_post_field('post_excerpt', '', $rev->ID);
1245 - endforeach;
1246 -
1247 - # Un-tag it for blanking.
1248 - delete_post_meta($p->ID, '_feedwordpress_zapped_blank_me');
1249 -
1250 - # Don't remove old_status indicator. A later
1251 - # update from the feed may cause us to once
1252 - # again have some content so we can un-zap.
1253 -
1254 - endforeach;
1255 - endif;
1256 -
1257 - $q = new WP_Query(array(
1258 - 'fields' => '_synfrom',
1259 - 'post_status' => 'fwpzapped',
1260 - 'ignore_sticky_posts' => true,
1261 - 'meta_key' => '_feedwordpress_zapped_blank_me',
1262 - 'meta_value' => 2,
1263 - ));
1264 -
1265 - if ($q->have_posts()) :
1266 - foreach ($q->posts as $p) :
1267 - update_post_meta($p->ID, '_feedwordpress_zapped_blank_me', 1);
1268 - endforeach;
1269 - endif;
1270 -
1271 - update_option('feedwordpress_process_zaps', 0);
1272 - endif;
1273 - } /* FeedWordPress::feedwordpress_cleanup () */
1274 -
1275 - public function init () {
1276 -
1277 - // If this is a FeedWordPress admin page, queue up scripts for AJAX
1278 - // functions that FWP uses. If it is a display page or a non-FWP admin
1279 - // page, don't.
1280 - wp_register_style('feedwordpress-elements', $this->plugin_dir_url( 'assets/css/feedwordpress-elements.css') );
1281 - if (FeedWordPressSettingsUI::is_admin()) :
1282 - // For JavaScript that needs to be generated dynamically
1283 - add_action('admin_print_scripts', array('FeedWordPressSettingsUI', 'admin_scripts'));
1284 -
1285 - // For CSS that needs to be generated dynamically.
1286 - add_action('admin_print_styles', array('FeedWordPressSettingsUI', 'admin_styles'));
1287 -
1288 - wp_enqueue_style('dashboard');
1289 - wp_enqueue_style('feedwordpress-elements');
1290 - endif;
1291 -
1292 - // These are a special post statuses for hiding posts that have
1293 - // expired from the feed or been marked for permanent zapping by
1294 - // the FWP admin.
1295 - register_post_status('fwpretired', array(
1296 - 'label' => _x('Retired', 'post'),
1297 - 'label_count' => _n_noop('Retired <span class="count">(%s)</span>', 'Retired <span class="count">(%s)</span>'),
1298 - 'exclude_from_search' => true,
1299 - 'public' => false,
1300 - 'publicly_queryable' => false,
1301 - 'show_in_admin_all_list' => false,
1302 - 'show_in_admin_status_list' => true,
1303 - ));
1304 - register_post_status('fwpzapped', array(
1305 - 'label' => _x('Zapped', 'post'),
1306 - 'label_count' => _n_noop('Zapped <span class="count">(%s)</span>', 'Retired <span class="count">(%s)</span>'),
1307 - 'exclude_from_search' => true,
1308 - 'public' => false,
1309 - 'publicly_queryable' => false,
1310 - 'show_in_admin_all_list' => false,
1311 - 'show_in_admin_status_list' => true,
1312 - ));
1313 - add_action(
1314 - /*hook=*/ 'template_redirect',
1315 - /*function=*/ array($this, 'redirect_retired'),
1316 - /*priority=*/ -100
1317 - );
1318 -
1319 - add_action('wp_ajax_fwp_feeds', array($this, 'fwp_feeds'));
1320 - add_action('wp_ajax_fwp_feedcontents', array($this, 'fwp_feedcontents'));
1321 - add_action('wp_ajax_fwp_xpathtest', array($this, 'fwp_xpathtest'));
1322 -
1323 - // Prepare for future translations... (gwyneth 20210714)
1324 - // add_action('init', array($this, 'load_textdomain');
1325 - } /* FeedWordPress::init() */
1326 -
1327 - /**
1328 - * FeedWordPress::wp_loaded (): Once all plugin and theme modules have been
1329 - * loaded and initialized (by actions on the init hook, etc.), check the HTTP
1330 - * request to see if we need to perform any special FeedWordPress-related
1331 - * actions.
1332 - *
1333 - * @since 2016.0614
1334 - */
1335 - public function wp_loaded () {
1071 + function init () {
1336 1072 $this->clear_cache_magic_url();
1337 1073 $this->update_magic_url();
1338 - } /* FeedWordPress::wp_loaded () */
1339 -
1340 - /**
1341 - * FeedWordPress::cron_schedules(): Filter hook to add WP-Cron schedules
1342 - * that plugins like FeedWordPress can use to carry out scheduled events.
1343 - *
1344 - * @param array $schedules An associative array containing the current set of cron schedules (hourly, daily, etc.)
1345 - * @return array The same array, with a new entry ('fwp_checkin_interval') added to the list.
1346 - *
1347 - * @since 2017.1021
1348 - */
1349 - public function cron_schedules ($schedules) {
1350 - $interval = FEEDWORDPRESS_DEFAULT_CHECKIN_INTERVAL*60 /*sec/min*/;
1351 -
1352 - // add 'fwp_checkin_interval' to the existing set
1353 - $schedules['fwp_checkin_interval'] = array(
1354 - 'interval' => $interval,
1355 - 'display' => 'FeedWordPress update schedule check-in',
1356 - );
1357 -
1358 - return $schedules;
1359 - } /* FeedWordPress::cron_schedules () */
1360 -
1361 - public function fwp_feeds () {
1362 - $feeds = array();
1363 - $feed_ids = $this->feeds;
1364 -
1365 - foreach ($feed_ids as $id) :
1366 - $sub = $this->subscription($id);
1367 - $feeds[] = array(
1368 - "id" => $id,
1369 - "url" => $sub->uri(),
1370 - "name" => $sub->name(/*fromFeed=*/ false),
1371 - );
1372 - endforeach;
1373 -
1374 - header("Content-Type: application/json");
1375 - echo json_encode($feeds);
1376 - exit;
1377 - } /* FeedWordPress::fwp_feeds () */
1378 -
1379 - public function fwp_feedcontents () {
1380 - $feed_id = FeedWordPress::param( 'feed_id' );
1381 -
1382 - // Let's load up some data from the feed . . .
1383 - $feed = $this->subscription($feed_id);
1384 - $posts = $feed->live_posts();
1385 -
1386 - if (is_wp_error($posts)) :
1387 - header("HTTP/1.1 502 Bad Gateway");
1388 - $result = $posts;
1389 - else :
1390 - $result = array();
1391 -
1392 - foreach ($posts as $post) :
1393 - $p = new SyndicatedPost($post, $feed);
1394 -
1395 - $result[] = array(
1396 - "post_title" => $p->entry->get_title(),
1397 - "post_link" => $p->permalink(),
1398 - "guid" => $p->guid(),
1399 - "post_date" => $p->published(),
1400 - );
1401 - endforeach;
1402 - endif;
1403 -
1404 - header("Content-Type: application/json");
1405 -
1406 - echo json_encode($result);
1407 -
1408 - // This is an AJAX request, so close it out thus.
1409 - die;
1410 - } /* FeedWordPress::fwp_feedcontents () */
1411 -
1412 - public function fwp_xpathtest () {
1413 - $xpath = FeedWordPress::param( 'xpath' );
1414 - $feed_id = FeedWordPress::param( 'feed_id' );
1415 - $post_id = FeedWordPress::param( 'post_id' );
1416 -
1417 - $expr = new FeedWordPressParsedPostMeta($xpath);
1418 -
1419 - // Let's load up some data from the feed . . .
1420 - $feed = $this->subscription($feed_id);
1421 - $posts = $feed->live_posts();
1422 -
1423 - if ( !is_wp_error($posts)) :
1424 - if (strlen($post_id) == 0) :
1425 - $post = $posts[0];
1426 - else :
1427 - $post = null;
1428 -
1429 - foreach ($posts as $p) :
1430 - if ($p->get_id() == $post_id) :
1431 - $post = $p;
1432 - endif;
1433 - endforeach;
1434 - endif;
1435 -
1436 - $post = new SyndicatedPost($post, $feed);
1437 - $meta = $expr->do_substitutions($post);
1438 -
1439 - $result = array(
1440 - "post_title" => $post->entry->get_title(),
1441 - "post_link" => $post->permalink(),
1442 - "guid" => $post->guid(),
1443 - "expression" => $xpath,
1444 - "results" => $meta
1445 - );
1446 - else :
1447 - $result = array(
1448 - "expression" => $xpath,
1449 - "feed_id" => $feed_id,
1450 - "post_id" => $post_id,
1451 - "results" => $posts
1452 - );
1453 -
1454 - header("HTTP/1.1 503 Bad Gateway");
1455 - endif;
1456 -
1457 - header("Content-Type: application/json");
1458 -
1459 - echo json_encode($result);
1460 -
1461 - // This is an AJAX request, so close it out thus.
1462 - die;
1463 - } /* FeedWordPress::fwp_xpathtest () */
1464 -
1465 - public function redirect_retired () {
1466 - global $wp_query;
1467 - if (is_singular()) :
1468 - if (
1469 - 'fwpretired'==$wp_query->post->post_status
1470 - or 'fwpzapped'==$wp_query->post->post_status
1471 - ) :
1472 - do_action('feedwordpress_redirect_retired', $wp_query->post);
1473 -
1474 - if ( !($template = get_404_template())) :
1475 - $template = get_index_template();
1476 - endif;
1477 - if ($template = apply_filters('template_include', $template)) :
1478 - header("HTTP/1.1 410 Gone");
1479 - include($template);
1480 - endif;
1481 - exit;
1482 - endif;
1483 - endif;
1484 - } /* FeedWordPress::redirect_retired () */
1485 -
1486 - public function row_actions ($actions, $post) {
1487 - if (is_syndicated($post->ID) && current_user_can('edit_post', $post->ID)) :
1488 - $link = get_delete_post_link($post->ID, '', true);
1489 - $eraseLink = MyPHP::url($link, array("fwp_post_delete" => "nuke"));
1490 -
1491 - $caption = apply_filters('feedwordpress_ui_erase_link_caption', __('Erase the record of this post (will be re-syndicated if it still appears on the feed).'));
1492 - $linktext = apply_filters('feedwordpress_ui_erase_link_text', __('Erase/Resyndicate'));
1493 -
1494 - $retireClass = null;
1495 - if ($post->post_status == 'fwpzapped') :
1496 - if (count(get_post_meta($post->ID, '_feedwordpress_zapped_blank_me')) > 0) :
1497 - $retireCap = 'Un-Zap this syndicated post (so it will appear on the site again)';
1498 - $retireText = 'Un-Zap &amp; Restore';
1499 - $retireLink = MyPHP::url($link, array("fwp_post_delete" => "unzap"));
1500 - else :
1501 - // No Un-Zap link for posts that have
1502 - // been blanked. You'll just have to
1503 - // Erase and hope you can resyndicate...
1504 - $retireLink = null;
1505 - endif;
1506 - else :
1507 - $retireCap = apply_filters('feedwordpress_ui_zap_link_caption', __('Zap this syndicated post (so it will not be re-syndicated if it still appears on the feed).'));
1508 - $retireText = apply_filters('feedwordpress_ui_zap_link_text', __('Zap/Don&rsquo;t Resyndicate'));
1509 - $retireLink = MyPHP::url($link, array("fwp_post_delete" => "zap"));
1510 - $retireClass = 'submitdelete';
1511 - endif;
1512 -
1513 - $keys = array_keys($actions);
1514 - $links = array();
1515 - foreach ($keys as $key) :
1516 - $links[$key] = $actions[$key];
1517 -
1518 - if ('trash'==$key) :
1519 - #$links[$key] = "<a class='submitdelete' title='" . esc_attr( __( 'Move this item to the Trash (will NOT be re-syndicated)' ) ) . "' href='" . get_delete_post_link( $post->ID ) . "'>" . __( 'Trash' ) . "</a>";
1520 -
1521 - // Placeholder.
1522 - if ( !is_null($retireLink)) :
1523 - $links['zap trash'] = '';
1524 - endif;
1525 - $links['delete'] = '';
1526 - endif;
1527 - endforeach;
1528 -
1529 - if ( !is_null($retireLink)) :
1530 - $links['zap trash'] = '<a class="'.esc_attr($retireClass).'" title="'.esc_attr(__($retireCap)).'" href="' . $retireLink . '">' . __($retireText) . '</a>';
1531 - endif;
1532 - $links['delete'] = '<a class="submitdelete" title="'.esc_attr(__($caption)).'" href="' . $eraseLink . '">' . __($linktext) . '</a>';
1533 -
1534 - $actions = $links;
1535 - endif;
1536 - return $actions;
1537 - } /* FeedWordPress::row_actions () */
1538 -
1539 - /**
1540 - * Sets up the FWP dashboard.
1541 - *
1542 - * @global $wp_meta_boxes
1543 - * @uses FeedWordPress::menu_cap
1544 - */
1545 - public function dashboard_setup() {
1546 - /** @var mixed User capability */
1074 + } /* FeedWordPress::init() */
1075 +
1076 + function dashboard_setup () {
1547 1077 $see_it = FeedWordPress::menu_cap();
1548 -
1549 - if ( current_user_can( $see_it ) ) :
1078 +
1079 + if (current_user_can($see_it)) :
1550 1080 // Get the stylesheet
1551 - wp_enqueue_style( 'feedwordpress-elements' );
1552 -
1553 - $widget_id = 'feedwordpress_dashboard';
1554 - $widget_name = __( 'Syndicated Sources' );
1555 - $column = 'side';
1556 - $priority = 'core';
1557 -
1081 + wp_enqueue_style('feedwordpress-elements');
1082 +
1083 + $widget_id = 'feedwordpress_dashboard';
1084 + $widget_name = __('Syndicated Sources');
1085 + $column = 'side';
1086 + $priority = 'core';
1087 +
1558 1088 // I would love to use wp_add_dashboard_widget() here and save
1559 1089 // myself some trouble. But WP 3 does not yet have any way to
1560 1090 // push a dashboard widget onto the side, or to give it a default
1561 1091 // location.
@@ -1561,135 +1091,122 @@
1561 1091 // location.
1562 1092 add_meta_box(
1563 1093 /*id=*/ $widget_id,
1564 1094 /*title=*/ $widget_name,
1565 - /*callback=*/ array( $this, 'dashboard' ),
1566 - /*screen=*/ 'dashboard',
1095 + /*callback=*/ array(&$this, 'dashboard'),
1096 + /*page=*/ 'dashboard',
1567 1097 /*context=*/ $column,
1568 1098 /*priority=*/ $priority
1569 1099 );
1570 - /*control_callback= array($this, 'dashboard_control') */
1571 -
1572 - /* This is kind of rude, I know, but the dashboard widget isn't
1573 - * worth much if users don't know that it exists, and I don't
1574 - * know of any better way to reorder the boxen.
1575 - *
1576 - * Gleefully ripped off of codex.wordpress.org/Dashboard_Widgets_API
1577 - */
1578 -
1579 - /** @var mixed Globalizes the metaboxes array, this holds all the widgets for wp-admin. */
1100 + /*control_callback= array(&$this, 'dashboard_control') */
1101 +
1102 + // This is kind of rude, I know, but the dashboard widget isn't
1103 + // worth much if users don't know that it exists, and I don't
1104 + // know of any better way to reorder the boxen.
1105 + //
1106 + // Gleefully ripped off of codex.wordpress.org/Dashboard_Widgets_API
1107 +
1108 + // Globalize the metaboxes array, this holds all the widgets for wp-admin
1580 1109 global $wp_meta_boxes;
1581 -
1582 - /** @var mixed Get the regular dashboard widgets array
1583 - * (which has our new widget already but at the end). */
1110 +
1111 + // Get the regular dashboard widgets array
1112 + // (which has our new widget already but at the end)
1113 +
1584 1114 $normal_dashboard = $wp_meta_boxes['dashboard'][$column][$priority];
1585 -
1115 +
1586 1116 // Backup and delete our new dashbaord widget from the end of the array
1587 - if ( isset( $normal_dashboard[ $widget_id ] ) ) :
1117 + if (isset($normal_dashboard[$widget_id])) :
1588 1118 $backup = array();
1589 - $backup[ $widget_id ] = $normal_dashboard[ $widget_id ];
1590 - unset( $normal_dashboard[ $widget_id ] );
1591 -
1592 - /** @var array Merge the two arrays together so our widget is at the beginning. */
1593 - $sorted_dashboard = array_merge( $backup, $normal_dashboard );
1594 -
1595 - // Save the sorted array back into the original €es
1596 - $wp_meta_boxes['dashboard'][ $column ][ $priority ] = $sorted_dashboard;
1119 + $backup[$widget_id] = $normal_dashboard[$widget_id];
1120 + unset($normal_dashboard[$widget_id]);
1121 +
1122 + // Merge the two arrays together so our widget is at the
1123 + // beginning
1124 + $sorted_dashboard = array_merge($backup, $normal_dashboard);
1125 +
1126 + // Save the sorted array back into the original metaboxes
1127 + $wp_meta_boxes['dashboard'][$column][$priority] = $sorted_dashboard;
1597 1128 endif;
1598 1129 endif;
1599 1130 } /* FeedWordPress::dashboard_setup () */
1600 -
1601 - public function dashboard () {
1131 +
1132 + function dashboard () {
1602 1133 $syndicationPage = new FeedWordPressSyndicationPage(dirname(__FILE__).'/syndication.php');
1603 1134 $syndicationPage->dashboard_box($syndicationPage);
1604 1135 } /* FeedWordPress::dashboard () */
1605 1136
1606 - public function user_can_richedit ($rich_edit) {
1607 -
1608 - $post = new FeedWordPressLocalPost;
1609 -
1610 - if ( ! $post->is_exposed_to_formatting_filters()) :
1611 - // Disable visual editor and only allow operations
1612 - // directly on HTML if post is bypassing fmt filters
1613 - # $rich_edit = false;
1614 - endif;
1615 -
1616 - return $rich_edit;
1617 -
1618 - } /* FeedWordPress::user_can_richedit () */
1619 -
1620 - public function clear_cache_magic_url () {
1621 - if ($this->clear_cache_requested()) :
1622 - $this->clear_cache();
1623 - endif;
1624 - } /* FeedWordPress::clear_cache_magic_url() */
1625 -
1626 - public function clear_cache_requested () {
1627 - return FeedWordPress::param( 'clear_cache' );
1628 - } /* FeedWordPress::clear_cache_requested() */
1629 -
1630 - public function update_magic_url () {
1137 + function update_magic_url () {
1631 1138 global $wpdb;
1632 1139
1633 1140 // Explicit update request in the HTTP request (e.g. from a cron job)
1634 - if (self::update_requested()) :
1635 - /*DBG*/ header("Content-Type: text/plain");
1636 - $this->update_hooked = "Initiating a CRON JOB CHECK-IN ON UPDATE SCHEDULE due to URL parameter = " . trim( $this->val( FeedWordPress::param('update_feedwordpress' ) ) );
1637 -
1141 + if ($this->update_requested()) :
1638 1142 $this->update($this->update_requested_url());
1639 -
1640 - if (FEEDWORDPRESS_DEBUG and is_array($wpdb->queries) and count($wpdb->queries) > 0) :
1143 +
1144 + if (FEEDWORDPRESS_DEBUG and count($wpdb->queries) > 0) :
1641 1145 $mysqlTime = 0.0;
1642 1146 $byTime = array();
1643 1147 foreach ($wpdb->queries as $query) :
1644 1148 $time = $query[1] * 1000000.0;
1645 1149 $mysqlTime += $query[1];
1646 - if ( !isset($byTime[$time])) : $byTime[$time] = array(); endif;
1647 - $byTime[$time][] = $query[0]. ' // STACK: ' . $query[2];
1150 + if (!isset($byTime[$time])) : $byTime[$time] = array(); endif;
1151 + $byTime[$time][] = $query[0]. ' // STACK: ' . $query[2];
1648 1152 endforeach;
1649 1153 krsort($byTime);
1650 -
1154 +
1651 1155 foreach ($byTime as $time => $querySet) :
1652 1156 foreach ($querySet as $query) :
1653 - printf( '[%s ms] %s', esc_html( sprintf( '%4.4f', $time/1000.0 ) ), esc_html( $query ) ) . "\n";
1157 + print "[".(sprintf('%4.4f', $time/1000.0)) . "ms] $query\n";
1654 1158 endforeach;
1655 1159 endforeach;
1656 - echo esc_html( self::log_prefix()."$wpdb->num_queries queries. $mysqlTime seconds in MySQL. Total of " ); timer_stop(1); print " seconds.";
1160 + echo $this->log_prefix()."$wpdb->num_queries queries. $mysqlTime seconds in MySQL. Total of "; timer_stop(1); print " seconds.";
1657 1161 endif;
1658 -
1162 +
1659 1163 debug_out_feedwordpress_footer();
1660 -
1164 +
1661 1165 // Magic URL should return nothing but a 200 OK header packet
1662 1166 // when successful.
1663 1167 exit;
1664 1168 endif;
1665 - } /* FeedWordPress::update_magic_url () */
1169 + } /* FeedWordPress::magic_update_url () */
1666 1170
1667 - public static function update_requested () {
1668 - return FeedWordPress::param( 'update_feedwordpress' );
1669 - } /* FeedWordPress::update_requested() */
1171 + function clear_cache_magic_url () {
1172 + if ($this->clear_cache_requested()) :
1173 + $this->clear_cache();
1174 + endif;
1175 + } /* FeedWordPress::clear_cache_magic_url() */
1176 +
1177 + function clear_cache_requested () {
1178 + return (
1179 + isset($_GET['clear_cache'])
1180 + and $_GET['clear_cache']
1181 + );
1182 + } /* FeedWordPress::clear_cache_requested() */
1670 1183
1671 - public function update_requested_url () {
1184 + function update_requested () {
1185 + return (
1186 + isset($_REQUEST['update_feedwordpress'])
1187 + and $_REQUEST['update_feedwordpress']
1188 + );
1189 + } // FeedWordPress::update_requested()
1190 +
1191 + function update_requested_url () {
1672 1192 $ret = null;
1673 -
1674 - $uf = FeedWordPress::update_requested();
1675 - if (
1676 - ( '*' == $uf )
1677 - || ( preg_match( '|^[a-z]+://.*|i', $uf ) )
1678 - ) :
1679 - $ret = $uf;
1193 +
1194 + if (($_REQUEST['update_feedwordpress']=='*')
1195 + or (preg_match('|^http://.*|i', $_REQUEST['update_feedwordpress']))) :
1196 + $ret = $_REQUEST['update_feedwordpress'];
1680 1197 endif;
1681 1198
1682 1199 return $ret;
1683 - } /* FeedWordPress::update_requested_url() */
1200 + } // FeedWordPress::update_requested_url()
1684 1201
1685 - public function auto_update () {
1202 + function auto_update () {
1686 1203 if ($this->stale()) :
1687 1204 $this->update();
1688 1205 endif;
1689 1206 } /* FeedWordPress::auto_update () */
1690 1207
1691 - public static function find_link ($uri, $field = 'link_rss') {
1208 + function find_link ($uri, $field = 'link_rss') {
1692 1209 global $wpdb;
1693 1210
1694 1211 $unslashed = untrailingslashit($uri);
1695 1212 $slashed = trailingslashit($uri);
@@ -1696,45 +1213,16 @@
1696 1213 $link_id = $wpdb->get_var($wpdb->prepare("
1697 1214 SELECT link_id FROM $wpdb->links WHERE $field IN ('%s', '%s')
1698 1215 LIMIT 1", $unslashed, $slashed
1699 1216 ));
1700 -
1217 +
1701 1218 return $link_id;
1702 1219 } /* FeedWordPress::find_link () */
1703 1220
1704 - /**
1705 - * FeedWordPress:syndicate_link(): add or update a feed subscription
1706 - *
1707 - * Add a new subscription to, or update an existing subscription in,
1708 - * FWP's list of subscribed feeds.
1709 - *
1710 - * Postcondition: If $rss is the URL of a feed not yet on FWP's list of
1711 - * subscribed feeds, then a new subscription will be added, using $name
1712 - * as its initial title and $uri as its initial homepage URL (normally
1713 - * these will be updated with new values taken from the feed, the first
1714 - * time the new feed is checked for syndicated content, unless feed
1715 - * settings prevent this). If $rss is the URL of a feed that is already
1716 - * on FWP's list of subscribed feeds, then that feed will be updated to
1717 - * use the title provided in $name and the homepage URL in $uri
1718 - *
1719 - * @param string $name The human-readable title of the feed (for example, "Rad Geek People's Daily")
1720 - * @param string $uri The URI for the human-readable homepage associated with the feed (for example, <http://radgeek.com/>)
1721 - * @param string $rss The URI for the feed itself (for example, <http://radgeek.com/feed/>)
1722 - *
1723 - * @return mixed Returns an int with the numeric ID of the new
1724 - * subscription's wp_links record if successful or a WP_Error object
1725 - * if wp_insert_link() failed.
1726 - *
1727 - * @uses FeedWordPress::link_category_id()
1728 - * @uses FeedWordPress::find_link()
1729 - * @uses is_wp_error()
1730 - * @uses wp_insert_link()
1731 - *
1732 - */
1733 - public static function syndicate_link ($name, $uri, $rss) {
1221 + function syndicate_link ($name, $uri, $rss) {
1734 1222 // Get the category ID#
1735 1223 $cat_id = FeedWordPress::link_category_id();
1736 - if ( !is_wp_error($cat_id)) :
1224 + if (!is_wp_error($cat_id)) :
1737 1225 $link_category = array($cat_id);
1738 1226 else :
1739 1227 $link_category = array();
1740 1228 endif;
@@ -1739,12 +1227,12 @@
1739 1227 $link_category = array();
1740 1228 endif;
1741 1229
1742 1230 // WordPress gets cranky if there's no homepage URI
1743 - if ( !is_string($uri) or strlen($uri)<1) : $uri = $rss; endif;
1744 -
1231 + if (!is_string($uri) or strlen($uri)<1) : $uri = $rss; endif;
1232 +
1745 1233 // Check if this feed URL is already being syndicated.
1746 - $link_id = wp_insert_link(/*linkdata=*/ array(
1234 + $link_id = wp_insert_link(array(
1747 1235 "link_id" => FeedWordPress::find_link($rss), // insert if nothing was found; else update
1748 1236 "link_rss" => $rss,
1749 1237 "link_name" => $name,
1750 1238 "link_url" => $uri,
@@ -1749,32 +1237,32 @@
1749 1237 "link_name" => $name,
1750 1238 "link_url" => $uri,
1751 1239 "link_category" => $link_category,
1752 1240 "link_visible" => 'Y', // reactivate if inactivated
1753 - ), /*wp_error=*/ true);
1241 + ));
1754 1242
1755 1243 return $link_id;
1756 1244 } /* function FeedWordPress::syndicate_link() */
1757 1245
1758 - static function syndicated_status ($what, $default) {
1246 + /*static*/ function syndicated_status ($what, $default) {
1759 1247 $ret = get_option("feedwordpress_syndicated_{$what}_status");
1760 - if ( ! $ret) :
1248 + if (!$ret) :
1761 1249 $ret = $default;
1762 1250 endif;
1763 1251 return $ret;
1764 1252 } /* FeedWordPress::syndicated_status() */
1765 1253
1766 - public static function on_unfamiliar ($what = 'author') {
1254 + function on_unfamiliar ($what = 'author') {
1767 1255 switch ($what) :
1768 1256 case 'category' : $suffix = ':category'; break;
1769 1257 case 'post_tag' : $suffix = ':post_tag'; break;
1770 1258 default: $suffix = '';
1771 1259 endswitch;
1772 -
1260 +
1773 1261 return get_option('feedwordpress_unfamiliar_'.$what, 'create'.$suffix);
1774 1262 } // function FeedWordPress::on_unfamiliar()
1775 1263
1776 - public static function null_email_set () {
1264 + function null_email_set () {
1777 1265 $base = get_option('feedwordpress_null_email_set');
1778 1266
1779 1267 if ($base===false) :
1780 1268 $ret = array('noreply@blogger.com'); // default
@@ -1786,18 +1274,18 @@
1786 1274 return $ret;
1787 1275
1788 1276 } /* FeedWordPress::null_email_set () */
1789 1277
1790 - public static function is_null_email( $email ) {
1791 - $ret = in_array( strtolower( trim( $email ) ), FeedWordPress::null_email_set() );
1792 - $ret = apply_filters( 'syndicated_item_author_is_null_email', $ret, $email );
1278 + function is_null_email ($email) {
1279 + $ret = in_array(strtolower(trim($email)), FeedWordPress::null_email_set());
1280 + $ret = apply_filters('syndicated_item_author_is_null_email', $ret, $email);
1793 1281 return $ret;
1794 1282 } /* FeedWordPress::is_null_email () */
1795 1283
1796 - public static function use_aggregator_source_data () {
1284 + function use_aggregator_source_data () {
1797 1285 $ret = get_option('feedwordpress_use_aggregator_source_data');
1798 1286 return apply_filters('syndicated_post_use_aggregator_source_data', ($ret=='yes'));
1799 - } /* FeedWordPress::use_aggregator_source_data () */
1287 + }
1800 1288
1801 1289 /**
1802 1290 * FeedWordPress::munge_permalinks: check whether or not FeedWordPress
1803 1291 * should rewrite permalinks for syndicated items to reflect their
@@ -1804,15 +1292,15 @@
1804 1292 * original location.
1805 1293 *
1806 1294 * @return bool TRUE if FeedWordPress SHOULD rewrite permalinks; FALSE otherwise
1807 1295 */
1808 - static function munge_permalinks () {
1296 + /*static*/ function munge_permalinks () {
1809 1297 return (get_option('feedwordpress_munge_permalink', /*default=*/ 'yes') != 'no');
1810 1298 } /* FeedWordPress::munge_permalinks() */
1811 1299
1812 - public static function syndicated_links ($args = array()) {
1300 + function syndicated_links ($args = array()) {
1813 1301 $contributors = FeedWordPress::link_category_id();
1814 - if ( !is_wp_error($contributors)) :
1302 + if (!is_wp_error($contributors)) :
1815 1303 $links = get_bookmarks(array_merge(
1816 1304 array("category" => $contributors),
1817 1305 $args
1818 1306 ));
@@ -1818,17 +1306,18 @@
1818 1306 ));
1819 1307 else :
1820 1308 $links = array();
1821 1309 endif;
1310 + return $links;
1311 + } // function FeedWordPress::syndicated_links()
1822 1312
1823 - return $links;
1824 - } /* FeedWordPress::syndicated_links() */
1313 + function link_category_id () {
1314 + global $wpdb, $wp_db_version;
1825 1315
1826 - public static function link_category_id () {
1827 1316 $cat_id = get_option('feedwordpress_cat_id');
1828 -
1317 +
1829 1318 // If we don't yet have the category ID stored, search by name
1830 - if ( ! $cat_id) :
1319 + if (!$cat_id) :
1831 1320 $cat_id = FeedWordPressCompatibility::link_category_id(DEFAULT_SYNDICATION_CATEGORY);
1832 1321
1833 1322 if ($cat_id) :
1834 1323 // We found it; let's stamp it.
@@ -1838,14 +1327,14 @@
1838 1327 // If we *do* have the category ID stored, verify that it exists
1839 1328 else :
1840 1329 $cat_id = FeedWordPressCompatibility::link_category_id((int) $cat_id, 'cat_id');
1841 1330 endif;
1842 -
1331 +
1843 1332 // If we could not find an appropriate link category,
1844 1333 // make a new one for ourselves.
1845 - if ( ! $cat_id) :
1334 + if (!$cat_id) :
1846 1335 $cat_id = FeedWordPressCompatibility::insert_link_category(DEFAULT_SYNDICATION_CATEGORY);
1847 - if ( !is_wp_error($cat_id)) :
1336 + if (!is_wp_error($cat_id)) :
1848 1337 // Stamp it
1849 1338 update_option('feedwordpress_cat_id', $cat_id);
1850 1339 endif;
1851 1340 endif;
@@ -1850,28 +1339,40 @@
1850 1339 endif;
1851 1340 endif;
1852 1341
1853 1342 return $cat_id;
1854 - } /* FeedWordPress::link_category_id() */
1343 + } // function FeedWordPress::link_category_id()
1855 1344
1856 1345 # Upgrades and maintenance...
1857 - static function needs_upgrade () {
1858 - $fwp_db_version = get_option('feedwordpress_version', null);
1346 + function needs_upgrade () {
1347 + global $wpdb;
1348 + $fwp_db_version = get_option('feedwordpress_version');
1859 1349 $ret = false; // innocent until proven guilty
1860 - if (is_null($fwp_db_version) or ($fwp_db_version < FEEDWORDPRESS_VERSION)) :
1350 + if (!$fwp_db_version or $fwp_db_version < FEEDWORDPRESS_VERSION) :
1351 + // This is an older version or a fresh install. Does it
1352 + // require a database upgrade or database initialization?
1353 + if ($fwp_db_version <= 0.96) :
1354 + // Yes. Check to see whether this is a fresh install or an upgrade.
1355 + $syn = $wpdb->get_col("
1356 + SELECT post_id
1357 + FROM $wpdb->postmeta
1358 + WHERE meta_key = 'syndication_feed'
1359 + ");
1360 + if (count($syn) > 0) : // contains at least one syndicated post
1361 + $ret = true;
1362 + else : // fresh install; brand it as ours
1363 + update_option('feedwordpress_version', FEEDWORDPRESS_VERSION);
1364 + endif;
1365 + elseif ($fwp_db_version < 2009.0707) :
1366 + // We need to clear out any busted AJAX crap
1367 + $wpdb->query("
1368 + DELETE FROM $wpdb->usermeta
1369 + WHERE LOCATE('feedwordpress', meta_key)
1370 + AND LOCATE('box', meta_key);
1371 + ");
1861 1372
1862 - // This is an older version or a fresh install. Does it require a database
1863 - // upgrade or database initialization?
1864 -
1865 - if (is_null($fwp_db_version)) :
1866 -
1867 - // Fresh install; brand it as ours. Or possibly a version of FWP
1868 - // from before 0.96. But I'm no longer supporting upgrade paths
1869 - // for versions from the previous decade. Sorry.
1870 1373 update_option('feedwordpress_version', FEEDWORDPRESS_VERSION);
1871 -
1872 1374 elseif ($fwp_db_version < 2010.0814) :
1873 -
1874 1375 // Change in terminology.
1875 1376 if (get_option('feedwordpress_unfamiliar_category', 'create')=='default') :
1876 1377 update_option('feedwordpress_unfamiliar_category', 'null');
1877 1378 endif;
@@ -1876,9 +1377,9 @@
1876 1377 update_option('feedwordpress_unfamiliar_category', 'null');
1877 1378 endif;
1878 1379 foreach (FeedWordPress::syndicated_links() as $link) :
1879 1380 $sub = new SyndicatedLink($link);
1880 -
1381 +
1881 1382 $remap_uf = array(
1882 1383 'default' => 'null',
1883 1384 'filter' => 'null',
1884 1385 'create' => 'create:category',
@@ -1893,39 +1394,36 @@
1893 1394 $sub->settings['unfamiliar category'] = $to;
1894 1395 endif;
1895 1396 endforeach;
1896 1397 endif;
1897 -
1398 +
1898 1399 if (isset($sub->settings['add global categories'])) :
1899 1400 $sub->settings['add/category'] = $sub->settings['add global categories'];
1900 1401 unset($sub->settings['add global categories']);
1901 1402 endif;
1902 -
1403 +
1903 1404 $sub->save_settings(/*reload=*/ true);
1904 1405 endforeach;
1905 1406 update_option('feedwordpress_version', FEEDWORDPRESS_VERSION);
1906 -
1907 1407 else :
1908 -
1909 - // No upgrade needed. Just brand it with the new version.
1408 + // No. Just brand it with the new version.
1910 1409 update_option('feedwordpress_version', FEEDWORDPRESS_VERSION);
1911 -
1912 1410 endif;
1913 -
1914 1411 endif;
1915 1412 return $ret;
1916 - } /* FeedWordPress::needs_upgrade () */
1413 + }
1917 1414
1918 - static function upgrade_database ($from = null)
1919 - {
1415 + function upgrade_database ($from = NULL) {
1416 + global $wpdb;
1417 +
1920 1418 if (is_null($from) or $from <= 0.96) : $from = 0.96; endif;
1921 1419
1922 1420 switch ($from) :
1923 1421 case 0.96:
1924 - // Dropping legacy upgrade code. If anyone is still
1925 - // using 0.96 and just now decided to upgrade, well, I'm
1926 - // sorry about that. You'll just have to cope with a few
1927 - // duplicate posts.
1422 + // Dropping legacy upgrade code. If anyone is still
1423 + // using 0.96 and just now decided to upgrade, well, I'm
1424 + // sorry about that. You'll just have to cope with a few
1425 + // duplicate posts.
1928 1426
1929 1427 // Mark the upgrade as successful.
1930 1428 update_option('feedwordpress_version', FEEDWORDPRESS_VERSION);
1931 1429 endswitch;
@@ -1931,11 +1429,11 @@
1931 1429 endswitch;
1932 1430 echo "<p>Upgrade complete. FeedWordPress is now ready to use again.</p>";
1933 1431 } /* FeedWordPress::upgrade_database() */
1934 1432
1935 - public static function has_guid_index () {
1433 + function has_guid_index () {
1936 1434 global $wpdb;
1937 -
1435 +
1938 1436 $found = false; // Guilty until proven innocent.
1939 1437
1940 1438 $results = $wpdb->get_results("
1941 1439 SHOW INDEXES FROM {$wpdb->posts}
@@ -1949,77 +1447,71 @@
1949 1447 endforeach;
1950 1448 endif;
1951 1449 return $found;
1952 1450 } /* FeedWordPress::has_guid_index () */
1953 -
1954 - public static function create_guid_index () {
1451 +
1452 + function create_guid_index () {
1955 1453 global $wpdb;
1956 -
1454 +
1957 1455 $wpdb->query("
1958 1456 CREATE INDEX {$wpdb->posts}_guid_idx ON {$wpdb->posts}(guid)
1959 1457 ");
1960 1458 } /* FeedWordPress::create_guid_index () */
1961 -
1962 - public static function remove_guid_index () {
1459 +
1460 + function remove_guid_index () {
1963 1461 global $wpdb;
1964 -
1462 +
1965 1463 $wpdb->query("
1966 1464 DROP INDEX {$wpdb->posts}_guid_idx ON {$wpdb->posts}
1967 1465 ");
1968 1466 }
1969 1467
1970 - static function fetch_timeout () {
1468 + /*static*/ function fetch_timeout () {
1971 1469 return apply_filters(
1972 1470 'feedwordpress_fetch_timeout',
1973 1471 intval(get_option('feedwordpress_fetch_timeout', FEEDWORDPRESS_FETCH_TIMEOUT_DEFAULT))
1974 1472 );
1975 1473 }
1976 -
1977 - static function fetch ($url, $params = array()) {
1978 - if (is_wp_error($url)) :
1979 - // Let's bounce.
1980 - return $url;
1981 - endif;
1982 -
1474 +
1475 + /*static*/ function fetch ($url, $params = array()) {
1983 1476 $force_feed = true; // Default
1984 1477
1985 - // Allow user to change default feed-fetch timeout with a global setting.
1986 - // Props Erigami Scholey-Fuller <http://www.piepalace.ca/blog/2010/11/feedwordpress-broke-my-heart.html>
1478 + // Allow user to change default feed-fetch timeout with a global setting. Props Erigami Scholey-Fuller <http://www.piepalace.ca/blog/2010/11/feedwordpress-broke-my-heart.html> 'timeout' =>
1987 1479 $timeout = FeedWordPress::fetch_timeout();
1988 -
1989 - if ( !is_array($params)) :
1480 +
1481 + if (!is_array($params)) :
1990 1482 $force_feed = $params;
1991 1483 else : // Parameter array
1992 - $args = wp_parse_args(array(
1484 + $args = shortcode_atts(array(
1993 1485 'force_feed' => $force_feed,
1994 1486 'timeout' => $timeout
1995 1487 ), $params);
1996 -
1488 +
1997 1489 extract($args);
1998 1490 endif;
1999 1491 $timeout = intval($timeout);
1492 +
1493 + $pie_class = apply_filters('feedwordpress_simplepie_class', 'SimplePie');
1494 + $cache_class = apply_filters('feedwordpress_cache_class', 'WP_Feed_Cache');
1495 + $file_class = apply_filters('feedwordpress_file_class', 'FeedWordPress_File');
1496 + $parser_class = apply_filters('feedwordpress_parser_class', 'FeedWordPress_Parser');
2000 1497
2001 - $pie_class = apply_filters('feedwordpress_simplepie_class', 'FeedWordPie');
2002 - $cache_class = apply_filters('feedwordpress_cache_class', 'FeedWordPie_Cache');
2003 - $file_class = apply_filters('feedwordpress_file_class', 'FeedWordPie_File');
2004 - $parser_class = apply_filters('feedwordpress_parser_class', 'FeedWordPie_Parser');
2005 - $item_class = apply_filters('feedwordpress_item_class', 'FeedWordPie_Item');
2006 - $sniffer_class = apply_filters('feedwordpress_sniffer_class', 'FeedWordPie_Content_Type_Sniffer');
1498 + $sniffer_class = apply_filters('feedwordpress_sniffer_class', 'FeedWordPress_Content_Type_Sniffer');
2007 1499
2008 1500 $feed = new $pie_class;
2009 1501 $feed->set_feed_url($url);
2010 - $feed->registry->register('Cache', $cache_class);
1502 + $feed->set_cache_class($cache_class);
2011 1503 $feed->set_timeout($timeout);
2012 -
1504 +
1505 + //$feed->set_file_class('WP_SimplePie_File');
2013 1506 $feed->set_content_type_sniffer_class($sniffer_class);
2014 1507 $feed->set_file_class($file_class);
2015 1508 $feed->set_parser_class($parser_class);
2016 - $feed->set_item_class($item_class);
2017 1509 $feed->force_feed($force_feed);
2018 - $feed->set_cache_duration(FeedWordPress::cache_duration($params));
1510 + $feed->set_cache_duration(FeedWordPress::cache_duration());
2019 1511 $feed->init();
2020 1512 $feed->handle_content_type();
2021 -
1513 +
2022 1514 if ($feed->error()) :
2023 1515 $ret = new WP_Error('simplepie-error', $feed->error());
2024 1516 else :
2025 1517 $ret = $feed;
@@ -2025,12 +1517,12 @@
2025 1517 $ret = $feed;
2026 1518 endif;
2027 1519 return $ret;
2028 1520 } /* FeedWordPress::fetch () */
2029 -
2030 - public function clear_cache () {
1521 +
1522 + function clear_cache () {
2031 1523 global $wpdb;
2032 -
1524 +
2033 1525 // Just in case, clear out any old MagpieRSS cache records.
2034 1526 $magpies = $wpdb->query("
2035 1527 DELETE FROM {$wpdb->options}
2036 1528 WHERE option_name LIKE 'rss_%' AND LENGTH(option_name) > 32
@@ -2051,23 +1543,16 @@
2051 1543
2052 1544 return ($magpies + $simplepies);
2053 1545 } /* FeedWordPress::clear_cache () */
2054 1546
2055 - static public function cache_duration ($params = array()) {
2056 - $params = wp_parse_args($params, array(
2057 - "cache" => true,
2058 - ));
2059 -
2060 - $duration = null;
2061 - if ( ! $params['cache']) :
2062 - $duration = 0;
2063 - elseif (defined('FEEDWORDPRESS_CACHE_AGE')) :
1547 + function cache_duration () {
1548 + $duration = NULL;
1549 + if (defined('FEEDWORDPRESS_CACHE_AGE')) :
2064 1550 $duration = FEEDWORDPRESS_CACHE_AGE;
2065 1551 endif;
2066 1552 return $duration;
2067 1553 }
2068 -
2069 - static public function cache_lifetime ($duration) {
1554 + function cache_lifetime ($duration) {
2070 1555 // Check for explicit setting of a lifetime duration
2071 1556 if (defined('FEEDWORDPRESS_CACHE_LIFETIME')) :
2072 1557 $duration = FEEDWORDPRESS_CACHE_LIFETIME;
2073 1558
@@ -2074,76 +1559,78 @@
2074 1559 // Fall back to the cache freshness duration
2075 1560 elseif (defined('FEEDWORDPRESS_CACHE_AGE')) :
2076 1561 $duration = FEEDWORDPRESS_CACHE_AGE;
2077 1562 endif;
2078 -
1563 +
2079 1564 // Fall back to WordPress default
2080 1565 return $duration;
2081 1566 } /* FeedWordPress::cache_lifetime () */
2082 1567
2083 1568 # Utility functions for handling text settings
2084 - static function get_field( $f, $setting = null ) {
1569 + function negative ($f, $setting) {
1570 + $nego = array ('n', 'no', 'f', 'false');
1571 + return (isset($f[$setting]) and in_array(strtolower($f[$setting]), $nego));
1572 + }
2085 1573
2086 - $ret = $f;
2087 - if ( ! is_null( $setting ) ) :
2088 - $ret = null;
2089 - if ( array_key_exists( $setting, $f ) ) :
2090 - $ret = $f[ $setting ];
2091 - endif;
2092 - endif;
2093 - return $ret;
1574 + function affirmative ($f, $setting) {
1575 + $affirmo = array ('y', 'yes', 't', 'true', 1);
1576 + return (isset($f[$setting]) and in_array(strtolower($f[$setting]), $affirmo));
1577 + }
2094 1578
2095 - } /* FeedWordPress::get_field () */
1579 + # Internal debugging functions
1580 + function critical_bug ($varname, $var, $line) {
1581 + global $wp_version;
2096 1582
2097 - static function negative ($f, $setting = null) {
2098 - $nego = array ('n', 'no', 'f', 'false');
2099 - $q = self::get_field( $f, $setting );
2100 - return in_array( strtolower( trim( $q ) ), $nego );
2101 - } /* FeedWordPress::negative () */
1583 + echo '<p>There may be a bug in FeedWordPress. Please <a href="'.FEEDWORDPRESS_AUTHOR_CONTACT.'">contact the author</a> and paste the following information into your e-mail:</p>';
1584 + echo "\n<plaintext>";
1585 + echo "Triggered at line # ".$line."\n";
1586 + echo "FeedWordPress version: ".FEEDWORDPRESS_VERSION."\n";
1587 + echo "WordPress version: {$wp_version}\n";
1588 + echo "PHP version: ".phpversion()."\n";
1589 + echo "\n";
1590 + echo $varname.": "; var_dump($var); echo "\n";
1591 + die;
1592 + }
1593 +
1594 + function noncritical_bug ($varname, $var, $line) {
1595 + if (FEEDWORDPRESS_DEBUG) : // halt only when we are doing debugging
1596 + FeedWordPress::critical_bug($varname, $var, $line);
1597 + endif;
1598 + }
1599 +
1600 + function val ($v, $no_newlines = false) {
1601 + ob_start();
1602 + var_dump($v);
1603 + $out = ob_get_contents(); ob_end_clean();
1604 +
1605 + if ($no_newlines) :
1606 + $out = preg_replace('/\s+/', " ", $out);
1607 + endif;
1608 + return $out;
1609 + } /* FeedWordPress::val () */
2102 1610
2103 - static function affirmative ($f, $setting = null) {
2104 - // Defining possible affirmative values
2105 - $affirmo = [ 'y', 'yes', 't', 'true', 1 ];
2106 -
2107 - // Get the field value (presumably from some form or other input)
2108 - $q = self::get_field( $f, $setting );
2109 -
2110 - // Ensure $q is treated properly even if it's null or not set
2111 - if ( null === $q ) {
2112 - return false; // Or you can return false or other fallback as needed
2113 - }
1611 + function diagnostic_on ($level) {
1612 + $show = get_option('feedwordpress_diagnostics_show', array());
1613 + return (in_array($level, $show));
1614 + } /* FeedWordPress::diagnostic_on () */
2114 1615
2115 - // Check if the value, after trimming and converting to lowercase, is in the affirmative array
2116 - return in_array( strtolower( trim( $q ) ), $affirmo, true ); // The third argument `true` ensures strict type checking
2117 - } /* FeedWordPress::affirmative () */
2118 -
2119 - /**
2120 - * Internal debugging functions.
2121 - *
2122 - * @todo radgeek needs to document this better. What levels exist, and
2123 - * how/where are they defined? (gwyneth 20230919)
2124 - *
2125 - * @global $feedwordpress_admin_footer
2126 - */
2127 - static function diagnostic( $level, $out, $persist = null, $since = null, $mostRecent = null ) {
1616 + function diagnostic ($level, $out, $persist = NULL, $since = NULL, $mostRecent = NULL) {
2128 1617 global $feedwordpress_admin_footer;
2129 1618
2130 - $output = (array) get_option( 'feedwordpress_diagnostics_output', array() );
2131 - $dlog = get_option( 'feedwordpress_diagnostics_log', array() );
1619 + $output = get_option('feedwordpress_diagnostics_output', array());
1620 + $dlog = get_option('feedwordpress_diagnostics_log', array());
2132 1621
2133 - $diagnostic_nesting = count( explode( ":", $level ) );
1622 + $diagnostic_nesting = count(explode(":", $level));
2134 1623
2135 - if (FeedWordPressDiagnostic::is_on($level)) :
1624 + if (FeedWordPress::diagnostic_on($level)) :
2136 1625 foreach ($output as $method) :
2137 1626 switch ($method) :
2138 1627 case 'echo' :
2139 - if ( !( self::update_requested() || wp_doing_ajax() ) ) :
2140 - echo "<div><pre><strong>Diag".esc_html( str_repeat('====', $diagnostic_nesting-1) ).'|</strong> '. esc_html( $out )."</pre></div>\n";
2141 - endif;
1628 + echo "<div><pre><strong>Diag".str_repeat('====', $diagnostic_nesting-1).'|</strong> '.$out."</pre></div>";
2142 1629 break;
2143 1630 case 'echo_in_cronjob' :
2144 - if (self::update_requested()) :
2145 - echo esc_html( self::log_prefix() ) . ' ' . esc_html( $out ) . "\n";
1631 + if (FeedWordPress::update_requested()) :
1632 + echo FeedWordPress::log_prefix()." ".$out."\n";
2146 1633 endif;
2147 1634 break;
2148 1635 case 'admin_footer' :
2149 1636 $feedwordpress_admin_footer[] = $out;
@@ -2148,12 +1635,11 @@
2148 1635 case 'admin_footer' :
2149 1636 $feedwordpress_admin_footer[] = $out;
2150 1637 break;
2151 1638 case 'error_log' :
2152 - error_log(self::log_prefix() . ' ' . $out);
1639 + error_log(FeedWordPress::log_prefix().' '.$out);
2153 1640 break;
2154 1641 case 'email' :
2155 -
2156 1642 if (is_null($persist)) :
2157 1643 $sect = 'occurrent';
2158 1644 $hook = (isset($dlog['mesg'][$sect]) ? count($dlog['mesg'][$sect]) : 0);
2159 1645 $line = array("Time" => time(), "Message" => $out);
@@ -2161,75 +1647,42 @@
2161 1647 $sect = 'persistent';
2162 1648 $hook = md5($level."\n".$persist);
2163 1649 $line = array("Since" => $since, "Message" => $out, "Most Recent" => $mostRecent);
2164 1650 endif;
2165 -
2166 - if ( !isset($dlog['mesg'])) : $dlog['mesg'] = array(); endif;
2167 - if ( !isset($dlog['mesg'][$sect])) : $dlog['mesg'][$sect] = array(); endif;
2168 -
1651 +
1652 + if (!isset($dlog['mesg'])) : $dlog['mesg'] = array(); endif;
1653 + if (!isset($dlog['mesg'][$sect])) : $dlog['mesg'][$sect] = array(); endif;
1654 +
2169 1655 $dlog['mesg'][$sect][$hook] = $line;
2170 1656 endswitch;
2171 1657 endforeach;
2172 1658 endif;
2173 -
2174 - update_option( 'feedwordpress_diagnostics_log', $dlog );
2175 - } /* FeedWordPress::diagnostic() */
2176 -
2177 - public function email_diagnostics_override () {
2178 - return ( $this->has_secret() and ! ! FeedWordPress::param( 'feedwordpress_email_diagnostics' ) );
2179 - } /* FeedWordPress::email_diagnostics_override() */
2180 -
2181 - public function has_emailed_diagnostics ($dlog) {
2182 - $ret = false;
2183 - if ($this->email_diagnostics_override()
2184 - or (isset($dlog['schedule']) and isset($dlog['schedule']['last']))) :
2185 - $ret = true;
2186 - endif;
2187 - return $ret;
2188 - } /* FeedWordPress::has_emailed_diagnostics() */
2189 -
2190 - public function ready_to_email_diagnostics ($dlog) {
2191 - $ret = false;
2192 - if ($this->email_diagnostics_override()
2193 - or (time() > ($dlog['schedule']['last'] + $dlog['schedule']['freq']))) :
2194 - $ret = true;
2195 - endif;
2196 - return $ret;
2197 - } /* FeedWordPress::ready_to_email_diagnostics() */
2198 -
2199 - /**
2200 - * Emails a diagnostic log to the WP administrator.
2201 - *
2202 - * @param Array $params See @wp_parse_args()
2203 - */
2204 - public function email_diagnostic_log( $params = array() ) {
2205 - $params = wp_parse_args( $params, array(
2206 - "force" => false,
2207 - ) );
2208 -
1659 +
1660 + update_option('feedwordpress_diagnostics_log', $dlog);
1661 + } /* FeedWordPress::diagnostic () */
1662 +
1663 + function email_diagnostic_log () {
2209 1664 $dlog = get_option('feedwordpress_diagnostics_log', array());
2210 -
2211 - if ($this->has_emailed_diagnostics($dlog)) :
2212 - if ($this->ready_to_email_diagnostics($dlog)) :
1665 +
1666 + if (isset($dlog['schedule']) and isset($dlog['schedule']['last'])) :
1667 + if (time() > ($dlog['schedule']['last'] + $dlog['schedule']['freq'])) :
2213 1668 // No news is good news; only send if
2214 1669 // there are some messages to send.
2215 - $body = null;
2216 - if ( !isset($dlog['mesg'])) : $dlog['mesg'] = array(); endif;
2217 -
1670 + $body = NULL;
2218 1671 foreach ($dlog['mesg'] as $sect => $mesgs) :
2219 1672 if (count($mesgs) > 0) :
2220 1673 if (is_null($body)) : $body = ''; endif;
2221 -
1674 +
2222 1675 $paradigm = reset($mesgs);
2223 1676 $body .= "<h2>".ucfirst($sect)." issues</h2>\n"
2224 1677 ."<table>\n"
2225 1678 ."<thead><tr>\n";
2226 - foreach ( $paradigm as $col => $value ) :
1679 + foreach ($paradigm as $col => $value) :
2227 1680 $body .= '<th scope="col">'.$col."</th>\n";
2228 1681 endforeach;
2229 1682 $body .= "</tr></thead>\n"
2230 1683 ."<tbody>\n";
2231 -
1684 +
2232 1685 foreach ($mesgs as $line) :
2233 1686 $body .= "<tr>\n";
2234 1687 foreach ($line as $col => $cell) :
2235 1688 if (is_numeric($cell)) :
@@ -2235,21 +1688,20 @@
2235 1688 if (is_numeric($cell)) :
2236 1689 $cell = date('j-M-y, h:i a', $cell);
2237 1690 endif;
2238 1691 $class = strtolower(preg_replace('/\s+/', '-', $col));
2239 - $body .= "<td class=\"$class\">{$cell}</td>";
1692 + $body .= "<td class=\"$class\">${cell}</td>";
2240 1693 endforeach;
2241 1694 $body .= "</tr>\n";
2242 1695 endforeach;
2243 -
1696 +
2244 1697 $body .= "</tbody>\n</table>\n\n";
2245 1698 endif;
2246 1699 endforeach;
2247 -
2248 - $body = apply_filters('feedwordpress_diagnostic_email_body', $body, $dlog);
2249 - if ( !is_null($body)) :
1700 +
1701 + if (!is_null($body)) :
2250 1702 $home = feedwordpress_display_url(get_bloginfo('url'));
2251 - $subj = apply_filters('feedwordpress_diagnostic_email_subject', $home . " syndication issues", $dlog);
1703 + $subj = $home . " syndication issues for ".date('j-M-y', time());
2252 1704 $agent = 'FeedWordPress '.FEEDWORDPRESS_VERSION;
2253 1705 $body = <<<EOMAIL
2254 1706 <html>
2255 1707 <head>
@@ -2278,53 +1730,30 @@
2278 1730
2279 1731 // e-mail address
2280 1732 if (preg_match('/^mailto:(.*)$/', $ded, $ref)) :
2281 1733 $recipients = array($ref[1]);
2282 -
1734 +
2283 1735 // userid
2284 1736 elseif (preg_match('/^user:(.*)$/', $ded, $ref)) :
2285 - if ( is_numeric( $ref[1] ) and function_exists( 'get_userdata' ) ) :
2286 - $userdata = get_userdata( (int) $ref[1]) ;
2287 - $recipients = array( $userdata->user_email );
2288 - else :
2289 - // get_userdata() might not have been loaded yet, so send
2290 - // to admins instead. (gwyneth 20230901)
2291 - $recipients = FeedWordPressDiagnostic::admin_emails();
2292 - endif;
2293 -
1737 + $userdata = get_userdata((int) $ref[1]);
1738 + $recipients = array($userdata->user_email);
1739 +
2294 1740 // admins
2295 1741 else :
2296 1742 $recipients = FeedWordPressDiagnostic::admin_emails();
2297 1743 endif;
2298 1744
2299 - $mesgId = 'feedwordpress+'.time().'@'.$home;
2300 - $parentId = get_option('feedwordpress_diagnostics_email_root_message_id', null);
2301 -
2302 - $head = array("Message-ID: <$mesgId>");
2303 - if ( !is_null($parentId)) :
2304 - // We've already sent off a diagnostic message in the past. Let's do some
2305 - // magic to help with threading, in the hopes that all diagnostic messages
2306 - // get threaded together.
2307 - $head[] = "References: <$parentId>";
2308 - $head[] = "In-Reply-To: <$parentId>";
2309 - $subj = "Re: ".$subj;
2310 - else :
2311 - // This is the first of its kind. Let's mark it as such.
2312 - update_option('feedwordpress_diagnostics_email_root_message_id', $mesgId);
2313 - endif;
2314 - $head = apply_filters('feedwordpress_diagnostic_email_headers', $head);
2315 -
2316 - foreach ($recipients as $email) :
1745 + foreach ($recipients as $email) :
2317 1746 add_filter('wp_mail_content_type', array('FeedWordPress', 'allow_html_mail'));
2318 - wp_mail($email, $subj, $body, $head);
1747 + wp_mail($email, $subj, $body);
2319 1748 remove_filter('wp_mail_content_type', array('FeedWordPress', 'allow_html_mail'));
2320 1749 endforeach;
2321 1750 endif;
2322 -
1751 +
2323 1752 // Clear the logs
2324 1753 $dlog['mesg']['persistent'] = array();
2325 1754 $dlog['mesg']['occurrent'] = array();
2326 -
1755 +
2327 1756 // Set schedule for next update
2328 1757 $dlog['schedule']['last'] = time();
2329 1758 endif;
2330 1759 else :
@@ -2332,31 +1761,24 @@
2332 1761 'freq' => 24 /*hr*/ * 60 /*min*/ * 60 /*s*/,
2333 1762 'last' => time(),
2334 1763 );
2335 1764 endif;
2336 -
2337 - update_option( 'feedwordpress_diagnostics_log', $dlog );
1765 +
1766 + update_option('feedwordpress_diagnostics_log', $dlog);
2338 1767 } /* FeedWordPress::email_diagnostic_log () */
2339 -
2340 -
2341 - static function allow_html_mail() {
1768 +
1769 + function allow_html_mail () {
2342 1770 return 'text/html';
2343 1771 } /* FeedWordPress::allow_html_mail () */
2344 1772
2345 - static function admin_footer () {
1773 + function admin_footer () {
2346 1774 global $feedwordpress_admin_footer;
2347 1775 foreach ($feedwordpress_admin_footer as $line) :
2348 - echo '<div><pre>' . esc_html( $line ) . '</pre></div>';
1776 + echo '<div><pre>'.$line.'</pre></div>';
2349 1777 endforeach;
2350 1778 } /* FeedWordPress::admin_footer () */
2351 -
2352 - /**
2353 - * Returns the log prefix, optionally with a date.
2354 - *
2355 - * @param boolean $date If true, a date timestamp is added to the prefix.
2356 - * @return string Generated log prefix.
2357 - */
2358 - static function log_prefix ($date = false) {
1779 +
1780 + function log_prefix ($date = false) {
2359 1781 $home = get_bloginfo('url');
2360 1782 $prefix = '['.feedwordpress_display_url($home).'] [feedwordpress] ';
2361 1783 if ($date) :
2362 1784 $prefix = "[".date('Y-m-d H:i:s')."]".$prefix;
@@ -2362,16 +1784,10 @@
2362 1784 $prefix = "[".date('Y-m-d H:i:s')."]".$prefix;
2363 1785 endif;
2364 1786 return $prefix;
2365 1787 } /* FeedWordPress::log_prefix () */
2366 -
2367 - /**
2368 - * Returns the menu capacity value.
2369 - *
2370 - * @param boolean $sub If true, we're on a menu sublevel.
2371 - * @return mixed Returns the capacity.
2372 - */
2373 - static function menu_cap ($sub = false) {
1788 +
1789 + function menu_cap ($sub = false) {
2374 1790 if ($sub) :
2375 1791 $cap = apply_filters('feedwordpress_menu_settings_capacity', 'manage_options');
2376 1792 else :
2377 1793 $cap = apply_filters('feedwordpress_menu_main_capacity', 'manage_links');
@@ -2377,124 +1793,397 @@
2377 1793 $cap = apply_filters('feedwordpress_menu_main_capacity', 'manage_links');
2378 1794 endif;
2379 1795 return $cap;
2380 1796 } /* FeedWordPress::menu_cap () */
2381 -
2382 - public function plugin_dir_path ($path = '') {
2383 - $dir = plugin_dir_path( __FILE__ );
2384 - $file_path = "{$dir}{$path}";
2385 - return apply_filters( "feedwordpress_plugin_dir_path", $file_path );
2386 - } /* FeedWordPress::plugin_dir_path () */
2387 -
2388 - public function plugin_dir_url ($path = '') {
2389 - $url_path = plugins_url( $path, __FILE__ );
2390 - return apply_filters( "feedwordpress_plugin_dir_url", $url_path );
2391 - } /* FeedWordPRess::plugin_dir_url () */
2392 -
2393 - static function path ($filename = '') {
1797 +
1798 + function path ($filename = '') {
2394 1799 global $fwp_path;
2395 -
1800 +
2396 1801 $path = $fwp_path;
2397 1802 if (strlen($filename) > 0) :
2398 1803 $path .= '/'.$filename;
2399 1804 endif;
1805 + return $path;
1806 + }
1807 +
1808 + function param ($key, $type = 'REQUEST', $default = NULL) {
1809 + $where = '_'.strtoupper($type);
1810 + $ret = $default;
1811 + if (isset($GLOBALS[$where]) and is_array($GLOBALS[$where])) :
1812 + if (isset($GLOBALS[$where][$key])) :
1813 + $ret = $GLOBALS[$where][$key];
1814 + if (get_magic_quotes_gpc()) :
1815 + $ret = stripslashes_deep($ret);
1816 + endif;
1817 + endif;
1818 + endif;
1819 + return $ret;
1820 + }
1821 + function post ($key, $default = NULL) {
1822 + return FeedWordPress::param($key, 'POST');
1823 + }
1824 +} // class FeedWordPress
2400 1825
2401 - return $path;
2402 - } /* FeedWordPress::path () */
1826 +class FeedWordPress_File extends WP_SimplePie_File {
1827 + function FeedWordPress_File ($url, $timeout = 10, $redirects = 5, $headers = null, $useragent = null, $force_fsockopen = false) {
1828 + WP_SimplePie_File::WP_SimplePie_File($url, $timeout, $redirects, $headers, $useragent, $force_fsockopen);
2403 1829
2404 - // -- DEPRCATED UTILITY FUNCTIONS -------------------------------------
2405 - // These are superceded by later code re-organization, (for example
2406 - // MyPHP::param/post/get/request, or FeedWordPressDiagnostic methods),
2407 - // but for the last several versions have been kept here for backward
2408 - // compatibility with add-ons, older code, etc. Maybe someday they
2409 - // will go away.
2410 - // -------------------------------------------------------------------
2411 - static function param( $key, $type = 'REQUEST', $default = null, $sanitizer = null ) {
2412 - return self::sanitized_parameter( MyPHP::param( $key, $default, $type ), $sanitizer );
2413 - } /* FeedWordPress::param () */
1830 + // SimplePie makes a strongly typed check against integers with
1831 + // this, but WordPress puts a string in. Which causes caching
1832 + // to break and fall on its ass when SimplePie is getting a 304,
1833 + // but doesn't realize it because this member is "304" instead.
1834 + $this->status_code = (int) $this->status_code;
1835 + }
1836 +} /* class FeedWordPress_File () */
2414 1837
2415 - static function post( $key, $default = null, $sanitizer = null ) {
2416 - return self::sanitized_parameter( MyPHP::post( $key, $default ), $sanitizer );
2417 - } /* FeedWordPress::post () */
1838 +class FeedWordPress_Parser extends SimplePie_Parser {
1839 + function parse (&$data, $encoding) {
1840 + // Use UTF-8 if we get passed US-ASCII, as every US-ASCII character is a UTF-8 character
1841 + if (strtoupper($encoding) === 'US-ASCII')
1842 + {
1843 + $this->encoding = 'UTF-8';
1844 + }
1845 + else
1846 + {
1847 + $this->encoding = $encoding;
1848 + }
2418 1849
2419 - static function shallow_sanitize( $item, $sanitizer = null ) {
2420 - if ( $sanitizer == 'raw' ) :
2421 - $value = $item;
2422 - elseif ( $sanitizer == 'textarea' ) :
2423 - $value = sanitize_textarea_field( $item );
2424 - else :
2425 - $value = sanitize_text_field( $item );
1850 + // Strip BOM:
1851 + // UTF-32 Big Endian BOM
1852 + if (substr($data, 0, 4) === "\x00\x00\xFE\xFF")
1853 + {
1854 + $data = substr($data, 4);
1855 + }
1856 + // UTF-32 Little Endian BOM
1857 + elseif (substr($data, 0, 4) === "\xFF\xFE\x00\x00")
1858 + {
1859 + $data = substr($data, 4);
1860 + }
1861 + // UTF-16 Big Endian BOM
1862 + elseif (substr($data, 0, 2) === "\xFE\xFF")
1863 + {
1864 + $data = substr($data, 2);
1865 + }
1866 + // UTF-16 Little Endian BOM
1867 + elseif (substr($data, 0, 2) === "\xFF\xFE")
1868 + {
1869 + $data = substr($data, 2);
1870 + }
1871 + // UTF-8 BOM
1872 + elseif (substr($data, 0, 3) === "\xEF\xBB\xBF")
1873 + {
1874 + $data = substr($data, 3);
1875 + }
1876 +
1877 + if (substr($data, 0, 5) === '<?xml' && strspn(substr($data, 5, 1), "\x09\x0A\x0D\x20") && ($pos = strpos($data, '?>')) !== false)
1878 + {
1879 + $declaration =& new SimplePie_XML_Declaration_Parser(substr($data, 5, $pos - 5));
1880 + if ($declaration->parse())
1881 + {
1882 + $data = substr($data, $pos + 2);
1883 + $data = '<?xml version="' . $declaration->version . '" encoding="' . $encoding . '" standalone="' . (($declaration->standalone) ? 'yes' : 'no') . '"?>' . $data;
1884 + }
1885 + else
1886 + {
1887 + $this->error_string = 'SimplePie bug! Please report this!';
1888 + return false;
1889 + }
1890 + }
1891 +
1892 + $return = true;
1893 +
1894 + static $xml_is_sane = null;
1895 + if ($xml_is_sane === null)
1896 + {
1897 + $parser_check = xml_parser_create();
1898 + xml_parse_into_struct($parser_check, '<foo>&amp;</foo>', $values);
1899 + xml_parser_free($parser_check);
1900 + $xml_is_sane = isset($values[0]['value']);
1901 + }
1902 +
1903 + // Create the parser
1904 + if ($xml_is_sane)
1905 + {
1906 + $xml = xml_parser_create_ns($this->encoding, $this->separator);
1907 + xml_parser_set_option($xml, XML_OPTION_SKIP_WHITE, 1);
1908 + xml_parser_set_option($xml, XML_OPTION_CASE_FOLDING, 0);
1909 + xml_set_object($xml, $this);
1910 + xml_set_character_data_handler($xml, 'cdata');
1911 + xml_set_element_handler($xml, 'tag_open', 'tag_close');
1912 + xml_set_start_namespace_decl_handler($xml, 'start_xmlns');
1913 +
1914 + // Parse!
1915 + if (!xml_parse($xml, $data, true))
1916 + {
1917 + $this->error_code = xml_get_error_code($xml);
1918 + $this->error_string = xml_error_string($this->error_code);
1919 + $return = false;
1920 + }
1921 +
1922 + $this->current_line = xml_get_current_line_number($xml);
1923 + $this->current_column = xml_get_current_column_number($xml);
1924 + $this->current_byte = xml_get_current_byte_index($xml);
1925 + xml_parser_free($xml);
1926 +
1927 + return $return;
1928 + }
1929 + else
1930 + {
1931 + libxml_clear_errors();
1932 + $xml =& new XMLReader();
1933 + $xml->xml($data);
1934 + while (@$xml->read())
1935 + {
1936 + switch ($xml->nodeType)
1937 + {
1938 +
1939 + case constant('XMLReader::END_ELEMENT'):
1940 + if ($xml->namespaceURI !== '')
1941 + {
1942 + $tagName = "{$xml->namespaceURI}{$this->separator}{$xml->localName}";
1943 + }
1944 + else
1945 + {
1946 + $tagName = $xml->localName;
1947 + }
1948 + $this->tag_close(null, $tagName);
1949 + break;
1950 + case constant('XMLReader::ELEMENT'):
1951 + $empty = $xml->isEmptyElement;
1952 + if ($xml->namespaceURI !== '')
1953 + {
1954 + $tagName = "{$xml->namespaceURI}{$this->separator}{$xml->localName}";
1955 + }
1956 + else
1957 + {
1958 + $tagName = $xml->localName;
1959 + }
1960 + $attributes = array();
1961 + while ($xml->moveToNextAttribute())
1962 + {
1963 + if ($xml->namespaceURI !== '')
1964 + {
1965 + $attrName = "{$xml->namespaceURI}{$this->separator}{$xml->localName}";
1966 + }
1967 + else
1968 + {
1969 + $attrName = $xml->localName;
1970 + }
1971 + $attributes[$attrName] = $xml->value;
1972 + }
1973 +
1974 + foreach ($attributes as $attr => $value) :
1975 + list($ns, $local) = $this->split_ns($attr);
1976 + if ($ns=='http://www.w3.org/2000/xmlns/') :
1977 + if ('xmlns' == $local) : $local = false; endif;
1978 + $this->start_xmlns(null, $local, $value);
1979 + endif;
1980 + endforeach;
1981 +
1982 + $this->tag_open(null, $tagName, $attributes);
1983 + if ($empty)
1984 + {
1985 + $this->tag_close(null, $tagName);
1986 + }
1987 + break;
1988 + case constant('XMLReader::TEXT'):
1989 +
1990 + case constant('XMLReader::CDATA'):
1991 + $this->cdata(null, $xml->value);
1992 + break;
1993 + }
1994 + }
1995 + if ($error = libxml_get_last_error())
1996 + {
1997 + $this->error_code = $error->code;
1998 + $this->error_string = $error->message;
1999 + $this->current_line = $error->line;
2000 + $this->current_column = $error->column;
2001 + return false;
2002 + }
2003 + else
2004 + {
2005 + return true;
2006 + }
2007 + }
2008 + } /* FeedWordPress_Parser::parse() */
2009 +
2010 + var $xmlns_stack = array();
2011 + var $xmlns_current = array();
2012 + function tag_open ($parser, $tag, $attributes) {
2013 + $ret = parent::tag_open($parser, $tag, $attributes);
2014 + if ($this->current_xhtml_construct < 0) :
2015 + $this->data['xmlns'] = $this->xmlns_current;
2016 + $this->xmlns_stack[] = $this->xmlns_current;
2426 2017 endif;
2427 - return $value;
2018 + return $ret;
2428 2019 }
2429 -
2430 - static function sanitized_parameter( $value, $sanitizer = null ) {
2431 - if ( $sanitizer === 'raw' || is_scalar( $value ) ) :
2432 - $ret = self::shallow_sanitize( $value, $sanitizer );
2433 - elseif ( is_array( $value ) ) :
2434 - $ret = array();
2435 - foreach ( $value as $key => $item ) :
2436 - $ret[ $key ] = self::sanitized_parameter( $item, $sanitizer );
2437 - endforeach;
2438 - else :
2439 - $ret = null; // "Sanitized" objects or resources currently get nothing.
2020 +
2021 + function tag_close($parser, $tag) {
2022 + if ($this->current_xhtml_construct < 0) :
2023 + $this->xmlns_current = array_pop($this->xmlns_stack);
2440 2024 endif;
2025 + $ret = parent::tag_close($parser, $tag);
2441 2026 return $ret;
2442 2027 }
2028 +
2029 + function start_xmlns ($parser, $prefix, $uri) {
2030 + if (!$prefix) :
2031 + $prefix = '';
2032 + endif;
2033 + if ($this->current_xhtml_construct < 0) :
2034 + $this->xmlns_current[$prefix] = $uri;
2035 + endif;
2036 + return true;
2037 + } /* FeedWordPress_Parser::start_xmlns() */
2038 +}
2443 2039
2444 - static function val ($v, $no_newlines = false) {
2445 - return MyPHP::val($v, $no_newlines);
2446 - } /* FeedWordPress::val () */
2040 +$feedwordpress_admin_footer = array();
2447 2041
2448 - static function critical_bug ($varname, $var, $line, $file = null) {
2449 - FeedWordPressDiagnostic::critical_bug($varname, $var, $line, $file);
2450 - } /* FeedWordPress::critical_bug () */
2042 +################################################################################
2043 +## XML-RPC HOOKS: accept XML-RPC update pings from Contributors ################
2044 +################################################################################
2451 2045
2452 - static function noncritical_bug ($varname, $var, $line, $file = null) {
2453 - FeedWordPressDiagnostic::noncritical_bug($varname, $var, $line, $file);
2454 - } /* FeedWordPress::noncritical_bug () */
2046 +class FeedWordPressRPC {
2047 + function FeedWordPressRPC () {
2048 + add_filter('xmlrpc_methods', array(&$this, 'xmlrpc_methods'));
2049 + }
2050 +
2051 + function xmlrpc_methods ($args = array()) {
2052 + $args['weblogUpdates.ping'] = array(&$this, 'ping');
2053 + $args['feedwordpress.subscribe'] = array(&$this, 'subscribe');
2054 + $args['feedwordpress.deactivate'] = array(&$this, 'deactivate');
2055 + $args['feedwordpress.delete'] = array(&$this, 'delete');
2056 + $args['feedwordpress.nuke'] = array(&$this, 'nuke');
2057 + return $args;
2058 + }
2059 +
2060 + function ping ($args) {
2061 + global $feedwordpress;
2062 +
2063 + $delta = @$feedwordpress->update($args[1]);
2064 + if (is_null($delta)):
2065 + return array('flerror' => true, 'message' => "Sorry. I don't syndicate <$args[1]>.");
2066 + else:
2067 + $mesg = array();
2068 + if (isset($delta['new'])) { $mesg[] = ' '.$delta['new'].' new posts were syndicated'; }
2069 + if (isset($delta['updated'])) { $mesg[] = ' '.$delta['updated'].' existing posts were updated'; }
2070 +
2071 + return array('flerror' => false, 'message' => "Thanks for the ping.".implode(' and', $mesg));
2072 + endif;
2073 + }
2074 +
2075 + function validate (&$args) {
2076 + global $wp_xmlrpc_server;
2455 2077
2456 - static function diagnostic_on ($level) {
2457 - return FeedWordPressDiagnostic::is_on($level);
2458 - } /* FeedWordPress::diagnostic_on () */
2078 + // First two params are username/password
2079 + $username = $wp_xmlrpc_server->escape(array_shift($args));
2080 + $password = $wp_xmlrpc_server->escape(array_shift($args));
2459 2081
2460 -} /* class FeedWordPress */
2082 + $ret = array();
2083 + if ( !$user = $wp_xmlrpc_server->login($username, $password) ) :
2084 + $ret = $wp_xmlrpc_server->error;
2085 + elseif (!current_user_can('manage_links')) :
2086 + $ret = new IXR_Error(401, 'Sorry, you cannot change the subscription list.');
2087 + endif;
2088 + return $ret;
2089 + }
2461 2090
2462 -$feedwordpress_admin_footer = array();
2091 + function subscribe ($args) {
2092 + $ret = $this->validate($args);
2093 + if (is_array($ret)) : // Success
2094 + // The remaining params are feed URLs
2095 + foreach ($args as $arg) :
2096 + $finder = new FeedFinder($arg, /*verify=*/ false, /*fallbacks=*/ 1);
2097 + $feeds = array_values(array_unique($finder->find()));
2098 +
2099 + if (count($feeds) > 0) :
2100 + $link_id = FeedWordPress::syndicate_link(
2101 + /*title=*/ feedwordpress_display_url($feeds[0]),
2102 + /*homepage=*/ $feeds[0],
2103 + /*feed=*/ $feeds[0]
2104 + );
2105 + $ret[] = array(
2106 + 'added',
2107 + $feeds[0],
2108 + $arg,
2109 + );
2110 + else :
2111 + $ret[] = array(
2112 + 'error',
2113 + $arg
2114 + );
2115 + endif;
2116 + endforeach;
2117 + endif;
2118 + return $ret;
2119 + } /* FeedWordPressRPC::subscribe () */
2120 +
2121 + function unsubscribe ($method, $args) {
2122 + $ret = $this->validate($args);
2123 + if (is_array($ret)) : // Success
2124 + // The remaining params are feed URLs
2125 + foreach ($args as $arg) :
2126 + $link_id = FeedWordPress::find_link($arg);
2127 +
2128 + if (!$link_id) :
2129 + $link_id = FeedWordPress::find_link($arg, 'link_url');
2130 + endif;
2131 +
2132 + if ($link_id) :
2133 + $link = new SyndicatedLink($link_id);
2134 +
2135 + $link->{$method}();
2136 + $ret[] = array(
2137 + 'deactivated',
2138 + $arg,
2139 + );
2140 + else :
2141 + $ret[] = array(
2142 + 'error',
2143 + $arg,
2144 + );
2145 + endif;
2146 + endforeach;
2147 + endif;
2148 + return $ret;
2149 + } /* FeedWordPress::unsubscribe () */
2150 +
2151 + function deactivate ($args) {
2152 + return $this->unsubscribe('deactivate', $args);
2153 + } /* FeedWordPressRPC::deactivate () */
2154 +
2155 + function delete ($args) {
2156 + return $this->unsubscribe('delete', $args);
2157 + } /* FeedWordPressRPC::delete () */
2158 +
2159 + function nuke ($args) {
2160 + return $this->unsubscribe('nuke', $args);
2161 + } /* FeedWordPressRPC::nuke () */
2162 +} /* class FeedWordPressRPC */
2463 2163
2464 2164 // take your best guess at the realname and e-mail, given a string
2465 -define( 'FWP_REGEX_EMAIL_ADDY', '([^@"(<\s]+@[^"@(<\s]+\.[^"@(<\s]+)' );
2466 -define( 'FWP_REGEX_EMAIL_NAME', '("([^"]*)"|([^"<(]+\S))' );
2467 -define( 'FWP_REGEX_EMAIL_POSTFIX_NAME', '/^\s*' . FWP_REGEX_EMAIL_ADDY . '\s+\(' . FWP_REGEX_EMAIL_NAME . '\)\s*$/' );
2468 -define( 'FWP_REGEX_EMAIL_PREFIX_NAME', '/^\s*' . FWP_REGEX_EMAIL_NAME . '\s*<' . FWP_REGEX_EMAIL_ADDY . '>\s*$/' );
2469 -define( 'FWP_REGEX_EMAIL_JUST_ADDY', '/^\s*' . FWP_REGEX_EMAIL_ADDY . '\s*$/' );
2470 -define( 'FWP_REGEX_EMAIL_JUST_NAME', '/^\s*' . FWP_REGEX_EMAIL_NAME . '\s*$/' );
2165 +define('FWP_REGEX_EMAIL_ADDY', '([^@"(<\s]+@[^"@(<\s]+\.[^"@(<\s]+)');
2166 +define('FWP_REGEX_EMAIL_NAME', '("([^"]*)"|([^"<(]+\S))');
2167 +define('FWP_REGEX_EMAIL_POSTFIX_NAME', '/^\s*'.FWP_REGEX_EMAIL_ADDY."\s+\(".FWP_REGEX_EMAIL_NAME.'\)\s*$/');
2168 +define('FWP_REGEX_EMAIL_PREFIX_NAME', '/^\s*'.FWP_REGEX_EMAIL_NAME.'\s*<'.FWP_REGEX_EMAIL_ADDY.'>\s*$/');
2169 +define('FWP_REGEX_EMAIL_JUST_ADDY', '/^\s*'.FWP_REGEX_EMAIL_ADDY.'\s*$/');
2170 +define('FWP_REGEX_EMAIL_JUST_NAME', '/^\s*'.FWP_REGEX_EMAIL_NAME.'\s*$/');
2471 2171
2472 -/**
2473 - * Parses an email address that includes the real name as well.
2474 - *
2475 - * @param string $email Email address to parse.
2476 - *
2477 - * @return array Associative array with 'name' and 'email' as fields (each may be null).
2478 - */
2479 -function parse_email_with_realname( $email ) {
2480 - $ret = array(
2481 - 'name' => null,
2482 - 'email' => null
2483 - ); // avoid uninitialized variables for return values, this will generate a notice/warning - and one day, an error! (gwyneth 20210714)
2484 -
2485 - if ( preg_match( FWP_REGEX_EMAIL_POSTFIX_NAME, $email, $matches ) ) :
2486 - ( $ret['name'] = $matches[3] ) || ( $ret['name'] = $matches[2] );
2172 +function parse_email_with_realname ($email) {
2173 + if (preg_match(FWP_REGEX_EMAIL_POSTFIX_NAME, $email, $matches)) :
2174 + ($ret['name'] = $matches[3]) or ($ret['name'] = $matches[2]);
2487 2175 $ret['email'] = $matches[1];
2488 - elseif ( preg_match( FWP_REGEX_EMAIL_PREFIX_NAME, $email, $matches ) ) :
2489 - ( $ret['name'] = $matches[2] ) || ( $ret['name'] = $matches[3] );
2176 + elseif (preg_match(FWP_REGEX_EMAIL_PREFIX_NAME, $email, $matches)) :
2177 + ($ret['name'] = $matches[2]) or ($ret['name'] = $matches[3]);
2490 2178 $ret['email'] = $matches[4];
2491 -
2492 - elseif ( preg_match( FWP_REGEX_EMAIL_JUST_ADDY, $email, $matches ) ) :
2493 - $ret['name'] = null;
2494 - $ret['email'] = $matches[1];
2495 - elseif ( preg_match( FWP_REGEX_EMAIL_JUST_NAME, $email, $matches ) ) :
2496 - $ret['email'] = null;
2497 - ( $ret['name'] = $matches[2] ) || ( $ret['name'] = $matches[3] );
2179 + elseif (preg_match(FWP_REGEX_EMAIL_JUST_ADDY, $email, $matches)) :
2180 + $ret['name'] = NULL; $ret['email'] = $matches[1];
2181 + elseif (preg_match(FWP_REGEX_EMAIL_JUST_NAME, $email, $matches)) :
2182 + $ret['email'] = NULL;
2183 + ($ret['name'] = $matches[2]) or ($ret['name'] = $matches[3]);
2184 + else :
2185 + $ret['name'] = NULL; $ret['email'] = NULL;
2498 2186 endif;
2499 2187 return $ret;
2500 2188 }
2189 +