PluginProbe
FeedWordPress / 2008.1214
FeedWordPress v2008.1214
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 +560 -1597 0.9932008.1214 View file →
@@ -2,13 +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: 0.993
6 +Version: 2008.1214
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 +Last modified: 2008-12-14 4:29pm PST
11 11 */
12 12
13 13 # This uses code derived from:
14 14 # - wp-rss-aggregate.php by Kellan Elliot-McCrea <kellan@protest.net>
@@ -15,20 +15,22 @@
15 15 # - HTTP Navigator 2 by Keyvan Minoukadeh <keyvan@k1m.com>
16 16 # - Ultra-Liberal Feed Finder by Mark Pilgrim <mark@diveintomark.org>
17 17 # according to the terms of the GNU General Public License.
18 18 #
19 -# INSTALLATION: see README.text or <http://projects.radgeek.com/install>
19 +# INSTALLATION: see readme.txt or <http://projects.radgeek.com/install>
20 20 #
21 21 # USAGE: once FeedWordPress is installed, you manage just about everything from
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
22 +# the WordPress Dashboard, under the Syndication menu. To ensure that fresh
23 +# content is added as it becomes available, you can convince your contributors
24 +# to put your XML-RPC URI (if WordPress is installed at
25 25 # <http://www.zyx.com/blog>, XML-RPC requests should be sent to
26 -# <http://www.zyx.com/blog/xmlrpc.php>), or see `update-feeds.php`
26 +# <http://www.zyx.com/blog/xmlrpc.php>), or update manually under the
27 +# Syndication menu, or set up automatic updates under Syndication --> Settings,
28 +# or use a cron job.
27 29
28 30 # -- Don't change these unless you know what you're doing...
29 31
30 -define ('FEEDWORDPRESS_VERSION', '0.993');
32 +define ('FEEDWORDPRESS_VERSION', '2008.1214');
31 33 define ('FEEDWORDPRESS_AUTHOR_CONTACT', 'http://radgeek.com/contact');
32 34 define ('DEFAULT_SYNDICATION_CATEGORY', 'Contributors');
33 35
34 36 define ('FEEDWORDPRESS_DEBUG', false);
@@ -39,12 +41,15 @@
39 41 define ('FEEDVALIDATOR_URI', 'http://feedvalidator.org/check.cgi');
40 42
41 43 define ('FEEDWORDPRESS_FRESHNESS_INTERVAL', 10*60); // Every ten minutes
42 44
45 +define ('FWP_SCHEMA_HAS_USERMETA', 2966);
43 46 define ('FWP_SCHEMA_20', 3308); // Database schema # for WP 2.0
44 47 define ('FWP_SCHEMA_21', 4772); // Database schema # for WP 2.1
45 48 define ('FWP_SCHEMA_23', 5495); // Database schema # for WP 2.3
46 49 define ('FWP_SCHEMA_25', 7558); // Database schema # for WP 2.5
50 +define ('FWP_SCHEMA_26', 8201); // Database schema # for WP 2.6
51 +define ('FWP_SCHEMA_27', 9872); // Database schema # for WP 2.7
47 52
48 53 if (FEEDWORDPRESS_DEBUG) :
49 54 // Help us to pick out errors, if any.
50 55 ini_set('error_reporting', E_ALL & ~E_NOTICE);
@@ -82,16 +87,9 @@
82 87 require_once (ABSPATH . 'wp-admin/admin-db.php'); // for wp_insert_category
83 88 endif;
84 89 endif;
85 90
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;
91 +require_once(dirname(__FILE__) . '/compatability.php'); // LEGACY API: Replicate or mock up functions for legacy support purposes
94 92
95 93 // Magic quotes are just about the stupidest thing ever.
96 94 if (is_array($_POST)) :
97 95 $fwp_post = stripslashes_deep($_POST);
@@ -109,8 +107,32 @@
109 107 else : // Something went wrong. Let's just guess.
110 108 $fwp_path = 'feedwordpress';
111 109 endif;
112 110
111 +// If this is a FeedWordPress admin page, queue up scripts for AJAX functions that FWP uses
112 +// If it is a display page or a non-FeedWordPress admin page, don't.
113 +if (is_admin() and isset($_REQUEST['page']) and preg_match("|^{$fwp_path}/|", $_REQUEST['page'])) :
114 + if (function_exists('wp_enqueue_script')) :
115 + if (isset($wp_db_version) and $wp_db_version >= FWP_SCHEMA_25) :
116 + wp_enqueue_script('post'); // for magic tag and category boxes
117 + wp_enqueue_script('thickbox'); // for fold-up boxes
118 + wp_enqueue_script('admin-forms'); // for checkbox selection
119 + else :
120 + wp_enqueue_script( 'ajaxcat' ); // Provides the handy-dandy new category text box
121 + endif;
122 + endif;
123 + if (function_exists('wp_enqueue_style')) :
124 + if (fwp_test_wp_version(FWP_SCHEMA_25)) :
125 + wp_enqueue_style('dashboard');
126 + endif;
127 + endif;
128 + if (function_exists('wp_admin_css')) :
129 + if (fwp_test_wp_version(FWP_SCHEMA_25)) :
130 + wp_admin_css('css/dashboard');
131 + endif;
132 + endif;
133 +endif;
134 +
113 135 if (!FeedWordPress::needs_upgrade()) : // only work if the conditions are safe!
114 136
115 137 # Syndicated items are generally received in output-ready (X)HTML and
116 138 # should not be folded, crumpled, mutilated, or spindled by WordPress
@@ -127,8 +149,10 @@
127 149
128 150 add_filter('the_content', 'feedwordpress_preserve_syndicated_content', -10000);
129 151 add_filter('the_content', 'feedwordpress_restore_syndicated_content', 10000);
130 152
153 + add_action('atom_entry', 'feedwordpress_item_feed_data');
154 +
131 155 # Filter in original permalinks if the user wants that
132 156 add_filter('post_link', 'syndication_permalink', 1);
133 157
134 158 # WTF? By default, wp_insert_link runs incoming link_url and link_rss
@@ -223,102 +247,85 @@
223 247 : implode(' and ', $mesg)));
224 248 }
225 249
226 250 ################################################################################
227 -## LEGACY API: Replicate or mock up functions for legacy support purposes ######
251 +## TEMPLATE API: functions to make your templates syndication-aware ############
228 252 ################################################################################
229 253
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;
254 +function is_syndicated () { return (strlen(get_syndication_feed_id()) > 0); }
239 255
240 - $can = false;
256 +function get_syndication_source_link ($original = NULL) {
257 + if (is_null($original)) : $original = FeedWordPress::use_aggregator_source_data();
258 + endif;
241 259
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'];
260 + if ($original) : $vals = get_post_custom_values('syndication_source_uri_original');
261 + else : $vals = array();
262 + endif;
263 +
264 + if (count($vals) == 0) : $vals = get_post_custom_values('syndication_source_uri');
265 + endif;
266 +
267 + if (count($vals) > 0) : $ret = $vals[0]; else : $ret = NULL; endif;
271 268
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 -}
269 + return $ret;
270 +} /* function get_syndication_source_link() */
288 271
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;
272 +function the_syndication_source_link ($original = NULL) { echo get_syndication_source_link($original); }
294 273
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();
274 +function get_syndication_source ($original = NULL) {
275 + if (is_null($original)) : $original = FeedWordPress::use_aggregator_source_data();
304 276 endif;
305 -}
306 -################################################################################
307 -## TEMPLATE API: functions to make your templates syndication-aware ############
308 -################################################################################
309 277
310 -function is_syndicated () { return (strlen(get_syndication_feed_id()) > 0); }
278 + if ($original) : $vals = get_post_custom_values('syndication_source_original');
279 + else : $vals = array();
280 + endif;
281 +
282 + if (count($vals) == 0) : $vals = get_post_custom_values('syndication_source');
283 + endif;
284 +
285 + if (count($vals) > 0) : $ret = $vals[0]; else : $ret = NULL; endif;
311 286
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; }
287 + return $ret;
288 +} /* function get_syndication_source() */
314 289
315 -function get_syndication_source () { list($n) = get_post_custom_values('syndication_source'); return $n; }
316 -function the_syndication_source () { echo get_syndication_source(); }
290 +function the_syndication_source ($original = NULL) { echo get_syndication_source($original); }
317 291
318 -function get_syndication_feed () { list($u) = get_post_custom_values('syndication_feed'); return $u; }
319 -function the_syndication_feed () { echo get_syndication_feed (); }
292 +function get_syndication_feed ($original = NULL) {
293 + if (is_null($original)) : $original = FeedWordPress::use_aggregator_source_data();
294 + endif;
320 295
296 + if ($original) : $vals = get_post_custom_values('syndication_feed_original');
297 + else : $vals = array();
298 + endif;
299 +
300 + if (count($vals) == 0) : $vals = get_post_custom_values('syndication_feed');
301 + endif;
302 +
303 + if (count($vals) > 0) : $ret = $vals[0]; else : $ret = NULL; endif;
304 +
305 + return $ret;
306 +} /* function get_syndication_feed() */
307 +
308 +function the_syndication_feed ($original = NULL) { echo get_syndication_feed ($original); }
309 +
310 +function get_syndication_feed_guid ($original = NULL) {
311 + if (is_null($original)) : $original = FeedWordPress::use_aggregator_source_data();
312 + endif;
313 +
314 + if ($original) : $vals = get_post_custom_values('syndication_source_id_original');
315 + else : $vals = array();
316 + endif;
317 +
318 + if (count($vals) == 0) : $vals = array(get_feed_meta('feed/id'));
319 + endif;
320 +
321 + if (count($vals) > 0) : $ret = $vals[0]; else : $ret = NULL; endif;
322 +
323 + return $ret;
324 +} /* function get_syndication_feed_guid () */
325 +
326 +function the_syndication_feed_guid ($original = NULL) { echo get_syndication_feed_guid($original); }
327 +
321 328 function get_syndication_feed_id () { list($u) = get_post_custom_values('syndication_feed_id'); return $u; }
322 329 function the_syndication_feed_id () { echo get_syndication_feed_id(); }
323 330
324 331 $feedwordpress_linkcache = array (); // only load links from database once
@@ -356,9 +363,9 @@
356 363
357 364 function feedwordpress_preserve_syndicated_content ($text) {
358 365 global $feedwordpress_the_syndicated_content;
359 366
360 - if ( is_syndicated() ) :
367 + if ( is_syndicated() and get_option('feedwordpress_formatting_filters') != 'yes' ) :
361 368 $feedwordpress_the_syndicated_content = $text;
362 369 else :
363 370 $feedwordpress_the_syndicated_content = NULL;
364 371 endif;
@@ -374,1382 +381,72 @@
374 381
375 382 return $text;
376 383 }
377 384
378 -function syndication_permalink ($permalink = '') {
379 - if (get_option('feedwordpress_munge_permalink') != 'no'):
380 - $uri = get_syndication_permalink();
381 - return ((strlen($uri) > 0) ? $uri : $permalink);
382 - else:
383 - return $permalink;
384 - endif;
385 -} // function syndication_permalink ()
386 -
387 -################################################################################
388 -## UPGRADE INTERFACE: Have users upgrade DB from older versions of FWP #########
389 -################################################################################
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;
385 +function feedwordpress_item_feed_data () {
386 + // In a post context....
387 + if (is_syndicated()) :
410 388 ?>
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>
389 +<source>
390 + <title><?php the_syndication_source(); ?></title>
391 + <link rel="alternate" type="text/html" href="<?php the_syndication_source_link(); ?>" />
392 + <link rel="self" href="<?php the_syndication_feed(); ?>" />
433 393 <?php
434 -} // function fwp_upgrade_page ()
435 -
436 -################################################################################
437 -## ADMIN MENU ADD-ONS: implement Dashboard management pages ####################
438 -################################################################################
439 -
440 -function fwp_add_pages () {
441 - global $legacy_capability_hack;
442 - global $fwp_path;
443 -
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';
452 - endif;
453 -
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) :
394 + $id = get_syndication_feed_guid();
395 + if (strlen($id) > 0) :
463 396 ?>
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>
397 + <id><?php print $id; ?></id>
489 398 <?php
490 399 endif;
491 -}
492 -
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>
400 + $updated = get_feed_meta('feed/updated');
401 + if (strlen($updated) > 0) : ?>
402 + <updated><?php print $updated; ?></updated>
501 403 <?php
502 404 endif;
503 -}
504 -
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 405 ?>
509 -<div id="<?php print $id; ?>" class="<?php print $class; ?>">
510 -<h3><?php print htmlspecialchars($legend); ?></h3>
511 -<div class="inside">
406 +</source>
512 407 <?php
513 - else :
514 -?>
515 -<fieldset class="options"><legend><?php print htmlspecialchars($legend); ?></legend>
516 -<?php
517 408 endif;
518 409 }
519 410
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
527 - else :
528 -?>
529 -</fieldset>
530 -<?php
531 - endif;
532 -}
533 -
534 -function fwp_tags_box ($tags) {
535 - if (!is_array($tags)) : $tags = array(); endif;
536 -?>
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>
587 - </div>
588 - </div>
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
598 - endif;
599 -}
600 -
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 -
615 -?>
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 -?>
627 -<?php
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;
734 -?>
735 - <td>
736 - <strong><a href="<?php echo wp_specialchars($link->link_rss, 'both'); ?>"><?php echo wp_specialchars($display_uri, 'both'); ?></a></strong></td>
737 -<?php
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;
411 +function syndication_permalink ($permalink = '') {
412 + if (get_option('feedwordpress_munge_permalink') != 'no'):
413 + $uri = get_syndication_permalink();
414 + return ((strlen($uri) > 0) ? $uri : $permalink);
753 415 else:
754 -?>
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;
416 + return $permalink;
801 417 endif;
802 -?>
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>
418 +} // function syndication_permalink ()
818 419
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; ?>
420 +################################################################################
421 +## ADMIN MENU ADD-ONS: register Dashboard management pages #####################
422 +################################################################################
823 423
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" />
424 +function fwp_add_pages () {
425 + global $fwp_capability;
426 + global $fwp_path;
827 427
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>";
428 + $menu = array('Syndicated Sites', 'Syndication', $fwp_capability['manage_links'], $fwp_path.'/syndication.php', NULL);
429 + if (fwp_test_wp_version(FWP_SCHEMA_27)) :
430 + // add icon parameter
431 + $menu[] = WP_PLUGIN_URL.'/'.$fwp_path.'/feedwordpress-tiny.png';
864 432 endif;
865 -?>
866 - </div>
867 433
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>
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;
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
434 + if (fwp_test_wp_version(FWP_SCHEMA_26)) :
435 + $options = __('Settings');
436 + $longoptions = __('Syndication Settings');
951 437 else :
952 - $link_id = (int) $_REQUEST['link_id'];
953 - $link =& new SyndicatedLink($link_id);
954 -
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);
1191 - else :
1192 - $updated_link = false;
1193 - endif;
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');
1385 -?>
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>
1407 -<?php
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++;
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
438 + $options = __('Options');
439 + $longoptions = __('Syndication Options');
1588 440 endif;
1589 - return false; // Don't continue
1590 -}
1591 441
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 -}
442 + call_user_func_array('add_menu_page', $menu);
443 + add_submenu_page($fwp_path.'/syndication.php', 'Syndicated Authors', 'Authors', $fwp_capability['manage_options'], $fwp_path.'/authors.php');
444 + add_submenu_page($fwp_path.'/syndication.php', $longoptions, $options, $fwp_capability['manage_options'], $fwp_path.'/syndication-options.php');
1604 445
1605 -function fwp_multidelete_page () {
1606 - global $wpdb;
446 + add_options_page($longoptions, 'Syndication', $fwp_capability['manage_options'], $fwp_path.'/syndication-options.php');
447 +} // function fwp_add_pages () */
1607 448
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 - ");
1695 -?>
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>
1747 -<?php
1748 - return false; // Don't continue on to Syndicated Sites listing
1749 - endif;
1750 -}
1751 -
1752 449 ################################################################################
1753 450 ## fwp_hold_pings() and fwp_release_pings(): Outbound XML-RPC ping reform ####
1754 451 ## ... 'coz it's rude to send 500 pings the first time your aggregator runs ####
1755 452 ################################################################################
@@ -1903,9 +600,9 @@
1903 600 #
1904 601 # * Updates to existing posts since the last poll are mirrored in the
1905 602 # WordPress store.
1906 603 #
1907 - function update ($uri = null) {
604 + function update ($uri = null, $crash_ts = null) {
1908 605 global $wpdb;
1909 606
1910 607 if (FeedWordPress::needs_upgrade()) : // Will make duplicate posts if we don't hold off
1911 608 return NULL;
@@ -1918,11 +615,28 @@
1918 615 endif;
1919 616
1920 617 do_action('feedwordpress_update', $uri);
1921 618
619 + if (is_null($crash_ts)) :
620 + $crash_dt = (int) get_option('feedwordpress_update_time_limit');
621 + if ($crash_dt > 0) :
622 + $crash_ts = time() + $crash_dt;
623 + else :
624 + $crash_ts = NULL;
625 + endif;
626 + endif;
627 +
628 + // Randomize order for load balancing purposes
629 + $feed_set = $this->feeds;
630 + shuffle($feed_set);
631 +
1922 632 // Loop through and check for new posts
1923 633 $delta = NULL;
1924 - foreach ($this->feeds as $feed) :
634 + foreach ($feed_set as $feed) :
635 + if (!is_null($crash_ts) and (time() > $crash_ts)) : // Check whether we've exceeded the time limit
636 + break;
637 + endif;
638 +
1925 639 $pinged_that = (is_null($uri) or in_array($uri, array($feed->uri(), $feed->homepage())));
1926 640
1927 641 if (!is_null($uri)) : // A site-specific ping always updates
1928 642 $timely = true;
@@ -1935,9 +649,12 @@
1935 649 endif;
1936 650
1937 651 if ($pinged_that and $timely) :
1938 652 do_action('feedwordpress_check_feed', $feed->settings);
1939 - $added = $feed->poll();
653 + $start_ts = time();
654 + $added = $feed->poll($crash_ts);
655 + do_action('feedwordpress_check_feed_complete', $feed->settings, $added, time() - $start_ts);
656 +
1940 657 if (isset($added['new'])) : $delta['new'] += $added['new']; endif;
1941 658 if (isset($added['updated'])) : $delta['updated'] += $added['updated']; endif;
1942 659 endif;
1943 660 endforeach;
@@ -1995,9 +712,9 @@
1995 712 if (function_exists('wp_insert_link')) { // WordPress 2.x
1996 713 $link_id = wp_insert_link(array(
1997 714 "link_name" => $name,
1998 715 "link_url" => $uri,
1999 - "link_category" => array($cat_id),
716 + "link_category" => (fwp_test_wp_version(0, FWP_SCHEMA_21) ? $cat_id : array($cat_id)),
2000 717 "link_rss" => $rss
2001 718 ));
2002 719 } else { // WordPress 1.5.x
2003 720 $result = $wpdb->query("
@@ -2013,17 +730,20 @@
2013 730 return $link_id;
2014 731 } // function FeedWordPress::syndicate_link()
2015 732
2016 733 function on_unfamiliar ($what = 'author', $override = NULL) {
2017 - $set = array('create', 'default', 'filter');
2018 -
734 + $set = array(
735 + 'author' => array('create', 'default', 'filter'),
736 + 'category' => array('create', 'tag', 'default', 'filter'),
737 + );
738 +
2019 739 if (is_string($override)) :
2020 740 $ret = strtolower($override);
2021 741 endif;
2022 742
2023 - if (!is_numeric($override) and !in_array($ret, $set)) :
743 + if (!is_numeric($override) and !in_array($ret, $set[$what])) :
2024 744 $ret = get_option('feedwordpress_unfamiliar_'.$what);
2025 - if (!is_numeric($ret) and !in_array($ret, $set)) :
745 + if (!is_numeric($ret) and !in_array($ret, $set[$what])) :
2026 746 $ret = 'create';
2027 747 endif;
2028 748 endif;
2029 749
@@ -2029,8 +749,33 @@
2029 749
2030 750 return $ret;
2031 751 } // function FeedWordPress::on_unfamiliar()
2032 752
753 + function null_email_set () {
754 + $base = get_option('feedwordpress_null_email_set');
755 +
756 + if ($base===false) :
757 + $ret = array('noreply@blogger.com'); // default
758 + else :
759 + $ret = array_map('strtolower',
760 + array_map('trim', explode("\n", $base)));
761 + endif;
762 + $ret = apply_filters('syndicated_item_author_null_email_set', $ret);
763 + return $ret;
764 +
765 + } /* FeedWordPress::null_email_set () */
766 +
767 + function is_null_email ($email) {
768 + $ret = in_array(strtolower(trim($email)), FeedWordPress::null_email_set());
769 + $ret = apply_filters('syndicated_item_author_is_null_email', $ret, $email);
770 + return $ret;
771 + } /* FeedWordPress::is_null_email () */
772 +
773 + function use_aggregator_source_data () {
774 + $ret = get_option('feedwordpress_use_aggregator_source_data');
775 + return apply_filters('syndicated_post_use_aggregator_source_data', ($ret=='yes'));
776 + }
777 +
2033 778 function syndicated_links () {
2034 779 $contributors = FeedWordPress::link_category_id();
2035 780 if (function_exists('get_bookmarks')) :
2036 781 $links = get_bookmarks(array("category" => $contributors));
@@ -2073,12 +818,12 @@
2073 818 if (function_exists('wp_insert_term')) :
2074 819 $term = wp_insert_term($cat, 'link_category');
2075 820 $cat_id = $term['term_id'];
2076 821 // WordPress 2.1, 2.2 category API. By the way, why the fuck is this API function only available in a wp-admin module?
2077 - elseif (function_exists('wp_insert_category')) :
822 + elseif (function_exists('wp_insert_category') and !fwp_test_wp_version(FWP_SCHEMA_20, FWP_SCHEMA_21)) :
2078 823 $cat_id = wp_insert_category(array('cat_name' => $cat));
2079 824 // WordPress 1.5 and 2.0.x
2080 - elseif (!isset($wp_db_version) or $wp_db_version < FWP_SCHEMA_21) :
825 + elseif (fwp_test_wp_version(0, FWP_SCHEMA_21)) :
2081 826 $result = $wpdb->query("
2082 827 INSERT INTO $wpdb->linkcategories
2083 828 SET
2084 829 cat_id = 0,
@@ -2188,8 +933,16 @@
2188 933 endswitch;
2189 934 echo "<p>Upgrade complete. FeedWordPress is now ready to use again.</p>";
2190 935 } /* FeedWordPress::upgrade_database() */
2191 936
937 + function create_guid_index () {
938 + global $wpdb;
939 +
940 + $wpdb->query("
941 + CREATE INDEX {$wpdb->posts}_guid_idx ON {$wpdb->posts}(guid)
942 + ");
943 + } /* FeedWordPress::create_guid_index () */
944 +
2192 945 # Utility functions for handling text settings
2193 946 function negative ($f, $setting) {
2194 947 $nego = array ('n', 'no', 'f', 'false');
2195 948 return (isset($f[$setting]) and in_array(strtolower($f[$setting]), $nego));
@@ -2214,8 +967,14 @@
2214 967 echo "\n";
2215 968 echo $varname.": "; var_dump($var); echo "\n";
2216 969 die;
2217 970 }
971 +
972 + function noncritical_bug ($varname, $var, $line) {
973 + if (FEEDWORDPRESS_DEBUG) : // halt only when we are doing debugging
974 + FeedWordPress::critical_bug($varname, $var, $line);
975 + endif;
976 + }
2218 977 } // class FeedWordPress
2219 978
2220 979 class SyndicatedPost {
2221 980 var $item = null;
@@ -2336,12 +1095,26 @@
2336 1095 // In case you want to point back to the blog this was syndicated from
2337 1096 if (isset($this->feed->channel['title'])) :
2338 1097 $this->post['meta']['syndication_source'] = apply_filters('syndicated_item_source_title', $this->feed->channel['title'], $this);
2339 1098 endif;
1099 +
2340 1100 if (isset($this->feed->channel['link'])) :
2341 1101 $this->post['meta']['syndication_source_uri'] = apply_filters('syndicated_item_source_link', $this->feed->channel['link'], $this);
2342 1102 endif;
2343 1103
1104 + // Make use of atom:source data, if present in an aggregated feed
1105 + if (isset($this->item['source_title'])) :
1106 + $this->post['meta']['syndication_source_original'] = $this->item['source_title'];
1107 + endif;
1108 +
1109 + if (isset($this->item['source_link'])) :
1110 + $this->post['meta']['syndication_source_uri_original'] = $this->item['source_link'];
1111 + endif;
1112 +
1113 + if (isset($this->item['source_id'])) :
1114 + $this->post['meta']['syndication_source_id_original'] = $this->item['source_id'];
1115 + endif;
1116 +
2344 1117 // Store information on human-readable and machine-readable comment URIs
2345 1118 if (isset($this->item['comments'])) :
2346 1119 $this->post['meta']['rss:comments'] = apply_filters('syndicated_item_comments', $this->item['comments']);
2347 1120 endif;
@@ -2352,11 +1125,18 @@
2352 1125 // Store information to identify the feed that this came from
2353 1126 $this->post['meta']['syndication_feed'] = $this->feedmeta['link/uri'];
2354 1127 $this->post['meta']['syndication_feed_id'] = $this->feedmeta['link/id'];
2355 1128
1129 + if (isset($this->item['source_link_self'])) :
1130 + $this->post['meta']['syndication_feed_original'] = $this->item['source_link_self'];
1131 + endif;
1132 +
2356 1133 // In case you want to know the external permalink...
2357 1134 $this->post['meta']['syndication_permalink'] = apply_filters('syndicated_item_link', $this->item['link']);
2358 1135
1136 + // Store a hash of the post content for checking whether something needs to be updated
1137 + $this->post['meta']['syndication_item_hash'] = $this->update_hash();
1138 +
2359 1139 // Feed-by-feed options for author and category creation
2360 1140 $this->post['named']['unfamiliar']['author'] = $this->feedmeta['unfamiliar author'];
2361 1141 $this->post['named']['unfamiliar']['category'] = $this->feedmeta['unfamiliar category'];
2362 1142
@@ -2391,9 +1171,9 @@
2391 1171
2392 1172 // Tags: start with default tags, if any
2393 1173 $ft = get_option("feedwordpress_syndication_tags");
2394 1174 if ($ft) :
2395 - $this->post['tags_input'] = explode('FEEDWORDPRESS_CAT_SEPARATOR', $ft);
1175 + $this->post['tags_input'] = explode(FEEDWORDPRESS_CAT_SEPARATOR, $ft);
2396 1176 else :
2397 1177 $this->post['tags_input'] = array();
2398 1178 endif;
2399 1179
@@ -2399,8 +1179,9 @@
2399 1179
2400 1180 if (is_array($this->feedmeta['tags'])) :
2401 1181 $this->post['tags_input'] = array_merge($this->post['tags_input'], $this->feedmeta['tags']);
2402 1182 endif;
1183 +
2403 1184 endif;
2404 1185 } // SyndicatedPost::SyndicatedPost()
2405 1186
2406 1187 function filtered () {
@@ -2421,18 +1202,35 @@
2421 1202 SELECT id, guid, post_modified_gmt
2422 1203 FROM $wpdb->posts WHERE guid='$guid'
2423 1204 ");
2424 1205
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]);
2427 1206 if (!$result) :
2428 1207 $this->_freshness = 2; // New content
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;
1208 + else:
1209 + $stored_update_hashes = get_post_custom_values('syndication_item_hash', $result->id);
1210 + if (count($stored_update_hashes) > 0) :
1211 + $stored_update_hash = $stored_update_hashes[0];
1212 + $update_hash_changed = ($stored_update_hash != $this->update_hash());
1213 + else :
1214 + $update_hash_changed = false;
1215 + endif;
1216 +
1217 + preg_match('/([0-9]+)-([0-9]+)-([0-9]+) ([0-9]+):([0-9]+):([0-9]+)/', $result->post_modified_gmt, $backref);
1218 +
1219 + $last_rev_ts = gmmktime($backref[4], $backref[5], $backref[6], $backref[2], $backref[3], $backref[1]);
1220 + $updated_ts = $this->updated(/*fallback=*/ true, /*default=*/ NULL);
1221 + $updated = ((
1222 + !is_null($updated_ts)
1223 + and ($updated_ts > $last_rev_ts)
1224 + ) or $update_hash_changed);
1225 +
1226 + if ($updated) :
1227 + $this->_freshness = 1; // Updated content
1228 + $this->_wp_id = $result->id;
1229 + else :
1230 + $this->_freshness = 0; // Same old, same old
1231 + $this->_wp_id = $result->id;
1232 + endif;
2435 1233 endif;
2436 1234 endif;
2437 1235 return $this->_freshness;
2438 1236 }
@@ -2468,13 +1266,17 @@
2468 1266 endif;
2469 1267
2470 1268 if (!$this->filtered() and $freshness > 0) :
2471 1269 # -- Look up, or create, numeric ID for categories
2472 - $this->post['post_category'] = $this->category_ids (
1270 + list($pcats, $ptags) = $this->category_ids (
2473 1271 $this->post['named']['category'],
2474 - FeedWordPress::on_unfamiliar('category', $this->post['named']['unfamiliar']['category'])
1272 + FeedWordPress::on_unfamiliar('category', $this->post['named']['unfamiliar']['category']),
1273 + /*tags_too=*/ true
2475 1274 );
2476 -
1275 +
1276 + $this->post['post_category'] = $pcats;
1277 + $this->post['tags_input'] = array_merge($this->post['tags_input'], $ptags);
1278 +
2477 1279 if (is_null($this->post['post_category'])) :
2478 1280 // filter mode on, no matching categories; drop the post
2479 1281 $this->post = NULL;
2480 1282 else :
@@ -2541,13 +1343,26 @@
2541 1343 endif;
2542 1344
2543 1345 if ($this->use_api('wp_insert_post')) :
2544 1346 $dbpost['post_pingback'] = false; // Tell WP 2.1 and 2.2 not to process for pingbacks
1347 +
1348 + // This is a ridiculous fucking kludge necessitated by WordPress 2.6 munging authorship meta-data
1349 + add_action('_wp_put_post_revision', array($this, 'fix_revision_meta'));
1350 +
1351 + // Kludge to prevent kses filters from stripping the
1352 + // content of posts when updating without a logged in
1353 + // user who has `unfiltered_html` capability.
1354 + add_filter('content_save_pre', array($this, 'avoid_kses_munge'), 11);
1355 +
2545 1356 $this->_wp_id = wp_insert_post($dbpost);
2546 -
1357 +
1358 + // Turn off ridiculous fucking kludges #1 and #2
1359 + remove_action('_wp_put_post_revision', array($this, 'fix_revision_meta'));
1360 + remove_filter('content_save_pre', array($this, 'avoid_kses_munge'), 11);
1361 +
2547 1362 // This should never happen.
2548 1363 if (!is_numeric($this->_wp_id) or ($this->_wp_id == 0)) :
2549 - FeedWordPress::critical_bug('SyndicatedPost (_wp_id problem)', array($dbpost, $this), __LINE__);
1364 + FeedWordPress::critical_bug('SyndicatedPost (_wp_id problem)', array("dbpost" => $dbpost, "this" => $this), __LINE__);
2550 1365 endif;
2551 1366
2552 1367 // Unfortunately, as of WordPress 2.3, wp_insert_post()
2553 1368 // *still* offers no way to use a guid of your choice,
@@ -2590,9 +1405,9 @@
2590 1405 $this->_wp_id = $wpdb->insert_id;
2591 1406
2592 1407 // This should never happen.
2593 1408 if (!is_numeric($this->_wp_id) or ($this->_wp_id == 0)) :
2594 - FeedWordPress::critical_bug('SyndicatedPost::_wp_id', $this->_wp_id, __LINE__);
1409 + FeedWordPress::critical_bug('SyndicatedPost (_wp_id problem)', array("dbpost" => $dbpost, "this" => $this), __LINE__);
2595 1410 endif;
2596 1411
2597 1412 // WordPress 1.5.x - 2.0.x
2598 1413 wp_set_post_cats('1', $this->wp_id(), $this->post['post_category']);
@@ -2621,13 +1436,26 @@
2621 1436 endforeach;
2622 1437
2623 1438 if ($this->use_api('wp_insert_post')) :
2624 1439 $dbpost['post_pingback'] = false; // Tell WP 2.1 and 2.2 not to process for pingbacks
1440 +
1441 + // This is a ridiculous fucking kludge necessitated by WordPress 2.6 munging authorship meta-data
1442 + add_action('_wp_put_post_revision', array($this, 'fix_revision_meta'));
1443 +
1444 + // Kludge to prevent kses filters from stripping the
1445 + // content of posts when updating without a logged in
1446 + // user who has `unfiltered_html` capability.
1447 + add_filter('content_save_pre', array($this, 'avoid_kses_munge'), 11);
1448 +
2625 1449 $this->_wp_id = wp_insert_post($dbpost);
2626 1450
1451 + // Turn off ridiculous fucking kludges #1 and #2
1452 + remove_action('_wp_put_post_revision', array($this, 'fix_revision_meta'));
1453 + remove_filter('content_save_pre', array($this, 'avoid_kses_munge'), 11);
1454 +
2627 1455 // This should never happen.
2628 1456 if (!is_numeric($this->_wp_id) or ($this->_wp_id == 0)) :
2629 - FeedWordPress::critical_bug('SyndicatedPost::_wp_id', $this->_wp_id, __LINE__);
1457 + FeedWordPress::critical_bug('SyndicatedPost (_wp_id problem)', array("dbpost" => $dbpost, "this" => $this), __LINE__);
2630 1458 endif;
2631 1459
2632 1460 // Unfortunately, as of WordPress 2.3, wp_insert_post()
2633 1461 // munges your post modified timestamp.
@@ -2660,9 +1488,9 @@
2660 1488 elseif (function_exists('wp_set_post_cats')) :
2661 1489 wp_set_post_cats('1', $this->wp_id(), $this->post['post_category']);
2662 1490 // This should never happen.
2663 1491 else :
2664 - FeedWordPress::critical_bug('SyndicatedPost::insert_new::wp_version', $GLOBALS['wp_version'], __LINE__);
1492 + FeedWordPress::critical_bug('SyndicatedPost (_wp_id problem)', array("dbpost" => $dbpost, "this" => $this), __LINE__);
2665 1493 endif;
2666 1494
2667 1495 // Since we are not going through official channels, we need to
2668 1496 // manually tell WordPress that we've published a new post.
@@ -2673,8 +1501,63 @@
2673 1501 do_action('edit_post', $this->post['ID']);
2674 1502 endif;
2675 1503 } /* SyndicatedPost::update_existing() */
2676 1504
1505 + /**
1506 + * SyndicatedPost::fix_revision_meta() - Fixes the way WP 2.6+ fucks up
1507 + * meta-data (authorship, etc.) when storing revisions of an updated
1508 + * syndicated post.
1509 + *
1510 + * In their infinite wisdom, the WordPress coders have made it completely
1511 + * impossible for a plugin that uses wp_insert_post() to set certain
1512 + * meta-data (such as the author) when you store an old revision of an
1513 + * updated post. Instead, it uses the WordPress defaults (= currently
1514 + * active user ID if the process is running with a user logged in, or
1515 + * = #0 if there is no user logged in). This results in bogus authorship
1516 + * data for revisions that are syndicated from off the feed, unless we
1517 + * use a ridiculous kludge like this to end-run the munging of meta-data
1518 + * by _wp_put_post_revision.
1519 + *
1520 + * @param int $revision_id The revision ID to fix up meta-data
1521 + */
1522 + function fix_revision_meta ($revision_id) {
1523 + global $wpdb;
1524 +
1525 + $post_author = (int) $this->post['post_author'];
1526 +
1527 + $revision_id = (int) $revision_id;
1528 + $wpdb->query("
1529 + UPDATE $wpdb->posts
1530 + SET post_author={$this->post['post_author']}
1531 + WHERE post_type = 'revision' AND ID='$revision_id'
1532 + ");
1533 + } /* SyndicatedPost::fix_revision_meta () */
1534 +
1535 + /**
1536 + * SyndicatedPost::avoid_kses_munge() -- If FeedWordPress is processing
1537 + * an automatic update, that generally means that wp_insert_post() is
1538 + * being called under the user credentials of whoever is viewing the
1539 + * blog at the time -- usually meaning no user at all. But if WordPress
1540 + * gets a wp_insert_post() when current_user_can('unfiltered_html') is
1541 + * false, it will run the content of the post through a kses function
1542 + * that strips out lots of HTML tags -- notably <object> and some others.
1543 + * This causes problems for syndicating (for example) feeds that contain
1544 + * YouTube videos. It also produces an unexpected asymmetry between
1545 + * automatically-initiated updates and updates initiated manually from
1546 + * the WordPress Dashboard (which are usually initiated under the
1547 + * credentials of a logged-in admin, and so don't get run through the
1548 + * kses function). So, to avoid the whole mess, what we do here is
1549 + * just forcibly disable the kses munging for a single syndicated post,
1550 + * by restoring the contents of the `post_content` field.
1551 + *
1552 + * @param string $content The content of the post, after other filters have gotten to it
1553 + * @return string The original content of the post, before other filters had a chance to munge it.
1554 + */
1555 + function avoid_kses_munge ($content) {
1556 + global $wpdb;
1557 + return $wpdb->escape($this->post['post_content']);
1558 + }
1559 +
2677 1560 // SyndicatedPost::add_rss_meta: adds interesting meta-data to each entry
2678 1561 // using the space for custom keys. The set of keys and values to add is
2679 1562 // specified by the keys and values of $post['meta']. This is used to
2680 1563 // store anything that the WordPress user might want to access from a
@@ -2726,9 +1609,9 @@
2726 1609
2727 1610 // SyndicatedPost::author_id (): get the ID for an author name from
2728 1611 // the feed. Create the author if necessary.
2729 1612 function author_id ($unfamiliar_author = 'create') {
2730 - global $wpdb, $wp_db_version; // test for WordPress 2.0 database schema
1613 + global $wpdb;
2731 1614
2732 1615 $a = $this->author();
2733 1616 $author = $a['name'];
2734 1617 $email = $a['email'];
@@ -2733,8 +1616,15 @@
2733 1616 $author = $a['name'];
2734 1617 $email = $a['email'];
2735 1618 $url = $a['uri'];
2736 1619
1620 + $match_author_by_email = !('yes' == get_option("feedwordpress_do_not_match_author_by_email"));
1621 + if ($match_author_by_email and !FeedWordPress::is_null_email($email)) :
1622 + $test_email = $email;
1623 + else :
1624 + $test_email = NULL;
1625 + endif;
1626 +
2737 1627 // Never can be too careful...
2738 1628 $login = sanitize_user($author, /*strict=*/ true);
2739 1629 $login = apply_filters('pre_user_login', $login);
2740 1630
@@ -2743,8 +1633,9 @@
2743 1633
2744 1634 $reg_author = $wpdb->escape(preg_quote($author));
2745 1635 $author = $wpdb->escape($author);
2746 1636 $email = $wpdb->escape($email);
1637 + $test_email = $wpdb->escape($test_email);
2747 1638 $url = $wpdb->escape($url);
2748 1639
2749 1640 // Check for an existing author rule....
2750 1641 if (isset($this->link->settings['map authors']['name'][strtolower(trim($author))])) :
@@ -2763,34 +1654,10 @@
2763 1654
2764 1655 else :
2765 1656 // Check the database for an existing author record that might fit
2766 1657
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 -
2791 1658 #-- WordPress 2.0+
2792 - elseif ($wp_db_version >= 2966) :
1659 + if (fwp_test_wp_version(FWP_SCHEMA_HAS_USERMETA)) :
2793 1660
2794 1661 // First try the user core data table.
2795 1662 $id = $wpdb->get_var(
2796 1663 "SELECT ID FROM $wpdb->users
@@ -2797,9 +1664,9 @@
2797 1664 WHERE
2798 1665 TRIM(LCASE(user_login)) = TRIM(LCASE('$login'))
2799 1666 OR (
2800 1667 LENGTH(TRIM(LCASE(user_email))) > 0
2801 - AND TRIM(LCASE(user_email)) = TRIM(LCASE('$email'))
1668 + AND TRIM(LCASE(user_email)) = TRIM(LCASE('$test_email'))
2802 1669 )
2803 1670 OR TRIM(LCASE(user_nicename)) = TRIM(LCASE('$nice_author'))
2804 1671 ");
2805 1672
@@ -2819,8 +1686,33 @@
2819 1686 )
2820 1687 )
2821 1688 ");
2822 1689 endif;
1690 +
1691 + #-- WordPress 1.5.x
1692 + else :
1693 + $id = $wpdb->get_var(
1694 + "SELECT ID from $wpdb->users
1695 + WHERE
1696 + TRIM(LCASE(user_login)) = TRIM(LCASE('$login')) OR
1697 + (
1698 + LENGTH(TRIM(LCASE(user_email))) > 0
1699 + AND TRIM(LCASE(user_email)) = TRIM(LCASE('$test_email'))
1700 + ) OR
1701 + TRIM(LCASE(user_firstname)) = TRIM(LCASE('$author')) OR
1702 + TRIM(LCASE(user_nickname)) = TRIM(LCASE('$author')) OR
1703 + TRIM(LCASE(user_nicename)) = TRIM(LCASE('$nice_author')) OR
1704 + TRIM(LCASE(user_description)) = TRIM(LCASE('$author')) OR
1705 + (
1706 + LOWER(user_description)
1707 + RLIKE CONCAT(
1708 + '(^|\\n)a\\.?k\\.?a\\.?( |\\t)*:?( |\\t)*',
1709 + LCASE('$reg_author'),
1710 + '( |\\t|\\r)*(\\n|\$)'
1711 + )
1712 + )
1713 + ");
1714 +
2823 1715 endif;
2824 1716
2825 1717 // ... if you don't find one, then do what you need to do
2826 1718 if (is_null($id)) :
@@ -2851,9 +1743,9 @@
2851 1743 return $id;
2852 1744 } // function SyndicatedPost::author_id ()
2853 1745
2854 1746 // look up (and create) category ids from a list of categories
2855 - function category_ids ($cats, $unfamiliar_category = 'create') {
1747 + function category_ids ($cats, $unfamiliar_category = 'create', $tags_too = false) {
2856 1748 global $wpdb;
2857 1749
2858 1750 // We need to normalize whitespace because (1) trailing
2859 1751 // whitespace can cause PHP and MySQL not to see eye to eye on
@@ -2862,8 +1754,10 @@
2862 1754 // because I doubt most people want to make a semantic
2863 1755 // distinction between 'Computers' and 'Computers '
2864 1756 $cats = array_map('trim', $cats);
2865 1757
1758 + $tags = array();
1759 +
2866 1760 $cat_ids = array ();
2867 1761 foreach ($cats as $cat_name) :
2868 1762 if (preg_match('/^{#([0-9]+)}$/', $cat_name, $backref)) :
2869 1763 $cat_id = (int) $backref[1];
@@ -2871,9 +1765,9 @@
2871 1765 $cat_ids[] = $cat_id;
2872 1766 elseif (get_category($cat_id)) :
2873 1767 $cat_ids[] = $cat_id;
2874 1768 endif;
2875 - else :
1769 + elseif (strlen($cat_name) > 0) :
2876 1770 $esc = $wpdb->escape($cat_name);
2877 1771 $resc = $wpdb->escape(preg_quote($cat_name));
2878 1772
2879 1773 // WordPress 2.3+
@@ -2891,11 +1785,17 @@
2891 1785 )) :
2892 1786 foreach ($results AS $term) :
2893 1787 $cat_ids[] = (int) $term->term_id;
2894 1788 endforeach;
1789 + elseif ('tag'==$unfamiliar_category) :
1790 + $tags[] = $cat_name;
2895 1791 elseif ('create'===$unfamiliar_category) :
2896 1792 $term = wp_insert_term($cat_name, 'category');
2897 - $cat_ids[] = $term['term_id'];
1793 + if (is_wp_error($term)) :
1794 + FeedWordPress::noncritical_bug('term insertion problem', array('cat_name' => $cat_name, 'term' => $term, 'this' => $this), __LINE__);
1795 + else :
1796 + $cat_ids[] = $term['term_id'];
1797 + endif;
2898 1798 endif;
2899 1799
2900 1800 // WordPress 1.5.x - 2.2.x
2901 1801 else :
@@ -2936,9 +1836,14 @@
2936 1836 $cat_ids = NULL; // Drop the post
2937 1837 else :
2938 1838 $cat_ids = array_unique($cat_ids);
2939 1839 endif;
2940 - return $cat_ids;
1840 +
1841 + if ($tags_too) : $ret = array($cat_ids, $tags);
1842 + else : $ret = $cat_ids;
1843 + endif;
1844 +
1845 + return $ret;
2941 1846 } // function SyndicatedPost::category_ids ()
2942 1847
2943 1848 function use_api ($tag) {
2944 1849 global $wp_db_version;
@@ -2990,14 +1895,18 @@
2990 1895 endif;
2991 1896
2992 1897 # If everything failed, then default to the current time.
2993 1898 if (is_null($epoch)) :
2994 - $epoch = time();
1899 + if (-1 == $default) :
1900 + $epoch = time();
1901 + else :
1902 + $epoch = $default;
1903 + endif;
2995 1904 endif;
2996 1905
2997 1906 return $epoch;
2998 1907 }
2999 - function updated ($fallback = true) {
1908 + function updated ($fallback = true, $default = -1) {
3000 1909 $epoch = null;
3001 1910
3002 1911 # As far as I know, only dcterms and Atom have reliable ways to
3003 1912 # specify when something was *modified* last. If neither is
@@ -3010,19 +1919,27 @@
3010 1919 $epoch = @parse_w3cdtf($this->item['modified']);
3011 1920 elseif (isset($this->item['updated'])): // Atom 1.0
3012 1921 $epoch = @parse_w3cdtf($this->item['updated']);
3013 1922 elseif ($fallback) : // Fall back to issued / dc:date
3014 - $epoch = $this->published(/*fallback=*/ false);
1923 + $epoch = $this->published(/*fallback=*/ false, /*default=*/ $default);
3015 1924 endif;
3016 1925
3017 1926 # If everything failed, then default to the current time.
3018 1927 if (is_null($epoch)) :
3019 - $epoch = time();
1928 + if (-1 == $default) :
1929 + $epoch = time();
1930 + else :
1931 + $epoch = $default;
1932 + endif;
3020 1933 endif;
3021 1934
3022 1935 return $epoch;
3023 1936 }
3024 1937
1938 + function update_hash () {
1939 + return md5(serialize($this->item));
1940 + }
1941 +
3025 1942 function guid () {
3026 1943 $guid = null;
3027 1944 if (isset($this->item['id'])): // Atom 0.3 / 1.0
3028 1945 $guid = $this->item['id'];
@@ -3255,13 +2172,13 @@
3255 2172 endforeach;
3256 2173 $this->settings['map authors'] = $ma;
3257 2174 endif;
3258 2175 endif;
3259 - } // SyndicatedLink::SyndicatedLink ()
2176 + } /* SyndicatedLink::SyndicatedLink () */
3260 2177
3261 2178 function found () {
3262 2179 return is_object($this->link);
3263 - }
2180 + } /* SyndicatedLink::found () */
3264 2181
3265 2182 function stale () {
3266 2183 $stale = true;
3267 2184 if (isset($this->settings['update/hold']) and ($this->settings['update/hold']=='ping')) :
@@ -3275,16 +2192,25 @@
3275 2192 +((int) $this->settings['update/ttl'] * 60);
3276 2193 $stale = (time() >= $after);
3277 2194 endif;
3278 2195 return $stale;
3279 - }
2196 + } /* SyndicatedLink::stale () */
3280 2197
3281 - function poll () {
2198 + function poll ($crash_ts = NULL) {
3282 2199 global $wpdb;
3283 2200
3284 2201 $this->magpie = fetch_rss($this->link->link_rss);
3285 2202 $new_count = NULL;
3286 2203
2204 + $resume = FeedWordPress::affirmative($this->settings, 'update/unfinished');
2205 + if ($resume) :
2206 + // pick up where we left off
2207 + $processed = array_map('trim', explode("\n", $this->settings['update/processed']));
2208 + else :
2209 + // begin at the beginning
2210 + $processed = array();
2211 + endif;
2212 +
3287 2213 if (is_object($this->magpie)) :
3288 2214 $new_count = array('new' => 0, 'updated' => 0);
3289 2215
3290 2216 # -- Update Link metadata live from feed
@@ -3320,44 +2246,17 @@
3320 2246 else :
3321 2247 $this->settings['update/ttl'] = rand(30, 120); // spread over time interval for staggered updates
3322 2248 $this->settings['update/timed'] = 'automatically';
3323 2249 endif;
3324 -
2250 +
3325 2251 if (!isset($this->settings['update/hold']) or $this->settings['update/hold']!='ping') :
3326 2252 $this->settings['update/hold'] = 'scheduled';
3327 2253 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 2254
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;
2255 + $this->settings['update/unfinished'] = 'yes';
3338 2256
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;
2257 + $update[] = "link_notes = '".$wpdb->escape($this->settings_to_notes())."'";
3348 2258
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 2259 $update_set = implode(',', $update);
3361 2260
3362 2261 // Update the properties of the link from the feed information
3363 2262 $result = $wpdb->query("
@@ -3366,14 +2265,24 @@
3366 2265 WHERE link_id='$this->id'
3367 2266 ");
3368 2267
3369 2268 # -- Add new posts from feed and update any updated posts
2269 + $crashed = false;
2270 +
3370 2271 if (is_array($this->magpie->items)) :
3371 2272 foreach ($this->magpie->items as $item) :
3372 2273 $post =& new SyndicatedPost($item, $this);
3373 - if (!$post->filtered()) :
3374 - $new = $post->store();
3375 - if ( $new !== false ) $new_count[$new]++;
2274 + if (!$resume or !in_array(trim($post->guid()), $processed)) :
2275 + $processed[] = $post->guid();
2276 + if (!$post->filtered()) :
2277 + $new = $post->store();
2278 + if ( $new !== false ) $new_count[$new]++;
2279 + endif;
2280 +
2281 + if (!is_null($crash_ts) and (time() > $crash_ts)) :
2282 + $crashed = true;
2283 + break;
2284 + endif;
3376 2285 endif;
3377 2286 endforeach;
3378 2287 endif;
3379 2288
@@ -3379,53 +2288,102 @@
3379 2288
3380 2289 // Copy back any changes to feed settings made in the course of updating (e.g. new author rules)
3381 2290 $to_notes = $this->settings;
3382 2291
3383 - if (is_array($to_notes['cats'])) :
3384 - $to_notes['cats'] = implode(FEEDWORDPRESS_CAT_SEPARATOR, $to_notes['cats']);
2292 + $this->settings['update/processed'] = $processed;
2293 + if (!$crashed) :
2294 + $this->settings['update/unfinished'] = 'no';
3385 2295 endif;
3386 - if (is_array($to_notes['tags'])) :
3387 - $to_notes['tags'] = implode(FEEDWORDPRESS_CAT_SEPARATOR, $to_notes['tags']);
3388 - endif;
3389 2296
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)."'";
2297 + $update_set = "link_notes = '".$wpdb->escape($this->settings_to_notes())."'";
3411 2298
3412 2299 // Update the properties of the link from the feed information
3413 2300 $result = $wpdb->query("
3414 - UPDATE $wpdb->links
3415 - SET $update_set
3416 - WHERE link_id='$this->id'
2301 + UPDATE $wpdb->links
2302 + SET $update_set
2303 + WHERE link_id='$this->id'
3417 2304 ");
3418 2305 endif;
2306 +
3419 2307 return $new_count;
3420 2308 } /* SyndicatedLink::poll() */
3421 -
2309 +
2310 + function map_name_to_new_user ($name, $newuser_name) {
2311 + global $wpdb;
2312 +
2313 + if (strlen($newuser_name) > 0) :
2314 + $userdata = array();
2315 + $userdata['ID'] = NULL;
2316 +
2317 + $userdata['user_login'] = sanitize_user($newuser_name);
2318 + $userdata['user_login'] = apply_filters('pre_user_login', $userdata['user_login']);
2319 +
2320 + $userdata['user_nicename'] = sanitize_title($newuser_name);
2321 + $userdata['user_nicename'] = apply_filters('pre_user_nicename', $userdata['user_nicename']);
2322 +
2323 + $userdata['display_name'] = $wpdb->escape($newuser_name);
2324 +
2325 + $newuser_id = wp_insert_user($userdata);
2326 + if (is_numeric($newuser_id)) :
2327 + if (is_null($name)) : // Unfamiliar author
2328 + $this->settings['unfamiliar author'] = $newuser_id;
2329 + else :
2330 + $this->settings['map authors']['name'][$name] = $newuser_id;
2331 + endif;
2332 + else :
2333 + // TODO: Add some error detection and reporting
2334 + endif;
2335 + else :
2336 + // TODO: Add some error reporting
2337 + endif;
2338 + } /* SyndicatedLink::map_name_to_new_user () */
2339 +
2340 + function settings_to_notes () {
2341 + $to_notes = $this->settings;
2342 +
2343 + unset($to_notes['link/id']); // Magic setting; don't save
2344 + unset($to_notes['link/uri']); // Magic setting; don't save
2345 + unset($to_notes['link/name']); // Magic setting; don't save
2346 + unset($to_notes['hardcode categories']); // Deprecated
2347 + unset($to_notes['unfamiliar categories']); // Deprecated
2348 +
2349 + // Collapse array settings
2350 + if (isset($to_notes['update/processed']) and (is_array($to_notes['update/processed']))) :
2351 + $to_notes['update/processed'] = implode("\n", $to_notes['update/processed']);
2352 + endif;
2353 +
2354 + if (is_array($to_notes['cats'])) :
2355 + $to_notes['cats'] = implode(FEEDWORDPRESS_CAT_SEPARATOR, $to_notes['cats']);
2356 + endif;
2357 + if (is_array($to_notes['tags'])) :
2358 + $to_notes['tags'] = implode(FEEDWORDPRESS_CAT_SEPARATOR, $to_notes['tags']);
2359 + endif;
2360 +
2361 + // Collapse the author mapping rule structure back into a flat string
2362 + if (isset($to_notes['map authors'])) :
2363 + $ma = array();
2364 + foreach ($to_notes['map authors'] as $rule_type => $author_rules) :
2365 + foreach ($author_rules as $author_name => $author_action) :
2366 + $ma[] = $rule_type."\n".$author_name."\n".$author_action;
2367 + endforeach;
2368 + endforeach;
2369 + $to_notes['map authors'] = implode("\n\n", $ma);
2370 + endif;
2371 +
2372 + $notes = '';
2373 + foreach ($to_notes as $key => $value) :
2374 + $notes .= $key . ": ". addcslashes($value, "\0..\37".'\\') . "\n";
2375 + endforeach;
2376 + return $notes;
2377 + } /* SyndicatedLink::settings_to_notes () */
2378 +
3422 2379 function uri () {
3423 2380 return (is_object($this->link) ? $this->link->link_rss : NULL);
3424 - }
2381 + } /* SyndicatedLink::uri () */
2382 +
3425 2383 function homepage () {
3426 2384 return (isset($this->settings['feed/link']) ? $this->settings['feed/link'] : NULL);
3427 - }
2385 + } /* SyndicatedLink::homepage () */
3428 2386
3429 2387 function ttl () {
3430 2388 if (is_object($this->magpie)) :
3431 2389 $channel = $this->magpie->channel;
@@ -3492,9 +2450,9 @@
3492 2450 endif;
3493 2451 endforeach;
3494 2452 endif;
3495 2453 return $ret;
3496 - } // function SyndicatedLink::flatten_array ()
2454 + } /* SyndicatedLink::flatten_array () */
3497 2455
3498 2456 function hardcode ($what) {
3499 2457 $default = get_option("feedwordpress_hardcode_$what");
3500 2458 if ( $default === 'yes' ) :
@@ -3508,9 +2466,9 @@
3508 2466 // setting is explicitly "yes"
3509 2467 $ret = FeedWordPress::affirmative($this->settings, "hardcode $what");
3510 2468 endif;
3511 2469 return $ret;
3512 - } // function SyndicatedLink::hardcode ()
2470 + } /* SyndicatedLink::hardcode () */
3513 2471
3514 2472 function syndicated_status ($what, $default) {
3515 2473 global $wpdb;
3516 2474
@@ -3520,9 +2478,9 @@
3520 2478 elseif (!$ret) :
3521 2479 $ret = $default;
3522 2480 endif;
3523 2481 return $wpdb->escape(trim(strtolower($ret)));
3524 - } // function SyndicatedLink:syndicated_status ()
2482 + } /* SyndicatedLink:syndicated_status () */
3525 2483 } // class SyndicatedLink
3526 2484
3527 2485 ################################################################################
3528 2486 ## XML-RPC HOOKS: accept XML-RPC update pings from Contributors ################
@@ -3557,8 +2515,9 @@
3557 2515
3558 2516 var $verify = FALSE;
3559 2517
3560 2518 var $_data = NULL;
2519 + var $_error = NULL;
3561 2520 var $_head = NULL;
3562 2521
3563 2522 # -- Recognition patterns
3564 2523 var $_feed_types = array(
@@ -3613,8 +2572,12 @@
3613 2572 $this->_get($uri);
3614 2573 return $this->_data;
3615 2574 }
3616 2575
2576 + function error () {
2577 + return $this->_error;
2578 + }
2579 +
3617 2580 function is_feed ($uri = NULL) {
3618 2581 $data = $this->data($uri);
3619 2582
3620 2583 return (
@@ -3633,23 +2596,23 @@
3633 2596 if ($uri) $this->uri = $uri;
3634 2597
3635 2598 // Is the result not yet cached?
3636 2599 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;
2600 + $headers['Connection'] = 'close';
2601 + $headers['Accept'] = 'application/atom+xml application/rdf+xml application/rss+xml application/xml text/html */*';
2602 + $headers['User-Agent'] = 'feedfinder/1.2 (compatible; PHP FeedFinder) +http://projects.radgeek.com/feedwordpress';
3649 2603
3650 - // Kilroy was here
3651 - $this->_cache_uri = $this->uri;
2604 + // Use function provided by MagpieRSS package
2605 + $client = _fetch_remote_file($this->uri, $headers);
2606 + if (isset($client->error)) :
2607 + $this->_error = $client->error;
2608 + else :
2609 + $this->_error = NULL;
2610 + endif;
2611 + $this->_data = $client->results;
2612 +
2613 + // Kilroy was here
2614 + $this->_cache_uri = $this->uri;
3652 2615 endif;
3653 2616 } /* FeedFinder::_get () */
3654 2617
3655 2618 function _link_rel_feeds () {
@@ -3910,5 +2873,5 @@
3910 2873 $ret['name'] = NULL; $ret['email'] = NULL;
3911 2874 endif;
3912 2875 return $ret;
3913 2876 }
3914 -?>
2877 +