PluginProbe
FeedWordPress / 0.993
FeedWordPress v0.993
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 +2178 -826 2009.06180.993 View file →
@@ -2,12 +2,13 @@
2 2 /*
3 3 Plugin Name: FeedWordPress
4 4 Plugin URI: http://projects.radgeek.com/feedwordpress
5 5 Description: simple and flexible Atom/RSS syndication for WordPress
6 -Version: 2009.0618
6 +Version: 0.993
7 7 Author: Charles Johnson
8 8 Author URI: http://radgeek.com/
9 9 License: GPL
10 +Last modified: 2008-05-08 4:48 PM PDT
10 11 */
11 12
12 13 # This uses code derived from:
13 14 # - wp-rss-aggregate.php by Kellan Elliot-McCrea <kellan@protest.net>
@@ -14,30 +15,24 @@
14 15 # - HTTP Navigator 2 by Keyvan Minoukadeh <keyvan@k1m.com>
15 16 # - Ultra-Liberal Feed Finder by Mark Pilgrim <mark@diveintomark.org>
16 17 # according to the terms of the GNU General Public License.
17 18 #
18 -# INSTALLATION: see readme.txt or <http://projects.radgeek.com/install>
19 +# INSTALLATION: see README.text or <http://projects.radgeek.com/install>
19 20 #
20 21 # USAGE: once FeedWordPress is installed, you manage just about everything from
21 -# the WordPress Dashboard, under the Syndication menu. To ensure that fresh
22 -# content is added as it becomes available, you can convince your contributors
23 -# to put your XML-RPC URI (if WordPress is installed at
22 +# the WordPress Dashboard, under Options --> Syndication or Links --> Syndicated
23 +# To ensure that fresh content is added as it becomes available, get your
24 +# contributors to put your XML-RPC URI (if WordPress is installed at
24 25 # <http://www.zyx.com/blog>, XML-RPC requests should be sent to
25 -# <http://www.zyx.com/blog/xmlrpc.php>), or update manually under the
26 -# Syndication menu, or set up automatic updates under Syndication --> Settings,
27 -# or use a cron job.
26 +# <http://www.zyx.com/blog/xmlrpc.php>), or see `update-feeds.php`
28 27
29 28 # -- Don't change these unless you know what you're doing...
30 29
31 -define ('FEEDWORDPRESS_VERSION', '2009.0612');
30 +define ('FEEDWORDPRESS_VERSION', '0.993');
32 31 define ('FEEDWORDPRESS_AUTHOR_CONTACT', 'http://radgeek.com/contact');
33 32 define ('DEFAULT_SYNDICATION_CATEGORY', 'Contributors');
34 33
35 -$feedwordpress_debug = get_option('feedwordpress_debug');
36 -if (is_string($feedwordpress_debug)) :
37 - $feedwordpress_debug = ($feedwordpress_debug == 'yes');
38 -endif;
39 -define ('FEEDWORDPRESS_DEBUG', $feedwordpress_debug);
34 +define ('FEEDWORDPRESS_DEBUG', false);
40 35
41 36 define ('FEEDWORDPRESS_CAT_SEPARATOR_PATTERN', '/[:\n]/');
42 37 define ('FEEDWORDPRESS_CAT_SEPARATOR', "\n");
43 38
@@ -44,15 +39,12 @@
44 39 define ('FEEDVALIDATOR_URI', 'http://feedvalidator.org/check.cgi');
45 40
46 41 define ('FEEDWORDPRESS_FRESHNESS_INTERVAL', 10*60); // Every ten minutes
47 42
48 -define ('FWP_SCHEMA_HAS_USERMETA', 2966);
49 43 define ('FWP_SCHEMA_20', 3308); // Database schema # for WP 2.0
50 44 define ('FWP_SCHEMA_21', 4772); // Database schema # for WP 2.1
51 45 define ('FWP_SCHEMA_23', 5495); // Database schema # for WP 2.3
52 46 define ('FWP_SCHEMA_25', 7558); // Database schema # for WP 2.5
53 -define ('FWP_SCHEMA_26', 8201); // Database schema # for WP 2.6
54 -define ('FWP_SCHEMA_27', 9872); // Database schema # for WP 2.7
55 47
56 48 if (FEEDWORDPRESS_DEBUG) :
57 49 // Help us to pick out errors, if any.
58 50 ini_set('error_reporting', E_ALL & ~E_NOTICE);
@@ -90,10 +82,16 @@
90 82 require_once (ABSPATH . 'wp-admin/admin-db.php'); // for wp_insert_category
91 83 endif;
92 84 endif;
93 85
94 -require_once(dirname(__FILE__) . '/compatability.php'); // LEGACY API: Replicate or mock up functions for legacy support purposes
95 -require_once(dirname(__FILE__) . '/feedwordpresshtml.class.php');
86 +if (function_exists('wp_enqueue_script')) :
87 + if (isset($wp_db_version) and $wp_db_version >= FWP_SCHEMA_25) :
88 + wp_enqueue_script('post');
89 + wp_enqueue_script('thickbox');
90 + else :
91 + wp_enqueue_script( 'ajaxcat' ); // Provides the handy-dandy new category text box
92 + endif;
93 +endif;
96 94
97 95 // Magic quotes are just about the stupidest thing ever.
98 96 if (is_array($_POST)) :
99 97 $fwp_post = stripslashes_deep($_POST);
@@ -111,32 +109,8 @@
111 109 else : // Something went wrong. Let's just guess.
112 110 $fwp_path = 'feedwordpress';
113 111 endif;
114 112
115 -// If this is a FeedWordPress admin page, queue up scripts for AJAX functions that FWP uses
116 -// If it is a display page or a non-FeedWordPress admin page, don't.
117 -if (is_admin() and isset($_REQUEST['page']) and preg_match("|^{$fwp_path}/|", $_REQUEST['page'])) :
118 - if (function_exists('wp_enqueue_script')) :
119 - if (isset($wp_db_version) and $wp_db_version >= FWP_SCHEMA_25) :
120 - wp_enqueue_script('post'); // for magic tag and category boxes
121 - wp_enqueue_script('thickbox'); // for fold-up boxes
122 - wp_enqueue_script('admin-forms'); // for checkbox selection
123 - else :
124 - wp_enqueue_script( 'ajaxcat' ); // Provides the handy-dandy new category text box
125 - endif;
126 - endif;
127 - if (function_exists('wp_enqueue_style')) :
128 - if (fwp_test_wp_version(FWP_SCHEMA_25)) :
129 - wp_enqueue_style('dashboard');
130 - endif;
131 - endif;
132 - if (function_exists('wp_admin_css')) :
133 - if (fwp_test_wp_version(FWP_SCHEMA_25)) :
134 - wp_admin_css('css/dashboard');
135 - endif;
136 - endif;
137 -endif;
138 -
139 113 if (!FeedWordPress::needs_upgrade()) : // only work if the conditions are safe!
140 114
141 115 # Syndicated items are generally received in output-ready (X)HTML and
142 116 # should not be folded, crumpled, mutilated, or spindled by WordPress
@@ -153,10 +127,8 @@
153 127
154 128 add_filter('the_content', 'feedwordpress_preserve_syndicated_content', -10000);
155 129 add_filter('the_content', 'feedwordpress_restore_syndicated_content', 10000);
156 130
157 - add_action('atom_entry', 'feedwordpress_item_feed_data');
158 -
159 131 # Filter in original permalinks if the user wants that
160 132 add_filter('post_link', 'syndication_permalink', 1);
161 133
162 134 # WTF? By default, wp_insert_link runs incoming link_url and link_rss
@@ -167,11 +139,9 @@
167 139 remove_filter('pre_link_url', 'wp_filter_kses');
168 140
169 141 # Admin menu
170 142 add_action('admin_menu', 'fwp_add_pages');
171 - add_action('admin_notices', 'fwp_check_debug');
172 - add_action('admin_notices', 'fwp_check_magpie');
173 -
143 +
174 144 # Inbound XML-RPC update methods
175 145 add_filter('xmlrpc_methods', 'feedwordpress_xmlrpc_hook');
176 146
177 147 # Outbound XML-RPC ping reform
@@ -195,12 +165,10 @@
195 165 endif;
196 166
197 167 # Cron-less auto-update. Hooray!
198 168 add_action('init', 'feedwordpress_auto_update');
199 - add_action('init', 'feedwordpress_check_for_magpie_fix');
200 169
201 170 # Default sanitizers
202 - add_filter('syndicated_item_content', array('SyndicatedPost', 'resolve_relative_uris'), 0, 2);
203 171 add_filter('syndicated_item_content', array('SyndicatedPost', 'sanitize_content'), 0, 2);
204 172
205 173 else :
206 174 # Hook in the menus, which will just point to the upgrade interface
@@ -206,33 +174,8 @@
206 174 # Hook in the menus, which will just point to the upgrade interface
207 175 add_action('admin_menu', 'fwp_add_pages');
208 176 endif; // if (!FeedWordPress::needs_upgrade())
209 177
210 -function feedwordpress_check_for_magpie_fix () {
211 - if (isset($_POST['action']) and $_POST['action']=='fix_magpie_version') :
212 - FeedWordPressCompatibility::validate_http_request(/*action=*/ 'feedwordpress_fix_magpie', /*capability=*/ 'edit_files');
213 -
214 - $back_to = $_SERVER['REQUEST_URI'];
215 - if (isset($_POST['ignore'])) :
216 - // kill error message by telling it we ignored the upgrade request for this version
217 - update_option('feedwordpress_magpie_ignored_upgrade_to', EXPECTED_MAGPIE_VERSION);
218 - $ret = 'ignored';
219 - elseif (isset($_POST['upgrade'])) :
220 - $source = dirname(__FILE__)."/MagpieRSS-upgrade/rss.php";
221 - $destination = ABSPATH . WPINC . '/rss.php';
222 - $success = @copy($source, $destination);
223 - $ret = (int) $success;
224 - endif;
225 -
226 - if (strpos($back_to, '?')===false) : $sep = '?';
227 - else : $sep = '&';
228 - endif;
229 -
230 - header("Location: {$back_to}{$sep}feedwordpress_magpie_fix=".$ret);
231 - exit;
232 - endif;
233 -} /* feedwordpress_check_for_magpie_fix() */
234 -
235 178 function feedwordpress_auto_update () {
236 179 if (FeedWordPress::stale()) :
237 180 $feedwordpress =& new FeedWordPress;
238 181 $feedwordpress->update();
@@ -280,85 +223,102 @@
280 223 : implode(' and ', $mesg)));
281 224 }
282 225
283 226 ################################################################################
284 -## TEMPLATE API: functions to make your templates syndication-aware ############
227 +## LEGACY API: Replicate or mock up functions for legacy support purposes ######
285 228 ################################################################################
286 229
287 -function is_syndicated () { return (strlen(get_syndication_feed_id()) > 0); }
230 +if (!function_exists('get_option')) {
231 + function get_option ($option) {
232 + return get_settings($option);
233 + }
234 +}
235 +if (!function_exists('current_user_can')) {
236 + $legacy_capability_hack = true;
237 + function current_user_can ($task) {
238 + global $user_level;
288 239
289 -function get_syndication_source_link ($original = NULL) {
290 - if (is_null($original)) : $original = FeedWordPress::use_aggregator_source_data();
291 - endif;
240 + $can = false;
292 241
293 - if ($original) : $vals = get_post_custom_values('syndication_source_uri_original');
294 - else : $vals = array();
295 - endif;
296 -
297 - if (count($vals) == 0) : $vals = get_post_custom_values('syndication_source_uri');
298 - endif;
299 -
300 - if (count($vals) > 0) : $ret = $vals[0]; else : $ret = NULL; endif;
242 + // This is **not** a full replacement for current_user_can. It
243 + // is only for checking the capabilities we care about via the
244 + // WordPress 1.5 user levels.
245 + switch ($task) {
246 + case 'manage_options':
247 + $can = ($user_level >= 6);
248 + break;
249 + case 'manage_links':
250 + $can = ($user_level >= 5);
251 + break;
252 + } /* switch */
253 + return $can;
254 + }
255 +} else {
256 + $legacy_capability_hack = false;
257 +}
258 +if (!function_exists('sanitize_user')) {
259 + function sanitize_user ($text, $strict) {
260 + return $text; // Don't munge it if it wasn't munged going in...
261 + }
262 +}
263 +if (!function_exists('wp_insert_user')) {
264 + function wp_insert_user ($userdata) {
265 + #-- Help WordPress 1.5.x quack like a duck
266 + $login = $userdata['user_login'];
267 + $author = $userdata['display_name'];
268 + $nice_author = $userdata['user_nicename'];
269 + $email = $userdata['user_email'];
270 + $url = $userdata['user_url'];
301 271
302 - return $ret;
303 -} /* function get_syndication_source_link() */
272 + $wpdb->query (
273 + "INSERT INTO $wpdb->users
274 + SET
275 + ID='0',
276 + user_login='$login',
277 + user_firstname='$author',
278 + user_nickname='$author',
279 + user_nicename='$nice_author',
280 + user_description='$author',
281 + user_email='$email',
282 + user_url='$url'");
283 + $id = $wpdb->insert_id;
284 +
285 + return $id;
286 + }
287 +}
304 288
305 -function the_syndication_source_link ($original = NULL) { echo get_syndication_source_link($original); }
289 +function fwp_category_checklist ($post_id = 0, $descendents_and_self = 0, $selected_cats = false) {
290 + if (function_exists('wp_category_checklist')) :
291 + wp_category_checklist($post_id, $descendents_and_self, $selected_cats);
292 + else :
293 + global $checked_categories;
306 294
307 -function get_syndication_source ($original = NULL) {
308 - if (is_null($original)) : $original = FeedWordPress::use_aggregator_source_data();
295 + // selected_cats is an array of integer cat_IDs / term_ids for
296 + // the categories that should be checked
297 + $cats = array();
298 + if ($post_id) : $cats = wp_get_post_categories($post_id);
299 + else : $cats = $selected_cats;
300 + endif;
301 +
302 + $checked_categories = $cats;
303 + dropdown_categories();
309 304 endif;
305 +}
306 +################################################################################
307 +## TEMPLATE API: functions to make your templates syndication-aware ############
308 +################################################################################
310 309
311 - if ($original) : $vals = get_post_custom_values('syndication_source_original');
312 - else : $vals = array();
313 - endif;
314 -
315 - if (count($vals) == 0) : $vals = get_post_custom_values('syndication_source');
316 - endif;
317 -
318 - if (count($vals) > 0) : $ret = $vals[0]; else : $ret = NULL; endif;
310 +function is_syndicated () { return (strlen(get_syndication_feed_id()) > 0); }
319 311
320 - return $ret;
321 -} /* function get_syndication_source() */
312 +function the_syndication_source_link () { echo get_syndication_source_link(); }
313 +function get_syndication_source_link () { list($n) = get_post_custom_values('syndication_source_uri'); return $n; }
322 314
323 -function the_syndication_source ($original = NULL) { echo get_syndication_source($original); }
315 +function get_syndication_source () { list($n) = get_post_custom_values('syndication_source'); return $n; }
316 +function the_syndication_source () { echo get_syndication_source(); }
324 317
325 -function get_syndication_feed ($original = NULL) {
326 - if (is_null($original)) : $original = FeedWordPress::use_aggregator_source_data();
327 - endif;
318 +function get_syndication_feed () { list($u) = get_post_custom_values('syndication_feed'); return $u; }
319 +function the_syndication_feed () { echo get_syndication_feed (); }
328 320
329 - if ($original) : $vals = get_post_custom_values('syndication_feed_original');
330 - else : $vals = array();
331 - endif;
332 -
333 - if (count($vals) == 0) : $vals = get_post_custom_values('syndication_feed');
334 - endif;
335 -
336 - if (count($vals) > 0) : $ret = $vals[0]; else : $ret = NULL; endif;
337 -
338 - return $ret;
339 -} /* function get_syndication_feed() */
340 -
341 -function the_syndication_feed ($original = NULL) { echo get_syndication_feed ($original); }
342 -
343 -function get_syndication_feed_guid ($original = NULL) {
344 - if (is_null($original)) : $original = FeedWordPress::use_aggregator_source_data();
345 - endif;
346 -
347 - if ($original) : $vals = get_post_custom_values('syndication_source_id_original');
348 - else : $vals = array();
349 - endif;
350 -
351 - if (count($vals) == 0) : $vals = array(get_feed_meta('feed/id'));
352 - endif;
353 -
354 - if (count($vals) > 0) : $ret = $vals[0]; else : $ret = NULL; endif;
355 -
356 - return $ret;
357 -} /* function get_syndication_feed_guid () */
358 -
359 -function the_syndication_feed_guid ($original = NULL) { echo get_syndication_feed_guid($original); }
360 -
361 321 function get_syndication_feed_id () { list($u) = get_post_custom_values('syndication_feed_id'); return $u; }
362 322 function the_syndication_feed_id () { echo get_syndication_feed_id(); }
363 323
364 324 $feedwordpress_linkcache = array (); // only load links from database once
@@ -396,13 +356,9 @@
396 356
397 357 function feedwordpress_preserve_syndicated_content ($text) {
398 358 global $feedwordpress_the_syndicated_content;
399 359
400 - $globalExpose = (get_option('feedwordpress_formatting_filters') == 'yes');
401 - $localExpose = get_post_custom_values('_feedwordpress_formatting_filters');
402 - $expose = ($globalExpose or ((count($localExpose) > 0) and $localExpose[0]));
403 -
404 - if ( is_syndicated() and !$expose ) :
360 + if ( is_syndicated() ) :
405 361 $feedwordpress_the_syndicated_content = $text;
406 362 else :
407 363 $feedwordpress_the_syndicated_content = NULL;
408 364 endif;
@@ -418,34 +374,8 @@
418 374
419 375 return $text;
420 376 }
421 377
422 -function feedwordpress_item_feed_data () {
423 - // In a post context....
424 - if (is_syndicated()) :
425 -?>
426 -<source>
427 - <title><?php the_syndication_source(); ?></title>
428 - <link rel="alternate" type="text/html" href="<?php the_syndication_source_link(); ?>" />
429 - <link rel="self" href="<?php the_syndication_feed(); ?>" />
430 -<?php
431 - $id = get_syndication_feed_guid();
432 - if (strlen($id) > 0) :
433 -?>
434 - <id><?php print $id; ?></id>
435 -<?php
436 - endif;
437 - $updated = get_feed_meta('feed/updated');
438 - if (strlen($updated) > 0) : ?>
439 - <updated><?php print $updated; ?></updated>
440 -<?php
441 - endif;
442 -?>
443 -</source>
444 -<?php
445 - endif;
446 -}
447 -
448 378 function syndication_permalink ($permalink = '') {
449 379 if (get_option('feedwordpress_munge_permalink') != 'no'):
450 380 $uri = get_syndication_permalink();
451 381 return ((strlen($uri) > 0) ? $uri : $permalink);
@@ -454,146 +384,1369 @@
454 384 endif;
455 385 } // function syndication_permalink ()
456 386
457 387 ################################################################################
458 -## ADMIN MENU ADD-ONS: register Dashboard management pages #####################
388 +## UPGRADE INTERFACE: Have users upgrade DB from older versions of FWP #########
459 389 ################################################################################
460 390
391 +function fwp_upgrade_page () {
392 + if (isset($GLOBALS['fwp_post']['action']) and $GLOBALS['fwp_post']['action']=='Upgrade') :
393 + $ver = get_option('feedwordpress_version');
394 + if (get_option('feedwordpress_version') != FEEDWORDPRESS_VERSION) :
395 + echo "<div class=\"wrap\">\n";
396 + echo "<h2>Upgrading FeedWordPress...</h2>";
397 +
398 + $feedwordpress =& new FeedWordPress;
399 + $feedwordpress->upgrade_database();
400 + echo "<p><strong>Done!</strong> Upgraded database to version ".FEEDWORDPRESS_VERSION.".</p>\n";
401 + echo "<form action=\"\" method=\"get\">\n";
402 + echo "<div class=\"submit\"><input type=\"hidden\" name=\"page\" value=\"".basename(__FILE__)."\" />";
403 + echo "<input type=\"submit\" value=\"Continue &raquo;\" /></form></div>\n";
404 + echo "</div>\n";
405 + return;
406 + else :
407 + echo "<div class=\"updated\"><p>Already at version ".FEEDWORDPRESS_VERSION."!</p></div>";
408 + endif;
409 + endif;
410 +?>
411 +<div class="wrap">
412 +<h2>Upgrade FeedWordPress</h2>
413 +
414 +<p>It appears that you have installed FeedWordPress
415 +<?php echo FEEDWORDPRESS_VERSION; ?> as an upgrade to an existing installation of
416 +FeedWordPress. That's no problem, but you will need to take a minute out first
417 +to upgrade your database: some necessary changes in how the software keeps
418 +track of posts and feeds will cause problems such as duplicate posts and broken
419 +templates if we were to continue without the upgrade.</p>
420 +
421 +<p>Note that most of FeedWordPress's functionality is temporarily disabled
422 +until we have successfully completed the upgrade. Everything should begin
423 +working as normal again once the upgrade is complete. There's extraordinarily
424 +little chance of any damage as the result of the upgrade, but if you're paranoid
425 +like me you may want to back up your database before you proceed.</p>
426 +
427 +<p>This may take several minutes for a large installation.</p>
428 +
429 +<form action="" method="post">
430 +<div class="submit"><input type="submit" name="action" value="Upgrade" /></div>
431 +</form>
432 +</div>
433 +<?php
434 +} // function fwp_upgrade_page ()
435 +
436 +################################################################################
437 +## ADMIN MENU ADD-ONS: implement Dashboard management pages ####################
438 +################################################################################
439 +
461 440 function fwp_add_pages () {
462 - global $fwp_capability;
441 + global $legacy_capability_hack;
463 442 global $fwp_path;
464 443
465 - $menu = array('Syndicated Sites', 'Syndication', $fwp_capability['manage_links'], $fwp_path.'/syndication.php', NULL);
466 - if (fwp_test_wp_version(FWP_SCHEMA_27)) :
467 - // add icon parameter
468 - $menu[] = WP_PLUGIN_URL.'/'.$fwp_path.'/feedwordpress-tiny.png';
444 + if ($legacy_capability_hack) :
445 + // old & busted: numeric user levels
446 + $manage_links = 5;
447 + $manage_options = 6;
448 + else :
449 + // new hotness: named capabilities
450 + $manage_links = 'manage_links';
451 + $manage_options = 'manage_options';
469 452 endif;
470 453
471 - if (fwp_test_wp_version(FWP_SCHEMA_26)) :
472 - $options = __('Settings');
473 - $longoptions = __('Syndication Settings');
474 - else :
475 - $options = __('Options');
476 - $longoptions = __('Syndication Options');
454 + //add_submenu_page('plugins.php', 'Akismet Configuration', 'Akismet Configuration', 'manage_options', 'syndication-manage-page', 'fwp_syndication_manage_page');
455 + add_menu_page('Syndicated Sites', 'Syndication', $manage_links, $fwp_path.'/'.basename(__FILE__), 'fwp_syndication_manage_page');
456 + add_submenu_page($fwp_path.'/'.basename(__FILE__), 'Syndication Options', 'Options', $manage_options, $fwp_path.'/syndication-options.php');
457 + add_options_page('Syndication Options', 'Syndication', $manage_options, $fwp_path.'/syndication-options.php');
458 +} // function fwp_add_pages () */
459 +
460 +function fwp_linkedit_single_submit ($status = NULL) {
461 + global $wp_db_version;
462 + if (isset($wp_db_version) and $wp_db_version >= FWP_SCHEMA_25) :
463 +?>
464 +<div class="submitbox" id="submitlink">
465 +<div id="previewview"></div>
466 +<div class="inside">
467 +<?php if (!is_null($status)) : ?>
468 + <p><strong>Publication</strong></p>
469 + <p>When a new post is syndicated from this feed...</p>
470 + <select name="feed_post_status">
471 + <option value="site-default" <?php echo $status['post']['site-default']; ?>> Use
472 + Syndication Options setting</option>
473 + <option value="publish" <?php echo $status['post']['publish']; ?>>Publish it immediately</option>
474 +
475 + <?php if (SyndicatedPost::use_api('post_status_pending')) : ?>
476 + <option value="pending" <?php echo $status['post']['pending']; ?>>Hold it Pending Review</option>
477 + <?php endif; ?>
478 +
479 + <option value="draft" <?php echo $status['post']['draft']; ?>>Save it as a draft</option>
480 + <option value="private" <?php echo $status['post']['private']; ?>>Keep it private</option>
481 + </select>
482 +<?php endif; ?>
483 +</div>
484 +
485 +<p class="submit">
486 +<input type="submit" name="submit" value="<?php _e('Save') ?>" />
487 +</p>
488 +</div>
489 +<?php
477 490 endif;
491 +}
478 492
479 - call_user_func_array('add_menu_page', $menu);
480 - add_submenu_page($fwp_path.'/syndication.php', 'Syndicated Posts', 'Posts', $fwp_capability['manage_options'], $fwp_path.'/posts-page.php');
481 - add_submenu_page($fwp_path.'/syndication.php', 'Syndicated Authors', 'Authors', $fwp_capability['manage_options'], $fwp_path.'/authors-page.php');
482 - add_submenu_page($fwp_path.'/syndication.php', 'Categories & Tags', 'Categories & Tags', $fwp_capability['manage_options'], $fwp_path.'/categories-page.php');
483 - add_submenu_page($fwp_path.'/syndication.php', $longoptions, $options, $fwp_capability['manage_options'], $fwp_path.'/syndication-options.php');
493 +function fwp_linkedit_periodic_submit ($caption = NULL) {
494 + global $wp_db_version;
495 + if (!(isset($wp_db_version) and $wp_db_version >= FWP_SCHEMA_25)) :
496 + if (is_null($caption)) : $caption = __('Save Changes &raquo;'); endif;
497 +?>
498 +<p class="submit">
499 +<input type="submit" name="submit" value="<?php print $caption; ?>" />
500 +</p>
501 +<?php
502 + endif;
503 +}
484 504
485 - add_options_page($longoptions, 'Syndication', $fwp_capability['manage_options'], $fwp_path.'/syndication-options.php');
486 -} /* function fwp_add_pages () */
505 +function fwp_option_box_opener ($legend, $id, $class = "stuffbox") {
506 + global $wp_db_version;
507 + if (isset($wp_db_version) and $wp_db_version >= FWP_SCHEMA_25) :
508 +?>
509 +<div id="<?php print $id; ?>" class="<?php print $class; ?>">
510 +<h3><?php print htmlspecialchars($legend); ?></h3>
511 +<div class="inside">
512 +<?php
513 + else :
514 +?>
515 +<fieldset class="options"><legend><?php print htmlspecialchars($legend); ?></legend>
516 +<?php
517 + endif;
518 +}
487 519
488 -function fwp_check_debug () {
489 - // This is a horrible fucking kludge that I have to do because the
490 - // admin notice code is triggered before the code that updates the
491 - // setting.
492 - if (isset($_POST['feedwordpress_debug'])) :
493 - $feedwordpress_debug = $_POST['feedwordpress_debug'];
520 +function fwp_option_box_closer () {
521 + global $wp_db_version;
522 + if (isset($wp_db_version) and $wp_db_version >= FWP_SCHEMA_25) :
523 +?>
524 + </div> <!-- class="inside" -->
525 + </div> <!-- class="stuffbox" -->
526 +<?php
494 527 else :
495 - $feedwordpress_debug = get_option('feedwordpress_debug');
528 +?>
529 +</fieldset>
530 +<?php
496 531 endif;
497 - if ($feedwordpress_debug==='yes') :
532 +}
533 +
534 +function fwp_tags_box ($tags) {
535 + if (!is_array($tags)) : $tags = array(); endif;
498 536 ?>
499 - <div class="error">
500 -<p><strong>FeedWordPress warning.</strong> Debugging mode is <strong>ON</strong>.
501 -While it remains on, FeedWordPress displays many diagnostic error messages,
502 -warnings, and notices that are ordinarily suppressed, and also turns off all
503 -caching of feeds. Use with caution: this setting is absolutely inappropriate
504 -for a production server.</p>
537 +<div id="tagsdiv" class="postbox">
538 + <h3><?php _e('Tags') ?></h3>
539 + <p style="font-size:smaller;font-style:bold;margin:0">Place <?php print $object; ?> under...</p>
540 + <div class="inside">
541 + <p id="jaxtag"><input type="text" name="tags_input" class="tags-input" id="tags-input" size="40" tabindex="3" value="<?php echo implode(",", $tags); ?>" /></p>
542 + <div id="tagchecklist"></div>
543 + </div>
544 +</div>
545 +<?php
546 +}
547 +
548 +function fwp_category_box ($checked, $object, $tags = array()) {
549 + global $wp_db_version;
550 +
551 + if (isset($wp_db_version) and $wp_db_version >= FWP_SCHEMA_25) : // WordPress 2.5.x
552 +?>
553 +<div id="category-adder" class="wp-hidden-children">
554 + <h4><a id="category-add-toggle" href="#category-add" class="hide-if-no-js" tabindex="3"><?php _e( '+ Add New Category' ); ?></a></h4>
555 + <p id="category-add" class="wp-hidden-child">
556 + <input type="text" name="newcat" id="newcat" class="form-required form-input-tip" value="<?php _e( 'New category name' ); ?>" tabindex="3" />
557 + <?php wp_dropdown_categories( array( 'hide_empty' => 0, 'name' => 'newcat_parent', 'orderby' => 'name', 'hierarchical' => 1, 'show_option_none' => __('Parent category'), 'tab_index' => 3 ) ); ?>
558 + <input type="button" id="category-add-sumbit" class="add:categorychecklist:category-add button" value="<?php _e( 'Add' ); ?>" tabindex="3" />
559 + <?php wp_nonce_field( 'add-category', '_ajax_nonce', false ); ?>
560 + <span id="category-ajax-response"></span>
561 + </p>
562 +</div>
563 +
564 +<ul id="category-tabs">
565 + <li class="ui-tabs-selected"><a href="#categories-all" tabindex="3"><?php _e( 'All posts' ); ?></a>
566 + <p style="font-size:smaller;font-style:bold;margin:0">Give <?php print $object; ?> these categories</p>
567 +</li>
568 +</ul>
569 +
570 +<div id="categories-all" class="ui-tabs-panel">
571 + <ul id="categorychecklist" class="list:category categorychecklist form-no-clear">
572 + <?php fwp_category_checklist(NULL, false, $checked) ?>
573 + </ul>
574 +</div>
575 +<?php
576 + elseif (isset($wp_db_version) and $wp_db_version >= FWP_SCHEMA_20) : // WordPress 2.x
577 +?>
578 + <div id="moremeta">
579 + <div id="grabit" class="dbx-group">
580 + <fieldset id="categorydiv" class="dbx-box">
581 + <h3 class="dbx-handle"><?php _e('Categories') ?></h3>
582 + <div class="dbx-content">
583 + <p style="font-size:smaller;font-style:bold;margin:0">Place <?php print $object; ?> under...</p>
584 + <p id="jaxcat"></p>
585 + <ul id="categorychecklist"><?php fwp_category_checklist(NULL, false, $checked); ?></ul></div>
586 + </fieldset>
505 587 </div>
588 + </div>
506 589 <?php
590 + else : // WordPress 1.5
591 +?>
592 + <fieldset id="categorydiv" style="width: 20%; margin-right: 2em">
593 + <legend><?php _e('Categories') ?></legend>
594 + <p style="font-size:smaller;font-style:bold;margin:0">Place <?php print $object; ?> under...</p>
595 + <div style="height: 20em"><?php fwp_category_checklist(NULL, false, $checked); ?></div>
596 + </fieldset>
597 +<?php
507 598 endif;
508 -} /* function fwp_check_debug () */
599 +}
509 600
510 -define('EXPECTED_MAGPIE_VERSION', '2009.0618');
511 -function fwp_check_magpie () {
512 - if (isset($_REQUEST['feedwordpress_magpie_fix'])) :
513 - if ($_REQUEST['feedwordpress_magpie_fix']=='ignored') :
601 +function update_feeds_mention ($feed) {
602 + echo "<li>Updating <cite>".$feed['link/name']."</cite> from &lt;<a href=\""
603 + .$feed['link/uri']."\">".$feed['link/uri']."</a>&gt; ...</li>\n";
604 + flush();
605 +}
606 +
607 +function fwp_syndication_manage_page () {
608 + global $wpdb;
609 +
610 + if (FeedWordPress::needs_upgrade()) :
611 + fwp_upgrade_page();
612 + return;
613 + endif;
614 +
514 615 ?>
515 -<div class="updated fade">
516 -<p>O.K., we'll ignore the problem for now. FeedWordPress will not display any
517 -more error messages.</p>
518 -</div>
616 +<?php $cont = true;
617 +if (isset($_REQUEST['action'])):
618 + if ($_REQUEST['action'] == 'feedfinder') : $cont = fwp_feedfinder_page();
619 + elseif ($_REQUEST['action'] == 'switchfeed') : $cont = fwp_switchfeed_page();
620 + elseif ($_REQUEST['action'] == 'linkedit') : $cont = fwp_linkedit_page();
621 + elseif ($_REQUEST['action'] == 'Unsubscribe from Checked Links' or $_REQUEST['action'] == 'Unsubscribe') : $cont = fwp_multidelete_page();
622 + endif;
623 +endif;
624 +
625 +if ($cont):
626 +?>
519 627 <?php
520 - elseif ((bool) $_REQUEST['feedwordpress_magpie_fix']) :
628 + $links = FeedWordPress::syndicated_links();
629 +
630 + if (isset($_POST['update']) or isset($_POST['action']) or isset($_POST['update_uri'])) :
631 + $fwp_update_invoke = 'post';
632 + else :
633 + $fwp_update_invoke = 'get';
634 + endif;
635 +
636 + $update_set = array();
637 + if (isset($_POST['link_ids']) and is_array($_POST['link_ids']) and ($_POST['action']=='Update Checked Links')) :
638 + $targets = $wpdb->get_results("
639 + SELECT * FROM $wpdb->links
640 + WHERE link_id IN (".implode(",",$_POST['link_ids']).")
641 + ");
642 + if (is_array($targets)) :
643 + foreach ($targets as $target) :
644 + $update_set[] = $target->link_rss;
645 + endforeach;
646 + else : // This should never happen
647 + FeedWordPress::critical_bug('fwp_syndication_manage_page::targets', $targets, __LINE__);
648 + endif;
649 + elseif (isset($_POST['update_uri'])) :
650 + $update_set[] = $_POST['update_uri'];
651 + endif;
652 +
653 + if ($fwp_update_invoke != 'get' and count($update_set) > 0) : // Only do things with side-effects for HTTP POST or command line
654 + $feedwordpress =& new FeedWordPress;
655 + add_action('feedwordpress_check_feed', 'update_feeds_mention');
656 +
657 + echo "<div class=\"updated\">\n";
658 + echo "<ul>\n";
659 + $tdelta = NULL;
660 + foreach ($update_set as $uri) :
661 + if ($uri == '*') : $uri = NULL; endif;
662 + $delta = $feedwordpress->update($uri);
663 + if (!is_null($delta)) :
664 + if (is_null($tdelta)) :
665 + $tdelta = $delta;
666 + else :
667 + $tdelta['new'] += $delta['new'];
668 + $tdelta['updated'] += $delta['updated'];
669 + endif;
670 + else :
671 + echo "<li><p><strong>Error:</strong> There was a problem updating <a href=\"$uri\">$uri</a></p></li>\n";
672 + endif;
673 + endforeach;
674 + echo "</ul>\n";
675 +
676 + if (!is_null($tdelta)) :
677 + $mesg = array();
678 + if (isset($delta['new'])) : $mesg[] = ' '.$tdelta['new'].' new posts were syndicated'; endif;
679 + if (isset($delta['updated'])) : $mesg[] = ' '.$tdelta['updated'].' existing posts were updated'; endif;
680 + echo "<p>Update complete.".implode(' and', $mesg)."</p>";
681 + echo "\n"; flush();
682 + endif;
683 + echo "</div> <!-- class=\"updated\" -->\n";
684 + endif;
685 +
686 + ?>
687 + <div class="wrap">
688 + <form action="" method="POST">
689 + <h2>Update feeds now</h2>
690 + <p>Check currently scheduled feeds for new and updated posts.</p>
691 +
692 +<?php if (!get_option('feedwordpress_automatic_updates')) : ?>
693 + <p><strong>Note:</strong> Automatic updates are currently turned
694 + <strong>off</strong>. New posts from your feeds will not be syndicated
695 + until you manually check for them here. You can turn on automatic
696 + updates under <a href="admin.php?page=<?php print $GLOBALS['fwp_path']; ?>/syndication-options.php">Syndication
697 + Options</a>.</p>
698 +<?php endif; ?>
699 +
700 +
701 + <div class="submit"><input type="hidden" name="update_uri" value="*" /><input type="submit" name="update" value="Update" /></div>
702 + </form>
703 + </div> <!-- class="wrap" -->
704 +
705 + <form action="admin.php?page=<?php print $GLOBALS['fwp_path']; ?>/<?php echo basename(__FILE__); ?>" method="post">
706 + <div class="wrap">
707 + <h2>Syndicated Sites</h2>
708 +<?php $alt_row = true;
709 + if ($links): ?>
710 +
711 +<table width="100%" cellpadding="3" cellspacing="3">
712 +<tr>
713 +<th width="20%"><?php _e('Name'); ?></th>
714 +<th width="40%"><?php _e('Feed'); ?></th>
715 +<th colspan="4"><?php _e('Action'); ?></th>
716 +</tr>
717 +
718 +<?php foreach ($links as $link):
719 + $alt_row = !$alt_row; ?>
720 +<tr<?php echo ($alt_row?' class="alternate"':''); ?>>
721 +<td><a href="<?php echo wp_specialchars($link->link_url, 'both'); ?>"><?php echo wp_specialchars($link->link_name, 'both'); ?></a></td>
722 +<?php
723 + if (strlen($link->link_rss) > 0):
724 + $caption='Switch Feed';
725 + $uri_bits = parse_url($link->link_rss);
726 + $uri_bits['host'] = preg_replace('/^www\./i', '', $uri_bits['host']);
727 + $display_uri =
728 + (isset($uri_bits['user'])?$uri_bits['user'].'@':'')
729 + .(isset($uri_bits['host'])?$uri_bits['host']:'')
730 + .(isset($uri_bits['port'])?':'.$uri_bits['port']:'')
731 + .(isset($uri_bits['path'])?$uri_bits['path']:'')
732 + .(isset($uri_bits['query'])?'?'.$uri_bits['query']:'');
733 + if (strlen($display_uri) > 32) : $display_uri = substr($display_uri, 0, 32).'&#8230;'; endif;
521 734 ?>
522 -<div class="updated fade">
523 -<p>Congratulations! Your MagpieRSS has been successfully upgraded to the version
524 -shipped with FeedWordPress.</p>
525 -</div>
735 + <td>
736 + <strong><a href="<?php echo wp_specialchars($link->link_rss, 'both'); ?>"><?php echo wp_specialchars($display_uri, 'both'); ?></a></strong></td>
526 737 <?php
527 - else :
528 - $source = dirname(__FILE__)."/MagpieRSS-upgrade/rss.php";
529 - $destination = ABSPATH . WPINC . '/rss.php';
530 - $cmd = "cp '".htmlspecialchars(addslashes($source))."' '".htmlspecialchars(addslashes($destination))."'";
531 - $cmd = wordwrap($cmd, /*width=*/ 75, /*break=*/ " \\\n\t");
738 + else:
739 + $caption='Find Feed';
740 +?>
741 + <td style="background-color:#FFFFD0"><p><strong>no
742 + feed assigned</strong></p></td>
743 +<?php
744 + endif;
745 +?>
746 + <td><a href="admin.php?page=<?php print $GLOBALS['fwp_path'] ?>/<?php echo basename(__FILE__); ?>&amp;link_id=<?php echo $link->link_id; ?>&amp;action=linkedit" class="edit"><?php _e('Edit')?></a></td>
747 + <td><a href="admin.php?page=<?php print $GLOBALS['fwp_path'] ?>/<?php echo basename(__FILE__); ?>&amp;link_id=<?php echo $link->link_id; ?>&amp;action=feedfinder" class="edit"><?php echo $caption; ?></a></td>
748 + <td><a href="admin.php?page=<?php print $GLOBALS['fwp_path'] ?>/<?php echo basename(__FILE__); ?>&amp;link_id=<?php echo $link->link_id; ?>&amp;action=Unsubscribe" class="delete"><?php _e('Unsubscribe'); ?></a></td>
749 + <td><input type="checkbox" name="link_ids[]" value="<?php echo $link->link_id; ?>" /></td>
750 +<?php
751 + echo "\n\t</tr>";
752 + endforeach;
753 + else:
754 +?>
532 755
756 +<p>There are no websites currently listed for syndication.</p>
757 +
758 +<?php endif; ?>
759 + </table>
760 +
761 + <br/><hr/>
762 + <div class="submit"><input type="submit" class="delete" name="action" value="Unsubscribe from Checked Links" />
763 + <input type="submit" name="action" value="Update Checked Links" /></div>
764 + </div> <!-- class="wrap" -->
765 + </form>
766 +
767 + <div class="wrap">
768 + <form action="admin.php?page=<?php print $GLOBALS['fwp_path'] ?>/<?php echo basename(__FILE__); ?>" method="post">
769 + <h2>Add a new syndicated site:</h2>
770 + <div>
771 + <label for="add-uri">Website or newsfeed:</label>
772 + <input type="text" name="lookup" id="add-uri" value="URI" size="64" />
773 + <input type="hidden" name="action" value="feedfinder" />
774 + </div>
775 + <div class="submit"><input type="submit" value="Syndicate &raquo;" /></div>
776 + </form>
777 + </div> <!-- class="wrap" -->
778 +<?php
779 +endif;
780 +}
781 +
782 +function fwp_feedfinder_page () {
783 + global $wpdb;
784 +
785 + $lookup = (isset($_REQUEST['lookup'])?$_REQUEST['lookup']:NULL);
786 +
787 + if (isset($_REQUEST['link_id']) and ($_REQUEST['link_id']!=0)):
788 + $link_id = $_REQUEST['link_id'];
789 + if (!is_numeric($link_id)) : FeedWordPress::critical_bug('fwp_feedfinder_page::link_id', $link_id, __LINE__); endif;
790 +
791 + $link = $wpdb->get_row("SELECT * FROM $wpdb->links WHERE link_id='".$wpdb->escape($link_id)."'");
792 + if (is_object($link)):
793 + if (is_null($lookup)) $lookup = $link->link_url;
794 + $name = wp_specialchars($link->link_name, 'both');
795 + else:
796 + die (__("Cheatin' uh ?"));
797 + endif;
798 + else:
799 + $name = "New Syndicated Feed";
800 + $link_id = 0;
801 + endif;
533 802 ?>
534 -<div class="error">
535 -<p><strong>FeedWordPress was unable to automatically upgrade your copy of MagpieRSS.</strong></p>
536 -<p>It's likely that you need to change the file permissions on <code><?php print htmlspecialchars($source); ?></code>
537 -to allow FeedWordPress to overwrite it.</p>
538 -<p><strong>To perform the upgrade manually,</strong> you can
539 -use a SFTP or FTP client to upload a copy of <code>rss.php</code> from the
540 -<code>MagpieRSS-upgrades/</code> directory of your FeedWordPress archive so that
541 -it overwrites <code><?php print htmlspecialchars($destination); ?></code>. Or,
542 -if your web host provides shell access, you can issue the following command from
543 -a command prompt to perform the upgrade:</p>
544 -<pre>
545 -<samp>$</samp> <kbd><?php print $cmd; ?></kbd>
546 -</pre>
547 -<p><strong>If you've fixed the file permissions,</strong> you can try the
548 -automatic upgrade again.</p>
803 + <div class="wrap">
804 + <h2>Feed Finder: <?php echo $name; ?></h2>
805 +<?php
806 + $f =& new FeedFinder($lookup);
807 + $feeds = $f->find();
808 + if (count($feeds) > 0):
809 + foreach ($feeds as $key => $f):
810 + $rss = fetch_rss($f);
811 + if ($rss):
812 + $feed_title = isset($rss->channel['title'])?$rss->channel['title']:$rss->channel['link'];
813 + $feed_link = isset($rss->channel['link'])?$rss->channel['link']:'';
814 +?>
815 + <form action="admin.php?page=<?php print $GLOBALS['fwp_path'] ?>/<?php echo basename(__FILE__); ?>" method="post">
816 + <fieldset style="clear: both">
817 + <legend><?php echo $rss->feed_type; ?> <?php echo $rss->feed_version; ?> feed</legend>
549 818
550 -<?php feedwordpress_upgrade_old_and_busted_buttons(); ?>
551 -</div>
819 + <?php if ($link_id===0): ?>
820 + <input type="hidden" name="feed_title" value="<?php echo wp_specialchars($feed_title, 'both'); ?>" />
821 + <input type="hidden" name="feed_link" value="<?php echo wp_specialchars($feed_link, 'both'); ?>" />
822 + <?php endif; ?>
823 +
824 + <input type="hidden" name="link_id" value="<?php echo $link_id; ?>" />
825 + <input type="hidden" name="feed" value="<?php echo wp_specialchars($f, 'both'); ?>" />
826 + <input type="hidden" name="action" value="switchfeed" />
827 +
828 + <div>
829 + <div style="float:right; background-color:#D0D0D0; color: black; width:45%; font-size:70%; border-left: 1px dotted #A0A0A0; padding-left: 0.5em; margin-left: 1.0em">
830 +<?php if (count($rss->items) > 0): ?>
831 + <?php $item = $rss->items[0]; ?>
832 + <h3>Sample Item</h3>
833 + <ul>
834 + <li><strong>Title:</strong> <a href="<?php echo $item['link']; ?>"><?php echo $item['title']; ?></a></li>
835 + <li><strong>Date:</strong> <?php echo isset($item['date_timestamp']) ? date('d-M-y g:i:s a', $item['date_timestamp']) : 'unknown'; ?></li>
836 + </ul>
837 + <div class="entry">
838 + <?php echo (isset($item['content']['encoded'])?$item['content']['encoded']:$item['description']); ?>
839 + </div>
840 +<?php else: ?>
841 + <h3>No Items</h3>
842 + <p>FeedWordPress found no posts on this feed.</p>
843 +<?php endif; ?>
844 + </div>
845 +
846 + <div>
847 + <h3>Feed Information</h3>
848 + <ul>
849 + <li><strong>Website:</strong> <a href="<?php echo $feed_link; ?>"><?php echo is_null($feed_title)?'<em>Unknown</em>':$feed_title; ?></a></li>
850 + <li><strong>Feed URI:</strong> <a href="<?php echo wp_specialchars($f, 'both'); ?>"><?php echo wp_specialchars($f, 'both'); ?></a> (<a title="Check feed &lt;<?php echo wp_specialchars($f, 'both'); ?>&gt; for validity" href="http://feedvalidator.org/check.cgi?url=<?php echo urlencode($f); ?>">validate</a>)</li>
851 + <li><strong>Encoding:</strong> <?php echo isset($rss->encoding)?wp_specialchars($rss->encoding, 'both'):"<em>Unknown</em>"; ?></li>
852 + <li><strong>Description:</strong> <?php echo isset($rss->channel['description'])?wp_specialchars($rss->channel['description'], 'both'):"<em>Unknown</em>"; ?></li>
853 + </ul>
854 + <div class="submit"><input type="submit" name="Use" value="&laquo; Use this feed" /></div>
855 + <div class="submit"><input type="submit" name="Cancel" value="&laquo; Cancel" /></div>
856 + </div>
857 + </div>
858 + </fieldset>
859 + </form>
860 +<?php endif;
861 + endforeach;
862 + else:
863 + echo "<p><strong>no feed found</strong></p>";
864 + endif;
865 +?>
866 + </div>
867 +
868 + <form action="admin.php?page=<?php print $GLOBALS['fwp_path'] ?>/<?php echo basename(__FILE__); ?>" method="post">
869 + <div class="wrap">
870 + <h2>Use another feed</h2>
871 + <div><label>Feed:</label>
872 + <input type="text" name="lookup" value="URI" />
873 + <input type="hidden" name="link_id" value="<?php echo $link_id; ?>" />
874 + <input type="hidden" name="action" value="feedfinder" /></div>
875 + <div class="submit"><input type="submit" value="Use this feed &raquo;" /></div>
876 + </div>
877 + </form>
552 878 <?php
879 + return false; // Don't continue
880 +}
881 +
882 +function fwp_switchfeed_page () {
883 + global $wpdb, $wp_db_version;
884 +
885 + check_admin_referer();
886 + if (!isset($_REQUEST['Cancel'])):
887 + if (!current_user_can('manage_links')):
888 + die (__("Cheatin' uh ?"));
889 + elseif (isset($_REQUEST['link_id']) and ($_REQUEST['link_id']==0)):
890 + $link_id = FeedWordPress::syndicate_link($_REQUEST['feed_title'], $_REQUEST['feed_link'], $_REQUEST['feed']);
891 + if ($link_id): ?>
892 +<div class="updated"><p><a href="<?php echo $_REQUEST['feed_link']; ?>"><?php echo wp_specialchars($_REQUEST['feed_title'], 'both'); ?></a>
893 +has been added as a contributing site, using the newsfeed at &lt;<a href="<?php echo $_REQUEST['feed']; ?>"><?php echo wp_specialchars($_REQUEST['feed'], 'both'); ?></a>&gt;.</p></div>
894 +<?php else: ?>
895 +<div class="updated"><p>There was a problem adding the newsfeed. [SQL: <?php echo wp_specialchars(mysql_error(), 'both'); ?>]</p></div>
896 +<?php endif;
897 + elseif (isset($_REQUEST['link_id'])):
898 + // Update link_rss
899 + $result = $wpdb->query("
900 + UPDATE $wpdb->links
901 + SET
902 + link_rss = '".$wpdb->escape($_REQUEST['feed'])."'
903 + WHERE link_id = '".$wpdb->escape($_REQUEST['link_id'])."'
904 + ");
905 +
906 + if ($result):
907 + $result = $wpdb->get_row("
908 + SELECT link_name, link_url FROM $wpdb->links
909 + WHERE link_id = '".$wpdb->escape($_REQUEST['link_id'])."'
910 + ");
911 + ?>
912 +<div class="updated"><p>Feed for <a href="<?php echo $result->link_url; ?>"><?php echo wp_specialchars($result->link_name, 'both'); ?></a>
913 +updated to &lt;<a href="<?php echo $_REQUEST['feed']; ?>"><?php echo wp_specialchars($_REQUEST['feed'], 'both'); ?></a>&gt;.</p></div>
914 + <?php else: ?>
915 +<div class="updated"><p>Nothing was changed.</p></div>
916 + <?php endif;
553 917 endif;
918 + endif;
919 + return true; // Continue
920 +}
921 +
922 +function fwp_linkedit_page () {
923 + global $wpdb, $wp_db_version;
924 +
925 + check_admin_referer(); // Make sure we arrived here from the Dashboard
926 +
927 + $special_settings = array ( /* Regular expression syntax is OK here */
928 + 'cats',
929 + 'cat_split',
930 + 'hardcode name',
931 + 'hardcode url',
932 + 'hardcode description',
933 + 'hardcode categories', /* Deprecated */
934 + 'post status',
935 + 'comment status',
936 + 'ping status',
937 + 'unfamiliar author',
938 + 'unfamliar categories', /* Deprecated */
939 + 'unfamiliar category',
940 + 'map authors',
941 + 'tags',
942 + 'update/.*',
943 + 'feed/.*',
944 + 'link/.*',
945 + );
946 +
947 + if (!current_user_can('manage_links')) :
948 + die (__("Cheatin' uh ?"));
949 + elseif (isset($_REQUEST['feedfinder'])) :
950 + return fwp_feedfinder_page(); // re-route to Feed Finder page
554 951 else :
555 - $magpie_version = FeedWordPress::magpie_version();
952 + $link_id = (int) $_REQUEST['link_id'];
953 + $link =& new SyndicatedLink($link_id);
556 954
557 - $ignored = get_option('feedwordpress_magpie_ignored_upgrade_to');
558 - if (EXPECTED_MAGPIE_VERSION != $magpie_version and EXPECTED_MAGPIE_VERSION != $ignored) :
559 - if (current_user_can('edit_files')) :
560 - $youAre = 'you are';
561 - $itIsRecommendedThatYou = 'It is <strong>strongly recommended</strong> that you';
955 + if ($link->found()) :
956 + if (isset($GLOBALS['fwp_post']['save'])) :
957 + $alter = array ();
958 +
959 + $meta = $link->settings;
960 + //if (isset($meta['cats'])):
961 + // $meta['cats'] = preg_split(FEEDWORDPRESS_CAT_SEPARATOR_PATTERN, $meta['cats']);
962 + //endif;
963 +
964 + // custom feed settings first
965 + foreach ($GLOBALS['fwp_post']['notes'] as $mn) :
966 + $mn['key0'] = trim($mn['key0']);
967 + $mn['key1'] = trim($mn['key1']);
968 + if (preg_match("\007^(("
969 + .implode(')|(',$special_settings)
970 + ."))$\007i",
971 + $mn['key1'])) :
972 + $mn['key1'] = 'user/'.$mn['key1'];
973 + endif;
974 +
975 + if (strlen($mn['key0']) > 0) :
976 + unset($meta[$mn['key0']]); // out with the old
977 + endif;
978 +
979 + if (($mn['action']=='update') and (strlen($mn['key1']) > 0)) :
980 + $meta[$mn['key1']] = $mn['value']; // in with the new
981 + endif;
982 + endforeach;
983 +
984 + // now stuff through the web form
985 + // hardcoded feed info
986 + if (isset($GLOBALS['fwp_post']['hardcode_name'])) :
987 + $meta['hardcode name'] = $GLOBALS['fwp_post']['hardcode_name'];
988 + if (FeedWordPress::affirmative($meta, 'hardcode name')) :
989 + $alter[] = "link_name = '".$wpdb->escape($GLOBALS['fwp_post']['name'])."'";
990 + endif;
991 + endif;
992 + if (isset($GLOBALS['fwp_post']['hardcode_description'])) :
993 + $meta['hardcode description'] = $GLOBALS['fwp_post']['hardcode_description'];
994 + if (FeedWordPress::affirmative($meta, 'hardcode description')) :
995 + $alter[] = "link_description = '".$wpdb->escape($GLOBALS['fwp_post']['description'])."'";
996 + endif;
997 + endif;
998 + if (isset($GLOBALS['fwp_post']['hardcode_url'])) :
999 + $meta['hardcode url'] = $GLOBALS['fwp_post']['hardcode_url'];
1000 + if (FeedWordPress::affirmative($meta, 'hardcode url')) :
1001 + $alter[] = "link_url = '".$wpdb->escape($GLOBALS['fwp_post']['linkurl'])."'";
1002 + endif;
1003 + endif;
1004 +
1005 + // Update scheduling
1006 + if (isset($GLOBALS['fwp_post']['update_schedule'])) :
1007 + $meta['update/hold'] = $GLOBALS['fwp_post']['update_schedule'];
1008 + endif;
1009 +
1010 + // Categories
1011 + if (isset($GLOBALS['fwp_post']['post_category'])) :
1012 + $meta['cats'] = array();
1013 + foreach ($GLOBALS['fwp_post']['post_category'] as $cat_id) :
1014 + $meta['cats'][] = '{#'.$cat_id.'}';
1015 + endforeach;
1016 + else :
1017 + unset($meta['cats']);
1018 + endif;
1019 +
1020 + // Tags
1021 + if (isset($GLOBALS['fwp_post']['tags_input'])) :
1022 + $meta['tags'] = array();
1023 + foreach (explode(',', $GLOBALS['fwp_post']['tags_input']) as $tag) :
1024 + $meta['tags'][] = trim($tag);
1025 + endforeach;
1026 + endif;
1027 +
1028 + // Post status, comment status, ping status
1029 + foreach (array('post', 'comment', 'ping') as $what) :
1030 + $sfield = "feed_{$what}_status";
1031 + if (isset($GLOBALS['fwp_post'][$sfield])) :
1032 + if ($GLOBALS['fwp_post'][$sfield]=='site-default') :
1033 + unset($meta["{$what} status"]);
1034 + else :
1035 + $meta["{$what} status"] = $GLOBALS['fwp_post'][$sfield];
1036 + endif;
1037 + endif;
1038 + endforeach;
1039 +
1040 + // Unfamiliar author, unfamiliar categories
1041 + foreach (array("author", "category") as $what) :
1042 + $sfield = "unfamiliar_{$what}";
1043 + if (isset($GLOBALS['fwp_post'][$sfield])) :
1044 + if ('site-default'==$GLOBALS['fwp_post'][$sfield]) :
1045 + unset($meta["unfamiliar {$what}"]);
1046 + elseif ('newuser'==$GLOBALS['fwp_post'][$sfield]) :
1047 + $newuser_name = trim($GLOBALS['fwp_post']["{$sfield}_newuser"]);
1048 + if (strlen($newuser_name) > 0) :
1049 + $userdata = array();
1050 + $userdata['ID'] = NULL;
1051 +
1052 + $userdata['user_login'] = sanitize_user($newuser_name);
1053 + $userdata['user_login'] = apply_filters('pre_user_login', $userdata['user_login']);
1054 +
1055 + $userdata['user_nicename'] = sanitize_title($newuser_name);
1056 + $userdata['user_nicename'] = apply_filters('pre_user_nicename', $userdata['user_nicename']);
1057 +
1058 + $userdata['display_name'] = $wpdb->escape($newuser_name);
1059 +
1060 + $newuser_id = wp_insert_user($userdata);
1061 + if (is_numeric($newuser_id)) :
1062 + $meta["unfamiliar {$what}"] = $newuser_id;
1063 + else :
1064 + // TODO: Add some error detection and reporting
1065 + endif;
1066 + else :
1067 + // TODO: Add some error reporting
1068 + endif;
1069 + else :
1070 + $meta["unfamiliar {$what}"] = $GLOBALS['fwp_post'][$sfield];
1071 + endif;
1072 + endif;
1073 + endforeach;
1074 +
1075 + // Handle author mapping rules
1076 + if (isset($GLOBALS['fwp_post']['author_rules_name']) and isset($GLOBALS['fwp_post']['author_rules_action'])) :
1077 + unset($meta['map authors']);
1078 + foreach ($GLOBALS['fwp_post']['author_rules_name'] as $key => $name) :
1079 + // Normalize for case and whitespace
1080 + $name = strtolower(trim($name));
1081 + $author_action = strtolower(trim($GLOBALS['fwp_post']['author_rules_action'][$key]));
1082 +
1083 + if (strlen($name) > 0) :
1084 + if ('newuser' == $author_action) :
1085 + $newuser_name = trim($GLOBALS['fwp_post']['author_rules_newuser'][$key]);
1086 + if (strlen($newuser_name) > 0) :
1087 + $userdata = array();
1088 + $userdata['ID'] = NULL;
1089 +
1090 + $userdata['user_login'] = sanitize_user($newuser_name);
1091 + $userdata['user_login'] = apply_filters('pre_user_login', $userdata['user_login']);
1092 +
1093 + $userdata['user_nicename'] = sanitize_title($newuser_name);
1094 + $userdata['user_nicename'] = apply_filters('pre_user_nicename', $userdata['user_nicename']);
1095 +
1096 + $userdata['display_name'] = $wpdb->escape($newuser_name);
1097 +
1098 + $newuser_id = wp_insert_user($userdata);
1099 + if (is_numeric($newuser_id)) :
1100 + $meta['map authors']['name'][$name] = $newuser_id;
1101 + else :
1102 + // TODO: Add some error detection and reporting
1103 + endif;
1104 + else :
1105 + // TODO: Add some error reporting
1106 + endif;
1107 + else :
1108 + $meta['map authors']['name'][$name] = $author_action;
1109 + endif;
1110 + endif;
1111 + endforeach;
1112 + endif;
1113 +
1114 + if (isset($GLOBALS['fwp_post']['add_author_rule_name']) and isset($GLOBALS['fwp_post']['add_author_rule_action'])) :
1115 + $name = strtolower(trim($GLOBALS['fwp_post']['add_author_rule_name']));
1116 + $author_action = strtolower(trim($GLOBALS['fwp_post']['add_author_rule_action']));
1117 + if (strlen($name) > 0) :
1118 + if ('newuser' == $author_action) :
1119 + $newuser_name = trim($GLOBALS['fwp_post']['add_author_rule_newuser']);
1120 + if (strlen($newuser_name) > 0) :
1121 + $userdata = array();
1122 + $userdata['ID'] = NULL;
1123 +
1124 + $userdata['user_login'] = sanitize_user($newuser_name);
1125 + $userdata['user_login'] = apply_filters('pre_user_login', $userdata['user_login']);
1126 +
1127 + $userdata['user_nicename'] = sanitize_title($newuser_name);
1128 + $userdata['user_nicename'] = apply_filters('pre_user_nicename', $userdata['user_nicename']);
1129 +
1130 + $userdata['display_name'] = $wpdb->escape($newuser_name);
1131 +
1132 + $newuser_id = wp_insert_user($userdata);
1133 + if (is_numeric($newuser_id)) :
1134 + $meta['map authors']['name'][$name] = $newuser_id;
1135 + else :
1136 + // TODO: Add some error detection and reporting
1137 + endif;
1138 + else :
1139 + // TODO: Add some error reporting
1140 + endif;
1141 + else :
1142 + $meta['map authors']['name'][$name] = $author_action;
1143 + endif;
1144 + endif;
1145 + endif;
1146 +
1147 + if (isset($GLOBALS['fwp_post']['cat_split'])) :
1148 + if (strlen(trim($GLOBALS['fwp_post']['cat_split'])) > 0) :
1149 + $meta['cat_split'] = trim($GLOBALS['fwp_post']['cat_split']);
1150 + else :
1151 + unset($meta['cat_split']);
1152 + endif;
1153 + endif;
1154 +
1155 + if (is_array($meta['cats'])) :
1156 + $meta['cats'] = implode(FEEDWORDPRESS_CAT_SEPARATOR, $meta['cats']);
1157 + endif;
1158 + if (is_array($meta['tags'])) :
1159 + $meta['tags'] = implode(FEEDWORDPRESS_CAT_SEPARATOR, $meta['tags']);
1160 + endif;
1161 +
1162 + // Collapse the author mapping rule structure back into a flat string
1163 + if (isset($meta['map authors'])) :
1164 + $ma = array();
1165 + foreach ($meta['map authors'] as $rule_type => $author_rules) :
1166 + foreach ($author_rules as $author_name => $author_action) :
1167 + $ma[] = $rule_type."\n".$author_name."\n".$author_action;
1168 + endforeach;
1169 + endforeach;
1170 + $meta['map authors'] = implode("\n\n", $ma);
1171 + endif;
1172 +
1173 + $notes = '';
1174 + foreach ($meta as $key => $value) :
1175 + $notes .= $key . ": ". addcslashes($value, "\0..\37".'\\') . "\n";
1176 + endforeach;
1177 + $alter[] = "link_notes = '".$wpdb->escape($notes)."'";
1178 +
1179 + $alter_set = implode(", ", $alter);
1180 +
1181 + // issue update query
1182 + $result = $wpdb->query("
1183 + UPDATE $wpdb->links
1184 + SET $alter_set
1185 + WHERE link_id='$link_id'
1186 + ");
1187 + $updated_link = true;
1188 +
1189 + // reload link information from DB
1190 + $link =& new SyndicatedLink($link_id);
562 1191 else :
563 - $youAre = 'this site is';
564 - $itIsRecommendedThatYou = 'You may want to contact the administrator of the site; it is <strong>strongly recommended</strong> that they';
1192 + $updated_link = false;
565 1193 endif;
566 - print '<div class="error">';
1194 +
1195 + $db_link = $link->link;
1196 + $link_url = wp_specialchars($db_link->link_url, 1);
1197 + $link_name = wp_specialchars($db_link->link_name, 1);
1198 + $link_description = wp_specialchars($db_link->link_description, 'both');
1199 + $link_notes = wp_specialchars($db_link->link_notes, 'both');
1200 + $link_rss_uri = wp_specialchars($db_link->link_rss, 'both');
1201 +
1202 + $meta = $link->settings;
1203 + $post_status_global = get_option('feedwordpress_syndicated_post_status');
1204 + $comment_status_global = get_option('feedwordpress_syndicated_comment_status');
1205 + $ping_status_global = get_option('feedwordpress_syndicated_ping_status');
1206 +
1207 + $status['post'] = array('publish' => '', 'private' => '', 'draft' => '', 'site-default' => '');
1208 + if (SyndicatedPost::use_api('post_status_pending')) :
1209 + $status['post']['pending'] = '';
1210 + endif;
1211 +
1212 + $status['comment'] = array('open' => '', 'closed' => '', 'site-default' => '');
1213 + $status['ping'] = array('open' => '', 'closed' => '', 'site-default' => '');
1214 +
1215 + foreach (array('post', 'comment', 'ping') as $what) :
1216 + if (isset($meta["{$what} status"])) :
1217 + $status[$what][$meta["{$what} status"]] = ' checked="checked"';
1218 + else :
1219 + $status[$what]['site-default'] = ' checked="checked"';
1220 + endif;
1221 + endforeach;
1222 +
1223 + $unfamiliar['author'] = array ('create' => '','default' => '','filter' => '');
1224 + $unfamiliar['category'] = array ('create'=>'','default'=>'','filter'=>'');
1225 +
1226 + foreach (array('author', 'category') as $what) :
1227 + if (is_string($meta["unfamiliar {$what}"]) and
1228 + array_key_exists($meta["unfamiliar {$what}"], $unfamiliar[$what])) :
1229 + $key = $meta["unfamiliar {$what}"];
1230 + else:
1231 + $key = 'site-default';
1232 + endif;
1233 + $unfamiliar[$what][$key] = ' checked="checked"';
1234 + endforeach;
1235 +
1236 + if (is_array($meta['cats'])) : $cats = $meta['cats'];
1237 + else : $cats = array();
1238 + endif;
1239 +
1240 + $dogs = SyndicatedPost::category_ids($cats, /*unfamiliar=*/ NULL);
1241 + else :
1242 + die( __('Link not found.') );
1243 + endif;
1244 +
1245 + ?>
1246 +<script type="text/javascript">
1247 + function flip_hardcode (item) {
1248 + ed=document.getElementById('basics-'+item+'-edit');
1249 + view=document.getElementById('basics-'+item+'-view');
1250 +
1251 + o = document.getElementById('basics-hardcode-'+item);
1252 + if (o.value=='yes') { ed.style.display='inline'; view.style.display='none'; }
1253 + else { ed.style.display='none'; view.style.display='inline'; }
1254 + }
1255 + function flip_newuser (item) {
1256 + rollup=document.getElementById(item);
1257 + newuser=document.getElementById(item+'-newuser');
1258 + sitewide=document.getElementById(item+'-default');
1259 + if (rollup) {
1260 + if ('newuser'==rollup.value) {
1261 + if (newuser) newuser.style.display='block';
1262 + if (sitewide) sitewide.style.display='none';
1263 + } else if ('site-default'==rollup.value) {
1264 + if (newuser) newuser.style.display='none';
1265 + if (sitewide) sitewide.style.display='block';
1266 + } else {
1267 + if (newuser) newuser.style.display='none';
1268 + if (sitewide) sitewide.style.display='none';
1269 + }
1270 + }
1271 + }
1272 +</script>
1273 +
1274 +<?php if ($updated_link) : ?>
1275 +<div class="updated"><p>Syndicated feed settings updated.</p></div>
1276 +<?php endif; ?>
1277 +
1278 +<form action="admin.php?page=<?php print $GLOBALS['fwp_path'] ?>/<?php echo basename(__FILE__); ?>" method="post">
1279 +<div class="wrap">
1280 +<input type="hidden" name="link_id" value="<?php echo $link_id; ?>" />
1281 +<input type="hidden" name="action" value="linkedit" />
1282 +<input type="hidden" name="save" value="link" />
1283 +
1284 +<h2>Edit a syndicated feed:</h2>
1285 +<div id="poststuff">
1286 +<?php fwp_linkedit_single_submit($status); ?>
1287 +
1288 +<div id="post-body">
1289 +<?php fwp_option_box_opener('Feed Information', 'feedinformationdiv'); ?>
1290 + <table class="editform" width="100%" cellspacing="2" cellpadding="5">
1291 + <tr>
1292 + <th scope="row" width="20%"><?php _e('Feed URI:') ?></th>
1293 + <td width="60%"><a href="<?php echo wp_specialchars($link_rss_uri, 'both'); ?>"><?php echo $link_rss_uri; ?></a>
1294 + (<a href="<?php echo FEEDVALIDATOR_URI; ?>?url=<?php echo urlencode($link_rss_uri); ?>"
1295 + title="Check feed &lt;<?php echo wp_specialchars($link_rss_uri, 'both'); ?>&gt; for validity">validate</a>)
1296 + </td>
1297 + <td width="20%"><input type="submit" name="feedfinder" value="switch &rarr;" style="font-size:smaller" /></td>
1298 + </tr>
1299 + <tr>
1300 + <th scope="row" width="20%"><?php _e('Link Name:') ?></th>
1301 + <td width="60%"><input type="text" id="basics-name-edit" name="name"
1302 + value="<?php echo $link_name; ?>" style="width: 95%" />
1303 + <span id="basics-name-view"><strong><?php echo $link_name; ?></strong></span>
1304 + </td>
1305 + <td>
1306 + <select id="basics-hardcode-name" onchange="flip_hardcode('name')" name="hardcode_name">
1307 + <option value="no" <?php echo $link->hardcode('name')?'':'selected="selected"'; ?>>update automatically</option>
1308 + <option value="yes" <?php echo $link->hardcode('name')?'selected="selected"':''; ?>>edit manually</option>
1309 + </select>
1310 + </td>
1311 + </tr>
1312 + <tr>
1313 + <th scope="row" width="20%"><?php _e('Short description:') ?></th>
1314 + <td width="60%">
1315 + <input id="basics-description-edit" type="text" name="description" value="<?php echo $link_description; ?>" style="width: 95%" />
1316 + <span id="basics-description-view"><strong><?php echo $link_description; ?></strong></span>
1317 + </td>
1318 + <td>
1319 + <select id="basics-hardcode-description" onchange="flip_hardcode('description')"
1320 + name="hardcode_description">
1321 + <option value="no" <?php echo $link->hardcode('description')?'':'selected="selected"'; ?>>update automatically</option>
1322 + <option value="yes" <?php echo $link->hardcode('description')?'selected="selected"':''; ?>>edit manually</option>
1323 + </select></td>
1324 + </tr>
1325 + <tr>
1326 + <th width="20%" scope="row"><?php _e('Homepage:') ?></th>
1327 + <td width="60%">
1328 + <input id="basics-url-edit" type="text" name="linkurl" value="<?php echo $link_url; ?>" style="width: 95%;" />
1329 + <a id="basics-url-view" href="<?php echo $link_url; ?>"><?php echo $link_url; ?></a></td>
1330 + <td>
1331 + <select id="basics-hardcode-url" onchange="flip_hardcode('url')" name="hardcode_url">
1332 + <option value="no"<?php echo $link->hardcode('url')?'':' selected="selected"'; ?>>update automatically</option>
1333 + <option value="yes"<?php echo $link->hardcode('url')?' selected="selected"':''; ?>>edit manually</option>
1334 + </select></td></tr>
1335 +
1336 + <tr>
1337 + <th width="20%"><?php _e('Last update') ?>:</th>
1338 + <td colspan="2"><?php
1339 + if (isset($meta['update/last'])) :
1340 + echo strftime('%x %X', $meta['update/last'])." ";
1341 + else :
1342 + echo " none yet";
1343 + endif;
1344 + ?></td></tr>
1345 + <tr><th width="20%">Next update:</th>
1346 + <td colspan="2"><?php
1347 + $holdem = (isset($meta['update/hold']) ? $meta['update/hold'] : 'scheduled');
1348 + ?>
1349 + <select name="update_schedule">
1350 + <option value="scheduled"<?php echo ($holdem=='scheduled')?' selected="selected"':''; ?>>update on schedule <?php
1351 + echo " (";
1352 + if (isset($meta['update/ttl']) and is_numeric($meta['update/ttl'])) :
1353 + if (isset($meta['update/timed']) and $meta['update/timed']=='automatically') :
1354 + echo 'next: ';
1355 + $next = $meta['update/last'] + ((int) $meta['update/ttl'] * 60);
1356 + if (strftime('%x', time()) != strftime('%x', $next)) :
1357 + echo strftime('%x', $next)." ";
1358 + endif;
1359 + echo strftime('%X', $meta['update/last']+((int) $meta['update/ttl']*60));
1360 + else :
1361 + echo "every ".$meta['update/ttl']." minute".(($meta['update/ttl']!=1)?"s":"");
1362 + endif;
1363 + else:
1364 + echo "next scheduled update";
1365 + endif;
1366 + echo ")";
1367 + ?></option>
1368 + <option value="next"<?php echo ($holdem=='next')?' selected="selected"':''; ?>>update ASAP</option>
1369 + <option value="ping"<?php echo ($holdem=='ping')?' selected="selected"':''; ?>>update only when pinged</option>
1370 + </select></tr>
1371 + </table>
1372 +<?php fwp_option_box_closer(); ?>
1373 +
1374 +<script type="text/javascript">
1375 +flip_hardcode('name');
1376 +flip_hardcode('description');
1377 +flip_hardcode('url');
1378 +</script>
1379 +
1380 +<?php fwp_linkedit_periodic_submit(); ?>
1381 +
1382 +<?php
1383 +if (!(isset($wp_db_version) and $wp_db_version >= FWP_SCHEMA_25)) :
1384 + fwp_option_box_opener('Syndicated Posts', 'syndicatedpostsdiv', 'postbox');
567 1385 ?>
568 -<p style="font-style: italic"><strong>FeedWordPress has detected that <?php print $youAre; ?> currently using a version of
569 -MagpieRSS other than the upgraded version that ships with this version of FeedWordPress.</strong></p>
570 -<ul>
571 -<li><strong>Currently running:</strong> MagpieRSS <?php print $magpie_version; ?></li>
572 -<li><strong>Version included with FeedWordPress <?php print FEEDWORDPRESS_VERSION; ?>:</strong> MagpieRSS <?php print EXPECTED_MAGPIE_VERSION; ?></li>
573 -</ul>
574 -<p><?php print $itIsRecommendedThatYou; ?> install the upgraded
575 -version of MagpieRSS supplied with FeedWordPress. The version of
576 -MagpieRSS that ships with WordPress is very old and buggy, and
577 -encounters a number of errors when trying to parse modern Atom
578 -and RSS feeds.</p>
1386 +<table class="editform" width="75%" cellspacing="2" cellpadding="5">
1387 +<tr><th width="27%" scope="row" style="vertical-align:top">Publication:</th>
1388 +<td width="73%" style="vertical-align:top"><ul style="margin:0; list-style:none">
1389 +<li><label><input type="radio" name="feed_post_status" value="site-default"
1390 +<?php echo $status['post']['site-default']; ?> /> Use site-wide setting from <a href="admin.php?page=<?php print $GLOBALS['fwp_path'] ?>/syndication-options.php">Syndication Options</a>
1391 +(currently: <strong><?php echo ($post_status_global ? $post_status_global : 'publish'); ?></strong>)</label></li>
1392 +<li><label><input type="radio" name="feed_post_status" value="publish"
1393 +<?php echo $status['post']['publish']; ?> /> Publish posts from this feed immediately</label></li>
1394 +
1395 +<?php if (SyndicatedPost::use_api('post_status_pending')) : ?>
1396 +<li><label><input type="radio" name="feed_post_status" value="pending"
1397 +<?php echo $status['post']['pending']; ?>/> Hold posts from this feed for review; mark as Pending</label></li>
1398 +<?php endif; ?>
1399 +
1400 +<li><label><input type="radio" name="feed_post_status" value="draft"
1401 +<?php echo $status['post']['draft']; ?> /> Save posts from this feed as drafts</label></li>
1402 +<li><label><input type="radio" name="feed_post_status" value="private"
1403 +<?php echo $status['post']['private']; ?> /> Save posts from this feed as private posts</label></li>
1404 +</ul></td>
1405 +</tr>
1406 +</table>
579 1407 <?php
580 - feedwordpress_upgrade_old_and_busted_buttons();
581 - print '</div>';
1408 + fwp_option_box_closer();
1409 + fwp_linkedit_periodic_submit();
1410 +endif;
1411 +
1412 + fwp_option_box_opener(__('Categories'), 'categorydiv', 'postbox');
1413 + fwp_category_box($dogs, 'all syndicated posts from this feed');
1414 +?>
1415 +<table>
1416 +<tr>
1417 +<th width="20%" scope="row" style="vertical-align:top">Unfamiliar categories:</th>
1418 +<td width="80%"><ul style="margin: 0; list-style:none">
1419 +<li><label><input type="radio" name="unfamiliar_category" value="site-default"<?php echo $unfamiliar['category']['site-default']; ?> /> use site-wide setting from <a href="admin.php?page=<?php print $GLOBALS['fwp_path'] ?>/syndication-options.php">Syndication Options</a>
1420 +(currently <strong><?php echo FeedWordPress::on_unfamiliar('category'); ?></strong>)</label></li>
1421 +<li><label><input type="radio" name="unfamiliar_category" value="create"<?php echo $unfamiliar['category']['create']; ?> /> create any categories the post is in</label></li>
1422 +<li><label><input type="radio" name="unfamiliar_category" value="default"<?php echo $unfamiliar['category']['default']; ?> /> don't create new categories</label></li>
1423 +<li><label><input type="radio" name="unfamiliar_category" value="filter"<?php echo $unfamiliar['category']['filter']; ?> /> don't create new categories and don't syndicate posts unless they match at least one familiar category</label></li>
1424 +</ul></td>
1425 +</tr>
1426 +
1427 +<tr>
1428 +<th width="20%" scope="row" style="vertical-align:top">Multiple categories:</th>
1429 +<td width="80%">
1430 +<input type="text" size="20" id="cat_split" name="cat_split" value="<?php if (isset($meta['cat_split'])) : echo htmlspecialchars($meta['cat_split']); endif; ?>" /><br/>
1431 +Enter a <a href="http://us.php.net/manual/en/reference.pcre.pattern.syntax.php">Perl-compatible regular expression</a> here if the feed provides multiple
1432 +categories in a single category element. The regular expression should match
1433 +the characters used to separate one category from the next. If the feed uses
1434 +spaces (like <a href="http://del.icio.us/">del.icio.us</a>), use the pattern "\s".
1435 +If the feed does not provide multiple categories in a single element, leave this
1436 +blank.</td>
1437 +</tr>
1438 +</table>
1439 +<?php
1440 + fwp_option_box_closer();
1441 + fwp_linkedit_periodic_submit();
1442 +
1443 +if (isset($wp_db_version) and $wp_db_version >= FWP_SCHEMA_25) :
1444 + fwp_tags_box($meta['tags']);
1445 + fwp_linkedit_periodic_submit();
1446 +endif; ?>
1447 +
1448 +<?php fwp_option_box_opener('Syndicated Authors', 'authordiv', 'postbox'); ?>
1449 +<?php $authorlist = fwp_author_list(); ?>
1450 +<table>
1451 +<tr><th colspan="3" style="text-align: left; padding-top: 1.0em; border-bottom: 1px dotted black;">For posts by authors that haven't been syndicated before:</th></tr>
1452 +<tr>
1453 + <th style="text-align: left">Posts by new authors</th>
1454 + <td>
1455 + <select id="unfamiliar-author" name="unfamiliar_author" onchange="flip_newuser('unfamiliar-author');">
1456 + <option value="site-default"<?php if (!isset($meta['unfamiliar author'])) : ?>selected="selected"<?php endif; ?>>are handled using site-wide settings</option>
1457 + <option value="create"<?php if ('create'==$meta['unfamiliar author']) : ?>selected="selected"<?php endif; ?>>create a new author account</option>
1458 + <?php foreach ($authorlist as $author_id => $author_name) : ?>
1459 + <option value="<?php echo $author_id; ?>"<?php if ($author_id==$meta['unfamiliar author']) : ?>selected="selected"<?php endif; ?>>are assigned to <?php echo $author_name; ?></option>
1460 + <?php endforeach; ?>
1461 + <option value="newuser">will be assigned to a new user...</option>
1462 + <option value="filter"<?php if ('filter'==$meta['unfamiliar author']) : ?>selected="selected"<?php endif; ?>>get filtered out</option>
1463 + </select>
1464 + </td>
1465 + <td>
1466 + <div id="unfamiliar-author-default">Site-wide settings can be set in <a href="admin.php?page=<?php print $GLOBALS['fwp_path'] ?>/syndication-options.php">Syndication Options</a></div>
1467 + <div id="unfamiliar-author-newuser">named <input type="text" name="unfamiliar_author_newuser" value="" /></div>
1468 + </td>
1469 +</tr>
1470 +
1471 +<tr><th colspan="3" style="text-align: left; padding-top: 1.0em; border-bottom: 1px dotted black;">For posts by specific authors. Blank out a name to delete the rule.</th></tr>
1472 +
1473 +<?php if (isset($meta['map authors'])) : $i=0; foreach ($meta['map authors'] as $author_rules) : foreach ($author_rules as $author_name => $author_action) : $i++; ?>
1474 +<tr>
1475 + <th style="text-align: left">Posts by <input type="text" name="author_rules_name[]" value="<?php echo htmlspecialchars($author_name); ?>" /></th>
1476 + <td>
1477 + <select id="author-rules-<?php echo $i; ?>" name="author_rules_action[]" onchange="flip_newuser('author-rules-<?php echo $i; ?>');">
1478 + <?php foreach ($authorlist as $local_author_id => $local_author_name) : ?>
1479 + <option value="<?php echo $local_author_id; ?>"<?php if ($local_author_id==$author_action) : echo ' selected="selected"'; endif; ?>>are assigned to <?php echo $local_author_name; ?></option>
1480 + <?php endforeach; ?>
1481 + <option value="newuser">will be assigned to a new user...</option>
1482 + <option value="filter"<?php if ('filter'==$author_action) : echo ' selected="selected"'; endif; ?>>get filtered out</option>
1483 + </select>
1484 + </td>
1485 + <td><div id="author-rules-<?php echo $i; ?>-newuser">named <input type="text" name="author_rules_newuser[]" value="" /></div></td>
1486 +</tr>
1487 +<?php endforeach; endforeach; endif; ?>
1488 +
1489 +<tr><th colspan="3" style="text-align: left; padding-top: 1.0em; border-bottom: 1px dotted black;">Fill in to set up a new rule:</th></tr>
1490 +
1491 +<tr>
1492 + <th style="text-align: left">Posts by <input type="text" name="add_author_rule_name" /></th>
1493 + <td>
1494 + <select id="add-author-rule" name="add_author_rule_action" onchange="flip_newuser('add-author-rule');">
1495 + <?php foreach ($authorlist as $author_id => $author_name) : ?>
1496 + <option value="<?php echo $author_id; ?>">are assigned to <?php echo $author_name; ?></option>
1497 + <?php endforeach; ?>
1498 + <option value="newuser">will be assigned to a new user...</option>
1499 + <option value="filter">get filtered out</option>
1500 + </select>
1501 + </td>
1502 + <td><div id="add-author-rule-newuser">named <input type="text" name="add_author_rule_newuser" value="" /></div></td>
1503 +</tr>
1504 +
1505 +</table>
1506 +<?php fwp_option_box_closer(); ?>
1507 +
1508 +<script>
1509 + flip_newuser('unfamiliar-author');
1510 +<?php for ($j=1; $j<=$i; $j++) : ?>
1511 + flip_newuser('author-rules-<?php echo $j; ?>');
1512 +<?php endfor; ?>
1513 + flip_newuser('add-author-rule');
1514 +</script>
1515 +
1516 +<?php
1517 + fwp_linkedit_periodic_submit();
1518 + fwp_option_box_opener('Comments & Pings', 'commentstatusdiv', 'postbox');
1519 +?>
1520 +<table class="editform" width="75%" cellspacing="2" cellpadding="5">
1521 +<tr><th width="27%" scope="row" style="vertical-align:top"><?php print __('Comments'); ?>:</th>
1522 +<td width="73%"><ul style="margin:0; list-style:none">
1523 +<li><label><input type="radio" name="feed_comment_status" value="site-default"
1524 +<?php echo $status['comment']['site-default']; ?> /> Use site-wide setting from <a href="admin.php?page=<?php print $GLOBALS['fwp_path'] ?>/syndication-options.php">Syndication Options</a>
1525 +(currently: <strong><?php echo ($comment_status_global ? $comment_status_global : 'closed'); ?>)</strong></label></li>
1526 +<li><label><input type="radio" name="feed_comment_status" value="open"
1527 +<?php echo $status['comment']['open']; ?> /> Allow comments on syndicated posts from this feed</label></li>
1528 +<li><label><input type="radio" name="feed_comment_status" value="closed"
1529 +<?php echo $status['comment']['closed']; ?> /> Don't allow comments on syndicated posts from this feed</label></li>
1530 +</ul></td></tr>
1531 +
1532 +<tr><th width="27%" scope="row" style="vertical-align:top"><?php print __('Pings'); ?>:</th>
1533 +<td width="73%"><ul style="margin:0; list-style:none">
1534 +<li><label><input type="radio" name="feed_ping_status" value="site-default"
1535 +<?php echo $status['ping']['site-default']; ?> /> Use site-wide setting from <a href="admin.php?page=<?php print $GLOBALS['fwp_path'] ?>/syndication-options.php">Syndication Options</a>
1536 +(currently: <strong><?php echo ($ping_status_global ? $ping_status_global : 'closed'); ?>)</strong></label></li>
1537 +<li><label><input type="radio" name="feed_ping_status" value="open"
1538 +<?php echo $status['ping']['open']; ?> /> Accept pings on syndicated posts from this feed</label></li>
1539 +<li><label><input type="radio" name="feed_ping_status" value="closed"
1540 +<?php echo $status['ping']['closed']; ?> /> Don't accept pings on syndicated posts from this feed</label></li>
1541 +</ul></td></tr>
1542 +
1543 +</table>
1544 +<?php fwp_option_box_closer(); ?>
1545 +<?php fwp_linkedit_periodic_submit(); ?>
1546 +
1547 +<?php fwp_option_box_opener('Custom Settings (for use in templates)', 'postcustom', 'postbox'); ?>
1548 +<div id="postcustomstuff">
1549 +<table id="meta-list" cellpadding="3">
1550 + <tr>
1551 + <th>Key</th>
1552 + <th>Value</th>
1553 + <th>Action</th>
1554 + </tr>
1555 +
1556 +<?php
1557 + $i = 0;
1558 + foreach ($meta as $key => $value) :
1559 + if (!preg_match("\007^((".implode(')|(', $special_settings)."))$\007i", $key)) :
1560 +?>
1561 + <tr style="vertical-align:top">
1562 + <th width="30%" scope="row"><input type="hidden" name="notes[<?php echo $i; ?>][key0]" value="<?php echo wp_specialchars($key, 'both'); ?>" />
1563 + <input id="notes-<?php echo $i; ?>-key" name="notes[<?php echo $i; ?>][key1]" value="<?php echo wp_specialchars($key, 'both'); ?>" /></th>
1564 + <td width="60%"><textarea rows="2" cols="40" id="notes-<?php echo $i; ?>-value" name="notes[<?php echo $i; ?>][value]"><?php echo wp_specialchars($value, 'both'); ?></textarea></td>
1565 + <td width="10%"><select name="notes[<?php echo $i; ?>][action]">
1566 + <option value="update">save changes</option>
1567 + <option value="delete">delete this setting</option>
1568 + </select></td>
1569 + </tr>
1570 +<?php
1571 + $i++;
582 1572 endif;
1573 + endforeach;
1574 +?>
1575 + <tr>
1576 + <th scope="row"><input type="text" size="10" name="notes[<?php echo $i; ?>][key1]" value="" /></th>
1577 + <td><textarea name="notes[<?php echo $i; ?>][value]" rows="2" cols="40"></textarea></td>
1578 + <td><em>add new setting...</em><input type="hidden" name="notes[<?php echo $i; ?>][action]" value="update" /></td>
1579 + </tr>
1580 +</table>
1581 +<?php fwp_option_box_closer(); ?>
1582 +
1583 +<?php fwp_linkedit_periodic_submit(); ?>
1584 +</div> <!-- id="post-body" -->
1585 +</div> <!-- id="poststuff" -->
1586 +</div>
1587 + <?php
583 1588 endif;
1589 + return false; // Don't continue
584 1590 }
585 1591
586 -function feedwordpress_upgrade_old_and_busted_buttons() {
587 - if (current_user_can('edit_files')) :
1592 +function fwp_author_list () {
1593 + global $wpdb;
1594 + $ret = array();
1595 + $users = $wpdb->get_results("SELECT * FROM $wpdb->users ORDER BY display_name");
1596 + if (is_array($users)) :
1597 + foreach ($users as $user) :
1598 + $id = (int) $user->ID;
1599 + $ret[$id] = $user->display_name;
1600 + endforeach;
1601 + endif;
1602 + return $ret;
1603 +}
1604 +
1605 +function fwp_multidelete_page () {
1606 + global $wpdb;
1607 +
1608 + check_admin_referer(); // Make sure the referers are kosher
1609 +
1610 + $link_ids = (isset($_REQUEST['link_ids']) ? $_REQUEST['link_ids'] : array());
1611 + if (isset($_REQUEST['link_id'])) : array_push($link_ids, $_REQUEST['link_id']); endif;
1612 +
1613 + if (!current_user_can('manage_links')):
1614 + die (__("Cheatin' uh ?"));
1615 + elseif (isset($GLOBALS['fwp_post']['confirm']) and $GLOBALS['fwp_post']['confirm']=='Delete'):
1616 + foreach ($GLOBALS['fwp_post']['link_action'] as $link_id => $what) :
1617 + $do_it[$what][] = $link_id;
1618 + endforeach;
1619 +
1620 + $alter = array();
1621 + if (count($do_it['hide']) > 0) :
1622 + $hidem = "(".implode(', ', $do_it['hide']).")";
1623 + $alter[] = "
1624 + UPDATE $wpdb->links
1625 + SET link_visible = 'N'
1626 + WHERE link_id IN {$hidem}
1627 + ";
1628 + endif;
1629 +
1630 + if (count($do_it['nuke']) > 0) :
1631 + $nukem = "(".implode(', ', $do_it['nuke']).")";
1632 +
1633 + // Make a list of the items syndicated from this feed...
1634 + $post_ids = $wpdb->get_col("
1635 + SELECT post_id FROM $wpdb->postmeta
1636 + WHERE meta_key = 'syndication_feed_id'
1637 + AND meta_value IN {$nukem}
1638 + ");
1639 +
1640 + // ... and kill them all
1641 + if (count($post_ids) > 0) :
1642 + foreach ($post_ids as $post_id) :
1643 + wp_delete_post($post_id);
1644 + endforeach;
1645 + endif;
1646 +
1647 + $alter[] = "
1648 + DELETE FROM $wpdb->links
1649 + WHERE link_id IN {$nukem}
1650 + ";
1651 + endif;
1652 +
1653 + if (count($do_it['delete']) > 0) :
1654 + $deletem = "(".implode(', ', $do_it['delete']).")";
1655 +
1656 + // Make the items syndicated from this feed appear to be locally-authored
1657 + $alter[] = "
1658 + DELETE FROM $wpdb->postmeta
1659 + WHERE meta_key = 'syndication_feed_id'
1660 + AND meta_value IN {$deletem}
1661 + ";
1662 +
1663 + // ... and delete the links themselves.
1664 + $alter[] = "
1665 + DELETE FROM $wpdb->links
1666 + WHERE link_id IN {$deletem}
1667 + ";
1668 + endif;
1669 +
1670 + $errs = array(); $success = array ();
1671 + foreach ($alter as $sql) :
1672 + $result = $wpdb->query($sql);
1673 + if (!$result):
1674 + $errs[] = mysql_error();
1675 + endif;
1676 + endforeach;
1677 +
1678 + if (count($alter) > 0) :
1679 + echo "<div class=\"updated\">\n";
1680 + if (count($errs) > 0) :
1681 + echo "There were some problems processing your ";
1682 + echo "unsubscribe request. [SQL: ".implode('; ', $errs)."]";
1683 + else :
1684 + echo "Your unsubscribe request(s) have been processed.";
1685 + endif;
1686 + echo "</div>\n";
1687 + endif;
1688 +
1689 + return true; // Continue on to Syndicated Sites listing
1690 + else :
1691 + $targets = $wpdb->get_results("
1692 + SELECT * FROM $wpdb->links
1693 + WHERE link_id IN (".implode(",",$link_ids).")
1694 + ");
588 1695 ?>
589 -<form action="" method="post"><div>
590 -<?php FeedWordPressCompatibility::stamp_nonce('feedwordpress_fix_magpie'); ?>
591 -<input type="hidden" name="action" value="fix_magpie_version" />
592 -<input class="button-secondary" type="submit" name="ignore" value="<?php _e('Ignore this problem'); ?>" />
593 -<input class="button-primary" type="submit" name="upgrade" value="<?php _e('Upgrade'); ?>" />
594 -</div></form>
1696 +<form action="admin.php?page=<?php print $GLOBALS['fwp_path'] ?>/<?php echo basename(__FILE__); ?>" method="post">
1697 +<div class="wrap">
1698 +<input type="hidden" name="action" value="Unsubscribe" />
1699 +<input type="hidden" name="confirm" value="Delete" />
1700 +
1701 +<h2>Unsubscribe from Syndicated Links:</h2>
1702 +<?php foreach ($targets as $link) :
1703 + $link_url = wp_specialchars($link->link_url, 1);
1704 + $link_name = wp_specialchars($link->link_name, 1);
1705 + $link_description = wp_specialchars($link->link_description, 'both');
1706 + $link_rss = wp_specialchars($link->link_rss, 'both');
1707 +?>
1708 +<fieldset>
1709 +<legend><?php echo $link_name; ?></legend>
1710 +<table class="editform" width="100%" cellspacing="2" cellpadding="5">
1711 +<tr><th scope="row" width="20%"><?php _e('Feed URI:') ?></th>
1712 +<td width="80%"><a href="<?php echo $link_rss; ?>"><?php echo $link_rss; ?></a></td></tr>
1713 +<tr><th scope="row" width="20%"><?php _e('Short description:') ?></th>
1714 +<td width="80%"><?php echo $link_description; ?></span></td></tr>
1715 +<tr><th width="20%" scope="row"><?php _e('Homepage:') ?></th>
1716 +<td width="80%"><a href="<?php echo $link_url; ?>"><?php echo $link_url; ?></a></td></tr>
1717 +<tr style="vertical-align:top"><th width="20%" scope="row">Subscription <?php _e('Options') ?>:</th>
1718 +<td width="80%"><ul style="margin:0; padding: 0; list-style: none">
1719 +<li><input type="radio" id="hide-<?php echo $link->link_id; ?>"
1720 +name="link_action[<?php echo $link->link_id; ?>]" value="hide" />
1721 +<label for="hide-<?php echo $link->link_id; ?>">Turn off the subscription for this
1722 +syndicated link<br/><span style="font-size:smaller">(Keep the feed information
1723 +and all the posts from this feed in the database, but don't syndicate any
1724 +new posts from the feed.)</span></label></li>
1725 +<li><input type="radio" id="nuke-<?php echo $link->link_id; ?>"
1726 +name="link_action[<?php echo $link->link_id; ?>]" value="nuke" />
1727 +<label for="nuke-<?php echo $link->link_id; ?>">Delete this syndicated link and all the
1728 +posts that were syndicated from it</label></li>
1729 +<li><input type="radio" id="delete-<?php echo $link->link_id; ?>"
1730 +name="link_action[<?php echo $link->link_id; ?>]" value="delete" />
1731 +<label for="delete-<?php echo $link->link_id; ?>">Delete this syndicated link, but
1732 +<em>keep</em> posts that were syndicated from it (as if they were authored
1733 +locally).</label></li>
1734 +<li><input type="radio" id="nothing-<?php echo $link->link_id; ?>"
1735 +name="link_action[<?php echo $link->link_id; ?>]" value="nothing" />
1736 +<label for="nothing-<?php echo $link->link_id; ?>">Keep this feed as it is. I changed
1737 +my mind.</label></li>
1738 +</ul>
1739 +</table>
1740 +</fieldset>
1741 +<?php endforeach; ?>
1742 +
1743 +<div class="submit">
1744 +<input class="delete" type="submit" name="submit" value="<?php _e('Unsubscribe from selected feeds &raquo;') ?>" />
1745 +</div>
1746 +</div>
595 1747 <?php
1748 + return false; // Don't continue on to Syndicated Sites listing
596 1749 endif;
597 1750 }
598 1751
599 1752 ################################################################################
@@ -750,9 +1903,9 @@
750 1903 #
751 1904 # * Updates to existing posts since the last poll are mirrored in the
752 1905 # WordPress store.
753 1906 #
754 - function update ($uri = null, $crash_ts = null) {
1907 + function update ($uri = null) {
755 1908 global $wpdb;
756 1909
757 1910 if (FeedWordPress::needs_upgrade()) : // Will make duplicate posts if we don't hold off
758 1911 return NULL;
@@ -765,28 +1918,11 @@
765 1918 endif;
766 1919
767 1920 do_action('feedwordpress_update', $uri);
768 1921
769 - if (is_null($crash_ts)) :
770 - $crash_dt = (int) get_option('feedwordpress_update_time_limit');
771 - if ($crash_dt > 0) :
772 - $crash_ts = time() + $crash_dt;
773 - else :
774 - $crash_ts = NULL;
775 - endif;
776 - endif;
777 -
778 - // Randomize order for load balancing purposes
779 - $feed_set = $this->feeds;
780 - shuffle($feed_set);
781 -
782 1922 // Loop through and check for new posts
783 1923 $delta = NULL;
784 - foreach ($feed_set as $feed) :
785 - if (!is_null($crash_ts) and (time() > $crash_ts)) : // Check whether we've exceeded the time limit
786 - break;
787 - endif;
788 -
1924 + foreach ($this->feeds as $feed) :
789 1925 $pinged_that = (is_null($uri) or in_array($uri, array($feed->uri(), $feed->homepage())));
790 1926
791 1927 if (!is_null($uri)) : // A site-specific ping always updates
792 1928 $timely = true;
@@ -799,12 +1935,9 @@
799 1935 endif;
800 1936
801 1937 if ($pinged_that and $timely) :
802 1938 do_action('feedwordpress_check_feed', $feed->settings);
803 - $start_ts = time();
804 - $added = $feed->poll($crash_ts);
805 - do_action('feedwordpress_check_feed_complete', $feed->settings, $added, time() - $start_ts);
806 -
1939 + $added = $feed->poll();
807 1940 if (isset($added['new'])) : $delta['new'] += $added['new']; endif;
808 1941 if (isset($added['updated'])) : $delta['updated'] += $added['updated']; endif;
809 1942 endif;
810 1943 endforeach;
@@ -862,9 +1995,9 @@
862 1995 if (function_exists('wp_insert_link')) { // WordPress 2.x
863 1996 $link_id = wp_insert_link(array(
864 1997 "link_name" => $name,
865 1998 "link_url" => $uri,
866 - "link_category" => (fwp_test_wp_version(0, FWP_SCHEMA_21) ? $cat_id : array($cat_id)),
1999 + "link_category" => array($cat_id),
867 2000 "link_rss" => $rss
868 2001 ));
869 2002 } else { // WordPress 1.5.x
870 2003 $result = $wpdb->query("
@@ -880,20 +2013,17 @@
880 2013 return $link_id;
881 2014 } // function FeedWordPress::syndicate_link()
882 2015
883 2016 function on_unfamiliar ($what = 'author', $override = NULL) {
884 - $set = array(
885 - 'author' => array('create', 'default', 'filter'),
886 - 'category' => array('create', 'tag', 'default', 'filter'),
887 - );
888 -
2017 + $set = array('create', 'default', 'filter');
2018 +
889 2019 if (is_string($override)) :
890 2020 $ret = strtolower($override);
891 2021 endif;
892 2022
893 - if (!is_numeric($override) and !in_array($ret, $set[$what])) :
2023 + if (!is_numeric($override) and !in_array($ret, $set)) :
894 2024 $ret = get_option('feedwordpress_unfamiliar_'.$what);
895 - if (!is_numeric($ret) and !in_array($ret, $set[$what])) :
2025 + if (!is_numeric($ret) and !in_array($ret, $set)) :
896 2026 $ret = 'create';
897 2027 endif;
898 2028 endif;
899 2029
@@ -899,33 +2029,8 @@
899 2029
900 2030 return $ret;
901 2031 } // function FeedWordPress::on_unfamiliar()
902 2032
903 - function null_email_set () {
904 - $base = get_option('feedwordpress_null_email_set');
905 -
906 - if ($base===false) :
907 - $ret = array('noreply@blogger.com'); // default
908 - else :
909 - $ret = array_map('strtolower',
910 - array_map('trim', explode("\n", $base)));
911 - endif;
912 - $ret = apply_filters('syndicated_item_author_null_email_set', $ret);
913 - return $ret;
914 -
915 - } /* FeedWordPress::null_email_set () */
916 -
917 - function is_null_email ($email) {
918 - $ret = in_array(strtolower(trim($email)), FeedWordPress::null_email_set());
919 - $ret = apply_filters('syndicated_item_author_is_null_email', $ret, $email);
920 - return $ret;
921 - } /* FeedWordPress::is_null_email () */
922 -
923 - function use_aggregator_source_data () {
924 - $ret = get_option('feedwordpress_use_aggregator_source_data');
925 - return apply_filters('syndicated_post_use_aggregator_source_data', ($ret=='yes'));
926 - }
927 -
928 2033 function syndicated_links () {
929 2034 $contributors = FeedWordPress::link_category_id();
930 2035 if (function_exists('get_bookmarks')) :
931 2036 $links = get_bookmarks(array("category" => $contributors));
@@ -950,12 +2055,12 @@
950 2055 // WordPress 2.3 introduces a new taxonomy/term API
951 2056 if (function_exists('is_term')) :
952 2057 $cat_id = is_term($cat, 'link_category');
953 2058 // WordPress 2.1 and 2.2 use a common table for both link and post categories
954 - elseif (fwp_test_wp_version(FWP_SCHEMA_21, FWP_SCHEMA_23)) :
2059 + elseif (isset($wp_db_version) and ($wp_db_version >= FWP_SCHEMA_21 and $wp_db_version < FWP_SCHEMA_23) ) :
955 2060 $cat_id = $wpdb->get_var("SELECT cat_id FROM {$wpdb->categories} WHERE cat_name='$cat'");
956 2061 // WordPress 1.5 and 2.0.x have a separate table for link categories
957 - elseif (fwp_test_wp_version(0, FWP_SCHEMA_21)):
2062 + elseif (!isset($wp_db_version) or $wp_db_version < FWP_SCHEMA_21) :
958 2063 $cat_id = $wpdb->get_var("SELECT cat_id FROM {$wpdb->linkcategories} WHERE cat_name='$cat'");
959 2064 // This should never happen.
960 2065 else :
961 2066 FeedWordPress::critical_bug('FeedWordPress::link_category_id::wp_db_version', $wp_db_version, __LINE__);
@@ -968,12 +2073,12 @@
968 2073 if (function_exists('wp_insert_term')) :
969 2074 $term = wp_insert_term($cat, 'link_category');
970 2075 $cat_id = $term['term_id'];
971 2076 // WordPress 2.1, 2.2 category API. By the way, why the fuck is this API function only available in a wp-admin module?
972 - elseif (function_exists('wp_insert_category') and !fwp_test_wp_version(FWP_SCHEMA_20, FWP_SCHEMA_21)) :
2077 + elseif (function_exists('wp_insert_category')) :
973 2078 $cat_id = wp_insert_category(array('cat_name' => $cat));
974 2079 // WordPress 1.5 and 2.0.x
975 - elseif (fwp_test_wp_version(0, FWP_SCHEMA_21)) :
2080 + elseif (!isset($wp_db_version) or $wp_db_version < FWP_SCHEMA_21) :
976 2081 $result = $wpdb->query("
977 2082 INSERT INTO $wpdb->linkcategories
978 2083 SET
979 2084 cat_id = 0,
@@ -1083,23 +2188,8 @@
1083 2188 endswitch;
1084 2189 echo "<p>Upgrade complete. FeedWordPress is now ready to use again.</p>";
1085 2190 } /* FeedWordPress::upgrade_database() */
1086 2191
1087 - function create_guid_index () {
1088 - global $wpdb;
1089 -
1090 - $wpdb->query("
1091 - CREATE INDEX {$wpdb->posts}_guid_idx ON {$wpdb->posts}(guid)
1092 - ");
1093 - } /* FeedWordPress::create_guid_index () */
1094 -
1095 - function magpie_version () {
1096 - if (!defined('MAGPIE_VERSION')) : $magpie_version = $GLOBALS['wp_version'].'-default';
1097 - else : $magpie_version = MAGPIE_VERSION;
1098 - endif;
1099 - return $magpie_version;
1100 - }
1101 -
1102 2192 # Utility functions for handling text settings
1103 2193 function negative ($f, $setting) {
1104 2194 $nego = array ('n', 'no', 'f', 'false');
1105 2195 return (isset($f[$setting]) and in_array(strtolower($f[$setting]), $nego));
@@ -1114,29 +2204,18 @@
1114 2204 # Internal debugging functions
1115 2205 function critical_bug ($varname, $var, $line) {
1116 2206 global $wp_version;
1117 2207
1118 - if (defined('MAGPIE_VERSION')) : $mv = MAGPIE_VERSION;
1119 - else : $mv = 'WordPress '.$wp_version.' default.';
1120 - endif;
1121 -
1122 2208 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>';
1123 2209 echo "\n<plaintext>";
1124 2210 echo "Triggered at line # ".$line."\n";
1125 2211 echo "FeedWordPress version: ".FEEDWORDPRESS_VERSION."\n";
1126 - echo "MagpieRSS version: {$mv}\n";
1127 - echo "WordPress version: {$wp_version}\n";
2212 + echo "WordPress version: $wp_version\n";
1128 2213 echo "PHP version: ".phpversion()."\n";
1129 2214 echo "\n";
1130 2215 echo $varname.": "; var_dump($var); echo "\n";
1131 2216 die;
1132 2217 }
1133 -
1134 - function noncritical_bug ($varname, $var, $line) {
1135 - if (FEEDWORDPRESS_DEBUG) : // halt only when we are doing debugging
1136 - FeedWordPress::critical_bug($varname, $var, $line);
1137 - endif;
1138 - }
1139 2218 } // class FeedWordPress
1140 2219
1141 2220 class SyndicatedPost {
1142 2221 var $item = null;
@@ -1145,8 +2224,9 @@
1145 2224 var $feed = null;
1146 2225 var $feedmeta = null;
1147 2226
1148 2227 var $post = array ();
2228 + var $_base = null;
1149 2229
1150 2230 var $_freshness = null;
1151 2231 var $_wp_id = null;
1152 2232
@@ -1190,11 +2270,9 @@
1190 2270 $this->post['named']['author'] = apply_filters('syndicated_item_author', $this->author(), $this);
1191 2271
1192 2272 # Identify content and sanitize it.
1193 2273 # ---------------------------------
1194 - if (isset($this->item['atom_content'])) :
1195 - $content = $this->item['atom_content'];
1196 - elseif (isset($this->item['xhtml']['body'])) :
2274 + if (isset($this->item['xhtml']['body'])) :
1197 2275 $content = $this->item['xhtml']['body'];
1198 2276 elseif (isset($this->item['xhtml']['div'])) :
1199 2277 $content = $this->item['xhtml']['div'];
1200 2278 elseif (isset($this->item['content']['encoded']) and $this->item['content']['encoded']):
@@ -1243,26 +2321,8 @@
1243 2321
1244 2322 // Unique ID (hopefully a unique tag: URI); failing that, the permalink
1245 2323 $this->post['guid'] = apply_filters('syndicated_item_guid', $this->guid(), $this);
1246 2324
1247 - // User-supplied custom settings to apply to each post. Do first so that FWP-generated custom settings will overwrite if necessary; thus preventing any munging
1248 - $default_custom_settings = get_option('feedwordpress_custom_settings');
1249 - if ($default_custom_settings) :
1250 - $default_custom_settings = unserialize($default_custom_settings);
1251 - endif;
1252 - if (!is_array($default_custom_settings)) :
1253 - $default_custom_settings = array();
1254 - endif;
1255 -
1256 - $custom_settings = (isset($this->link->settings['postmeta']) ? $this->link->settings['postmeta'] : null);
1257 - if ($custom_settings) :
1258 - $custom_settings = unserialize($custom_settings);
1259 - endif;
1260 - if (!is_array($custom_settings)) :
1261 - $custom_settings = array();
1262 - endif;
1263 - $this->post['meta'] = array_merge($default_custom_settings, $custom_settings);
1264 -
1265 2325 // RSS 2.0 / Atom 1.0 enclosure support
1266 2326 if ( isset($this->item['enclosure#']) ) :
1267 2327 for ($i = 1; $i <= $this->item['enclosure#']; $i++) :
1268 2328 $eid = (($i > 1) ? "#{$id}" : "");
@@ -1276,26 +2336,12 @@
1276 2336 // In case you want to point back to the blog this was syndicated from
1277 2337 if (isset($this->feed->channel['title'])) :
1278 2338 $this->post['meta']['syndication_source'] = apply_filters('syndicated_item_source_title', $this->feed->channel['title'], $this);
1279 2339 endif;
1280 -
1281 2340 if (isset($this->feed->channel['link'])) :
1282 2341 $this->post['meta']['syndication_source_uri'] = apply_filters('syndicated_item_source_link', $this->feed->channel['link'], $this);
1283 2342 endif;
1284 2343
1285 - // Make use of atom:source data, if present in an aggregated feed
1286 - if (isset($this->item['source_title'])) :
1287 - $this->post['meta']['syndication_source_original'] = $this->item['source_title'];
1288 - endif;
1289 -
1290 - if (isset($this->item['source_link'])) :
1291 - $this->post['meta']['syndication_source_uri_original'] = $this->item['source_link'];
1292 - endif;
1293 -
1294 - if (isset($this->item['source_id'])) :
1295 - $this->post['meta']['syndication_source_id_original'] = $this->item['source_id'];
1296 - endif;
1297 -
1298 2344 // Store information on human-readable and machine-readable comment URIs
1299 2345 if (isset($this->item['comments'])) :
1300 2346 $this->post['meta']['rss:comments'] = apply_filters('syndicated_item_comments', $this->item['comments']);
1301 2347 endif;
@@ -1306,21 +2352,14 @@
1306 2352 // Store information to identify the feed that this came from
1307 2353 $this->post['meta']['syndication_feed'] = $this->feedmeta['link/uri'];
1308 2354 $this->post['meta']['syndication_feed_id'] = $this->feedmeta['link/id'];
1309 2355
1310 - if (isset($this->item['source_link_self'])) :
1311 - $this->post['meta']['syndication_feed_original'] = $this->item['source_link_self'];
1312 - endif;
1313 -
1314 2356 // In case you want to know the external permalink...
1315 2357 $this->post['meta']['syndication_permalink'] = apply_filters('syndicated_item_link', $this->item['link']);
1316 2358
1317 - // Store a hash of the post content for checking whether something needs to be updated
1318 - $this->post['meta']['syndication_item_hash'] = $this->update_hash();
1319 -
1320 2359 // Feed-by-feed options for author and category creation
1321 - $this->post['named']['unfamiliar']['author'] = (isset($this->feedmeta['unfamiliar author']) ? $this->feedmeta['unfamiliar author'] : null);
1322 - $this->post['named']['unfamiliar']['category'] = (isset($this->feedmeta['unfamiliar category']) ? $this->feedmeta['unfamiliar category'] : null);
2360 + $this->post['named']['unfamiliar']['author'] = $this->feedmeta['unfamiliar author'];
2361 + $this->post['named']['unfamiliar']['category'] = $this->feedmeta['unfamiliar category'];
1323 2362
1324 2363 // Categories: start with default categories, if any
1325 2364 $fc = get_option("feedwordpress_syndication_cats");
1326 2365 if ($fc) :
@@ -1328,9 +2367,9 @@
1328 2367 else :
1329 2368 $this->post['named']['preset/category'] = array();
1330 2369 endif;
1331 2370
1332 - if (isset($this->feedmeta['cats']) and is_array($this->feedmeta['cats'])) :
2371 + if (is_array($this->feedmeta['cats'])) :
1333 2372 $this->post['named']['preset/category'] = array_merge($this->post['named']['preset/category'], $this->feedmeta['cats']);
1334 2373 endif;
1335 2374
1336 2375 // Now add categories from the post, if we have 'em
@@ -1352,17 +2391,16 @@
1352 2391
1353 2392 // Tags: start with default tags, if any
1354 2393 $ft = get_option("feedwordpress_syndication_tags");
1355 2394 if ($ft) :
1356 - $this->post['tags_input'] = explode(FEEDWORDPRESS_CAT_SEPARATOR, $ft);
2395 + $this->post['tags_input'] = explode('FEEDWORDPRESS_CAT_SEPARATOR', $ft);
1357 2396 else :
1358 2397 $this->post['tags_input'] = array();
1359 2398 endif;
1360 2399
1361 - if (isset($this->feedmeta['tags']) and is_array($this->feedmeta['tags'])) :
2400 + if (is_array($this->feedmeta['tags'])) :
1362 2401 $this->post['tags_input'] = array_merge($this->post['tags_input'], $this->feedmeta['tags']);
1363 2402 endif;
1364 -
1365 2403 endif;
1366 2404 } // SyndicatedPost::SyndicatedPost()
1367 2405
1368 2406 function filtered () {
@@ -1383,35 +2421,18 @@
1383 2421 SELECT id, guid, post_modified_gmt
1384 2422 FROM $wpdb->posts WHERE guid='$guid'
1385 2423 ");
1386 2424
2425 + preg_match('/([0-9]+)-([0-9]+)-([0-9]+) ([0-9]+):([0-9]+):([0-9]+)/', $result->post_modified_gmt, $backref);
2426 + $updated = gmmktime($backref[4], $backref[5], $backref[6], $backref[2], $backref[3], $backref[1]);
1387 2427 if (!$result) :
1388 2428 $this->_freshness = 2; // New content
1389 - else:
1390 - $stored_update_hashes = get_post_custom_values('syndication_item_hash', $result->id);
1391 - if (count($stored_update_hashes) > 0) :
1392 - $stored_update_hash = $stored_update_hashes[0];
1393 - $update_hash_changed = ($stored_update_hash != $this->update_hash());
1394 - else :
1395 - $update_hash_changed = false;
1396 - endif;
1397 -
1398 - preg_match('/([0-9]+)-([0-9]+)-([0-9]+) ([0-9]+):([0-9]+):([0-9]+)/', $result->post_modified_gmt, $backref);
1399 -
1400 - $last_rev_ts = gmmktime($backref[4], $backref[5], $backref[6], $backref[2], $backref[3], $backref[1]);
1401 - $updated_ts = $this->updated(/*fallback=*/ true, /*default=*/ NULL);
1402 - $updated = ((
1403 - !is_null($updated_ts)
1404 - and ($updated_ts > $last_rev_ts)
1405 - ) or $update_hash_changed);
1406 -
1407 - if ($updated) :
1408 - $this->_freshness = 1; // Updated content
1409 - $this->_wp_id = $result->id;
1410 - else :
1411 - $this->_freshness = 0; // Same old, same old
1412 - $this->_wp_id = $result->id;
1413 - endif;
2429 + elseif ($this->updated() > $updated) :
2430 + $this->_freshness = 1; // Updated content
2431 + $this->_wp_id = $result->id;
2432 + else :
2433 + $this->_freshness = 0; // Same old, same old
2434 + $this->_wp_id = $result->id;
1414 2435 endif;
1415 2436 endif;
1416 2437 return $this->_freshness;
1417 2438 }
@@ -1447,17 +2468,13 @@
1447 2468 endif;
1448 2469
1449 2470 if (!$this->filtered() and $freshness > 0) :
1450 2471 # -- Look up, or create, numeric ID for categories
1451 - list($pcats, $ptags) = $this->category_ids (
2472 + $this->post['post_category'] = $this->category_ids (
1452 2473 $this->post['named']['category'],
1453 - FeedWordPress::on_unfamiliar('category', $this->post['named']['unfamiliar']['category']),
1454 - /*tags_too=*/ true
2474 + FeedWordPress::on_unfamiliar('category', $this->post['named']['unfamiliar']['category'])
1455 2475 );
1456 -
1457 - $this->post['post_category'] = $pcats;
1458 - $this->post['tags_input'] = array_merge($this->post['tags_input'], $ptags);
1459 -
2476 +
1460 2477 if (is_null($this->post['post_category'])) :
1461 2478 // filter mode on, no matching categories; drop the post
1462 2479 $this->post = NULL;
1463 2480 else :
@@ -1503,278 +2520,161 @@
1503 2520 } // function SyndicatedPost::store ()
1504 2521
1505 2522 function insert_new () {
1506 2523 global $wpdb, $wp_db_version;
1507 -
1508 - $dbpost = $this->normalize_post(/*new=*/ true);
1509 - if (!is_null($dbpost)) :
1510 - if ($this->use_api('wp_insert_post')) :
1511 - $dbpost['post_pingback'] = false; // Tell WP 2.1 and 2.2 not to process for pingbacks
1512 -
1513 - // This is a ridiculous fucking kludge necessitated by WordPress 2.6 munging authorship meta-data
1514 - add_action('_wp_put_post_revision', array($this, 'fix_revision_meta'));
1515 -
1516 - // Kludge to prevent kses filters from stripping the
1517 - // content of posts when updating without a logged in
1518 - // user who has `unfiltered_html` capability.
1519 - add_filter('content_save_pre', array($this, 'avoid_kses_munge'), 11);
1520 -
1521 - $this->_wp_id = wp_insert_post($dbpost);
1522 -
1523 - // Turn off ridiculous fucking kludges #1 and #2
1524 - remove_action('_wp_put_post_revision', array($this, 'fix_revision_meta'));
1525 - remove_filter('content_save_pre', array($this, 'avoid_kses_munge'), 11);
1526 -
1527 - $this->validate_post_id($dbpost, array(__CLASS__, __FUNCTION__));
1528 -
1529 - // Unfortunately, as of WordPress 2.3, wp_insert_post()
1530 - // *still* offers no way to use a guid of your choice,
1531 - // and munges your post modified timestamp, too.
1532 - $result = $wpdb->query("
1533 - UPDATE $wpdb->posts
1534 - SET
1535 - guid='{$dbpost['guid']}',
1536 - post_modified='{$dbpost['post_modified']}',
1537 - post_modified_gmt='{$dbpost['post_modified_gmt']}'
1538 - WHERE ID='{$this->_wp_id}'
1539 - ");
2524 +
2525 + // Why the fuck doesn't wp_insert_post already do this?
2526 + foreach ($this->post as $key => $value) :
2527 + if (is_string($value)) :
2528 + $dbpost[$key] = $wpdb->escape($value);
1540 2529 else :
1541 - # The right way to do this is the above. But, alas,
1542 - # in earlier versions of WordPress, wp_insert_post has
1543 - # too much behavior (mainly related to pings) that can't
1544 - # be overridden. In WordPress 1.5, it's enough of a
1545 - # resource hog to make PHP segfault after inserting
1546 - # 50-100 posts. This can get pretty annoying, especially
1547 - # if you are trying to update your feeds for the first
1548 - # time.
1549 -
1550 - $result = $wpdb->query("
1551 - INSERT INTO $wpdb->posts
1552 - SET
1553 - guid = '{$dbpost['guid']}',
1554 - post_author = '{$dbpost['post_author']}',
1555 - post_date = '{$dbpost['post_date']}',
1556 - post_date_gmt = '{$dbpost['post_date_gmt']}',
1557 - post_content = '{$dbpost['post_content']}',"
1558 - .(isset($dbpost['post_excerpt']) ? "post_excerpt = '{$dbpost['post_excerpt']}'," : "")."
1559 - post_title = '{$dbpost['post_title']}',
1560 - post_name = '{$dbpost['post_name']}',
1561 - post_modified = '{$dbpost['post_modified']}',
1562 - post_modified_gmt = '{$dbpost['post_modified_gmt']}',
1563 - comment_status = '{$dbpost['comment_status']}',
1564 - ping_status = '{$dbpost['ping_status']}',
1565 - post_status = '{$dbpost['post_status']}'
1566 - ");
1567 - $this->_wp_id = $wpdb->insert_id;
1568 -
1569 - $this->validate_post_id($dbpost, array(__CLASS__, __FUNCTION__));
1570 -
1571 - // WordPress 1.5.x - 2.0.x
1572 - wp_set_post_cats('1', $this->wp_id(), $this->post['post_category']);
1573 -
1574 - // Since we are not going through official channels, we need to
1575 - // manually tell WordPress that we've published a new post.
1576 - // We need to make sure to do this in order for FeedWordPress
1577 - // to play well with the staticize-reloaded plugin (something
1578 - // that a large aggregator website is going to *want* to be
1579 - // able to use).
1580 - do_action('publish_post', $this->_wp_id);
2530 + $dbpost[$key] = $value;
1581 2531 endif;
2532 + endforeach;
2533 +
2534 + if (strlen($dbpost['post_title'].$dbpost['post_content'].$dbpost['post_excerpt']) == 0) :
2535 + // FIXME: Option for filtering out empty posts
1582 2536 endif;
1583 - } /* SyndicatedPost::insert_new() */
2537 + if (strlen($dbpost['post_title'])==0) :
2538 + $dbpost['post_title'] = $this->post['meta']['syndication_source']
2539 + .' '.gmdate('Y-m-d H:i:s', $this->published() + $offset);
2540 + // FIXME: Option for what to fill a blank title with...
2541 + endif;
1584 2542
1585 - function update_existing () {
1586 - global $wpdb;
2543 + if ($this->use_api('wp_insert_post')) :
2544 + $dbpost['post_pingback'] = false; // Tell WP 2.1 and 2.2 not to process for pingbacks
2545 + $this->_wp_id = wp_insert_post($dbpost);
2546 +
2547 + // This should never happen.
2548 + if (!is_numeric($this->_wp_id) or ($this->_wp_id == 0)) :
2549 + FeedWordPress::critical_bug('SyndicatedPost (_wp_id problem)', array($dbpost, $this), __LINE__);
2550 + endif;
2551 +
2552 + // Unfortunately, as of WordPress 2.3, wp_insert_post()
2553 + // *still* offers no way to use a guid of your choice,
2554 + // and munges your post modified timestamp, too.
2555 + $result = $wpdb->query("
2556 + UPDATE $wpdb->posts
2557 + SET
2558 + guid='{$dbpost['guid']}',
2559 + post_modified='{$dbpost['post_modified']}',
2560 + post_modified_gmt='{$dbpost['post_modified_gmt']}'
2561 + WHERE ID='{$this->_wp_id}'
2562 + ");
2563 + else :
2564 + # The right way to do this is the above. But, alas,
2565 + # in earlier versions of WordPress, wp_insert_post has
2566 + # too much behavior (mainly related to pings) that can't
2567 + # be overridden. In WordPress 1.5, it's enough of a
2568 + # resource hog to make PHP segfault after inserting
2569 + # 50-100 posts. This can get pretty annoying, especially
2570 + # if you are trying to update your feeds for the first
2571 + # time.
1587 2572
1588 - // Why the fuck doesn't wp_insert_post already do this?
1589 - $dbpost = $this->normalize_post(/*new=*/ false);
1590 - if (!is_null($dbpost)) :
1591 - if ($this->use_api('wp_insert_post')) :
1592 - $dbpost['post_pingback'] = false; // Tell WP 2.1 and 2.2 not to process for pingbacks
1593 -
1594 - // This is a ridiculous fucking kludge necessitated by WordPress 2.6 munging authorship meta-data
1595 - add_action('_wp_put_post_revision', array($this, 'fix_revision_meta'));
1596 -
1597 - // Kludge to prevent kses filters from stripping the
1598 - // content of posts when updating without a logged in
1599 - // user who has `unfiltered_html` capability.
1600 - add_filter('content_save_pre', array($this, 'avoid_kses_munge'), 11);
2573 + $result = $wpdb->query("
2574 + INSERT INTO $wpdb->posts
2575 + SET
2576 + guid = '{$dbpost['guid']}',
2577 + post_author = '{$dbpost['post_author']}',
2578 + post_date = '{$dbpost['post_date']}',
2579 + post_date_gmt = '{$dbpost['post_date_gmt']}',
2580 + post_content = '{$dbpost['post_content']}',"
2581 + .(isset($dbpost['post_excerpt']) ? "post_excerpt = '{$dbpost['post_excerpt']}'," : "")."
2582 + post_title = '{$dbpost['post_title']}',
2583 + post_name = '{$dbpost['post_name']}',
2584 + post_modified = '{$dbpost['post_modified']}',
2585 + post_modified_gmt = '{$dbpost['post_modified_gmt']}',
2586 + comment_status = '{$dbpost['comment_status']}',
2587 + ping_status = '{$dbpost['ping_status']}',
2588 + post_status = '{$dbpost['post_status']}'
2589 + ");
2590 + $this->_wp_id = $wpdb->insert_id;
1601 2591
1602 - // Don't munge status fields that the user may have reset manually
1603 - if (function_exists('get_post_field')) :
1604 - $doNotMunge = array('post_status', 'comment_status', 'ping_status');
1605 - foreach ($doNotMunge as $field) :
1606 - $dbpost[$field] = get_post_field($field, $this->wp_id());
1607 - endforeach;
1608 - endif;
2592 + // This should never happen.
2593 + if (!is_numeric($this->_wp_id) or ($this->_wp_id == 0)) :
2594 + FeedWordPress::critical_bug('SyndicatedPost::_wp_id', $this->_wp_id, __LINE__);
2595 + endif;
1609 2596
1610 - $this->_wp_id = wp_insert_post($dbpost);
2597 + // WordPress 1.5.x - 2.0.x
2598 + wp_set_post_cats('1', $this->wp_id(), $this->post['post_category']);
1611 2599
1612 - // Turn off ridiculous fucking kludges #1 and #2
1613 - remove_action('_wp_put_post_revision', array($this, 'fix_revision_meta'));
1614 - remove_filter('content_save_pre', array($this, 'avoid_kses_munge'), 11);
1615 -
1616 - $this->validate_post_id($dbpost, array(__CLASS__, __FUNCTION__));
1617 -
1618 - // Unfortunately, as of WordPress 2.3, wp_insert_post()
1619 - // munges your post modified timestamp.
1620 - $result = $wpdb->query("
1621 - UPDATE $wpdb->posts
1622 - SET
1623 - post_modified='{$dbpost['post_modified']}',
1624 - post_modified_gmt='{$dbpost['post_modified_gmt']}'
1625 - WHERE ID='{$this->_wp_id}'
1626 - ");
1627 - else :
1628 -
1629 - $result = $wpdb->query("
1630 - UPDATE $wpdb->posts
1631 - SET
1632 - post_author = '{$dbpost['post_author']}',
1633 - post_content = '{$dbpost['post_content']}',"
1634 - .(isset($dbpost['post_excerpt']) ? "post_excerpt = '{$dbpost['post_excerpt']}'," : "")."
1635 - post_title = '{$dbpost['post_title']}',
1636 - post_name = '{$dbpost['post_name']}',
1637 - post_modified = '{$dbpost['post_modified']}',
1638 - post_modified_gmt = '{$dbpost['post_modified_gmt']}'
1639 - WHERE guid='{$dbpost['guid']}'
1640 - ");
1641 -
1642 - // WordPress 2.1.x and up
1643 - if (function_exists('wp_set_post_categories')) :
1644 - wp_set_post_categories($this->wp_id(), $this->post['post_category']);
1645 - // WordPress 1.5.x - 2.0.x
1646 - elseif (function_exists('wp_set_post_cats')) :
1647 - wp_set_post_cats('1', $this->wp_id(), $this->post['post_category']);
1648 - // This should never happen.
1649 - else :
1650 - FeedWordPress::critical_bug(__CLASS__.'::'.__FUNCTION.'(): no post categorizing function', array("dbpost" => $dbpost, "this" => $this), __LINE__);
1651 - endif;
1652 -
1653 - // Since we are not going through official channels, we need to
1654 - // manually tell WordPress that we've published a new post.
1655 - // We need to make sure to do this in order for FeedWordPress
1656 - // to play well with the staticize-reloaded plugin (something
1657 - // that a large aggregator website is going to *want* to be
1658 - // able to use).
1659 - do_action('edit_post', $this->post['ID']);
1660 - endif;
2600 + // Since we are not going through official channels, we need to
2601 + // manually tell WordPress that we've published a new post.
2602 + // We need to make sure to do this in order for FeedWordPress
2603 + // to play well with the staticize-reloaded plugin (something
2604 + // that a large aggregator website is going to *want* to be
2605 + // able to use).
2606 + do_action('publish_post', $this->_wp_id);
1661 2607 endif;
1662 - } /* SyndicatedPost::update_existing() */
2608 + } /* SyndicatedPost::insert_new() */
1663 2609
1664 - /**
1665 - * SyndicatedPost::normalize_post()
1666 - *
1667 - * @param bool $new If true, this post is to be inserted anew. If false, it is an update of an existing post.
1668 - * @return array A normalized representation of the post ready to be inserted into the database or sent to the WordPress API functions
1669 - */
1670 - function normalize_post ($new = true) {
2610 + function update_existing () {
1671 2611 global $wpdb;
1672 2612
1673 - $out = array();
1674 -
1675 2613 // Why the fuck doesn't wp_insert_post already do this?
2614 + $dbpost = array();
1676 2615 foreach ($this->post as $key => $value) :
1677 2616 if (is_string($value)) :
1678 - $out[$key] = $wpdb->escape($value);
2617 + $dbpost[$key] = $wpdb->escape($value);
1679 2618 else :
1680 - $out[$key] = $value;
2619 + $dbpost[$key] = $value;
1681 2620 endif;
1682 2621 endforeach;
1683 2622
1684 - if (strlen($out['post_title'].$out['post_content'].$out['post_excerpt']) == 0) :
1685 - // FIXME: Option for filtering out empty posts
1686 - endif;
1687 - if (strlen($out['post_title'])==0) :
1688 - $offset = (int) get_option('gmt_offset') * 60 * 60;
1689 - $out['post_title'] =
1690 - $this->post['meta']['syndication_source']
1691 - .' '.gmdate('Y-m-d H:i:s', $this->published() + $offset);
1692 - // FIXME: Option for what to fill a blank title with...
1693 - endif;
2623 + if ($this->use_api('wp_insert_post')) :
2624 + $dbpost['post_pingback'] = false; // Tell WP 2.1 and 2.2 not to process for pingbacks
2625 + $this->_wp_id = wp_insert_post($dbpost);
1694 2626
1695 - return $out;
1696 - }
2627 + // This should never happen.
2628 + if (!is_numeric($this->_wp_id) or ($this->_wp_id == 0)) :
2629 + FeedWordPress::critical_bug('SyndicatedPost::_wp_id', $this->_wp_id, __LINE__);
2630 + endif;
1697 2631
1698 - /**
1699 - * SyndicatedPost::validate_post_id()
1700 - *
1701 - * @param array $dbpost An array representing the post we attempted to insert or update
1702 - * @param mixed $ns A string or array representing the namespace (class, method) whence this method was called.
1703 - */
1704 - function validate_post_id ($dbpost, $ns) {
1705 - if (is_array($ns)) : $ns = implode('::', $ns);
1706 - else : $ns = (string) $ns; endif;
1707 -
1708 - // This should never happen.
1709 - if (!is_numeric($this->_wp_id) or ($this->_wp_id == 0)) :
1710 - FeedWordPress::critical_bug(
1711 - /*name=*/ $ns.'::_wp_id',
1712 - /*var =*/ array(
1713 - "\$this->_wp_id" => $this->_wp_id,
1714 - "\$dbpost" => $dbpost,
1715 - "\$this" => $this
1716 - ),
1717 - /*line # =*/ __LINE__
1718 - );
2632 + // Unfortunately, as of WordPress 2.3, wp_insert_post()
2633 + // munges your post modified timestamp.
2634 + $result = $wpdb->query("
2635 + UPDATE $wpdb->posts
2636 + SET
2637 + post_modified='{$dbpost['post_modified']}',
2638 + post_modified_gmt='{$dbpost['post_modified_gmt']}'
2639 + WHERE ID='{$this->_wp_id}'
2640 + ");
2641 + else :
2642 +
2643 + $result = $wpdb->query("
2644 + UPDATE $wpdb->posts
2645 + SET
2646 + post_author = '{$dbpost['post_author']}',
2647 + post_content = '{$dbpost['post_content']}',"
2648 + .(isset($dbpost['post_excerpt']) ? "post_excerpt = '{$dbpost['post_excerpt']}'," : "")."
2649 + post_title = '{$dbpost['post_title']}',
2650 + post_name = '{$dbpost['post_name']}',
2651 + post_modified = '{$dbpost['post_modified']}',
2652 + post_modified_gmt = '{$dbpost['post_modified_gmt']}'
2653 + WHERE guid='{$dbpost['guid']}'
2654 + ");
2655 +
2656 + // WordPress 2.1.x and up
2657 + if (function_exists('wp_set_post_categories')) :
2658 + wp_set_post_categories($this->wp_id(), $this->post['post_category']);
2659 + // WordPress 1.5.x - 2.0.x
2660 + elseif (function_exists('wp_set_post_cats')) :
2661 + wp_set_post_cats('1', $this->wp_id(), $this->post['post_category']);
2662 + // This should never happen.
2663 + else :
2664 + FeedWordPress::critical_bug('SyndicatedPost::insert_new::wp_version', $GLOBALS['wp_version'], __LINE__);
2665 + endif;
2666 +
2667 + // Since we are not going through official channels, we need to
2668 + // manually tell WordPress that we've published a new post.
2669 + // We need to make sure to do this in order for FeedWordPress
2670 + // to play well with the staticize-reloaded plugin (something
2671 + // that a large aggregator website is going to *want* to be
2672 + // able to use).
2673 + do_action('edit_post', $this->post['ID']);
1719 2674 endif;
1720 - } /* SyndicatedPost::validate_post_id() */
1721 -
1722 - /**
1723 - * SyndicatedPost::fix_revision_meta() - Fixes the way WP 2.6+ fucks up
1724 - * meta-data (authorship, etc.) when storing revisions of an updated
1725 - * syndicated post.
1726 - *
1727 - * In their infinite wisdom, the WordPress coders have made it completely
1728 - * impossible for a plugin that uses wp_insert_post() to set certain
1729 - * meta-data (such as the author) when you store an old revision of an
1730 - * updated post. Instead, it uses the WordPress defaults (= currently
1731 - * active user ID if the process is running with a user logged in, or
1732 - * = #0 if there is no user logged in). This results in bogus authorship
1733 - * data for revisions that are syndicated from off the feed, unless we
1734 - * use a ridiculous kludge like this to end-run the munging of meta-data
1735 - * by _wp_put_post_revision.
1736 - *
1737 - * @param int $revision_id The revision ID to fix up meta-data
1738 - */
1739 - function fix_revision_meta ($revision_id) {
1740 - global $wpdb;
1741 -
1742 - $post_author = (int) $this->post['post_author'];
1743 -
1744 - $revision_id = (int) $revision_id;
1745 - $wpdb->query("
1746 - UPDATE $wpdb->posts
1747 - SET post_author={$this->post['post_author']}
1748 - WHERE post_type = 'revision' AND ID='$revision_id'
1749 - ");
1750 - } /* SyndicatedPost::fix_revision_meta () */
2675 + } /* SyndicatedPost::update_existing() */
1751 2676
1752 - /**
1753 - * SyndicatedPost::avoid_kses_munge() -- If FeedWordPress is processing
1754 - * an automatic update, that generally means that wp_insert_post() is
1755 - * being called under the user credentials of whoever is viewing the
1756 - * blog at the time -- usually meaning no user at all. But if WordPress
1757 - * gets a wp_insert_post() when current_user_can('unfiltered_html') is
1758 - * false, it will run the content of the post through a kses function
1759 - * that strips out lots of HTML tags -- notably <object> and some others.
1760 - * This causes problems for syndicating (for example) feeds that contain
1761 - * YouTube videos. It also produces an unexpected asymmetry between
1762 - * automatically-initiated updates and updates initiated manually from
1763 - * the WordPress Dashboard (which are usually initiated under the
1764 - * credentials of a logged-in admin, and so don't get run through the
1765 - * kses function). So, to avoid the whole mess, what we do here is
1766 - * just forcibly disable the kses munging for a single syndicated post,
1767 - * by restoring the contents of the `post_content` field.
1768 - *
1769 - * @param string $content The content of the post, after other filters have gotten to it
1770 - * @return string The original content of the post, before other filters had a chance to munge it.
1771 - */
1772 - function avoid_kses_munge ($content) {
1773 - global $wpdb;
1774 - return $wpdb->escape($this->post['post_content']);
1775 - }
1776 -
1777 2677 // SyndicatedPost::add_rss_meta: adds interesting meta-data to each entry
1778 2678 // using the space for custom keys. The set of keys and values to add is
1779 2679 // specified by the keys and values of $post['meta']. This is used to
1780 2680 // store anything that the WordPress user might want to access from a
@@ -1826,9 +2726,9 @@
1826 2726
1827 2727 // SyndicatedPost::author_id (): get the ID for an author name from
1828 2728 // the feed. Create the author if necessary.
1829 2729 function author_id ($unfamiliar_author = 'create') {
1830 - global $wpdb;
2730 + global $wpdb, $wp_db_version; // test for WordPress 2.0 database schema
1831 2731
1832 2732 $a = $this->author();
1833 2733 $author = $a['name'];
1834 2734 $email = $a['email'];
@@ -1833,15 +2733,8 @@
1833 2733 $author = $a['name'];
1834 2734 $email = $a['email'];
1835 2735 $url = $a['uri'];
1836 2736
1837 - $match_author_by_email = !('yes' == get_option("feedwordpress_do_not_match_author_by_email"));
1838 - if ($match_author_by_email and !FeedWordPress::is_null_email($email)) :
1839 - $test_email = $email;
1840 - else :
1841 - $test_email = NULL;
1842 - endif;
1843 -
1844 2737 // Never can be too careful...
1845 2738 $login = sanitize_user($author, /*strict=*/ true);
1846 2739 $login = apply_filters('pre_user_login', $login);
1847 2740
@@ -1850,9 +2743,8 @@
1850 2743
1851 2744 $reg_author = $wpdb->escape(preg_quote($author));
1852 2745 $author = $wpdb->escape($author);
1853 2746 $email = $wpdb->escape($email);
1854 - $test_email = $wpdb->escape($test_email);
1855 2747 $url = $wpdb->escape($url);
1856 2748
1857 2749 // Check for an existing author rule....
1858 2750 if (isset($this->link->settings['map authors']['name'][strtolower(trim($author))])) :
@@ -1871,10 +2763,34 @@
1871 2763
1872 2764 else :
1873 2765 // Check the database for an existing author record that might fit
1874 2766
2767 + #-- WordPress 1.5.x
2768 + if (!isset($wp_db_version)) :
2769 + $id = $wpdb->get_var(
2770 + "SELECT ID from $wpdb->users
2771 + WHERE
2772 + TRIM(LCASE(user_login)) = TRIM(LCASE('$login')) OR
2773 + (
2774 + LENGTH(TRIM(LCASE(user_email))) > 0
2775 + AND TRIM(LCASE(user_email)) = TRIM(LCASE('$email'))
2776 + ) OR
2777 + TRIM(LCASE(user_firstname)) = TRIM(LCASE('$author')) OR
2778 + TRIM(LCASE(user_nickname)) = TRIM(LCASE('$author')) OR
2779 + TRIM(LCASE(user_nicename)) = TRIM(LCASE('$nice_author')) OR
2780 + TRIM(LCASE(user_description)) = TRIM(LCASE('$author')) OR
2781 + (
2782 + LOWER(user_description)
2783 + RLIKE CONCAT(
2784 + '(^|\\n)a\\.?k\\.?a\\.?( |\\t)*:?( |\\t)*',
2785 + LCASE('$reg_author'),
2786 + '( |\\t|\\r)*(\\n|\$)'
2787 + )
2788 + )
2789 + ");
2790 +
1875 2791 #-- WordPress 2.0+
1876 - if (fwp_test_wp_version(FWP_SCHEMA_HAS_USERMETA)) :
2792 + elseif ($wp_db_version >= 2966) :
1877 2793
1878 2794 // First try the user core data table.
1879 2795 $id = $wpdb->get_var(
1880 2796 "SELECT ID FROM $wpdb->users
@@ -1881,9 +2797,9 @@
1881 2797 WHERE
1882 2798 TRIM(LCASE(user_login)) = TRIM(LCASE('$login'))
1883 2799 OR (
1884 2800 LENGTH(TRIM(LCASE(user_email))) > 0
1885 - AND TRIM(LCASE(user_email)) = TRIM(LCASE('$test_email'))
2801 + AND TRIM(LCASE(user_email)) = TRIM(LCASE('$email'))
1886 2802 )
1887 2803 OR TRIM(LCASE(user_nicename)) = TRIM(LCASE('$nice_author'))
1888 2804 ");
1889 2805
@@ -1903,33 +2819,8 @@
1903 2819 )
1904 2820 )
1905 2821 ");
1906 2822 endif;
1907 -
1908 - #-- WordPress 1.5.x
1909 - else :
1910 - $id = $wpdb->get_var(
1911 - "SELECT ID from $wpdb->users
1912 - WHERE
1913 - TRIM(LCASE(user_login)) = TRIM(LCASE('$login')) OR
1914 - (
1915 - LENGTH(TRIM(LCASE(user_email))) > 0
1916 - AND TRIM(LCASE(user_email)) = TRIM(LCASE('$test_email'))
1917 - ) OR
1918 - TRIM(LCASE(user_firstname)) = TRIM(LCASE('$author')) OR
1919 - TRIM(LCASE(user_nickname)) = TRIM(LCASE('$author')) OR
1920 - TRIM(LCASE(user_nicename)) = TRIM(LCASE('$nice_author')) OR
1921 - TRIM(LCASE(user_description)) = TRIM(LCASE('$author')) OR
1922 - (
1923 - LOWER(user_description)
1924 - RLIKE CONCAT(
1925 - '(^|\\n)a\\.?k\\.?a\\.?( |\\t)*:?( |\\t)*',
1926 - LCASE('$reg_author'),
1927 - '( |\\t|\\r)*(\\n|\$)'
1928 - )
1929 - )
1930 - ");
1931 -
1932 2823 endif;
1933 2824
1934 2825 // ... if you don't find one, then do what you need to do
1935 2826 if (is_null($id)) :
@@ -1960,9 +2851,9 @@
1960 2851 return $id;
1961 2852 } // function SyndicatedPost::author_id ()
1962 2853
1963 2854 // look up (and create) category ids from a list of categories
1964 - function category_ids ($cats, $unfamiliar_category = 'create', $tags_too = false) {
2855 + function category_ids ($cats, $unfamiliar_category = 'create') {
1965 2856 global $wpdb;
1966 2857
1967 2858 // We need to normalize whitespace because (1) trailing
1968 2859 // whitespace can cause PHP and MySQL not to see eye to eye on
@@ -1971,10 +2862,8 @@
1971 2862 // because I doubt most people want to make a semantic
1972 2863 // distinction between 'Computers' and 'Computers '
1973 2864 $cats = array_map('trim', $cats);
1974 2865
1975 - $tags = array();
1976 -
1977 2866 $cat_ids = array ();
1978 2867 foreach ($cats as $cat_name) :
1979 2868 if (preg_match('/^{#([0-9]+)}$/', $cat_name, $backref)) :
1980 2869 $cat_id = (int) $backref[1];
@@ -1982,9 +2871,9 @@
1982 2871 $cat_ids[] = $cat_id;
1983 2872 elseif (get_category($cat_id)) :
1984 2873 $cat_ids[] = $cat_id;
1985 2874 endif;
1986 - elseif (strlen($cat_name) > 0) :
2875 + else :
1987 2876 $esc = $wpdb->escape($cat_name);
1988 2877 $resc = $wpdb->escape(preg_quote($cat_name));
1989 2878
1990 2879 // WordPress 2.3+
@@ -2002,17 +2891,11 @@
2002 2891 )) :
2003 2892 foreach ($results AS $term) :
2004 2893 $cat_ids[] = (int) $term->term_id;
2005 2894 endforeach;
2006 - elseif ('tag'==$unfamiliar_category) :
2007 - $tags[] = $cat_name;
2008 2895 elseif ('create'===$unfamiliar_category) :
2009 2896 $term = wp_insert_term($cat_name, 'category');
2010 - if (is_wp_error($term)) :
2011 - FeedWordPress::noncritical_bug('term insertion problem', array('cat_name' => $cat_name, 'term' => $term, 'this' => $this), __LINE__);
2012 - else :
2013 - $cat_ids[] = $term['term_id'];
2014 - endif;
2897 + $cat_ids[] = $term['term_id'];
2015 2898 endif;
2016 2899
2017 2900 // WordPress 1.5.x - 2.2.x
2018 2901 else :
@@ -2053,14 +2936,9 @@
2053 2936 $cat_ids = NULL; // Drop the post
2054 2937 else :
2055 2938 $cat_ids = array_unique($cat_ids);
2056 2939 endif;
2057 -
2058 - if ($tags_too) : $ret = array($cat_ids, $tags);
2059 - else : $ret = $cat_ids;
2060 - endif;
2061 -
2062 - return $ret;
2940 + return $cat_ids;
2063 2941 } // function SyndicatedPost::category_ids ()
2064 2942
2065 2943 function use_api ($tag) {
2066 2944 global $wp_db_version;
@@ -2112,18 +2990,14 @@
2112 2990 endif;
2113 2991
2114 2992 # If everything failed, then default to the current time.
2115 2993 if (is_null($epoch)) :
2116 - if (-1 == $default) :
2117 - $epoch = time();
2118 - else :
2119 - $epoch = $default;
2120 - endif;
2994 + $epoch = time();
2121 2995 endif;
2122 2996
2123 2997 return $epoch;
2124 2998 }
2125 - function updated ($fallback = true, $default = -1) {
2999 + function updated ($fallback = true) {
2126 3000 $epoch = null;
2127 3001
2128 3002 # As far as I know, only dcterms and Atom have reliable ways to
2129 3003 # specify when something was *modified* last. If neither is
@@ -2136,27 +3010,19 @@
2136 3010 $epoch = @parse_w3cdtf($this->item['modified']);
2137 3011 elseif (isset($this->item['updated'])): // Atom 1.0
2138 3012 $epoch = @parse_w3cdtf($this->item['updated']);
2139 3013 elseif ($fallback) : // Fall back to issued / dc:date
2140 - $epoch = $this->published(/*fallback=*/ false, /*default=*/ $default);
3014 + $epoch = $this->published(/*fallback=*/ false);
2141 3015 endif;
2142 3016
2143 3017 # If everything failed, then default to the current time.
2144 3018 if (is_null($epoch)) :
2145 - if (-1 == $default) :
2146 - $epoch = time();
2147 - else :
2148 - $epoch = $default;
2149 - endif;
3019 + $epoch = time();
2150 3020 endif;
2151 3021
2152 3022 return $epoch;
2153 3023 }
2154 3024
2155 - function update_hash () {
2156 - return md5(serialize($this->item));
2157 - }
2158 -
2159 3025 function guid () {
2160 3026 $guid = null;
2161 3027 if (isset($this->item['id'])): // Atom 0.3 / 1.0
2162 3028 $guid = $this->item['id'];
@@ -2244,87 +3110,25 @@
2244 3110
2245 3111 return $author;
2246 3112 } // SyndicatedPost::author()
2247 3113
2248 - var $uri_attrs = array (
2249 - array('a', 'href'),
2250 - array('applet', 'codebase'),
2251 - array('area', 'href'),
2252 - array('blockquote', 'cite'),
2253 - array('body', 'background'),
2254 - array('del', 'cite'),
2255 - array('form', 'action'),
2256 - array('frame', 'longdesc'),
2257 - array('frame', 'src'),
2258 - array('iframe', 'longdesc'),
2259 - array('iframe', 'src'),
2260 - array('head', 'profile'),
2261 - array('img', 'longdesc'),
2262 - array('img', 'src'),
2263 - array('img', 'usemap'),
2264 - array('input', 'src'),
2265 - array('input', 'usemap'),
2266 - array('ins', 'cite'),
2267 - array('link', 'href'),
2268 - array('object', 'classid'),
2269 - array('object', 'codebase'),
2270 - array('object', 'data'),
2271 - array('object', 'usemap'),
2272 - array('q', 'cite'),
2273 - array('script', 'src')
2274 - ); /* var SyndicatedPost::$uri_attrs */
2275 -
2276 - var $_base = null;
2277 -
2278 - function resolve_single_relative_uri ($refs) {
2279 - $tag = FeedWordPressHTML::attributeMatch($refs);
2280 - $url = Relative_URI::resolve($tag['value'], $this->_base);
2281 - return $tag['prefix'] . $url . $tag['suffix'];
2282 - } /* function SyndicatedPost::resolve_single_relative_uri() */
2283 -
2284 - function resolve_relative_uris ($content, $obj) {
2285 - # The MagpieRSS upgrade has some `xml:base` support baked in.
2286 - # However, sometimes people do silly things, like putting
2287 - # relative URIs out on a production RSS 2.0 feed or other feeds
2288 - # with no good support for `xml:base`. So we'll do our best to
2289 - # try to catch any remaining relative URIs and resolve them as
2290 - # best we can.
2291 - $obj->_base = $obj->item['link']; // Reset the base for resolving relative URIs
2292 -
2293 - foreach ($obj->uri_attrs as $pair) :
2294 - list($tag, $attr) = $pair;
2295 - $pattern = FeedWordPressHTML::attributeRegex($tag, $attr);
2296 - $content = preg_replace_callback (
2297 - $pattern,
2298 - array(&$obj, 'resolve_single_relative_uri'),
2299 - $content
2300 - );
2301 - endforeach;
2302 -
2303 - return $content;
2304 - } /* function SyndicatedPost::resolve_relative_uris () */
2305 -
2306 3114 var $strip_attrs = array (
2307 - array('[a-z]+', 'target'),
2308 -// array('[a-z]+', 'style'),
2309 -// array('[a-z]+', 'on[a-z]+'),
3115 + array('[a-z]+', 'style'),
3116 + array('[a-z]+', 'target'),
2310 3117 );
2311 -
2312 - function strip_attribute_from_tag ($refs) {
2313 - $tag = FeedWordPressHTML::attributeMatch($refs);
2314 - return $tag['before_attribute'].$tag['after_attribute'];
2315 - }
2316 -
2317 3118 function sanitize_content ($content, $obj) {
3119 + # FeedWordPress used to resolve URIs relative to the
3120 + # feed URI. It now relies on the xml:base support
3121 + # baked in to the MagpieRSS upgrade. So all we do here
3122 + # now is to sanitize problematic attributes.
3123 + #
2318 3124 # This kind of sucks. I intend to replace it with
2319 3125 # lib_filter sometime soon.
2320 3126 foreach ($obj->strip_attrs as $pair):
2321 3127 list($tag,$attr) = $pair;
2322 - $pattern = FeedWordPressHTML::attributeRegex($tag, $attr);
2323 -
2324 - $content = preg_replace_callback (
2325 - $pattern,
2326 - array(&$obj, 'strip_attribute_from_tag'),
3128 + $content = preg_replace (
3129 + ":(<$tag [^>]*)($attr=(\"[^\">]*\"|[^>\\s]+))([^>]*>):i",
3130 + "\\1\\4",
2327 3131 $content
2328 3132 );
2329 3133 endforeach;
2330 3134 return $content;
@@ -2330,10 +3134,397 @@
2330 3134 return $content;
2331 3135 }
2332 3136 } // class SyndicatedPost
2333 3137
2334 -require_once(dirname(__FILE__) . '/syndicatedlink.class.php');
3138 +# class SyndicatedLink: represents a syndication feed stored within the
3139 +# WordPress database
3140 +#
3141 +# To keep things compact and editable from within WordPress, we use all the
3142 +# links under a particular category in the WordPress "Blogroll" for the list of
3143 +# feeds to syndicate. "Contributors" is the category used by default; you can
3144 +# configure that under Options --> Syndication.
3145 +#
3146 +# Fields used are:
3147 +#
3148 +# * link_rss: the URI of the Atom/RSS feed to syndicate
3149 +#
3150 +# * link_notes: user-configurable options, with keys and values
3151 +# like so:
3152 +#
3153 +# key: value
3154 +# cats: computers\nweb
3155 +# feed/key: value
3156 +#
3157 +# Keys that start with "feed/" are gleaned from the data supplied
3158 +# by the feed itself, and will be overwritten with each update.
3159 +#
3160 +# Values have linebreak characters escaped with C-style
3161 +# backslashes (so, for example, a newline becomes "\n").
3162 +#
3163 +# The value of `cats` is used as a newline-separated list of
3164 +# default categories for any post coming from a particular feed.
3165 +# (In the example above, any posts from this feed will be placed
3166 +# in the "computers" and "web" categories--*in addition to* any
3167 +# categories that may already be applied to the posts.)
3168 +#
3169 +# Values of keys in link_notes are accessible from templates using
3170 +# the function `get_feed_meta($key)` if this plugin is activated.
2335 3171
3172 +class SyndicatedLink {
3173 + var $id = null;
3174 + var $link = null;
3175 + var $settings = array ();
3176 + var $magpie = null;
3177 +
3178 + function SyndicatedLink ($link) {
3179 + global $wpdb;
3180 +
3181 + if (is_object($link)) :
3182 + $this->link = $link;
3183 + $this->id = $link->link_id;
3184 + else :
3185 + $this->id = $link;
3186 + if (function_exists('get_bookmark')) : // WP 2.1+
3187 + $this->link = get_bookmark($link);
3188 + else :
3189 + $this->link = $wpdb->get_row("
3190 + SELECT * FROM $wpdb->links
3191 + WHERE (link_id = '".$wpdb->escape($link)."')"
3192 + );
3193 + endif;
3194 + endif;
3195 +
3196 + if (strlen($this->link->link_rss) > 0) :
3197 + // Read off feed settings from link_notes
3198 + $notes = explode("\n", $this->link->link_notes);
3199 + foreach ($notes as $note):
3200 + list($key, $value) = explode(": ", $note, 2);
3201 +
3202 + if (strlen($key) > 0) :
3203 + // Unescape and trim() off the whitespace.
3204 + // Thanks to Ray Lischner for pointing out the
3205 + // need to trim off whitespace.
3206 + $this->settings[$key] = stripcslashes (trim($value));
3207 + endif;
3208 + endforeach;
3209 +
3210 + // "Magic" feed settings
3211 + $this->settings['link/uri'] = $this->link->link_rss;
3212 + $this->settings['link/name'] = $this->link->link_name;
3213 + $this->settings['link/id'] = $this->link->link_id;
3214 +
3215 + // `hardcode categories` and `unfamiliar categories` are deprecated in favor of `unfamiliar category`
3216 + if (
3217 + isset($this->settings['unfamiliar categories'])
3218 + and !isset($this->settings['unfamiliar category'])
3219 + ) :
3220 + $this->settings['unfamiliar category'] = $this->settings['unfamiliar categories'];
3221 + endif;
3222 + if (
3223 + FeedWordPress::affirmative($this->settings, 'hardcode categories')
3224 + and !isset($this->settings['unfamiliar category'])
3225 + ) :
3226 + $this->settings['unfamiliar category'] = 'default';
3227 + endif;
3228 +
3229 + // Set this up automagically for del.icio.us
3230 + $bits = parse_url($this->link->link_rss);
3231 + $tagspacers = array('del.icio.us', 'feeds.delicious.com');
3232 + if (!isset($this->settings['cat_split']) and in_array($bits['host'], $tagspacers)) :
3233 + $this->settings['cat_split'] = '\s'; // Whitespace separates multiple tags in del.icio.us RSS feeds
3234 + endif;
3235 +
3236 + if (isset($this->settings['cats'])):
3237 + $this->settings['cats'] = preg_split(FEEDWORDPRESS_CAT_SEPARATOR_PATTERN, $this->settings['cats']);
3238 + endif;
3239 + if (isset($this->settings['tags'])):
3240 + $this->settings['tags'] = preg_split(FEEDWORDPRESS_CAT_SEPARATOR_PATTERN, $this->settings['tags']);
3241 + endif;
3242 +
3243 + if (isset($this->settings['map authors'])) :
3244 + $author_rules = explode("\n\n", $this->settings['map authors']);
3245 + $ma = array();
3246 + foreach ($author_rules as $rule) :
3247 + list($rule_type, $author_name, $author_action) = explode("\n", $rule);
3248 +
3249 + // Normalize for case and whitespace
3250 + $rule_type = strtolower(trim($rule_type));
3251 + $author_name = strtolower(trim($author_name));
3252 + $author_action = strtolower(trim($author_action));
3253 +
3254 + $ma[$rule_type][$author_name] = $author_action;
3255 + endforeach;
3256 + $this->settings['map authors'] = $ma;
3257 + endif;
3258 + endif;
3259 + } // SyndicatedLink::SyndicatedLink ()
3260 +
3261 + function found () {
3262 + return is_object($this->link);
3263 + }
3264 +
3265 + function stale () {
3266 + $stale = true;
3267 + if (isset($this->settings['update/hold']) and ($this->settings['update/hold']=='ping')) :
3268 + $stale = false; // don't update on any timed updates; pings only
3269 + elseif (isset($this->settings['update/hold']) and ($this->settings['update/hold']=='next')) :
3270 + $stale = true; // update on the next timed update
3271 + elseif (!isset($this->settings['update/ttl']) or !isset($this->settings['update/last'])) :
3272 + $stale = true; // initial update
3273 + else :
3274 + $after = ((int) $this->settings['update/last'])
3275 + +((int) $this->settings['update/ttl'] * 60);
3276 + $stale = (time() >= $after);
3277 + endif;
3278 + return $stale;
3279 + }
3280 +
3281 + function poll () {
3282 + global $wpdb;
3283 +
3284 + $this->magpie = fetch_rss($this->link->link_rss);
3285 + $new_count = NULL;
3286 +
3287 + if (is_object($this->magpie)) :
3288 + $new_count = array('new' => 0, 'updated' => 0);
3289 +
3290 + # -- Update Link metadata live from feed
3291 + $channel = $this->magpie->channel;
3292 +
3293 + if (!isset($channel['id'])) :
3294 + $channel['id'] = $this->link->link_rss;
3295 + endif;
3296 +
3297 + $update = array();
3298 + if (!$this->hardcode('url') and isset($channel['link'])) :
3299 + $update[] = "link_url = '".$wpdb->escape($channel['link'])."'";
3300 + endif;
3301 +
3302 + if (!$this->hardcode('name') and isset($channel['title'])) :
3303 + $update[] = "link_name = '".$wpdb->escape($channel['title'])."'";
3304 + endif;
3305 +
3306 + if (!$this->hardcode('description')) :
3307 + if (isset($channel['tagline'])) :
3308 + $update[] = "link_description = '".$wpdb->escape($channel['tagline'])."'";
3309 + elseif (isset($channel['description'])) :
3310 + $update[] = "link_description = '".$wpdb->escape($channel['description'])."'";
3311 + endif;
3312 + endif;
3313 +
3314 + $this->settings = array_merge($this->settings, $this->flatten_array($channel));
3315 +
3316 + $this->settings['update/last'] = time(); $ttl = $this->ttl();
3317 + if (!is_null($ttl)) :
3318 + $this->settings['update/ttl'] = $ttl;
3319 + $this->settings['update/timed'] = 'feed';
3320 + else :
3321 + $this->settings['update/ttl'] = rand(30, 120); // spread over time interval for staggered updates
3322 + $this->settings['update/timed'] = 'automatically';
3323 + endif;
3324 +
3325 + if (!isset($this->settings['update/hold']) or $this->settings['update/hold']!='ping') :
3326 + $this->settings['update/hold'] = 'scheduled';
3327 + endif;
3328 +
3329 + // Copy back without a few things that we don't want to save in the notes
3330 + $to_notes = $this->settings;
3331 +
3332 + if (is_array($to_notes['cats'])) :
3333 + $to_notes['cats'] = implode(FEEDWORDPRESS_CAT_SEPARATOR, $to_notes['cats']);
3334 + endif;
3335 + if (is_array($to_notes['tags'])) :
3336 + $to_notes['tags'] = implode(FEEDWORDPRESS_CAT_SEPARATOR, $to_notes['tags']);
3337 + endif;
3338 +
3339 + if (isset($to_notes['map authors'])) :
3340 + $ma = array();
3341 + foreach ($to_notes['map authors'] as $rule_type => $author_rules) :
3342 + foreach ($author_rules as $author_name => $author_action) :
3343 + $ma[] = $rule_type."\n".$author_name."\n".$author_action;
3344 + endforeach;
3345 + endforeach;
3346 + $to_notes['map authors'] = implode("\n\n", $ma);
3347 + endif;
3348 +
3349 + unset($to_notes['link/id']); unset($to_notes['link/uri']);
3350 + unset($to_notes['link/name']);
3351 + unset($to_notes['hardcode categories']); // Deprecated
3352 + unset($to_notes['unfamiliar categories']); // Deprecated
3353 +
3354 + $notes = '';
3355 + foreach ($to_notes as $key => $value) :
3356 + $notes .= $key . ": ". addcslashes($value, "\0..\37".'\\') . "\n";
3357 + endforeach;
3358 + $update[] = "link_notes = '".$wpdb->escape($notes)."'";
3359 +
3360 + $update_set = implode(',', $update);
3361 +
3362 + // Update the properties of the link from the feed information
3363 + $result = $wpdb->query("
3364 + UPDATE $wpdb->links
3365 + SET $update_set
3366 + WHERE link_id='$this->id'
3367 + ");
3368 +
3369 + # -- Add new posts from feed and update any updated posts
3370 + if (is_array($this->magpie->items)) :
3371 + foreach ($this->magpie->items as $item) :
3372 + $post =& new SyndicatedPost($item, $this);
3373 + if (!$post->filtered()) :
3374 + $new = $post->store();
3375 + if ( $new !== false ) $new_count[$new]++;
3376 + endif;
3377 + endforeach;
3378 + endif;
3379 +
3380 + // Copy back any changes to feed settings made in the course of updating (e.g. new author rules)
3381 + $to_notes = $this->settings;
3382 +
3383 + if (is_array($to_notes['cats'])) :
3384 + $to_notes['cats'] = implode(FEEDWORDPRESS_CAT_SEPARATOR, $to_notes['cats']);
3385 + endif;
3386 + if (is_array($to_notes['tags'])) :
3387 + $to_notes['tags'] = implode(FEEDWORDPRESS_CAT_SEPARATOR, $to_notes['tags']);
3388 + endif;
3389 +
3390 + if (isset($to_notes['map authors'])) :
3391 + $ma = array();
3392 + foreach ($to_notes['map authors'] as $rule_type => $author_rules) :
3393 + foreach ($author_rules as $author_name => $author_action) :
3394 + $ma[] = $rule_type."\n".$author_name."\n".$author_action;
3395 + endforeach;
3396 + endforeach;
3397 + $to_notes['map authors'] = implode("\n\n", $ma);
3398 + endif;
3399 +
3400 + unset($to_notes['link/id']); unset($to_notes['link/uri']);
3401 + unset($to_notes['link/name']);
3402 + unset($to_notes['hardcode categories']); // Deprecated
3403 + unset($to_notes['unfamiliar categories']); // Deprecated
3404 +
3405 + $notes = '';
3406 + foreach ($to_notes as $key => $value) :
3407 + $notes .= $key . ": ". addcslashes($value, "\0..\37".'\\') . "\n";
3408 + endforeach;
3409 +
3410 + $update_set = "link_notes = '".$wpdb->escape($notes)."'";
3411 +
3412 + // Update the properties of the link from the feed information
3413 + $result = $wpdb->query("
3414 + UPDATE $wpdb->links
3415 + SET $update_set
3416 + WHERE link_id='$this->id'
3417 + ");
3418 + endif;
3419 + return $new_count;
3420 + } /* SyndicatedLink::poll() */
3421 +
3422 + function uri () {
3423 + return (is_object($this->link) ? $this->link->link_rss : NULL);
3424 + }
3425 + function homepage () {
3426 + return (isset($this->settings['feed/link']) ? $this->settings['feed/link'] : NULL);
3427 + }
3428 +
3429 + function ttl () {
3430 + if (is_object($this->magpie)) :
3431 + $channel = $this->magpie->channel;
3432 + else :
3433 + $channel = array();
3434 + endif;
3435 +
3436 + if (isset($channel['ttl'])) :
3437 + // "ttl stands for time to live. It's a number of
3438 + // minutes that indicates how long a channel can be
3439 + // cached before refreshing from the source."
3440 + // <http://blogs.law.harvard.edu/tech/rss#ltttlgtSubelementOfLtchannelgt>
3441 + $ret = $channel['ttl'];
3442 + elseif (isset($channel['sy']['updatefrequency']) or isset($channel['sy']['updateperiod'])) :
3443 + $period_minutes = array (
3444 + 'hourly' => 60, /* minutes in an hour */
3445 + 'daily' => 1440, /* minutes in a day */
3446 + 'weekly' => 10080, /* minutes in a week */
3447 + 'monthly' => 43200, /* minutes in a month */
3448 + 'yearly' => 525600, /* minutes in a year */
3449 + );
3450 +
3451 + // "sy:updatePeriod: Describes the period over which the
3452 + // channel format is updated. Acceptable values are:
3453 + // hourly, daily, weekly, monthly, yearly. If omitted,
3454 + // daily is assumed." <http://web.resource.org/rss/1.0/modules/syndication/>
3455 + if (isset($channel['sy']['updateperiod'])) : $period = $channel['sy']['updateperiod'];
3456 + else : $period = 'daily';
3457 + endif;
3458 +
3459 + // "sy:updateFrequency: Used to describe the frequency
3460 + // of updates in relation to the update period. A
3461 + // positive integer indicates how many times in that
3462 + // period the channel is updated. ... If omitted a value
3463 + // of 1 is assumed." <http://web.resource.org/rss/1.0/modules/syndication/>
3464 + if (isset($channel['sy']['updatefrequency'])) : $freq = (int) $channel['sy']['updatefrequency'];
3465 + else : $freq = 1;
3466 + endif;
3467 +
3468 + $ret = (int) ($period_minutes[$period] / $freq);
3469 + else :
3470 + $ret = NULL;
3471 + endif;
3472 + return $ret;
3473 + } /* SyndicatedLink::ttl() */
3474 +
3475 + // SyndicatedLink::flatten_array (): flatten an array. Useful for
3476 + // hierarchical and namespaced elements.
3477 + //
3478 + // Given an array which may contain array or object elements in it,
3479 + // return a "flattened" array: a one-dimensional array of scalars
3480 + // containing each of the scalar elements contained within the array
3481 + // structure. Thus, for example, if $a['b']['c']['d'] == 'e', then the
3482 + // returned array for FeedWordPress::flatten_array($a) will contain a key
3483 + // $a['feed/b/c/d'] with value 'e'.
3484 + function flatten_array ($arr, $prefix = 'feed/', $separator = '/') {
3485 + $ret = array ();
3486 + if (is_array($arr)) :
3487 + foreach ($arr as $key => $value) :
3488 + if (is_scalar($value)) :
3489 + $ret[$prefix.$key] = $value;
3490 + else :
3491 + $ret = array_merge($ret, $this->flatten_array($value, $prefix.$key.$separator, $separator));
3492 + endif;
3493 + endforeach;
3494 + endif;
3495 + return $ret;
3496 + } // function SyndicatedLink::flatten_array ()
3497 +
3498 + function hardcode ($what) {
3499 + $default = get_option("feedwordpress_hardcode_$what");
3500 + if ( $default === 'yes' ) :
3501 + // If the default is to hardcode, then we want the
3502 + // negation of negative(): TRUE by default and FALSE if
3503 + // the setting is explicitly "no"
3504 + $ret = !FeedWordPress::negative($this->settings, "hardcode $what");
3505 + else :
3506 + // If the default is NOT to hardcode, then we want
3507 + // affirmative(): FALSE by default and TRUE if the
3508 + // setting is explicitly "yes"
3509 + $ret = FeedWordPress::affirmative($this->settings, "hardcode $what");
3510 + endif;
3511 + return $ret;
3512 + } // function SyndicatedLink::hardcode ()
3513 +
3514 + function syndicated_status ($what, $default) {
3515 + global $wpdb;
3516 +
3517 + $ret = get_option("feedwordpress_syndicated_{$what}_status");
3518 + if ( isset($this->settings["$what status"]) ) :
3519 + $ret = $this->settings["$what status"];
3520 + elseif (!$ret) :
3521 + $ret = $default;
3522 + endif;
3523 + return $wpdb->escape(trim(strtolower($ret)));
3524 + } // function SyndicatedLink:syndicated_status ()
3525 +} // class SyndicatedLink
3526 +
2336 3527 ################################################################################
2337 3528 ## XML-RPC HOOKS: accept XML-RPC update pings from Contributors ################
2338 3529 ################################################################################
2339 3530
@@ -2355,8 +3546,169 @@
2355 3546 return array('flerror' => false, 'message' => "Thanks for the ping.".implode(' and', $mesg));
2356 3547 endif;
2357 3548 }
2358 3549
3550 +################################################################################
3551 +## class FeedFinder: find likely feeds using autodetection and/or guesswork ####
3552 +################################################################################
3553 +
3554 +class FeedFinder {
3555 + var $uri = NULL;
3556 + var $_cache_uri = NULL;
3557 +
3558 + var $verify = FALSE;
3559 +
3560 + var $_data = NULL;
3561 + var $_head = NULL;
3562 +
3563 + # -- Recognition patterns
3564 + var $_feed_types = array(
3565 + 'application/rss+xml',
3566 + 'text/xml',
3567 + 'application/atom+xml',
3568 + 'application/x.atom+xml',
3569 + 'application/x-atom+xml'
3570 + );
3571 + var $_feed_markers = array('\\<feed', '\\<rss', 'xmlns="http://purl.org/rss/1.0');
3572 + var $_html_markers = array('\\<html');
3573 + var $_obvious_feed_url = array('[./]rss', '[./]rdf', '[./]atom', '[./]feed', '\.xml');
3574 + var $_maybe_feed_url = array ('rss', 'rdf', 'atom', 'feed', 'xml');
3575 +
3576 + function FeedFinder ($uri = NULL, $verify = TRUE) {
3577 + $this->uri = $uri; $this->verify = $verify;
3578 + } /* FeedFinder::FeedFinder () */
3579 +
3580 + function find ($uri = NULL) {
3581 + $ret = array ();
3582 + if (!is_null($this->data($uri))) {
3583 + if ($this->is_feed($uri)) {
3584 + $ret = array($this->uri);
3585 + } else {
3586 + // Assume that we have HTML or XHTML (even if we don't, who's it gonna hurt?)
3587 + // Autodiscovery is the preferred method
3588 + $href = $this->_link_rel_feeds();
3589 +
3590 + // ... but we'll also take the little orange buttons
3591 + $href = array_merge($href, $this->_a_href_feeds(TRUE));
3592 +
3593 + // If all that failed, look harder
3594 + if (count($href) == 0) $href = $this->_a_href_feeds(FALSE);
3595 +
3596 + // Verify feeds and resolve relative URIs
3597 + foreach ($href as $u) {
3598 + $the_uri = Relative_URI::resolve($u, $this->uri);
3599 + if ($this->verify) {
3600 + $feed =& new FeedFinder($the_uri);
3601 + if ($feed->is_feed()) $ret[] = $the_uri;
3602 + $feed = NULL;
3603 + } else {
3604 + $ret[] = $the_uri;
3605 + }
3606 + } /* foreach */
3607 + } /* if */
3608 + } /* if */
3609 + return array_unique($ret);
3610 + } /* FeedFinder::find () */
3611 +
3612 + function data ($uri = NULL) {
3613 + $this->_get($uri);
3614 + return $this->_data;
3615 + }
3616 +
3617 + function is_feed ($uri = NULL) {
3618 + $data = $this->data($uri);
3619 +
3620 + return (
3621 + preg_match (
3622 + "\007(".implode('|',$this->_feed_markers).")\007i",
3623 + $data
3624 + ) and !preg_match (
3625 + "\007(".implode('|',$this->_html_markers).")\007i",
3626 + $data
3627 + )
3628 + );
3629 + } /* FeedFinder::is_feed () */
3630 +
3631 + # --- Private methods ---
3632 + function _get ($uri = NULL) {
3633 + if ($uri) $this->uri = $uri;
3634 +
3635 + // Is the result not yet cached?
3636 + if ($this->_cache_uri !== $this->uri) :
3637 + // Snoopy is an HTTP client in PHP
3638 + $client = new Snoopy();
3639 +
3640 + // Prepare headers and internal settings
3641 + $client->rawheaders['Connection'] = 'close';
3642 + $client->accept = 'application/atom+xml application/rdf+xml application/rss+xml application/xml text/html */*';
3643 + $client->agent = 'feedfinder/1.2 (compatible; PHP FeedFinder) +http://projects.radgeek.com/feedwordpress';
3644 + $client->read_timeout = 25;
3645 +
3646 + // Fetch the HTML or feed
3647 + @$client->fetch($this->uri);
3648 + $this->_data = $client->results;
3649 +
3650 + // Kilroy was here
3651 + $this->_cache_uri = $this->uri;
3652 + endif;
3653 + } /* FeedFinder::_get () */
3654 +
3655 + function _link_rel_feeds () {
3656 + $links = $this->_tags('link');
3657 + $link_count = count($links);
3658 +
3659 + // now figure out which one points to the RSS file
3660 + $href = array ();
3661 + for ($n=0; $n<$link_count; $n++) {
3662 + if (strtolower($links[$n]['rel']) == 'alternate') {
3663 + if (in_array(strtolower($links[$n]['type']), $this->_feed_types)) {
3664 + $href[] = $links[$n]['href'];
3665 + } /* if */
3666 + } /* if */
3667 + } /* for */
3668 + return $href;
3669 + }
3670 +
3671 + function _a_href_feeds ($obvious = TRUE) {
3672 + $pattern = ($obvious ? $this->_obvious_feed_url : $this->_maybe_feed_url);
3673 +
3674 + $links = $this->_tags('a');
3675 + $link_count = count($links);
3676 +
3677 + // now figure out which one points to the RSS file
3678 + $href = array ();
3679 + for ($n=0; $n<$link_count; $n++) {
3680 + if (preg_match("\007(".implode('|',$pattern).")\007i", $links[$n]['href'])) {
3681 + $href[] = $links[$n]['href'];
3682 + } /* if */
3683 + } /* for */
3684 + return $href;
3685 + }
3686 +
3687 + function _tags ($tag) {
3688 + $html = $this->data();
3689 +
3690 + // search through the HTML, save all <link> tags
3691 + // and store each link's attributes in an associative array
3692 + preg_match_all('/<'.$tag.'\s+(.*?)\s*\/?>/si', $html, $matches);
3693 + $links = $matches[1];
3694 + $ret = array();
3695 + $link_count = count($links);
3696 + for ($n=0; $n<$link_count; $n++) {
3697 + $attributes = preg_split('/\s+/s', $links[$n]);
3698 + foreach($attributes as $attribute) {
3699 + $att = preg_split('/\s*=\s*/s', $attribute, 2);
3700 + if (isset($att[1])) {
3701 + $att[1] = preg_replace('/([\'"]?)(.*)\1/', '$2', $att[1]);
3702 + $final_link[strtolower($att[0])] = $att[1];
3703 + } /* if */
3704 + } /* foreach */
3705 + $ret[$n] = $final_link;
3706 + } /* for */
3707 + return $ret;
3708 + }
3709 +} /* class FeedFinder */
3710 +
2359 3711 # Relative URI static class: PHP class for resolving relative URLs
2360 3712 #
2361 3713 # This class is derived (under the terms of the GPL) from URL Class 0.3 by
2362 3714 # Keyvan Minoukadeh <keyvan@k1m.com>, which is great but more than we need
@@ -2558,5 +3910,5 @@
2558 3910 $ret['name'] = NULL; $ret['email'] = NULL;
2559 3911 endif;
2560 3912 return $ret;
2561 3913 }
2562 -
3914 +?>