PluginProbe
FeedWordPress / 0.991
FeedWordPress v0.991
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 +1634 -971 2009.06120.991 View file →
@@ -2,12 +2,13 @@
2 2 /*
3 3 Plugin Name: FeedWordPress
4 4 Plugin URI: http://projects.radgeek.com/feedwordpress
5 5 Description: simple and flexible Atom/RSS syndication for WordPress
6 -Version: 2009.0612
6 +Version: 0.991
7 7 Author: Charles Johnson
8 8 Author URI: http://radgeek.com/
9 9 License: GPL
10 +Last modified: 2007-09-25 12:48 PDT
10 11 */
11 12
12 13 # This uses code derived from:
13 14 # - wp-rss-aggregate.php by Kellan Elliot-McCrea <kellan@protest.net>
@@ -14,30 +15,24 @@
14 15 # - HTTP Navigator 2 by Keyvan Minoukadeh <keyvan@k1m.com>
15 16 # - Ultra-Liberal Feed Finder by Mark Pilgrim <mark@diveintomark.org>
16 17 # according to the terms of the GNU General Public License.
17 18 #
18 -# INSTALLATION: see readme.txt or <http://projects.radgeek.com/install>
19 +# INSTALLATION: see README.text or <http://projects.radgeek.com/install>
19 20 #
20 21 # USAGE: once FeedWordPress is installed, you manage just about everything from
21 -# the WordPress Dashboard, under the Syndication menu. To ensure that fresh
22 -# content is added as it becomes available, you can convince your contributors
23 -# to put your XML-RPC URI (if WordPress is installed at
22 +# the WordPress Dashboard, under Options --> Syndication or Links --> Syndicated
23 +# To ensure that fresh content is added as it becomes available, get your
24 +# contributors to put your XML-RPC URI (if WordPress is installed at
24 25 # <http://www.zyx.com/blog>, XML-RPC requests should be sent to
25 -# <http://www.zyx.com/blog/xmlrpc.php>), or update manually under the
26 -# Syndication menu, or set up automatic updates under Syndication --> Settings,
27 -# or use a cron job.
26 +# <http://www.zyx.com/blog/xmlrpc.php>), or see `update-feeds.php`
28 27
29 28 # -- Don't change these unless you know what you're doing...
30 29
31 -define ('FEEDWORDPRESS_VERSION', '2009.0612');
30 +define ('FEEDWORDPRESS_VERSION', '0.991');
32 31 define ('FEEDWORDPRESS_AUTHOR_CONTACT', 'http://radgeek.com/contact');
33 32 define ('DEFAULT_SYNDICATION_CATEGORY', 'Contributors');
34 33
35 -$feedwordpress_debug = get_option('feedwordpress_debug');
36 -if (is_string($feedwordpress_debug)) :
37 - $feedwordpress_debug = ($feedwordpress_debug == 'yes');
38 -endif;
39 -define ('FEEDWORDPRESS_DEBUG', $feedwordpress_debug);
34 +define ('FEEDWORDPRESS_DEBUG', false);
40 35
41 36 define ('FEEDWORDPRESS_CAT_SEPARATOR_PATTERN', '/[:\n]/');
42 37 define ('FEEDWORDPRESS_CAT_SEPARATOR', "\n");
43 38
@@ -44,15 +39,11 @@
44 39 define ('FEEDVALIDATOR_URI', 'http://feedvalidator.org/check.cgi');
45 40
46 41 define ('FEEDWORDPRESS_FRESHNESS_INTERVAL', 10*60); // Every ten minutes
47 42
48 -define ('FWP_SCHEMA_HAS_USERMETA', 2966);
49 43 define ('FWP_SCHEMA_20', 3308); // Database schema # for WP 2.0
50 44 define ('FWP_SCHEMA_21', 4772); // Database schema # for WP 2.1
51 45 define ('FWP_SCHEMA_23', 5495); // Database schema # for WP 2.3
52 -define ('FWP_SCHEMA_25', 7558); // Database schema # for WP 2.5
53 -define ('FWP_SCHEMA_26', 8201); // Database schema # for WP 2.6
54 -define ('FWP_SCHEMA_27', 9872); // Database schema # for WP 2.7
55 46
56 47 if (FEEDWORDPRESS_DEBUG) :
57 48 // Help us to pick out errors, if any.
58 49 ini_set('error_reporting', E_ALL & ~E_NOTICE);
@@ -90,10 +81,11 @@
90 81 require_once (ABSPATH . 'wp-admin/admin-db.php'); // for wp_insert_category
91 82 endif;
92 83 endif;
93 84
94 -require_once(dirname(__FILE__) . '/compatability.php'); // LEGACY API: Replicate or mock up functions for legacy support purposes
95 -require_once(dirname(__FILE__) . '/feedwordpresshtml.class.php');
85 +if (function_exists('wp_enqueue_script')) :
86 + wp_enqueue_script( 'ajaxcat' ); // Provides the handy-dandy new category text box
87 +endif;
96 88
97 89 // Magic quotes are just about the stupidest thing ever.
98 90 if (is_array($_POST)) :
99 91 $fwp_post = stripslashes_deep($_POST);
@@ -98,45 +90,9 @@
98 90 if (is_array($_POST)) :
99 91 $fwp_post = stripslashes_deep($_POST);
100 92 endif;
101 93
102 -// Get the path relative to the plugins directory in which FWP is stored
103 -preg_match (
104 - '|/wp-content/plugins/(.+)$|',
105 - dirname(__FILE__),
106 - $ref
107 -);
108 94
109 -if (isset($ref[1])) :
110 - $fwp_path = $ref[1];
111 -else : // Something went wrong. Let's just guess.
112 - $fwp_path = 'feedwordpress';
113 -endif;
114 -
115 -// If this is a FeedWordPress admin page, queue up scripts for AJAX functions that FWP uses
116 -// If it is a display page or a non-FeedWordPress admin page, don't.
117 -if (is_admin() and isset($_REQUEST['page']) and preg_match("|^{$fwp_path}/|", $_REQUEST['page'])) :
118 - if (function_exists('wp_enqueue_script')) :
119 - if (isset($wp_db_version) and $wp_db_version >= FWP_SCHEMA_25) :
120 - wp_enqueue_script('post'); // for magic tag and category boxes
121 - wp_enqueue_script('thickbox'); // for fold-up boxes
122 - wp_enqueue_script('admin-forms'); // for checkbox selection
123 - else :
124 - wp_enqueue_script( 'ajaxcat' ); // Provides the handy-dandy new category text box
125 - endif;
126 - endif;
127 - if (function_exists('wp_enqueue_style')) :
128 - if (fwp_test_wp_version(FWP_SCHEMA_25)) :
129 - wp_enqueue_style('dashboard');
130 - endif;
131 - endif;
132 - if (function_exists('wp_admin_css')) :
133 - if (fwp_test_wp_version(FWP_SCHEMA_25)) :
134 - wp_admin_css('css/dashboard');
135 - endif;
136 - endif;
137 -endif;
138 -
139 95 if (!FeedWordPress::needs_upgrade()) : // only work if the conditions are safe!
140 96
141 97 # Syndicated items are generally received in output-ready (X)HTML and
142 98 # should not be folded, crumpled, mutilated, or spindled by WordPress
@@ -153,25 +109,14 @@
153 109
154 110 add_filter('the_content', 'feedwordpress_preserve_syndicated_content', -10000);
155 111 add_filter('the_content', 'feedwordpress_restore_syndicated_content', 10000);
156 112
157 - add_action('atom_entry', 'feedwordpress_item_feed_data');
158 -
159 113 # Filter in original permalinks if the user wants that
160 114 add_filter('post_link', 'syndication_permalink', 1);
161 -
162 - # WTF? By default, wp_insert_link runs incoming link_url and link_rss
163 - # URIs through default filters that include `wp_kses()`. But `wp_kses()`
164 - # just happens to escape any occurrence of & to &amp; -- which just
165 - # happens to fuck up any URI with a & to separate GET parameters.
166 - remove_filter('pre_link_rss', 'wp_filter_kses');
167 - remove_filter('pre_link_url', 'wp_filter_kses');
168 115
169 116 # Admin menu
170 117 add_action('admin_menu', 'fwp_add_pages');
171 - add_action('admin_notices', 'fwp_check_debug');
172 - add_action('admin_notices', 'fwp_check_magpie');
173 -
118 +
174 119 # Inbound XML-RPC update methods
175 120 add_filter('xmlrpc_methods', 'feedwordpress_xmlrpc_hook');
176 121
177 122 # Outbound XML-RPC ping reform
@@ -195,44 +140,13 @@
195 140 endif;
196 141
197 142 # Cron-less auto-update. Hooray!
198 143 add_action('init', 'feedwordpress_auto_update');
199 - add_action('init', 'feedwordpress_check_for_magpie_fix');
200 -
201 - # Default sanitizers
202 - add_filter('syndicated_item_content', array('SyndicatedPost', 'resolve_relative_uris'), 0, 2);
203 - add_filter('syndicated_item_content', array('SyndicatedPost', 'sanitize_content'), 0, 2);
204 -
205 144 else :
206 145 # Hook in the menus, which will just point to the upgrade interface
207 146 add_action('admin_menu', 'fwp_add_pages');
208 147 endif; // if (!FeedWordPress::needs_upgrade())
209 148
210 -function feedwordpress_check_for_magpie_fix () {
211 - if (isset($_POST['action']) and $_POST['action']=='fix_magpie_version') :
212 - FeedWordPressCompatibility::validate_http_request(/*action=*/ 'feedwordpress_fix_magpie', /*capability=*/ 'edit_files');
213 -
214 - $back_to = $_SERVER['REQUEST_URI'];
215 - if (isset($_POST['ignore'])) :
216 - // kill error message by telling it to expect whatever we've got
217 - update_option('feedwordpress_expected_magpie', FeedWordPress::magpie_version());
218 - $ret = 'ignored';
219 - elseif (isset($_POST['upgrade'])) :
220 - $source = dirname(__FILE__)."/MagpieRSS-upgrade/rss.php";
221 - $destination = ABSPATH . WPINC . '/rss.php';
222 - $success = @copy($source, $destination);
223 - $ret = (int) $success;
224 - endif;
225 -
226 - if (strpos($back_to, '?')===false) : $sep = '?';
227 - else : $sep = '&';
228 - endif;
229 -
230 - header("Location: {$back_to}{$sep}feedwordpress_magpie_fix=".$ret);
231 - exit;
232 - endif;
233 -} /* feedwordpress_check_for_magpie_fix() */
234 -
235 149 function feedwordpress_auto_update () {
236 150 if (FeedWordPress::stale()) :
237 151 $feedwordpress =& new FeedWordPress;
238 152 $feedwordpress->update();
@@ -280,85 +194,60 @@
280 194 : implode(' and ', $mesg)));
281 195 }
282 196
283 197 ################################################################################
284 -## TEMPLATE API: functions to make your templates syndication-aware ############
198 +## LEGACY API: Replicate or mock up functions for legacy support purposes ######
285 199 ################################################################################
286 200
287 -function is_syndicated () { return (strlen(get_syndication_feed_id()) > 0); }
201 +if (!function_exists('get_option')) {
202 + function get_option ($option) {
203 + return get_settings($option);
204 + }
205 +}
206 +if (!function_exists('current_user_can')) {
207 + $legacy_capability_hack = true;
208 + function current_user_can ($task) {
209 + global $user_level;
288 210
289 -function get_syndication_source_link ($original = NULL) {
290 - if (is_null($original)) : $original = FeedWordPress::use_aggregator_source_data();
291 - endif;
211 + $can = false;
292 212
293 - if ($original) : $vals = get_post_custom_values('syndication_source_uri_original');
294 - else : $vals = array();
295 - endif;
296 -
297 - if (count($vals) == 0) : $vals = get_post_custom_values('syndication_source_uri');
298 - endif;
299 -
300 - if (count($vals) > 0) : $ret = $vals[0]; else : $ret = NULL; endif;
213 + // This is **not** a full replacement for current_user_can. It
214 + // is only for checking the capabilities we care about via the
215 + // WordPress 1.5 user levels.
216 + switch ($task) {
217 + case 'manage_options':
218 + $can = ($user_level >= 6);
219 + break;
220 + case 'manage_links':
221 + $can = ($user_level >= 5);
222 + break;
223 + } /* switch */
224 + return $can;
225 + }
226 +} else {
227 + $legacy_capability_hack = false;
228 +}
229 +if (!function_exists('sanitize_user')) {
230 + function sanitize_user ($text, $strict) {
231 + return $text; // Don't munge it if it wasn't munged going in...
232 + }
233 +}
301 234
302 - return $ret;
303 -} /* function get_syndication_source_link() */
235 +################################################################################
236 +## TEMPLATE API: functions to make your templates syndication-aware ############
237 +################################################################################
304 238
305 -function the_syndication_source_link ($original = NULL) { echo get_syndication_source_link($original); }
239 +function is_syndicated () { return (strlen(get_syndication_feed_id()) > 0); }
306 240
307 -function get_syndication_source ($original = NULL) {
308 - if (is_null($original)) : $original = FeedWordPress::use_aggregator_source_data();
309 - endif;
241 +function the_syndication_source_link () { echo get_syndication_source_link(); }
242 +function get_syndication_source_link () { list($n) = get_post_custom_values('syndication_source_uri'); return $n; }
310 243
311 - if ($original) : $vals = get_post_custom_values('syndication_source_original');
312 - else : $vals = array();
313 - endif;
314 -
315 - if (count($vals) == 0) : $vals = get_post_custom_values('syndication_source');
316 - endif;
317 -
318 - if (count($vals) > 0) : $ret = $vals[0]; else : $ret = NULL; endif;
244 +function get_syndication_source () { list($n) = get_post_custom_values('syndication_source'); return $n; }
245 +function the_syndication_source () { echo get_syndication_source(); }
319 246
320 - return $ret;
321 -} /* function get_syndication_source() */
247 +function get_syndication_feed () { list($u) = get_post_custom_values('syndication_feed'); return $u; }
248 +function the_syndication_feed () { echo get_syndication_feed (); }
322 249
323 -function the_syndication_source ($original = NULL) { echo get_syndication_source($original); }
324 -
325 -function get_syndication_feed ($original = NULL) {
326 - if (is_null($original)) : $original = FeedWordPress::use_aggregator_source_data();
327 - endif;
328 -
329 - if ($original) : $vals = get_post_custom_values('syndication_feed_original');
330 - else : $vals = array();
331 - endif;
332 -
333 - if (count($vals) == 0) : $vals = get_post_custom_values('syndication_feed');
334 - endif;
335 -
336 - if (count($vals) > 0) : $ret = $vals[0]; else : $ret = NULL; endif;
337 -
338 - return $ret;
339 -} /* function get_syndication_feed() */
340 -
341 -function the_syndication_feed ($original = NULL) { echo get_syndication_feed ($original); }
342 -
343 -function get_syndication_feed_guid ($original = NULL) {
344 - if (is_null($original)) : $original = FeedWordPress::use_aggregator_source_data();
345 - endif;
346 -
347 - if ($original) : $vals = get_post_custom_values('syndication_source_id_original');
348 - else : $vals = array();
349 - endif;
350 -
351 - if (count($vals) == 0) : $vals = array(get_feed_meta('feed/id'));
352 - endif;
353 -
354 - if (count($vals) > 0) : $ret = $vals[0]; else : $ret = NULL; endif;
355 -
356 - return $ret;
357 -} /* function get_syndication_feed_guid () */
358 -
359 -function the_syndication_feed_guid ($original = NULL) { echo get_syndication_feed_guid($original); }
360 -
361 250 function get_syndication_feed_id () { list($u) = get_post_custom_values('syndication_feed_id'); return $u; }
362 251 function the_syndication_feed_id () { echo get_syndication_feed_id(); }
363 252
364 253 $feedwordpress_linkcache = array (); // only load links from database once
@@ -396,13 +285,9 @@
396 285
397 286 function feedwordpress_preserve_syndicated_content ($text) {
398 287 global $feedwordpress_the_syndicated_content;
399 288
400 - $globalExpose = (get_option('feedwordpress_formatting_filters') == 'yes');
401 - $localExpose = get_post_custom_values('_feedwordpress_formatting_filters');
402 - $expose = ($globalExpose or ((count($localExpose) > 0) and $localExpose[0]));
403 -
404 - if ( is_syndicated() and !$expose ) :
289 + if ( is_syndicated() ) :
405 290 $feedwordpress_the_syndicated_content = $text;
406 291 else :
407 292 $feedwordpress_the_syndicated_content = NULL;
408 293 endif;
@@ -418,34 +303,8 @@
418 303
419 304 return $text;
420 305 }
421 306
422 -function feedwordpress_item_feed_data () {
423 - // In a post context....
424 - if (is_syndicated()) :
425 -?>
426 -<source>
427 - <title><?php the_syndication_source(); ?></title>
428 - <link rel="alternate" type="text/html" href="<?php the_syndication_source_link(); ?>" />
429 - <link rel="self" href="<?php the_syndication_feed(); ?>" />
430 -<?php
431 - $id = get_syndication_feed_guid();
432 - if (strlen($id) > 0) :
433 -?>
434 - <id><?php print $id; ?></id>
435 -<?php
436 - endif;
437 - $updated = get_feed_meta('feed/updated');
438 - if (strlen($updated) > 0) : ?>
439 - <updated><?php print $updated; ?></updated>
440 -<?php
441 - endif;
442 -?>
443 -</source>
444 -<?php
445 - endif;
446 -}
447 -
448 307 function syndication_permalink ($permalink = '') {
449 308 if (get_option('feedwordpress_munge_permalink') != 'no'):
450 309 $uri = get_syndication_permalink();
451 310 return ((strlen($uri) > 0) ? $uri : $permalink);
@@ -454,150 +313,1047 @@
454 313 endif;
455 314 } // function syndication_permalink ()
456 315
457 316 ################################################################################
458 -## ADMIN MENU ADD-ONS: register Dashboard management pages #####################
317 +## UPGRADE INTERFACE: Have users upgrade DB from older versions of FWP #########
459 318 ################################################################################
460 319
320 +function fwp_upgrade_page () {
321 + if (isset($GLOBALS['fwp_post']['action']) and $GLOBALS['fwp_post']['action']=='Upgrade') :
322 + $ver = get_option('feedwordpress_version');
323 + if (get_option('feedwordpress_version') != FEEDWORDPRESS_VERSION) :
324 + echo "<div class=\"wrap\">\n";
325 + echo "<h2>Upgrading FeedWordPress...</h2>";
326 +
327 + $feedwordpress =& new FeedWordPress;
328 + $feedwordpress->upgrade_database();
329 + echo "<p><strong>Done!</strong> Upgraded database to version ".FEEDWORDPRESS_VERSION.".</p>\n";
330 + echo "<form action=\"\" method=\"get\">\n";
331 + echo "<div class=\"submit\"><input type=\"hidden\" name=\"page\" value=\"".basename(__FILE__)."\" />";
332 + echo "<input type=\"submit\" value=\"Continue &raquo;\" /></form></div>\n";
333 + echo "</div>\n";
334 + return;
335 + else :
336 + echo "<div class=\"updated\"><p>Already at version ".FEEDWORDPRESS_VERSION."!</p></div>";
337 + endif;
338 + endif;
339 +?>
340 +<div class="wrap">
341 +<h2>Upgrade FeedWordPress</h2>
342 +
343 +<p>It appears that you have installed FeedWordPress
344 +<?php echo FEEDWORDPRESS_VERSION; ?> as an upgrade to an existing installation of
345 +FeedWordPress. That's no problem, but you will need to take a minute out first
346 +to upgrade your database: some necessary changes in how the software keeps
347 +track of posts and feeds will cause problems such as duplicate posts and broken
348 +templates if we were to continue without the upgrade.</p>
349 +
350 +<p>Note that most of FeedWordPress's functionality is temporarily disabled
351 +until we have successfully completed the upgrade. Everything should begin
352 +working as normal again once the upgrade is complete. There's extraordinarily
353 +little chance of any damage as the result of the upgrade, but if you're paranoid
354 +like me you may want to back up your database before you proceed.</p>
355 +
356 +<p>This may take several minutes for a large installation.</p>
357 +
358 +<form action="" method="post">
359 +<div class="submit"><input type="submit" name="action" value="Upgrade" /></div>
360 +</form>
361 +</div>
362 +<?php
363 +} // function fwp_upgrade_page ()
364 +
365 +################################################################################
366 +## ADMIN MENU ADD-ONS: implement Dashboard management pages ####################
367 +################################################################################
368 +
461 369 function fwp_add_pages () {
462 - global $fwp_capability;
463 - global $fwp_path;
370 + global $legacy_capability_hack;
464 371
465 - $menu = array('Syndicated Sites', 'Syndication', $fwp_capability['manage_links'], $fwp_path.'/syndication.php', NULL);
466 - if (fwp_test_wp_version(FWP_SCHEMA_27)) :
467 - // add icon parameter
468 - $menu[] = WP_PLUGIN_URL.'/'.$fwp_path.'/feedwordpress-tiny.png';
372 + if ($legacy_capability_hack) :
373 + // old & busted: numeric user levels
374 + $manage_links = 5;
375 + $manage_options = 6;
376 + else :
377 + // new hotness: named capabilities
378 + $manage_links = 'manage_links';
379 + $manage_options = 'manage_options';
469 380 endif;
470 381
471 - if (fwp_test_wp_version(FWP_SCHEMA_26)) :
472 - $options = __('Settings');
473 - $longoptions = __('Syndication Settings');
474 - else :
475 - $options = __('Options');
476 - $longoptions = __('Syndication Options');
382 + //add_submenu_page('plugins.php', 'Akismet Configuration', 'Akismet Configuration', 'manage_options', 'syndication-manage-page', 'fwp_syndication_manage_page');
383 + add_menu_page('Syndicated Sites', 'Syndication', $manage_links, 'feedwordpress/'.basename(__FILE__), 'fwp_syndication_manage_page');
384 + add_submenu_page('feedwordpress/'.basename(__FILE__), 'Syndication Options', 'Options', $manage_options, 'feedwordpress/syndication-options.php');
385 + add_options_page('Syndication Options', 'Syndication', $manage_options, 'feedwordpress/syndication-options.php');
386 +} // function fwp_add_pages () */
387 +
388 +function fwp_category_box ($checked, $object) {
389 + global $wp_db_version;
390 +
391 + if (isset($wp_db_version) and $wp_db_version >= FWP_SCHEMA_20) : // WordPress 2.x
392 +?>
393 + <div id="poststuff">
394 +
395 + <div id="moremeta">
396 + <div id="grabit" class="dbx-group">
397 + <fieldset id="categorydiv" class="dbx-box">
398 + <h3 class="dbx-handle"><?php _e('Categories') ?></h3>
399 + <div class="dbx-content">
400 + <p style="font-size:smaller;font-style:bold;margin:0">Place <?php print $object; ?> under...</p>
401 + <p id="jaxcat"></p>
402 + <ul id="categorychecklist"><?php write_nested_categories($checked); ?></ul></div>
403 + </fieldset>
404 + </div>
405 + </div>
406 + </div>
407 +<?php
408 + else : // WordPress 1.5
409 +?>
410 + <fieldset id="categorydiv" style="width: 20%; margin-right: 2em">
411 + <legend><?php _e('Categories') ?></legend>
412 + <p style="font-size:smaller;font-style:bold;margin:0">Place <?php print $object; ?> under...</p>
413 + <div style="height: 20em"><?php write_nested_categories($checked); ?></div>
414 + </fieldset>
415 +<?php
477 416 endif;
417 +}
478 418
479 - call_user_func_array('add_menu_page', $menu);
480 - add_submenu_page($fwp_path.'/syndication.php', 'Syndicated Posts', 'Posts', $fwp_capability['manage_options'], $fwp_path.'/posts-page.php');
481 - add_submenu_page($fwp_path.'/syndication.php', 'Syndicated Authors', 'Authors', $fwp_capability['manage_options'], $fwp_path.'/authors-page.php');
482 - add_submenu_page($fwp_path.'/syndication.php', 'Categories & Tags', 'Categories & Tags', $fwp_capability['manage_options'], $fwp_path.'/categories-page.php');
483 - add_submenu_page($fwp_path.'/syndication.php', $longoptions, $options, $fwp_capability['manage_options'], $fwp_path.'/syndication-options.php');
419 +function update_feeds_mention ($feed) {
420 + echo "<li>Updating <cite>".$feed['link/name']."</cite> from &lt;<a href=\""
421 + .$feed['link/uri']."\">".$feed['link/uri']."</a>&gt; ...</li>\n";
422 + flush();
423 +}
484 424
485 - add_options_page($longoptions, 'Syndication', $fwp_capability['manage_options'], $fwp_path.'/syndication-options.php');
486 -} /* function fwp_add_pages () */
425 +function fwp_syndication_manage_page () {
426 + global $wpdb;
487 427
488 -function fwp_check_debug () {
489 - // This is a horrible fucking kludge that I have to do because the
490 - // admin notice code is triggered before the code that updates the
491 - // setting.
492 - if (isset($_POST['feedwordpress_debug'])) :
493 - $feedwordpress_debug = $_POST['feedwordpress_debug'];
494 - else :
495 - $feedwordpress_debug = get_option('feedwordpress_debug');
428 + if (FeedWordPress::needs_upgrade()) :
429 + fwp_upgrade_page();
430 + return;
496 431 endif;
497 - if ($feedwordpress_debug==='yes') :
432 +
498 433 ?>
499 - <div class="error">
500 -<p><strong>FeedWordPress warning.</strong> Debugging mode is <strong>ON</strong>.
501 -While it remains on, FeedWordPress displays many diagnostic error messages,
502 -warnings, and notices that are ordinarily suppressed, and also turns off all
503 -caching of feeds. Use with caution: this setting is absolutely inappropriate
504 -for a production server.</p>
505 - </div>
434 +<?php $cont = true;
435 +if (isset($_REQUEST['action'])):
436 + if ($_REQUEST['action'] == 'feedfinder') : $cont = fwp_feedfinder_page();
437 + elseif ($_REQUEST['action'] == 'switchfeed') : $cont = fwp_switchfeed_page();
438 + elseif ($_REQUEST['action'] == 'linkedit') : $cont = fwp_linkedit_page();
439 + elseif ($_REQUEST['action'] == 'Unsubscribe from Checked Links' or $_REQUEST['action'] == 'Unsubscribe') : $cont = fwp_multidelete_page();
440 + endif;
441 +endif;
442 +
443 +if ($cont):
444 +?>
506 445 <?php
446 + $links = FeedWordPress::syndicated_links();
447 +
448 + if (isset($_POST['update']) or isset($_POST['action']) or isset($_POST['update_uri'])) :
449 + $fwp_update_invoke = 'post';
450 + else :
451 + $fwp_update_invoke = 'get';
507 452 endif;
508 -} /* function fwp_check_debug () */
509 453
510 -define('DEFAULT_EXPECTED_MAGPIE_VERSION', '0.85');
511 -function fwp_check_magpie () {
512 - if (isset($_REQUEST['feedwordpress_magpie_fix'])) :
513 - if ($_REQUEST['feedwordpress_magpie_fix']=='ignored') :
454 + $update_set = array();
455 + if (isset($_POST['link_ids']) and is_array($_POST['link_ids']) and ($_POST['action']=='Update Checked Links')) :
456 + $targets = $wpdb->get_results("
457 + SELECT * FROM $wpdb->links
458 + WHERE link_id IN (".implode(",",$_POST['link_ids']).")
459 + ");
460 + if (is_array($targets)) :
461 + foreach ($targets as $target) :
462 + $update_set[] = $target->link_rss;
463 + endforeach;
464 + else : // This should never happen
465 + FeedWordPress::critical_bug('fwp_syndication_manage_page::targets', $targets, __LINE__);
466 + endif;
467 + elseif (isset($_POST['update_uri'])) :
468 + $update_set[] = $_POST['update_uri'];
469 + endif;
470 +
471 + if ($fwp_update_invoke != 'get' and count($update_set) > 0) : // Only do things with side-effects for HTTP POST or command line
472 + $feedwordpress =& new FeedWordPress;
473 + add_action('feedwordpress_check_feed', 'update_feeds_mention');
474 +
475 + echo "<div class=\"updated\">\n";
476 + echo "<ul>\n";
477 + $tdelta = NULL;
478 + foreach ($update_set as $uri) :
479 + if ($uri == '*') : $uri = NULL; endif;
480 + $delta = $feedwordpress->update($uri);
481 + if (!is_null($delta)) :
482 + if (is_null($tdelta)) :
483 + $tdelta = $delta;
484 + else :
485 + $tdelta['new'] += $delta['new'];
486 + $tdelta['updated'] += $delta['updated'];
487 + endif;
488 + else :
489 + echo "<li><p><strong>Error:</strong> There was a problem updating <a href=\"$uri\">$uri</a></p></li>\n";
490 + endif;
491 + endforeach;
492 + echo "</ul>\n";
493 +
494 + if (!is_null($tdelta)) :
495 + $mesg = array();
496 + if (isset($delta['new'])) : $mesg[] = ' '.$tdelta['new'].' new posts were syndicated'; endif;
497 + if (isset($delta['updated'])) : $mesg[] = ' '.$tdelta['updated'].' existing posts were updated'; endif;
498 + echo "<p>Update complete.".implode(' and', $mesg)."</p>";
499 + echo "\n"; flush();
500 + endif;
501 + echo "</div> <!-- class=\"updated\" -->\n";
502 + endif;
503 +
504 + ?>
505 + <div class="wrap">
506 + <form action="" method="POST">
507 + <h2>Update feeds now</h2>
508 + <p>Check currently scheduled feeds for new and updated posts.</p>
509 +
510 +<?php if (!get_option('feedwordpress_automatic_updates')) : ?>
511 + <p><strong>Note:</strong> Automatic updates are currently turned
512 + <strong>off</strong>. New posts from your feeds will not be syndicated
513 + until you manually check for them here. You can turn on automatic
514 + updates under <a href="admin.php?page=feedwordpress/syndication-options.php">Syndication
515 + Options</a>.</p>
516 +<?php endif; ?>
517 +
518 +
519 + <div class="submit"><input type="hidden" name="update_uri" value="*" /><input type="submit" name="update" value="Update" /></div>
520 + </form>
521 + </div> <!-- class="wrap" -->
522 +
523 + <form action="admin.php?page=feedwordpress/<?php echo basename(__FILE__); ?>" method="post">
524 + <div class="wrap">
525 + <h2>Syndicated Sites</h2>
526 +<?php $alt_row = true;
527 + if ($links): ?>
528 +
529 +<table width="100%" cellpadding="3" cellspacing="3">
530 +<tr>
531 +<th width="20%"><?php _e('Name'); ?></th>
532 +<th width="40%"><?php _e('Feed'); ?></th>
533 +<th colspan="4"><?php _e('Action'); ?></th>
534 +</tr>
535 +
536 +<?php foreach ($links as $link):
537 + $alt_row = !$alt_row; ?>
538 +<tr<?php echo ($alt_row?' class="alternate"':''); ?>>
539 +<td><a href="<?php echo wp_specialchars($link->link_url, 'both'); ?>"><?php echo wp_specialchars($link->link_name, 'both'); ?></a></td>
540 +<?php
541 + if (strlen($link->link_rss) > 0):
542 + $caption='Switch Feed';
543 + $uri_bits = parse_url($link->link_rss);
544 + $uri_bits['host'] = preg_replace('/^www\./i', '', $uri_bits['host']);
545 + $display_uri =
546 + (isset($uri_bits['user'])?$uri_bits['user'].'@':'')
547 + .(isset($uri_bits['host'])?$uri_bits['host']:'')
548 + .(isset($uri_bits['port'])?':'.$uri_bits['port']:'')
549 + .(isset($uri_bits['path'])?$uri_bits['path']:'')
550 + .(isset($uri_bits['query'])?'?'.$uri_bits['query']:'');
551 + if (strlen($display_uri) > 32) : $display_uri = substr($display_uri, 0, 32).'&#8230;'; endif;
514 552 ?>
515 -<div class="updated fade">
516 -<p>O.K., we'll ignore the problem for now. FeedWordPress will not display any
517 -more error messages.</p>
518 -</div>
553 + <td>
554 + <strong><a href="<?php echo $link->link_rss; ?>"><?php echo wp_specialchars($display_uri, 'both'); ?></a></strong></td>
519 555 <?php
520 - elseif ((bool) $_REQUEST['feedwordpress_magpie_fix']) :
556 + else:
557 + $caption='Find Feed';
521 558 ?>
522 -<div class="updated fade">
523 -<p>Congratulations! Your MagpieRSS has been successfully upgraded to the version
524 -shipped with FeedWordPress.</p>
525 -</div>
559 + <td style="background-color:#FFFFD0"><p><strong>no
560 + feed assigned</strong></p></td>
526 561 <?php
527 - else :
528 - $source = dirname(__FILE__)."/MagpieRSS-upgrade/rss.php";
529 - $destination = ABSPATH . WPINC . '/rss.php';
530 - $cmd = "cp '".htmlspecialchars(addslashes($source))."' '".htmlspecialchars(addslashes($destination))."'";
531 - $cmd = wordwrap($cmd, /*width=*/ 75, /*break=*/ " \\\n\t");
562 + endif;
563 +?>
564 + <td><a href="admin.php?page=feedwordpress/<?php echo basename(__FILE__); ?>&amp;link_id=<?php echo $link->link_id; ?>&amp;action=linkedit" class="edit"><?php _e('Edit')?></a></td>
565 + <td><a href="admin.php?page=feedwordpress/<?php echo basename(__FILE__); ?>&amp;link_id=<?php echo $link->link_id; ?>&amp;action=feedfinder" class="edit"><?php echo $caption; ?></a></td>
566 + <td><a href="admin.php?page=feedwordpress/<?php echo basename(__FILE__); ?>&amp;link_id=<?php echo $link->link_id; ?>&amp;action=Unsubscribe" class="delete"><?php _e('Unsubscribe'); ?></a></td>
567 + <td><input type="checkbox" name="link_ids[]" value="<?php echo $link->link_id; ?>" /></td>
568 +<?php
569 + echo "\n\t</tr>";
570 + endforeach;
571 + else:
572 +?>
532 573
574 +<p>There are no websites currently listed for syndication.</p>
575 +
576 +<?php endif; ?>
577 + </table>
578 +
579 + <br/><hr/>
580 + <div class="submit"><input type="submit" class="delete" name="action" value="Unsubscribe from Checked Links" />
581 + <input type="submit" name="action" value="Update Checked Links" /></div>
582 + </div> <!-- class="wrap" -->
583 + </form>
584 +
585 + <div class="wrap">
586 + <form action="admin.php?page=feedwordpress/<?php echo basename(__FILE__); ?>" method="post">
587 + <h2>Add a new syndicated site:</h2>
588 + <div>
589 + <label for="add-uri">Website or newsfeed:</label>
590 + <input type="text" name="lookup" id="add-uri" value="URI" size="64" />
591 + <input type="hidden" name="action" value="feedfinder" />
592 + </div>
593 + <div class="submit"><input type="submit" value="Syndicate &raquo;" /></div>
594 + </form>
595 + </div> <!-- class="wrap" -->
596 +<?php
597 +endif;
598 +}
599 +
600 +function fwp_feedfinder_page () {
601 + global $wpdb;
602 +
603 + $lookup = (isset($_REQUEST['lookup'])?$_REQUEST['lookup']:NULL);
604 +
605 + if (isset($_REQUEST['link_id']) and ($_REQUEST['link_id']!=0)):
606 + $link_id = $_REQUEST['link_id'];
607 + if (!is_numeric($link_id)) : FeedWordPress::critical_bug('fwp_feedfinder_page::link_id', $link_id, __LINE__); endif;
608 +
609 + $link = $wpdb->get_row("SELECT * FROM $wpdb->links WHERE link_id='".$wpdb->escape($link_id)."'");
610 + if (is_object($link)):
611 + if (is_null($lookup)) $lookup = $link->link_url;
612 + $name = wp_specialchars($link->link_name, 'both');
613 + else:
614 + die (__("Cheatin' uh ?"));
615 + endif;
616 + else:
617 + $name = "New Syndicated Feed";
618 + $link_id = 0;
619 + endif;
533 620 ?>
534 -<div class="error">
535 -<p><strong>FeedWordPress was unable to automatically upgrade your copy of MagpieRSS.</strong></p>
536 -<p>It's likely that you need to change the file permissions on <code><?php print htmlspecialchars($source); ?></code>
537 -to allow FeedWordPress to overwrite it.</p>
538 -<p><strong>To perform the upgrade manually,</strong> you can
539 -use a SFTP or FTP client to upload a copy of <code>rss.php</code> from the
540 -<code>MagpieRSS-upgrades/</code> directory of your FeedWordPress archive so that
541 -it overwrites <code><?php print htmlspecialchars($destination); ?></code>. Or,
542 -if your web host provides shell access, you can issue the following command from
543 -a command prompt to perform the upgrade:</p>
544 -<pre>
545 -<samp>$</samp> <kbd><?php print $cmd; ?></kbd>
546 -</pre>
547 -<p><strong>If you've fixed the file permissions,</strong> you can try the
548 -automatic upgrade again.</p>
621 + <div class="wrap">
622 + <h2>Feed Finder: <?php echo $name; ?></h2>
623 +<?php
624 + $f =& new FeedFinder($lookup);
625 + $feeds = $f->find();
626 + if (count($feeds) > 0):
627 + foreach ($feeds as $key => $f):
628 + $rss = fetch_rss($f);
629 + if ($rss):
630 + $feed_title = isset($rss->channel['title'])?$rss->channel['title']:$rss->channel['link'];
631 + $feed_link = isset($rss->channel['link'])?$rss->channel['link']:'';
632 +?>
633 + <form action="admin.php?page=feedwordpress/<?php echo basename(__FILE__); ?>" method="post">
634 + <fieldset style="clear: both">
635 + <legend><?php echo $rss->feed_type; ?> <?php echo $rss->feed_version; ?> feed</legend>
549 636
550 -<?php feedwordpress_upgrade_old_and_busted_buttons(); ?>
551 -</div>
637 + <?php if ($link_id===0): ?>
638 + <input type="hidden" name="feed_title" value="<?php echo wp_specialchars($feed_title, 'both'); ?>" />
639 + <input type="hidden" name="feed_link" value="<?php echo wp_specialchars($feed_link, 'both'); ?>" />
640 + <?php endif; ?>
641 +
642 + <input type="hidden" name="link_id" value="<?php echo $link_id; ?>" />
643 + <input type="hidden" name="feed" value="<?php echo wp_specialchars($f, 'both'); ?>" />
644 + <input type="hidden" name="action" value="switchfeed" />
645 +
646 + <div>
647 + <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">
648 +<?php if (count($rss->items) > 0): ?>
649 + <?php $item = $rss->items[0]; ?>
650 + <h3>Sample Item</h3>
651 + <ul>
652 + <li><strong>Title:</strong> <a href="<?php echo $item['link']; ?>"><?php echo $item['title']; ?></a></li>
653 + <li><strong>Date:</strong> <?php echo isset($item['date_timestamp']) ? date('d-M-y g:i:s a', $item['date_timestamp']) : 'unknown'; ?></li>
654 + </ul>
655 + <div class="entry">
656 + <?php echo (isset($item['content']['encoded'])?$item['content']['encoded']:$item['description']); ?>
657 + </div>
658 +<?php else: ?>
659 + <h3>No Items</h3>
660 + <p>FeedWordPress found no posts on this feed.</p>
661 +<?php endif; ?>
662 + </div>
663 +
664 + <div>
665 + <h3>Feed Information</h3>
666 + <ul>
667 + <li><strong>Website:</strong> <a href="<?php echo $feed_link; ?>"><?php echo is_null($feed_title)?'<em>Unknown</em>':$feed_title; ?></a></li>
668 + <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); ?>"><img src="../wp-images/smilies/icon_arrow.gif" alt="(&rarr;)" /></a></li>
669 + <li><strong>Encoding:</strong> <?php echo isset($rss->encoding)?wp_specialchars($rss->encoding, 'both'):"<em>Unknown</em>"; ?></li>
670 + <li><strong>Description:</strong> <?php echo isset($rss->channel['description'])?wp_specialchars($rss->channel['description'], 'both'):"<em>Unknown</em>"; ?></li>
671 + </ul>
672 + <div class="submit"><input type="submit" name="Use" value="&laquo; Use this feed" /></div>
673 + <div class="submit"><input type="submit" name="Cancel" value="&laquo; Cancel" /></div>
674 + </div>
675 + </div>
676 + </fieldset>
677 + </form>
678 +<?php endif;
679 + endforeach;
680 + else:
681 + echo "<p><strong>no feed found</strong></p>";
682 + endif;
683 +?>
684 + </div>
685 +
686 + <form action="admin.php?page=feedwordpress/<?php echo basename(__FILE__); ?>" method="post">
687 + <div class="wrap">
688 + <h2>Use another feed</h2>
689 + <div><label>Feed:</label>
690 + <input type="text" name="lookup" value="URI" />
691 + <input type="hidden" name="link_id" value="<?php echo $link_id; ?>" />
692 + <input type="hidden" name="action" value="feedfinder" /></div>
693 + <div class="submit"><input type="submit" value="Use this feed &raquo;" /></div>
694 + </div>
695 + </form>
552 696 <?php
697 + return false; // Don't continue
698 +}
699 +
700 +function fwp_switchfeed_page () {
701 + global $wpdb, $wp_db_version;
702 +
703 + check_admin_referer();
704 + if (!isset($_REQUEST['Cancel'])):
705 + if (!current_user_can('manage_links')):
706 + die (__("Cheatin' uh ?"));
707 + elseif (isset($_REQUEST['link_id']) and ($_REQUEST['link_id']==0)):
708 + $link_id = FeedWordPress::syndicate_link($_REQUEST['feed_title'], $_REQUEST['feed_link'], $_REQUEST['feed']);
709 + if ($link_id): ?>
710 +<div class="updated"><p><a href="<?php echo $_REQUEST['feed_link']; ?>"><?php echo wp_specialchars($_REQUEST['feed_title'], 'both'); ?></a>
711 +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>
712 +<?php else: ?>
713 +<div class="updated"><p>There was a problem adding the newsfeed. [SQL: <?php echo wp_specialchars(mysql_error(), 'both'); ?>]</p></div>
714 +<?php endif;
715 + elseif (isset($_REQUEST['link_id'])):
716 + // Update link_rss
717 + $result = $wpdb->query("
718 + UPDATE $wpdb->links
719 + SET
720 + link_rss = '".$wpdb->escape($_REQUEST['feed'])."'
721 + WHERE link_id = '".$wpdb->escape($_REQUEST['link_id'])."'
722 + ");
723 +
724 + if ($result):
725 + $result = $wpdb->get_row("
726 + SELECT link_name, link_url FROM $wpdb->links
727 + WHERE link_id = '".$wpdb->escape($_REQUEST['link_id'])."'
728 + ");
729 + ?>
730 +<div class="updated"><p>Feed for <a href="<?php echo $result->link_url; ?>"><?php echo wp_specialchars($result->link_name, 'both'); ?></a>
731 +updated to &lt;<a href="<?php echo $_REQUEST['feed']; ?>"><?php echo wp_specialchars($_REQUEST['feed'], 'both'); ?></a>&gt;.</p></div>
732 + <?php else: ?>
733 +<div class="updated"><p>Nothing was changed.</p></div>
734 + <?php endif;
553 735 endif;
736 + endif;
737 + return true; // Continue
738 +}
739 +
740 +function fwp_linkedit_page () {
741 + global $wpdb;
742 +
743 + check_admin_referer(); // Make sure we arrived here from the Dashboard
744 +
745 + $special_settings = array ( /* Regular expression syntax is OK here */
746 + 'cats',
747 + 'cat_split',
748 + 'hardcode name',
749 + 'hardcode url',
750 + 'hardcode description',
751 + 'hardcode categories', /* Deprecated */
752 + 'post status',
753 + 'comment status',
754 + 'ping status',
755 + 'unfamiliar author',
756 + 'unfamliar categories',
757 + 'update/.*',
758 + 'feed/.*',
759 + 'link/.*',
760 + );
761 +
762 + if (!current_user_can('manage_links')) :
763 + die (__("Cheatin' uh ?"));
764 + elseif (isset($_REQUEST['feedfinder'])) :
765 + return fwp_feedfinder_page(); // re-route to Feed Finder page
554 766 else :
555 - $magpie_version = FeedWordPress::magpie_version();
556 -
557 - $exp = get_option('feedwordpress_expected_magpie');
558 - if ($exp) : $expected = array($exp, DEFAULT_EXPECTED_MAGPIE_VERSION);
559 - else : $expected = array(DEFAULT_EXPECTED_MAGPIE_VERSION);
767 + $link_id = (int) $_REQUEST['link_id'];
768 + $link =& new SyndicatedLink($link_id);
769 +
770 + if ($link->found()) :
771 + if (isset($GLOBALS['fwp_post']['save'])) :
772 + $alter = array ();
773 +
774 + $meta = $link->settings;
775 + if (isset($meta['cats'])):
776 + $meta['cats'] = preg_split(FEEDWORDPRESS_CAT_SEPARATOR_PATTERN, $meta['cats']);
777 + endif;
778 +
779 + // custom feed settings first
780 + foreach ($GLOBALS['fwp_post']['notes'] as $mn) :
781 + $mn['key0'] = trim($mn['key0']);
782 + $mn['key1'] = trim($mn['key1']);
783 + if (preg_match("\007^(("
784 + .implode(')|(',$special_settings)
785 + ."))$\007i",
786 + $mn['key1'])) :
787 + $mn['key1'] = 'user/'.$mn['key1'];
788 + endif;
789 +
790 + if (strlen($mn['key0']) > 0) :
791 + unset($meta[$mn['key0']]); // out with the old
792 + endif;
793 +
794 + if (($mn['action']=='update') and (strlen($mn['key1']) > 0)) :
795 + $meta[$mn['key1']] = $mn['value']; // in with the new
796 + endif;
797 + endforeach;
798 +
799 + // now stuff through the web form
800 + // hardcoded feed info
801 + if (isset($GLOBALS['fwp_post']['hardcode_name'])) :
802 + $meta['hardcode name'] = $GLOBALS['fwp_post']['hardcode_name'];
803 + if (FeedWordPress::affirmative($meta, 'hardcode name')) :
804 + $alter[] = "link_name = '".$wpdb->escape($GLOBALS['fwp_post']['name'])."'";
805 + endif;
806 + endif;
807 + if (isset($GLOBALS['fwp_post']['hardcode_description'])) :
808 + $meta['hardcode description'] = $GLOBALS['fwp_post']['hardcode_description'];
809 + if (FeedWordPress::affirmative($meta, 'hardcode description')) :
810 + $alter[] = "link_description = '".$wpdb->escape($GLOBALS['fwp_post']['description'])."'";
811 + endif;
812 + endif;
813 + if (isset($GLOBALS['fwp_post']['hardcode_url'])) :
814 + $meta['hardcode url'] = $GLOBALS['fwp_post']['hardcode_url'];
815 + if (FeedWordPress::affirmative($meta, 'hardcode url')) :
816 + $alter[] = "link_url = '".$wpdb->escape($GLOBALS['fwp_post']['linkurl'])."'";
817 + endif;
818 + endif;
819 +
820 + // Update scheduling
821 + if (isset($GLOBALS['fwp_post']['update_schedule'])) :
822 + $meta['update/hold'] = $GLOBALS['fwp_post']['update_schedule'];
823 + endif;
824 +
825 + // Categories
826 + if (isset($GLOBALS['fwp_post']['post_category'])) :
827 + $meta['cats'] = array();
828 + foreach ($GLOBALS['fwp_post']['post_category'] as $cat_id) :
829 + $meta['cats'][] = '{#'.$cat_id.'}';
830 + endforeach;
831 + else :
832 + unset($meta['cats']);
833 + endif;
834 +
835 + // Post status, comment status, ping status
836 + foreach (array('post', 'comment', 'ping') as $what) :
837 + $sfield = "feed_{$what}_status";
838 + if (isset($GLOBALS['fwp_post'][$sfield])) :
839 + if ($GLOBALS['fwp_post'][$sfield]=='site-default') :
840 + unset($meta["{$what} status"]);
841 + else :
842 + $meta["{$what} status"] = $GLOBALS['fwp_post'][$sfield];
843 + endif;
844 + endif;
845 + endforeach;
846 +
847 + // Unfamiliar author, unfamiliar categories
848 + foreach (array("author", "category") as $what) :
849 + $sfield = "unfamiliar_{$what}";
850 + if (isset($GLOBALS['fwp_post'][$sfield])) :
851 + if ($GLOBALS['fwp_post'][$sfield]=='site-default') :
852 + unset($meta["unfamiliar {$what}"]);
853 + else :
854 + $meta["unfamiliar {$what}"] = $GLOBALS['fwp_post'][$sfield];
855 + endif;
856 + endif;
857 + endforeach;
858 +
859 + if (isset($GLOBALS['fwp_post']['cat_split'])) :
860 + if (strlen(trim($GLOBALS['fwp_post']['cat_split'])) > 0) :
861 + $meta['cat_split'] = trim($GLOBALS['fwp_post']['cat_split']);
862 + else :
863 + unset($meta['cat_split']);
864 + endif;
865 + endif;
866 +
867 + if (is_array($meta['cats'])) :
868 + $meta['cats'] = implode(FEEDWORDPRESS_CAT_SEPARATOR, $meta['cats']);
869 + endif;
870 +
871 + $notes = '';
872 + foreach ($meta as $key => $value) :
873 + $notes .= $key . ": ". addcslashes($value, "\0..\37".'\\') . "\n";
874 + endforeach;
875 + $alter[] = "link_notes = '".$wpdb->escape($notes)."'";
876 +
877 + $alter_set = implode(", ", $alter);
878 +
879 + // issue update query
880 + $result = $wpdb->query("
881 + UPDATE $wpdb->links
882 + SET $alter_set
883 + WHERE link_id='$link_id'
884 + ");
885 + $updated_link = true;
886 +
887 + // reload link information from DB
888 + $link =& new SyndicatedLink($link_id);
889 + else :
890 + $updated_link = false;
891 + endif;
892 +
893 + $db_link = $link->link;
894 + $link_url = wp_specialchars($db_link->link_url, 1);
895 + $link_name = wp_specialchars($db_link->link_name, 1);
896 + $link_description = wp_specialchars($db_link->link_description, 'both');
897 + $link_notes = wp_specialchars($db_link->link_notes, 'both');
898 + $link_rss_uri = wp_specialchars($db_link->link_rss, 'both');
899 +
900 + $meta = $link->settings;
901 + $post_status_global = get_option('feedwordpress_syndicated_post_status');
902 + $comment_status_global = get_option('feedwordpress_syndicated_comment_status');
903 + $ping_status_global = get_option('feedwordpress_syndicated_ping_status');
904 +
905 + $status['post'] = array('publish' => '', 'private' => '', 'draft' => '', 'site-default' => '');
906 + $status['comment'] = array('open' => '', 'closed' => '', 'site-default' => '');
907 + $status['ping'] = array('open' => '', 'closed' => '', 'site-default' => '');
908 +
909 + foreach (array('post', 'comment', 'ping') as $what) :
910 + if (isset($meta["{$what} status"])) :
911 + $status[$what][$meta["{$what} status"]] = ' checked="checked"';
912 + else :
913 + $status[$what]['site-default'] = ' checked="checked"';
914 + endif;
915 + endforeach;
916 +
917 + $unfamiliar['author'] = array ('create' => '','default' => '','filter' => '');
918 + $unfamiliar['category'] = array ('create'=>'','default'=>'','filter'=>'');
919 +
920 + foreach (array('author', 'category') as $what) :
921 + if (is_string($meta["unfamiliar {$what}"]) and
922 + array_key_exists($meta["unfamiliar {$what}"], $unfamiliar[$what])) :
923 + $key = $meta["unfamiliar {$what}"];
924 + else:
925 + $key = 'site-default';
926 + endif;
927 + $unfamiliar[$what][$key] = ' checked="checked"';
928 + endforeach;
929 +
930 + $dogs = get_nested_categories(-1, 0);
931 + if (is_array($meta['cats'])) :
932 + $cats = array_map('strtolower',
933 + array_map('trim',
934 + $meta['cats']
935 + ));
936 + else:
937 + $cats = array();
938 + endif;
939 +
940 + foreach ($dogs as $tag => $dog) :
941 + $found_by_name = in_array(strtolower(trim($dog['cat_name'])), $cats);
942 +
943 + if (isset($dog['cat_ID'])) : $dog['cat_id'] = $dog['cat_ID']; endif;
944 + $found_by_id = in_array('{#'.trim($dog['cat_id']).'}', $cats);
945 +
946 + if ($found_by_name or $found_by_id) :
947 + $dogs[$tag]['checked'] = true;
948 + endif;
949 + endforeach;
950 + else :
951 + die( __('Link not found.') );
560 952 endif;
561 953
562 - if (in_array($magpie_version, $expected)) :
563 - if ($magpie_version != $exp) :
564 - update_option('feedwordpress_expected_magpie', $magpie_version);
954 + ?>
955 +<script type="text/javascript">
956 + function flip_hardcode (item) {
957 + ed=document.getElementById('basics-'+item+'-edit');
958 + view=document.getElementById('basics-'+item+'-view');
959 +
960 + o = document.getElementById('basics-hardcode-'+item);
961 + if (o.value=='yes') { ed.style.display='inline'; view.style.display='none'; }
962 + else { ed.style.display='none'; view.style.display='inline'; }
963 + }
964 +</script>
965 +
966 +<?php if ($updated_link) : ?>
967 +<div class="updated"><p>Syndicated feed settings updated.</p></div>
968 +<?php endif; ?>
969 +
970 +<form action="admin.php?page=feedwordpress/<?php echo basename(__FILE__); ?>" method="post">
971 +<div class="wrap">
972 +<input type="hidden" name="link_id" value="<?php echo $link_id; ?>" />
973 +<input type="hidden" name="action" value="linkedit" />
974 +<input type="hidden" name="save" value="link" />
975 +
976 +<h2>Edit a syndicated feed:</h2>
977 +<fieldset><legend>Basics</legend>
978 +<table class="editform" width="100%" cellspacing="2" cellpadding="5">
979 +<tr>
980 +<th scope="row" width="20%"><?php _e('Feed URI:') ?></th>
981 +<td width="60%"><a href="<?php echo wp_specialchars($link_rss_uri, 'both'); ?>"><?php echo $link_rss_uri; ?></a>
982 +<a href="<?php echo FEEDVALIDATOR_URI; ?>?url=<?php echo urlencode($link_rss_uri); ?>"
983 +title="Check feed &lt;<?php echo wp_specialchars($link_rss_uri, 'both'); ?>&gt; for validity"><img src="../wp-images/smilies/icon_arrow.gif" alt="&rarr;" /></a>
984 +</td>
985 +<td width="20%"><input type="submit" name="feedfinder" value="switch &rarr;" style="font-size:smaller" /></td>
986 +</tr>
987 +<tr>
988 +<th scope="row" width="20%"><?php _e('Link Name:') ?></th>
989 +<td width="60%"><input type="text" id="basics-name-edit" name="name"
990 +value="<?php echo $link_name; ?>" style="width: 95%" />
991 +<span id="basics-name-view"><strong><?php echo $link_name; ?></strong></span>
992 +</td>
993 +<td>
994 +<select id="basics-hardcode-name" onchange="flip_hardcode('name')" name="hardcode_name">
995 +<option value="no" <?php echo $link->hardcode('name')?'':'selected="selected"'; ?>>update automatically</option>
996 +<option value="yes" <?php echo $link->hardcode('name')?'selected="selected"':''; ?>>edit manually</option>
997 +</select>
998 +</td>
999 +</tr>
1000 +<tr>
1001 +<th scope="row" width="20%"><?php _e('Short description:') ?></th>
1002 +<td width="60%">
1003 +<input id="basics-description-edit" type="text" name="description" value="<?php echo $link_description; ?>" style="width: 95%" />
1004 +<span id="basics-description-view"><strong><?php echo $link_description; ?></strong></span>
1005 +</td>
1006 +<td>
1007 +<select id="basics-hardcode-description" onchange="flip_hardcode('description')"
1008 +name="hardcode_description">
1009 +<option value="no" <?php echo $link->hardcode('description')?'':'selected="selected"'; ?>>update automatically</option>
1010 +<option value="yes" <?php echo $link->hardcode('description')?'selected="selected"':''; ?>>edit manually</option>
1011 +</select></td>
1012 +</tr>
1013 +<tr>
1014 +<th width="20%" scope="row"><?php _e('Homepage:') ?></th>
1015 +<td width="60%">
1016 +<input id="basics-url-edit" type="text" name="linkurl" value="<?php echo $link_url; ?>" style="width: 95%;" />
1017 +<a id="basics-url-view" href="<?php echo $link_url; ?>"><?php echo $link_url; ?></a></td>
1018 +<td>
1019 +<select id="basics-hardcode-url" onchange="flip_hardcode('url')" name="hardcode_url">
1020 +<option value="no"<?php echo $link->hardcode('url')?'':' selected="selected"'; ?>>update automatically</option>
1021 +<option value="yes"<?php echo $link->hardcode('url')?' selected="selected"':''; ?>>edit manually</option>
1022 +</select></td></tr>
1023 +
1024 +<tr>
1025 +<th width="20%"><?php _e('Last update') ?>:</th>
1026 +<td colspan="2"><?php
1027 + if (isset($meta['update/last'])) :
1028 + echo strftime('%x %X', $meta['update/last'])." ";
1029 + else :
1030 + echo " none yet";
1031 + endif;
1032 +?></td></tr>
1033 +<tr><th width="20%">Next update:</th>
1034 +<td colspan="2"><?php
1035 + $holdem = (isset($meta['update/hold']) ? $meta['update/hold'] : 'scheduled');
1036 +?>
1037 +<select name="update_schedule">
1038 +<option value="scheduled"<?php echo ($holdem=='scheduled')?' selected="selected"':''; ?>>update on schedule <?php
1039 + echo " (";
1040 + if (isset($meta['update/ttl']) and is_numeric($meta['update/ttl'])) :
1041 + if (isset($meta['update/timed']) and $meta['update/timed']=='automatically') :
1042 + echo 'next: ';
1043 + $next = $meta['update/last'] + ((int) $meta['update/ttl'] * 60);
1044 + if (strftime('%x', time()) != strftime('%x', $next)) :
1045 + echo strftime('%x', $next)." ";
565 1046 endif;
1047 + echo strftime('%X', $meta['update/last']+((int) $meta['update/ttl']*60));
566 1048 else :
567 - if (current_user_can('edit_files')) :
568 - $youAre = 'you are';
569 - $itIsRecommendedThatYou = 'It is <strong>strongly recommended</strong> that you';
570 - else :
571 - $youAre = 'this site is';
572 - $itIsRecommendedThatYou = 'You may want to contact the administrator of the site; it is <strong>strongly recommended</strong> that they';
573 - endif;
574 - print '<div class="error">';
1049 + echo "every ".$meta['update/ttl']." minute".(($meta['update/ttl']!=1)?"s":"");
1050 + endif;
1051 + else:
1052 + echo "next scheduled update";
1053 + endif;
1054 + echo ")";
1055 +?></option>
1056 +<option value="next"<?php echo ($holdem=='next')?' selected="selected"':''; ?>>update ASAP</option>
1057 +<option value="ping"<?php echo ($holdem=='ping')?' selected="selected"':''; ?>>update only when pinged</option>
1058 +</select></tr>
1059 +</table>
1060 +</fieldset>
1061 +
1062 +<script type="text/javascript">
1063 +flip_hardcode('name');
1064 +flip_hardcode('description');
1065 +flip_hardcode('url');
1066 +</script>
1067 +
1068 +<p class="submit">
1069 +<input type="submit" name="submit" value="<?php _e('Save Changes &raquo;') ?>" />
1070 +</p>
1071 +
1072 +<fieldset>
1073 +<legend>Syndicated Posts</legend>
1074 +
1075 +<?php fwp_category_box($dogs, 'all syndicated posts from this feed'); ?>
1076 +
1077 +<table class="editform" width="75%" cellspacing="2" cellpadding="5">
1078 +<tr><th width="27%" scope="row" style="vertical-align:top">Publication:</th>
1079 +<td width="73%" style="vertical-align:top"><ul style="margin:0; list-style:none">
1080 +<li><label><input type="radio" name="feed_post_status" value="site-default"
1081 +<?php echo $status['post']['site-default']; ?> /> Use site-wide setting from <a href="admin.php?page=feedwordpress/syndication-options.php">Syndication Options</a>
1082 +(currently: <strong><?php echo ($post_status_global ? $post_status_global : 'publish'); ?></strong>)</label></li>
1083 +<li><label><input type="radio" name="feed_post_status" value="publish"
1084 +<?php echo $status['post']['publish']; ?> /> Publish posts from this feed immediately</label></li>
1085 +<li><label><input type="radio" name="feed_post_status" value="private"
1086 +<?php echo $status['post']['private']; ?> /> Hold posts from this feed as private posts</label></li>
1087 +<li><label><input type="radio" name="feed_post_status" value="draft"
1088 +<?php echo $status['post']['draft']; ?> /> Hold posts from this feed as drafts</label></li>
1089 +</ul></td>
1090 +</tr>
1091 +
1092 +<tr><th width="27%" scope="row" style="vertical-align:top">Comments:</th>
1093 +<td width="73%"><ul style="margin:0; list-style:none">
1094 +<li><label><input type="radio" name="feed_comment_status" value="site-default"
1095 +<?php echo $status['comment']['site-default']; ?> /> Use site-wide setting from <a href="admin.php?page=feedwordpress/syndication-options.php">Syndication Options</a>
1096 +(currently: <strong><?php echo ($comment_status_global ? $comment_status_global : 'closed'); ?>)</strong></label></li>
1097 +<li><label><input type="radio" name="feed_comment_status" value="open"
1098 +<?php echo $status['comment']['open']; ?> /> Allow comments on syndicated posts from this feed</label></li>
1099 +<li><label><input type="radio" name="feed_comment_status" value="closed"
1100 +<?php echo $status['comment']['closed']; ?> /> Don't allow comments on syndicated posts from this feed</label></li>
1101 +</ul></td>
1102 +</tr>
1103 +
1104 +<tr><th width="27%" scope="row" style="vertical-align:top">Trackback and Pingback:</th>
1105 +<td width="73%"><ul style="margin:0; list-style:none">
1106 +<li><label><input type="radio" name="feed_ping_status" value="site-default"
1107 +<?php echo $status['ping']['site-default']; ?> /> Use site-wide setting from <a href="admin.php?page=feedwordpress/syndication-options.php">Syndication Options</a>
1108 +(currently: <strong><?php echo ($ping_status_global ? $ping_status_global : 'closed'); ?>)</strong></label></li>
1109 +<li><label><input type="radio" name="feed_ping_status" value="open"
1110 +<?php echo $status['ping']['open']; ?> /> Accept pings on syndicated posts from this feed</label></li>
1111 +<li><label><input type="radio" name="feed_ping_status" value="closed"
1112 +<?php echo $status['ping']['closed']; ?> /> Don't accept pings on syndicated posts from this feed</label></li>
1113 +</ul></td>
1114 +</tr>
1115 +</table>
1116 +</fieldset>
1117 +
1118 +<p class="submit">
1119 +<input type="submit" name="submit" value="<?php _e('Save Changes &raquo;') ?>" />
1120 +</p>
1121 +
1122 +<fieldset>
1123 +<legend>Advanced Feed Options</legend>
1124 +<table class="editform" width="100%" cellspacing="2" cellpadding="5">
1125 +<tr>
1126 +<th width="20%" scope="row" style="vertical-align:top">Unfamiliar authors:</th>
1127 +<td width="80%"><ul style="margin: 0; list-style:none">
1128 +<li><label><input type="radio" name="unfamiliar_author" value="site-default"<?php echo $unfamiliar['author']['site-default']; ?> /> use site-wide setting from <a href="admin.php?page=feedwordpress/syndication-options.php">Syndication Options</a>
1129 +(currently <strong><?php echo FeedWordPress::on_unfamiliar('author');; ?></strong>)</label></li>
1130 +<li><label><input type="radio" name="unfamiliar_author" value="create"<?php echo $unfamiliar['author']['create']; ?>/> create a new author account</label></li>
1131 +<li><label><input type="radio" name="unfamiliar_author" value="default"<?php echo $unfamiliar['author']['default']; ?> /> attribute the post to the default author</label></li>
1132 +<li><label><input type="radio" name="unfamiliar_author" value="filter"<?php echo $unfamiliar['author']['filter']; ?> /> don't syndicate the post</label></li>
1133 +</ul></td>
1134 +</tr>
1135 +
1136 +<tr>
1137 +<th width="20%" scope="row" style="vertical-align:top">Unfamiliar categories:</th>
1138 +<td width="80%"><ul style="margin: 0; list-style:none">
1139 +<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=feedwordpress/syndication-options.php">Syndication Options</a>
1140 +(currently <strong><?php echo FeedWordPress::on_unfamiliar('category');; ?></strong>)</label></li>
1141 +<li><label><input type="radio" name="unfamiliar_category" value="create"<?php echo $unfamiliar['category']['create']; ?> /> create any categories the post is in</label></li>
1142 +<li><label><input type="radio" name="unfamiliar_category" value="default"<?php echo $unfamiliar['category']['default']; ?> /> don't create new categories</label></li>
1143 +<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>
1144 +</ul></td>
1145 +</tr>
1146 +
1147 +<tr>
1148 +<th width="20%" scope="row" style="vertical-align:top">Multiple categories:</th>
1149 +<td width="80%">
1150 +<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/>
1151 +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
1152 +categories in a single category element. The regular expression should match
1153 +the characters used to separate one category from the next. If the feed uses
1154 +spaces (like <a href="http://del.icio.us/">del.icio.us</a>), use the pattern "\s".
1155 +If the feed does not provide multiple categories in a single element, leave this
1156 +blank.</td>
1157 +</tr>
1158 +</table>
1159 +</fieldset>
1160 +
1161 +<p class="submit">
1162 +<input type="submit" name="submit" value="<?php _e('Save Changes &raquo;') ?>" />
1163 +</p>
1164 +
1165 +<fieldset id="postcustom">
1166 +<legend>Custom Settings (for use in templates)</legend>
1167 +<div id="postcustomstuff">
1168 +<table id="meta-list" cellpadding="3">
1169 + <tr>
1170 + <th>Key</th>
1171 + <th>Value</th>
1172 + <th>Action</th>
1173 + </tr>
1174 +
1175 +<?php
1176 + $i = 0;
1177 + foreach ($meta as $key => $value) :
1178 + if (!preg_match("\007^((".implode(')|(', $special_settings)."))$\007i", $key)) :
575 1179 ?>
576 -<p style="font-style: italic"><strong>FeedWordPress has detected that <?php print $youAre; ?> currently using a version of
577 -MagpieRSS other than the upgraded version that ships with FeedWordPress.</strong></p>
578 -<p><?php print $itIsRecommendedThatYou; ?> install the upgraded
579 -version of MagpieRSS supplied with FeedWordPress. The version of
580 -MagpieRSS that ships with WordPress is very old and buggy, and
581 -encounters a number of errors when trying to parse modern Atom
582 -and RSS feeds.</p>
1180 + <tr style="vertical-align:top">
1181 + <th width="30%" scope="row"><input type="hidden" name="notes[<?php echo $i; ?>][key0]" value="<?php echo wp_specialchars($key, 'both'); ?>" />
1182 + <input id="notes-<?php echo $i; ?>-key" name="notes[<?php echo $i; ?>][key1]" value="<?php echo wp_specialchars($key, 'both'); ?>" /></th>
1183 + <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>
1184 + <td width="10%"><select name="notes[<?php echo $i; ?>][action]">
1185 + <option value="update">save changes</option>
1186 + <option value="delete">delete this setting</option>
1187 + </select></td>
1188 + </tr>
583 1189 <?php
584 - feedwordpress_upgrade_old_and_busted_buttons();
585 - print '</div>';
1190 + $i++;
586 1191 endif;
1192 + endforeach;
1193 +?>
1194 + <tr>
1195 + <th scope="row"><input type="text" size="10" name="notes[<?php echo $i; ?>][key1]" value="" /></th>
1196 + <td><textarea name="notes[<?php echo $i; ?>][value]" rows="2" cols="40"></textarea></td>
1197 + <td><em>add new setting...</em><input type="hidden" name="notes[<?php echo $i; ?>][action]" value="update" /></td>
1198 + </tr>
1199 +</table>
1200 +</fieldset>
1201 +
1202 +<p class="submit">
1203 +<input type="submit" name="submit" value="<?php _e('Save Changes &raquo;') ?>" />
1204 +</p>
1205 +
1206 +</div>
1207 + <?php
587 1208 endif;
1209 + return false; // Don't continue
588 1210 }
589 1211
590 -function feedwordpress_upgrade_old_and_busted_buttons() {
591 - if (current_user_can('edit_files')) :
1212 +function fwp_multidelete_page () {
1213 + global $wpdb;
1214 +
1215 + check_admin_referer(); // Make sure the referers are kosher
1216 +
1217 + $link_ids = (isset($_REQUEST['link_ids']) ? $_REQUEST['link_ids'] : array());
1218 + if (isset($_REQUEST['link_id'])) : array_push($link_ids, $_REQUEST['link_id']); endif;
1219 +
1220 + if (!current_user_can('manage_links')):
1221 + die (__("Cheatin' uh ?"));
1222 + elseif (isset($GLOBALS['fwp_post']['confirm']) and $GLOBALS['fwp_post']['confirm']=='Delete'):
1223 + foreach ($GLOBALS['fwp_post']['link_action'] as $link_id => $what) :
1224 + $do_it[$what][] = $link_id;
1225 + endforeach;
1226 +
1227 + $alter = array();
1228 + if (count($do_it['hide']) > 0) :
1229 + $hidem = "(".implode(', ', $do_it['hide']).")";
1230 + $alter[] = "
1231 + UPDATE $wpdb->links
1232 + SET link_visible = 'N'
1233 + WHERE link_id IN {$hidem}
1234 + ";
1235 + endif;
1236 +
1237 + if (count($do_it['nuke']) > 0) :
1238 + $nukem = "(".implode(', ', $do_it['nuke']).")";
1239 +
1240 + // Make a list of the items syndicated from this feed...
1241 + $post_ids = $wpdb->get_col("
1242 + SELECT post_id FROM $wpdb->postmeta
1243 + WHERE meta_key = 'syndication_feed_id'
1244 + AND meta_value IN {$nukem}
1245 + ");
1246 +
1247 + // ... and kill them all
1248 + if (count($post_ids) > 0) :
1249 + foreach ($post_ids as $post_id) :
1250 + wp_delete_post($post_id);
1251 + endforeach;
1252 + endif;
1253 +
1254 + $alter[] = "
1255 + DELETE FROM $wpdb->links
1256 + WHERE link_id IN {$nukem}
1257 + ";
1258 + endif;
1259 +
1260 + if (count($do_it['delete']) > 0) :
1261 + $deletem = "(".implode(', ', $do_it['delete']).")";
1262 +
1263 + // Make the items syndicated from this feed appear to be locally-authored
1264 + $alter[] = "
1265 + DELETE FROM $wpdb->postmeta
1266 + WHERE meta_key = 'syndication_feed_id'
1267 + AND meta_value IN {$deletem}
1268 + ";
1269 +
1270 + // ... and delete the links themselves.
1271 + $alter[] = "
1272 + DELETE FROM $wpdb->links
1273 + WHERE link_id IN {$deletem}
1274 + ";
1275 + endif;
1276 +
1277 + $errs = array(); $success = array ();
1278 + foreach ($alter as $sql) :
1279 + $result = $wpdb->query($sql);
1280 + if (!$result):
1281 + $errs[] = mysql_error();
1282 + endif;
1283 + endforeach;
1284 +
1285 + if (count($alter) > 0) :
1286 + echo "<div class=\"updated\">\n";
1287 + if (count($errs) > 0) :
1288 + echo "There were some problems processing your ";
1289 + echo "unsubscribe request. [SQL: ".implode('; ', $errs)."]";
1290 + else :
1291 + echo "Your unsubscribe request(s) have been processed.";
1292 + endif;
1293 + echo "</div>\n";
1294 + endif;
1295 +
1296 + return true; // Continue on to Syndicated Sites listing
1297 + else :
1298 + $targets = $wpdb->get_results("
1299 + SELECT * FROM $wpdb->links
1300 + WHERE link_id IN (".implode(",",$link_ids).")
1301 + ");
592 1302 ?>
593 -<form action="" method="post"><div>
594 -<?php FeedWordPressCompatibility::stamp_nonce('feedwordpress_fix_magpie'); ?>
595 -<input type="hidden" name="action" value="fix_magpie_version" />
596 -<input class="button-secondary" type="submit" name="ignore" value="<?php _e('Ignore this problem'); ?>" />
597 -<input class="button-primary" type="submit" name="upgrade" value="<?php _e('Upgrade'); ?>" />
598 -</div></form>
1303 +<form action="admin.php?page=feedwordpress/<?php echo basename(__FILE__); ?>" method="post">
1304 +<div class="wrap">
1305 +<input type="hidden" name="action" value="Unsubscribe" />
1306 +<input type="hidden" name="confirm" value="Delete" />
1307 +
1308 +<h2>Unsubscribe from Syndicated Links:</h2>
1309 +<?php foreach ($targets as $link) :
1310 + $link_url = wp_specialchars($link->link_url, 1);
1311 + $link_name = wp_specialchars($link->link_name, 1);
1312 + $link_description = wp_specialchars($link->link_description, 'both');
1313 + $link_rss = wp_specialchars($link->link_rss, 'both');
1314 +?>
1315 +<fieldset>
1316 +<legend><?php echo $link_name; ?></legend>
1317 +<table class="editform" width="100%" cellspacing="2" cellpadding="5">
1318 +<tr><th scope="row" width="20%"><?php _e('Feed URI:') ?></th>
1319 +<td width="80%"><a href="<?php echo $link_rss; ?>"><?php echo $link_rss; ?></a></td></tr>
1320 +<tr><th scope="row" width="20%"><?php _e('Short description:') ?></th>
1321 +<td width="80%"><?php echo $link_description; ?></span></td></tr>
1322 +<tr><th width="20%" scope="row"><?php _e('Homepage:') ?></th>
1323 +<td width="80%"><a href="<?php echo $link_url; ?>"><?php echo $link_url; ?></a></td></tr>
1324 +<tr style="vertical-align:top"><th width="20%" scope="row">Subscription <?php _e('Options') ?>:</th>
1325 +<td width="80%"><ul style="margin:0; padding: 0; list-style: none">
1326 +<li><input type="radio" id="hide-<?php echo $link->link_id; ?>"
1327 +name="link_action[<?php echo $link->link_id; ?>]" value="hide" />
1328 +<label for="hide-<?php echo $link->link_id; ?>">Turn off the subscription for this
1329 +syndicated link<br/><span style="font-size:smaller">(Keep the feed information
1330 +and all the posts from this feed in the database, but don't syndicate any
1331 +new posts from the feed.)</span></label></li>
1332 +<li><input type="radio" id="nuke-<?php echo $link->link_id; ?>"
1333 +name="link_action[<?php echo $link->link_id; ?>]" value="nuke" />
1334 +<label for="nuke-<?php echo $link->link_id; ?>">Delete this syndicated link and all the
1335 +posts that were syndicated from it</label></li>
1336 +<li><input type="radio" id="delete-<?php echo $link->link_id; ?>"
1337 +name="link_action[<?php echo $link->link_id; ?>]" value="delete" />
1338 +<label for="delete-<?php echo $link->link_id; ?>">Delete this syndicated link, but
1339 +<em>keep</em> posts that were syndicated from it (as if they were authored
1340 +locally).</label></li>
1341 +<li><input type="radio" id="nothing-<?php echo $link->link_id; ?>"
1342 +name="link_action[<?php echo $link->link_id; ?>]" value="nothing" />
1343 +<label for="nothing-<?php echo $link->link_id; ?>">Keep this feed as it is. I changed
1344 +my mind.</label></li>
1345 +</ul>
1346 +</table>
1347 +</fieldset>
1348 +<?php endforeach; ?>
1349 +
1350 +<div class="submit">
1351 +<input class="delete" type="submit" name="submit" value="<?php _e('Unsubscribe from selected feeds &raquo;') ?>" />
1352 +</div>
1353 +</div>
599 1354 <?php
1355 + return false; // Don't continue on to Syndicated Sites listing
600 1356 endif;
601 1357 }
602 1358
603 1359 ################################################################################
@@ -754,9 +1510,9 @@
754 1510 #
755 1511 # * Updates to existing posts since the last poll are mirrored in the
756 1512 # WordPress store.
757 1513 #
758 - function update ($uri = null, $crash_ts = null) {
1514 + function update ($uri = null) {
759 1515 global $wpdb;
760 1516
761 1517 if (FeedWordPress::needs_upgrade()) : // Will make duplicate posts if we don't hold off
762 1518 return NULL;
@@ -769,28 +1525,11 @@
769 1525 endif;
770 1526
771 1527 do_action('feedwordpress_update', $uri);
772 1528
773 - if (is_null($crash_ts)) :
774 - $crash_dt = (int) get_option('feedwordpress_update_time_limit');
775 - if ($crash_dt > 0) :
776 - $crash_ts = time() + $crash_dt;
777 - else :
778 - $crash_ts = NULL;
779 - endif;
780 - endif;
781 -
782 - // Randomize order for load balancing purposes
783 - $feed_set = $this->feeds;
784 - shuffle($feed_set);
785 -
786 1529 // Loop through and check for new posts
787 1530 $delta = NULL;
788 - foreach ($feed_set as $feed) :
789 - if (!is_null($crash_ts) and (time() > $crash_ts)) : // Check whether we've exceeded the time limit
790 - break;
791 - endif;
792 -
1531 + foreach ($this->feeds as $feed) :
793 1532 $pinged_that = (is_null($uri) or in_array($uri, array($feed->uri(), $feed->homepage())));
794 1533
795 1534 if (!is_null($uri)) : // A site-specific ping always updates
796 1535 $timely = true;
@@ -803,12 +1542,9 @@
803 1542 endif;
804 1543
805 1544 if ($pinged_that and $timely) :
806 1545 do_action('feedwordpress_check_feed', $feed->settings);
807 - $start_ts = time();
808 - $added = $feed->poll($crash_ts);
809 - do_action('feedwordpress_check_feed_complete', $feed->settings, $added, time() - $start_ts);
810 -
1546 + $added = $feed->poll();
811 1547 if (isset($added['new'])) : $delta['new'] += $added['new']; endif;
812 1548 if (isset($added['updated'])) : $delta['updated'] += $added['updated']; endif;
813 1549 endif;
814 1550 endforeach;
@@ -866,9 +1602,9 @@
866 1602 if (function_exists('wp_insert_link')) { // WordPress 2.x
867 1603 $link_id = wp_insert_link(array(
868 1604 "link_name" => $name,
869 1605 "link_url" => $uri,
870 - "link_category" => (fwp_test_wp_version(0, FWP_SCHEMA_21) ? $cat_id : array($cat_id)),
1606 + "link_category" => array($cat_id),
871 1607 "link_rss" => $rss
872 1608 ));
873 1609 } else { // WordPress 1.5.x
874 1610 $result = $wpdb->query("
@@ -884,20 +1620,14 @@
884 1620 return $link_id;
885 1621 } // function FeedWordPress::syndicate_link()
886 1622
887 1623 function on_unfamiliar ($what = 'author', $override = NULL) {
888 - $set = array(
889 - 'author' => array('create', 'default', 'filter'),
890 - 'category' => array('create', 'tag', 'default', 'filter'),
891 - );
892 -
893 - if (is_string($override)) :
894 - $ret = strtolower($override);
895 - endif;
1624 + $set = array('create', 'default', 'filter');
896 1625
897 - if (!is_numeric($override) and !in_array($ret, $set[$what])) :
1626 + $ret = strtolower($override);
1627 + if (!in_array($ret, $set)) :
898 1628 $ret = get_option('feedwordpress_unfamiliar_'.$what);
899 - if (!is_numeric($ret) and !in_array($ret, $set[$what])) :
1629 + if (!in_array($ret, $set)) :
900 1630 $ret = 'create';
901 1631 endif;
902 1632 endif;
903 1633
@@ -903,33 +1633,8 @@
903 1633
904 1634 return $ret;
905 1635 } // function FeedWordPress::on_unfamiliar()
906 1636
907 - function null_email_set () {
908 - $base = get_option('feedwordpress_null_email_set');
909 -
910 - if ($base===false) :
911 - $ret = array('noreply@blogger.com'); // default
912 - else :
913 - $ret = array_map('strtolower',
914 - array_map('trim', explode("\n", $base)));
915 - endif;
916 - $ret = apply_filters('syndicated_item_author_null_email_set', $ret);
917 - return $ret;
918 -
919 - } /* FeedWordPress::null_email_set () */
920 -
921 - function is_null_email ($email) {
922 - $ret = in_array(strtolower(trim($email)), FeedWordPress::null_email_set());
923 - $ret = apply_filters('syndicated_item_author_is_null_email', $ret, $email);
924 - return $ret;
925 - } /* FeedWordPress::is_null_email () */
926 -
927 - function use_aggregator_source_data () {
928 - $ret = get_option('feedwordpress_use_aggregator_source_data');
929 - return apply_filters('syndicated_post_use_aggregator_source_data', ($ret=='yes'));
930 - }
931 -
932 1637 function syndicated_links () {
933 1638 $contributors = FeedWordPress::link_category_id();
934 1639 if (function_exists('get_bookmarks')) :
935 1640 $links = get_bookmarks(array("category" => $contributors));
@@ -954,12 +1659,12 @@
954 1659 // WordPress 2.3 introduces a new taxonomy/term API
955 1660 if (function_exists('is_term')) :
956 1661 $cat_id = is_term($cat, 'link_category');
957 1662 // WordPress 2.1 and 2.2 use a common table for both link and post categories
958 - elseif (fwp_test_wp_version(FWP_SCHEMA_21, FWP_SCHEMA_23)) :
1663 + elseif (isset($wp_db_version) and ($wp_db_version >= FWP_SCHEMA_21 and $wp_db_version < FWP_SCHEMA_23) ) :
959 1664 $cat_id = $wpdb->get_var("SELECT cat_id FROM {$wpdb->categories} WHERE cat_name='$cat'");
960 1665 // WordPress 1.5 and 2.0.x have a separate table for link categories
961 - elseif (fwp_test_wp_version(0, FWP_SCHEMA_21)):
1666 + elseif (!isset($wp_db_version) or $wp_db_version < FWP_SCHEMA_21) :
962 1667 $cat_id = $wpdb->get_var("SELECT cat_id FROM {$wpdb->linkcategories} WHERE cat_name='$cat'");
963 1668 // This should never happen.
964 1669 else :
965 1670 FeedWordPress::critical_bug('FeedWordPress::link_category_id::wp_db_version', $wp_db_version, __LINE__);
@@ -972,12 +1677,12 @@
972 1677 if (function_exists('wp_insert_term')) :
973 1678 $term = wp_insert_term($cat, 'link_category');
974 1679 $cat_id = $term['term_id'];
975 1680 // WordPress 2.1, 2.2 category API. By the way, why the fuck is this API function only available in a wp-admin module?
976 - elseif (function_exists('wp_insert_category') and !fwp_test_wp_version(FWP_SCHEMA_20, FWP_SCHEMA_21)) :
1681 + elseif (function_exists('wp_insert_category')) :
977 1682 $cat_id = wp_insert_category(array('cat_name' => $cat));
978 1683 // WordPress 1.5 and 2.0.x
979 - elseif (fwp_test_wp_version(0, FWP_SCHEMA_21)) :
1684 + elseif (!isset($wp_db_version) or $wp_db_version < FWP_SCHEMA_21) :
980 1685 $result = $wpdb->query("
981 1686 INSERT INTO $wpdb->linkcategories
982 1687 SET
983 1688 cat_id = 0,
@@ -1087,23 +1792,8 @@
1087 1792 endswitch;
1088 1793 echo "<p>Upgrade complete. FeedWordPress is now ready to use again.</p>";
1089 1794 } /* FeedWordPress::upgrade_database() */
1090 1795
1091 - function create_guid_index () {
1092 - global $wpdb;
1093 -
1094 - $wpdb->query("
1095 - CREATE INDEX {$wpdb->posts}_guid_idx ON {$wpdb->posts}(guid)
1096 - ");
1097 - } /* FeedWordPress::create_guid_index () */
1098 -
1099 - function magpie_version () {
1100 - if (!defined('MAGPIE_VERSION')) : $magpie_version = $GLOBALS['wp_version'].'-default';
1101 - else : $magpie_version = MAGPIE_VERSION;
1102 - endif;
1103 - return $magpie_version;
1104 - }
1105 -
1106 1796 # Utility functions for handling text settings
1107 1797 function negative ($f, $setting) {
1108 1798 $nego = array ('n', 'no', 'f', 'false');
1109 1799 return (isset($f[$setting]) and in_array(strtolower($f[$setting]), $nego));
@@ -1118,29 +1808,18 @@
1118 1808 # Internal debugging functions
1119 1809 function critical_bug ($varname, $var, $line) {
1120 1810 global $wp_version;
1121 1811
1122 - if (defined('MAGPIE_VERSION')) : $mv = MAGPIE_VERSION;
1123 - else : $mv = 'WordPress '.$wp_version.' default.';
1124 - endif;
1125 -
1126 1812 echo '<p>There may be a bug in FeedWordPress. Please <a href="'.FEEDWORDPRESS_AUTHOR_CONTACT.'">contact the author</a> and paste the following information into your e-mail:</p>';
1127 1813 echo "\n<plaintext>";
1128 1814 echo "Triggered at line # ".$line."\n";
1129 1815 echo "FeedWordPress version: ".FEEDWORDPRESS_VERSION."\n";
1130 - echo "MagpieRSS version: {$mv}\n";
1131 - echo "WordPress version: {$wp_version}\n";
1816 + echo "WordPress version: $wp_version\n";
1132 1817 echo "PHP version: ".phpversion()."\n";
1133 1818 echo "\n";
1134 1819 echo $varname.": "; var_dump($var); echo "\n";
1135 1820 die;
1136 1821 }
1137 -
1138 - function noncritical_bug ($varname, $var, $line) {
1139 - if (FEEDWORDPRESS_DEBUG) : // halt only when we are doing debugging
1140 - FeedWordPress::critical_bug($varname, $var, $line);
1141 - endif;
1142 - }
1143 1822 } // class FeedWordPress
1144 1823
1145 1824 class SyndicatedPost {
1146 1825 var $item = null;
@@ -1149,12 +1828,18 @@
1149 1828 var $feed = null;
1150 1829 var $feedmeta = null;
1151 1830
1152 1831 var $post = array ();
1832 + var $_base = null;
1153 1833
1154 1834 var $_freshness = null;
1155 1835 var $_wp_id = null;
1156 1836
1837 + var $strip_attrs = array (
1838 + array('[a-z]+', 'style'),
1839 + array('[a-z]+', 'target'),
1840 + );
1841 +
1157 1842 function SyndicatedPost ($item, $link) {
1158 1843 global $wpdb;
1159 1844
1160 1845 $this->link = $link;
@@ -1185,20 +1870,18 @@
1185 1870 # That's deliberate. The escaping is done at the point
1186 1871 # of insertion, not here, to avoid double-escaping and
1187 1872 # to avoid screwing with syndicated_post filters
1188 1873
1189 - $this->post['post_title'] = apply_filters('syndicated_item_title', $this->item['title'], $this);
1874 + $this->post['post_title'] = $this->item['title'];
1190 1875
1191 - // This just gives us an alphanumeric representation of
1876 + // This just gives usan alphanumeric representation of
1192 1877 // the author. We will look up (or create) the numeric
1193 1878 // ID for the author in SyndicatedPost::add()
1194 - $this->post['named']['author'] = apply_filters('syndicated_item_author', $this->author(), $this);
1879 + $this->post['named']['author'] = $this->author();
1195 1880
1196 1881 # Identify content and sanitize it.
1197 1882 # ---------------------------------
1198 - if (isset($this->item['atom_content'])) :
1199 - $content = $this->item['atom_content'];
1200 - elseif (isset($this->item['xhtml']['body'])) :
1883 + if (isset($this->item['xhtml']['body'])) :
1201 1884 $content = $this->item['xhtml']['body'];
1202 1885 elseif (isset($this->item['xhtml']['div'])) :
1203 1886 $content = $this->item['xhtml']['div'];
1204 1887 elseif (isset($this->item['content']['encoded']) and $this->item['content']['encoded']):
@@ -1205,9 +1888,24 @@
1205 1888 $content = $this->item['content']['encoded'];
1206 1889 else:
1207 1890 $content = $this->item['description'];
1208 1891 endif;
1209 - $this->post['post_content'] = apply_filters('syndicated_item_content', $content, $this);
1892 +
1893 + # FeedWordPress used to resolve URIs relative to the
1894 + # feed URI. It now relies on the xml:base support
1895 + # baked in to the MagpieRSS upgrade. So all we do here
1896 + # now is to sanitize problematic attributes.
1897 + #
1898 + # This kind of sucks. I intend to replace it with
1899 + # lib_filter sometime soon.
1900 + foreach ($this->strip_attrs as $pair):
1901 + list($tag,$attr) = $pair;
1902 + $content = preg_replace (
1903 + ":(<$tag [^>]*)($attr=(\"[^\">]*\"|[^>\\s]+))([^>]*>):i",
1904 + "\\1\\4",
1905 + $content
1906 + );
1907 + endforeach;
1210 1908
1211 1909 # Identify and sanitize excerpt
1212 1910 $excerpt = NULL;
1213 1911 if ( isset($this->item['description']) and $this->item['description'] ) :
@@ -1217,10 +1915,11 @@
1217 1915 if (strlen($excerpt) > 255) :
1218 1916 $excerpt = substr($excerpt,0,252).'...';
1219 1917 endif;
1220 1918 endif;
1221 - $excerpt = apply_filters('syndicated_item_excerpt', $excerpt, $this);
1222 1919
1920 + $this->post['post_content'] = $content;
1921 +
1223 1922 if (!is_null($excerpt)):
1224 1923 $this->post['post_excerpt'] = $excerpt;
1225 1924 endif;
1226 1925
@@ -1228,11 +1927,11 @@
1228 1927 if (!$this->use_api('wp_insert_post')) :
1229 1928 $this->post['post_name'] = sanitize_title($this->post['post_title']);
1230 1929 endif;
1231 1930
1232 - $this->post['epoch']['issued'] = apply_filters('syndicated_item_published', $this->published(), $this);
1233 - $this->post['epoch']['created'] = apply_filters('syndicated_item_created', $this->created(), $this);
1234 - $this->post['epoch']['modified'] = apply_filters('syndicated_item_updated', $this->updated(), $this);
1931 + $this->post['epoch']['issued'] = $this->published();
1932 + $this->post['epoch']['created'] = $this->created();
1933 + $this->post['epoch']['modified'] = $this->updated();
1235 1934
1236 1935 // Dealing with timestamps in WordPress is so fucking fucked.
1237 1936 $offset = (int) get_option('gmt_offset') * 60 * 60;
1238 1937 $this->post['post_date'] = gmdate('Y-m-d H:i:s', $this->published() + $offset);
@@ -1245,67 +1944,35 @@
1245 1944 $this->post['comment_status'] = $this->link->syndicated_status('comment', 'closed');
1246 1945 $this->post['ping_status'] = $this->link->syndicated_status('ping', 'closed');
1247 1946
1248 1947 // Unique ID (hopefully a unique tag: URI); failing that, the permalink
1249 - $this->post['guid'] = apply_filters('syndicated_item_guid', $this->guid(), $this);
1948 + $this->post['guid'] = $this->guid();
1250 1949
1251 - // User-supplied custom settings to apply to each post. Do first so that FWP-generated custom settings will overwrite if necessary; thus preventing any munging
1252 - $default_custom_settings = get_option('feedwordpress_custom_settings');
1253 - if ($default_custom_settings) :
1254 - $default_custom_settings = unserialize($default_custom_settings);
1255 - endif;
1256 - if (!is_array($default_custom_settings)) :
1257 - $default_custom_settings = array();
1258 - endif;
1259 -
1260 - $custom_settings = $this->link->settings['postmeta'];
1261 - if ($custom_settings) :
1262 - $custom_settings = unserialize($custom_settings);
1263 - endif;
1264 - if (!is_array($custom_settings)) :
1265 - $custom_settings = array();
1266 - endif;
1267 - $this->post['meta'] = array_merge($default_custom_settings, $custom_settings);
1268 -
1269 1950 // RSS 2.0 / Atom 1.0 enclosure support
1270 1951 if ( isset($this->item['enclosure#']) ) :
1271 1952 for ($i = 1; $i <= $this->item['enclosure#']; $i++) :
1272 1953 $eid = (($i > 1) ? "#{$id}" : "");
1273 1954 $this->post['meta']['enclosure'][] =
1274 - apply_filters('syndicated_item_enclosure_url', $this->item["enclosure{$eid}@url"], $this)."\n".
1275 - apply_filters('syndicated_item_enclosure_length', $this->item["enclosure{$eid}@length"], $this)."\n".
1276 - apply_filters('syndicated_item_enclosure_type', $this->item["enclosure{$eid}@type"], $this);
1955 + $this->item["enclosure{$eid}@url"]."\n".
1956 + $this->item["enclosure{$eid}@length"]."\n".
1957 + $this->item["enclosure{$eid}@type"];
1277 1958 endfor;
1278 1959 endif;
1279 1960
1280 1961 // In case you want to point back to the blog this was syndicated from
1281 1962 if (isset($this->feed->channel['title'])) :
1282 - $this->post['meta']['syndication_source'] = apply_filters('syndicated_item_source_title', $this->feed->channel['title'], $this);
1963 + $this->post['meta']['syndication_source'] = $this->feed->channel['title'];
1283 1964 endif;
1284 -
1285 1965 if (isset($this->feed->channel['link'])) :
1286 - $this->post['meta']['syndication_source_uri'] = apply_filters('syndicated_item_source_link', $this->feed->channel['link'], $this);
1966 + $this->post['meta']['syndication_source_uri'] = $this->feed->channel['link'];
1287 1967 endif;
1288 1968
1289 - // Make use of atom:source data, if present in an aggregated feed
1290 - if (isset($this->item['source_title'])) :
1291 - $this->post['meta']['syndication_source_original'] = $this->item['source_title'];
1292 - endif;
1293 -
1294 - if (isset($this->item['source_link'])) :
1295 - $this->post['meta']['syndication_source_uri_original'] = $this->item['source_link'];
1296 - endif;
1297 -
1298 - if (isset($this->item['source_id'])) :
1299 - $this->post['meta']['syndication_source_id_original'] = $this->item['source_id'];
1300 - endif;
1301 -
1302 1969 // Store information on human-readable and machine-readable comment URIs
1303 1970 if (isset($this->item['comments'])) :
1304 - $this->post['meta']['rss:comments'] = apply_filters('syndicated_item_comments', $this->item['comments']);
1971 + $this->post['meta']['rss:comments'] = $this->item['comments'];
1305 1972 endif;
1306 1973 if (isset($this->item['wfw']['commentrss'])) :
1307 - $this->post['meta']['wfw:commentRSS'] = apply_filters('syndicated_item_commentrss', $this->item['wfw']['commentrss']);
1974 + $this->post['meta']['wfw:commentRSS'] = $this->item['wfw']['commentrss'];
1308 1975 endif;
1309 1976
1310 1977 // Store information to identify the feed that this came from
1311 1978 $this->post['meta']['syndication_feed'] = $this->feedmeta['link/uri'];
@@ -1310,21 +1977,14 @@
1310 1977 // Store information to identify the feed that this came from
1311 1978 $this->post['meta']['syndication_feed'] = $this->feedmeta['link/uri'];
1312 1979 $this->post['meta']['syndication_feed_id'] = $this->feedmeta['link/id'];
1313 1980
1314 - if (isset($this->item['source_link_self'])) :
1315 - $this->post['meta']['syndication_feed_original'] = $this->item['source_link_self'];
1316 - endif;
1317 -
1318 1981 // In case you want to know the external permalink...
1319 - $this->post['meta']['syndication_permalink'] = apply_filters('syndicated_item_link', $this->item['link']);
1982 + $this->post['meta']['syndication_permalink'] = $this->item['link'];
1320 1983
1321 - // Store a hash of the post content for checking whether something needs to be updated
1322 - $this->post['meta']['syndication_item_hash'] = $this->update_hash();
1323 -
1324 1984 // Feed-by-feed options for author and category creation
1325 1985 $this->post['named']['unfamiliar']['author'] = $this->feedmeta['unfamiliar author'];
1326 - $this->post['named']['unfamiliar']['category'] = $this->feedmeta['unfamiliar category'];
1986 + $this->post['named']['unfamiliar']['category'] = $this->feedmeta['unfamiliar categories'];
1327 1987
1328 1988 // Categories: start with default categories, if any
1329 1989 $fc = get_option("feedwordpress_syndication_cats");
1330 1990 if ($fc) :
@@ -1351,22 +2011,8 @@
1351 2011 $this->post['named']['category'][] = $cat;
1352 2012 endif;
1353 2013 endfor;
1354 2014 endif;
1355 - $this->post['named']['category'] = apply_filters('syndicated_item_categories', $this->post['named']['category'], $this);
1356 -
1357 - // Tags: start with default tags, if any
1358 - $ft = get_option("feedwordpress_syndication_tags");
1359 - if ($ft) :
1360 - $this->post['tags_input'] = explode(FEEDWORDPRESS_CAT_SEPARATOR, $ft);
1361 - else :
1362 - $this->post['tags_input'] = array();
1363 - endif;
1364 -
1365 - if (is_array($this->feedmeta['tags'])) :
1366 - $this->post['tags_input'] = array_merge($this->post['tags_input'], $this->feedmeta['tags']);
1367 - endif;
1368 -
1369 2015 endif;
1370 2016 } // SyndicatedPost::SyndicatedPost()
1371 2017
1372 2018 function filtered () {
@@ -1387,35 +2033,18 @@
1387 2033 SELECT id, guid, post_modified_gmt
1388 2034 FROM $wpdb->posts WHERE guid='$guid'
1389 2035 ");
1390 2036
2037 + preg_match('/([0-9]+)-([0-9]+)-([0-9]+) ([0-9]+):([0-9]+):([0-9]+)/', $result->post_modified_gmt, $backref);
2038 + $updated = gmmktime($backref[4], $backref[5], $backref[6], $backref[2], $backref[3], $backref[1]);
1391 2039 if (!$result) :
1392 2040 $this->_freshness = 2; // New content
1393 - else:
1394 - $stored_update_hashes = get_post_custom_values('syndication_item_hash', $result->id);
1395 - if (count($stored_update_hashes) > 0) :
1396 - $stored_update_hash = $stored_update_hashes[0];
1397 - $update_hash_changed = ($stored_update_hash != $this->update_hash());
1398 - else :
1399 - $update_hash_changed = false;
1400 - endif;
1401 -
1402 - preg_match('/([0-9]+)-([0-9]+)-([0-9]+) ([0-9]+):([0-9]+):([0-9]+)/', $result->post_modified_gmt, $backref);
1403 -
1404 - $last_rev_ts = gmmktime($backref[4], $backref[5], $backref[6], $backref[2], $backref[3], $backref[1]);
1405 - $updated_ts = $this->updated(/*fallback=*/ true, /*default=*/ NULL);
1406 - $updated = ((
1407 - !is_null($updated_ts)
1408 - and ($updated_ts > $last_rev_ts)
1409 - ) or $update_hash_changed);
1410 -
1411 - if ($updated) :
1412 - $this->_freshness = 1; // Updated content
1413 - $this->_wp_id = $result->id;
1414 - else :
1415 - $this->_freshness = 0; // Same old, same old
1416 - $this->_wp_id = $result->id;
1417 - endif;
2041 + elseif ($this->updated() > $updated) :
2042 + $this->_freshness = 1; // Updated content
2043 + $this->_wp_id = $result->id;
2044 + else :
2045 + $this->_freshness = 0; // Same old, same old
2046 + $this->_wp_id = $result->id;
1418 2047 endif;
1419 2048 endif;
1420 2049 return $this->_freshness;
1421 2050 }
@@ -1451,17 +2080,13 @@
1451 2080 endif;
1452 2081
1453 2082 if (!$this->filtered() and $freshness > 0) :
1454 2083 # -- Look up, or create, numeric ID for categories
1455 - list($pcats, $ptags) = $this->category_ids (
2084 + $this->post['post_category'] = $this->category_ids (
1456 2085 $this->post['named']['category'],
1457 - FeedWordPress::on_unfamiliar('category', $this->post['named']['unfamiliar']['category']),
1458 - /*tags_too=*/ true
2086 + FeedWordPress::on_unfamiliar('category', $this->post['named']['unfamiliar']['category'])
1459 2087 );
1460 -
1461 - $this->post['post_category'] = $pcats;
1462 - $this->post['tags_input'] = array_merge($this->post['tags_input'], $ptags);
1463 -
2088 +
1464 2089 if (is_null($this->post['post_category'])) :
1465 2090 // filter mode on, no matching categories; drop the post
1466 2091 $this->post = NULL;
1467 2092 else :
@@ -1507,278 +2132,152 @@
1507 2132 } // function SyndicatedPost::store ()
1508 2133
1509 2134 function insert_new () {
1510 2135 global $wpdb, $wp_db_version;
2136 +
2137 + // Why the fuck doesn't wp_insert_post already do this?
2138 + foreach ($this->post as $key => $value) :
2139 + if (is_string($value)) :
2140 + $dbpost[$key] = $wpdb->escape($value);
2141 + else :
2142 + $dbpost[$key] = $value;
2143 + endif;
2144 + endforeach;
1511 2145
1512 - $dbpost = $this->normalize_post(/*new=*/ true);
1513 - if (!is_null($dbpost)) :
1514 - if ($this->use_api('wp_insert_post')) :
1515 - $dbpost['post_pingback'] = false; // Tell WP 2.1 and 2.2 not to process for pingbacks
2146 + if ($this->use_api('wp_insert_post')) :
2147 + $dbpost['post_pingback'] = false; // Tell WP 2.1 and 2.2 not to process for pingbacks
2148 + $this->_wp_id = wp_insert_post($dbpost);
2149 +
2150 + // This should never happen.
2151 + if (!is_numeric($this->_wp_id) or ($this->_wp_id == 0)) :
2152 + FeedWordPress::critical_bug('SyndicatedPost (_wp_id problem)', $this, __LINE__);
2153 + endif;
1516 2154
1517 - // This is a ridiculous fucking kludge necessitated by WordPress 2.6 munging authorship meta-data
1518 - add_action('_wp_put_post_revision', array($this, 'fix_revision_meta'));
1519 -
1520 - // Kludge to prevent kses filters from stripping the
1521 - // content of posts when updating without a logged in
1522 - // user who has `unfiltered_html` capability.
1523 - add_filter('content_save_pre', array($this, 'avoid_kses_munge'), 11);
1524 -
1525 - $this->_wp_id = wp_insert_post($dbpost);
1526 -
1527 - // Turn off ridiculous fucking kludges #1 and #2
1528 - remove_action('_wp_put_post_revision', array($this, 'fix_revision_meta'));
1529 - remove_filter('content_save_pre', array($this, 'avoid_kses_munge'), 11);
1530 -
1531 - $this->validate_post_id($dbpost, array(__CLASS__, __FUNCTION__));
1532 -
1533 - // Unfortunately, as of WordPress 2.3, wp_insert_post()
1534 - // *still* offers no way to use a guid of your choice,
1535 - // and munges your post modified timestamp, too.
1536 - $result = $wpdb->query("
1537 - UPDATE $wpdb->posts
1538 - SET
1539 - guid='{$dbpost['guid']}',
1540 - post_modified='{$dbpost['post_modified']}',
1541 - post_modified_gmt='{$dbpost['post_modified_gmt']}'
1542 - WHERE ID='{$this->_wp_id}'
1543 - ");
1544 - else :
1545 - # The right way to do this is the above. But, alas,
1546 - # in earlier versions of WordPress, wp_insert_post has
1547 - # too much behavior (mainly related to pings) that can't
1548 - # be overridden. In WordPress 1.5, it's enough of a
1549 - # resource hog to make PHP segfault after inserting
1550 - # 50-100 posts. This can get pretty annoying, especially
1551 - # if you are trying to update your feeds for the first
1552 - # time.
1553 -
1554 - $result = $wpdb->query("
1555 - INSERT INTO $wpdb->posts
2155 + // Unfortunately, as of WordPress 2.3, wp_insert_post()
2156 + // *still* offers no way to use a guid of your choice,
2157 + // and munges your post modified timestamp, too.
2158 + $result = $wpdb->query("
2159 + UPDATE $wpdb->posts
1556 2160 SET
1557 - guid = '{$dbpost['guid']}',
1558 - post_author = '{$dbpost['post_author']}',
1559 - post_date = '{$dbpost['post_date']}',
1560 - post_date_gmt = '{$dbpost['post_date_gmt']}',
1561 - post_content = '{$dbpost['post_content']}',"
1562 - .(isset($dbpost['post_excerpt']) ? "post_excerpt = '{$dbpost['post_excerpt']}'," : "")."
1563 - post_title = '{$dbpost['post_title']}',
1564 - post_name = '{$dbpost['post_name']}',
1565 - post_modified = '{$dbpost['post_modified']}',
1566 - post_modified_gmt = '{$dbpost['post_modified_gmt']}',
1567 - comment_status = '{$dbpost['comment_status']}',
1568 - ping_status = '{$dbpost['ping_status']}',
1569 - post_status = '{$dbpost['post_status']}'
1570 - ");
1571 - $this->_wp_id = $wpdb->insert_id;
1572 -
1573 - $this->validate_post_id($dbpost, array(__CLASS__, __FUNCTION__));
1574 -
1575 - // WordPress 1.5.x - 2.0.x
1576 - wp_set_post_cats('1', $this->wp_id(), $this->post['post_category']);
1577 -
1578 - // Since we are not going through official channels, we need to
1579 - // manually tell WordPress that we've published a new post.
1580 - // We need to make sure to do this in order for FeedWordPress
1581 - // to play well with the staticize-reloaded plugin (something
1582 - // that a large aggregator website is going to *want* to be
1583 - // able to use).
1584 - do_action('publish_post', $this->_wp_id);
1585 - endif;
1586 - endif;
1587 - } /* SyndicatedPost::insert_new() */
2161 + guid='{$dbpost['guid']}',
2162 + post_modified='{$dbpost['post_modified']}',
2163 + post_modified_gmt='{$dbpost['post_modified_gmt']}'
2164 + WHERE ID='{$this->_wp_id}'
2165 + ");
2166 + else :
2167 + # The right way to do this is the above. But, alas,
2168 + # in earlier versions of WordPress, wp_insert_post has
2169 + # too much behavior (mainly related to pings) that can't
2170 + # be overridden. In WordPress 1.5, it's enough of a
2171 + # resource hog to make PHP segfault after inserting
2172 + # 50-100 posts. This can get pretty annoying, especially
2173 + # if you are trying to update your feeds for the first
2174 + # time.
1588 2175
1589 - function update_existing () {
1590 - global $wpdb;
2176 + $result = $wpdb->query("
2177 + INSERT INTO $wpdb->posts
2178 + SET
2179 + guid = '{$dbpost['guid']}',
2180 + post_author = '{$dbpost['post_author']}',
2181 + post_date = '{$dbpost['post_date']}',
2182 + post_date_gmt = '{$dbpost['post_date_gmt']}',
2183 + post_content = '{$dbpost['post_content']}',"
2184 + .(isset($dbpost['post_excerpt']) ? "post_excerpt = '{$dbpost['post_excerpt']}'," : "")."
2185 + post_title = '{$dbpost['post_title']}',
2186 + post_name = '{$dbpost['post_name']}',
2187 + post_modified = '{$dbpost['post_modified']}',
2188 + post_modified_gmt = '{$dbpost['post_modified_gmt']}',
2189 + comment_status = '{$dbpost['comment_status']}',
2190 + ping_status = '{$dbpost['ping_status']}',
2191 + post_status = '{$dbpost['post_status']}'
2192 + ");
2193 + $this->_wp_id = $wpdb->insert_id;
1591 2194
1592 - // Why the fuck doesn't wp_insert_post already do this?
1593 - $dbpost = $this->normalize_post(/*new=*/ false);
1594 - if (!is_null($dbpost)) :
1595 - if ($this->use_api('wp_insert_post')) :
1596 - $dbpost['post_pingback'] = false; // Tell WP 2.1 and 2.2 not to process for pingbacks
1597 -
1598 - // This is a ridiculous fucking kludge necessitated by WordPress 2.6 munging authorship meta-data
1599 - add_action('_wp_put_post_revision', array($this, 'fix_revision_meta'));
1600 -
1601 - // Kludge to prevent kses filters from stripping the
1602 - // content of posts when updating without a logged in
1603 - // user who has `unfiltered_html` capability.
1604 - add_filter('content_save_pre', array($this, 'avoid_kses_munge'), 11);
2195 + // This should never happen.
2196 + if (!is_numeric($this->_wp_id) or ($this->_wp_id == 0)) :
2197 + FeedWordPress::critical_bug('SyndicatedPost::_wp_id', $this->_wp_id, __LINE__);
2198 + endif;
1605 2199
1606 - // Don't munge status fields that the user may have reset manually
1607 - if (function_exists('get_post_field')) :
1608 - $doNotMunge = array('post_status', 'comment_status', 'ping_status');
1609 - foreach ($doNotMunge as $field) :
1610 - $dbpost[$field] = get_post_field($field, $this->wp_id());
1611 - endforeach;
1612 - endif;
1613 -
1614 - $this->_wp_id = wp_insert_post($dbpost);
2200 + // WordPress 1.5.x - 2.0.x
2201 + wp_set_post_cats('1', $this->wp_id(), $this->post['post_category']);
1615 2202
1616 - // Turn off ridiculous fucking kludges #1 and #2
1617 - remove_action('_wp_put_post_revision', array($this, 'fix_revision_meta'));
1618 - remove_filter('content_save_pre', array($this, 'avoid_kses_munge'), 11);
1619 -
1620 - $this->validate_post_id($dbpost, array(__CLASS__, __FUNCTION__));
1621 -
1622 - // Unfortunately, as of WordPress 2.3, wp_insert_post()
1623 - // munges your post modified timestamp.
1624 - $result = $wpdb->query("
1625 - UPDATE $wpdb->posts
1626 - SET
1627 - post_modified='{$dbpost['post_modified']}',
1628 - post_modified_gmt='{$dbpost['post_modified_gmt']}'
1629 - WHERE ID='{$this->_wp_id}'
1630 - ");
1631 - else :
1632 -
1633 - $result = $wpdb->query("
1634 - UPDATE $wpdb->posts
1635 - SET
1636 - post_author = '{$dbpost['post_author']}',
1637 - post_content = '{$dbpost['post_content']}',"
1638 - .(isset($dbpost['post_excerpt']) ? "post_excerpt = '{$dbpost['post_excerpt']}'," : "")."
1639 - post_title = '{$dbpost['post_title']}',
1640 - post_name = '{$dbpost['post_name']}',
1641 - post_modified = '{$dbpost['post_modified']}',
1642 - post_modified_gmt = '{$dbpost['post_modified_gmt']}'
1643 - WHERE guid='{$dbpost['guid']}'
1644 - ");
1645 -
1646 - // WordPress 2.1.x and up
1647 - if (function_exists('wp_set_post_categories')) :
1648 - wp_set_post_categories($this->wp_id(), $this->post['post_category']);
1649 - // WordPress 1.5.x - 2.0.x
1650 - elseif (function_exists('wp_set_post_cats')) :
1651 - wp_set_post_cats('1', $this->wp_id(), $this->post['post_category']);
1652 - // This should never happen.
1653 - else :
1654 - FeedWordPress::critical_bug(__CLASS__.'::'.__FUNCTION.'(): no post categorizing function', array("dbpost" => $dbpost, "this" => $this), __LINE__);
1655 - endif;
1656 -
1657 - // Since we are not going through official channels, we need to
1658 - // manually tell WordPress that we've published a new post.
1659 - // We need to make sure to do this in order for FeedWordPress
1660 - // to play well with the staticize-reloaded plugin (something
1661 - // that a large aggregator website is going to *want* to be
1662 - // able to use).
1663 - do_action('edit_post', $this->post['ID']);
1664 - endif;
2203 + // Since we are not going through official channels, we need to
2204 + // manually tell WordPress that we've published a new post.
2205 + // We need to make sure to do this in order for FeedWordPress
2206 + // to play well with the staticize-reloaded plugin (something
2207 + // that a large aggregator website is going to *want* to be
2208 + // able to use).
2209 + do_action('publish_post', $this->_wp_id);
1665 2210 endif;
1666 - } /* SyndicatedPost::update_existing() */
2211 + } /* SyndicatedPost::insert_new() */
1667 2212
1668 - /**
1669 - * SyndicatedPost::normalize_post()
1670 - *
1671 - * @param bool $new If true, this post is to be inserted anew. If false, it is an update of an existing post.
1672 - * @return array A normalized representation of the post ready to be inserted into the database or sent to the WordPress API functions
1673 - */
1674 - function normalize_post ($new = true) {
2213 + function update_existing () {
1675 2214 global $wpdb;
1676 2215
1677 - $out = array();
1678 -
1679 2216 // Why the fuck doesn't wp_insert_post already do this?
2217 + $dbpost = array();
1680 2218 foreach ($this->post as $key => $value) :
1681 2219 if (is_string($value)) :
1682 - $out[$key] = $wpdb->escape($value);
2220 + $dbpost[$key] = $wpdb->escape($value);
1683 2221 else :
1684 - $out[$key] = $value;
2222 + $dbpost[$key] = $value;
1685 2223 endif;
1686 2224 endforeach;
1687 2225
1688 - if (strlen($out['post_title'].$out['post_content'].$out['post_excerpt']) == 0) :
1689 - // FIXME: Option for filtering out empty posts
1690 - endif;
1691 - if (strlen($out['post_title'])==0) :
1692 - $offset = (int) get_option('gmt_offset') * 60 * 60;
1693 - $out['post_title'] =
1694 - $this->post['meta']['syndication_source']
1695 - .' '.gmdate('Y-m-d H:i:s', $this->published() + $offset);
1696 - // FIXME: Option for what to fill a blank title with...
1697 - endif;
2226 + if ($this->use_api('wp_insert_post')) :
2227 + $dbpost['post_pingback'] = false; // Tell WP 2.1 and 2.2 not to process for pingbacks
2228 + $this->_wp_id = wp_insert_post($dbpost);
1698 2229
1699 - return $out;
1700 - }
2230 + // This should never happen.
2231 + if (!is_numeric($this->_wp_id) or ($this->_wp_id == 0)) :
2232 + FeedWordPress::critical_bug('SyndicatedPost::_wp_id', $this->_wp_id, __LINE__);
2233 + endif;
1701 2234
1702 - /**
1703 - * SyndicatedPost::validate_post_id()
1704 - *
1705 - * @param array $dbpost An array representing the post we attempted to insert or update
1706 - * @param mixed $ns A string or array representing the namespace (class, method) whence this method was called.
1707 - */
1708 - function validate_post_id ($dbpost, $ns) {
1709 - if (is_array($ns)) : $ns = implode('::', $ns);
1710 - else : $ns = (string) $ns; endif;
1711 -
1712 - // This should never happen.
1713 - if (!is_numeric($this->_wp_id) or ($this->_wp_id == 0)) :
1714 - FeedWordPress::critical_bug(
1715 - /*name=*/ $ns.'::_wp_id',
1716 - /*var =*/ array(
1717 - "\$this->_wp_id" => $this->_wp_id,
1718 - "\$dbpost" => $dbpost,
1719 - "\$this" => $this
1720 - ),
1721 - /*line # =*/ __LINE__
1722 - );
2235 + // Unfortunately, as of WordPress 2.3, wp_insert_post()
2236 + // munges your post modified timestamp.
2237 + $result = $wpdb->query("
2238 + UPDATE $wpdb->posts
2239 + SET
2240 + post_modified='{$dbpost['post_modified']}',
2241 + post_modified_gmt='{$dbpost['post_modified_gmt']}'
2242 + WHERE ID='{$this->_wp_id}'
2243 + ");
2244 + else :
2245 +
2246 + $result = $wpdb->query("
2247 + UPDATE $wpdb->posts
2248 + SET
2249 + post_author = '{$dbpost['post_author']}',
2250 + post_content = '{$dbpost['post_content']}',"
2251 + .(isset($dbpost['post_excerpt']) ? "post_excerpt = '{$dbpost['post_excerpt']}'," : "")."
2252 + post_title = '{$dbpost['post_title']}',
2253 + post_name = '{$dbpost['post_name']}',
2254 + post_modified = '{$dbpost['post_modified']}',
2255 + post_modified_gmt = '{$dbpost['post_modified_gmt']}'
2256 + WHERE guid='{$dbpost['guid']}'
2257 + ");
2258 +
2259 + // WordPress 2.1.x and up
2260 + if (function_exists('wp_set_post_categories')) :
2261 + wp_set_post_categories($this->wp_id(), $this->post['post_category']);
2262 + // WordPress 1.5.x - 2.0.x
2263 + elseif (function_exists('wp_set_post_cats')) :
2264 + wp_set_post_cats('1', $this->wp_id(), $this->post['post_category']);
2265 + // This should never happen.
2266 + else :
2267 + FeedWordPress::critical_bug('SyndicatedPost::insert_new::wp_version', $GLOBALS['wp_version'], __LINE__);
2268 + endif;
2269 +
2270 + // Since we are not going through official channels, we need to
2271 + // manually tell WordPress that we've published a new post.
2272 + // We need to make sure to do this in order for FeedWordPress
2273 + // to play well with the staticize-reloaded plugin (something
2274 + // that a large aggregator website is going to *want* to be
2275 + // able to use).
2276 + do_action('edit_post', $this->post['ID']);
1723 2277 endif;
1724 - } /* SyndicatedPost::validate_post_id() */
1725 -
1726 - /**
1727 - * SyndicatedPost::fix_revision_meta() - Fixes the way WP 2.6+ fucks up
1728 - * meta-data (authorship, etc.) when storing revisions of an updated
1729 - * syndicated post.
1730 - *
1731 - * In their infinite wisdom, the WordPress coders have made it completely
1732 - * impossible for a plugin that uses wp_insert_post() to set certain
1733 - * meta-data (such as the author) when you store an old revision of an
1734 - * updated post. Instead, it uses the WordPress defaults (= currently
1735 - * active user ID if the process is running with a user logged in, or
1736 - * = #0 if there is no user logged in). This results in bogus authorship
1737 - * data for revisions that are syndicated from off the feed, unless we
1738 - * use a ridiculous kludge like this to end-run the munging of meta-data
1739 - * by _wp_put_post_revision.
1740 - *
1741 - * @param int $revision_id The revision ID to fix up meta-data
1742 - */
1743 - function fix_revision_meta ($revision_id) {
1744 - global $wpdb;
1745 -
1746 - $post_author = (int) $this->post['post_author'];
1747 -
1748 - $revision_id = (int) $revision_id;
1749 - $wpdb->query("
1750 - UPDATE $wpdb->posts
1751 - SET post_author={$this->post['post_author']}
1752 - WHERE post_type = 'revision' AND ID='$revision_id'
1753 - ");
1754 - } /* SyndicatedPost::fix_revision_meta () */
2278 + } /* SyndicatedPost::update_existing() */
1755 2279
1756 - /**
1757 - * SyndicatedPost::avoid_kses_munge() -- If FeedWordPress is processing
1758 - * an automatic update, that generally means that wp_insert_post() is
1759 - * being called under the user credentials of whoever is viewing the
1760 - * blog at the time -- usually meaning no user at all. But if WordPress
1761 - * gets a wp_insert_post() when current_user_can('unfiltered_html') is
1762 - * false, it will run the content of the post through a kses function
1763 - * that strips out lots of HTML tags -- notably <object> and some others.
1764 - * This causes problems for syndicating (for example) feeds that contain
1765 - * YouTube videos. It also produces an unexpected asymmetry between
1766 - * automatically-initiated updates and updates initiated manually from
1767 - * the WordPress Dashboard (which are usually initiated under the
1768 - * credentials of a logged-in admin, and so don't get run through the
1769 - * kses function). So, to avoid the whole mess, what we do here is
1770 - * just forcibly disable the kses munging for a single syndicated post,
1771 - * by restoring the contents of the `post_content` field.
1772 - *
1773 - * @param string $content The content of the post, after other filters have gotten to it
1774 - * @return string The original content of the post, before other filters had a chance to munge it.
1775 - */
1776 - function avoid_kses_munge ($content) {
1777 - global $wpdb;
1778 - return $wpdb->escape($this->post['post_content']);
1779 - }
1780 -
1781 2280 // SyndicatedPost::add_rss_meta: adds interesting meta-data to each entry
1782 2281 // using the space for custom keys. The set of keys and values to add is
1783 2282 // specified by the keys and values of $post['meta']. This is used to
1784 2283 // store anything that the WordPress user might want to access from a
@@ -1830,9 +2329,9 @@
1830 2329
1831 2330 // SyndicatedPost::author_id (): get the ID for an author name from
1832 2331 // the feed. Create the author if necessary.
1833 2332 function author_id ($unfamiliar_author = 'create') {
1834 - global $wpdb;
2333 + global $wpdb, $wp_db_version; // test for WordPress 2.0 database schema
1835 2334
1836 2335 $a = $this->author();
1837 2336 $author = $a['name'];
1838 2337 $email = $a['email'];
@@ -1837,15 +2336,8 @@
1837 2336 $author = $a['name'];
1838 2337 $email = $a['email'];
1839 2338 $url = $a['uri'];
1840 2339
1841 - $match_author_by_email = !('yes' == get_option("feedwordpress_do_not_match_author_by_email"));
1842 - if ($match_author_by_email and !FeedWordPress::is_null_email($email)) :
1843 - $test_email = $email;
1844 - else :
1845 - $test_email = NULL;
1846 - endif;
1847 -
1848 2340 // Never can be too careful...
1849 2341 $login = sanitize_user($author, /*strict=*/ true);
1850 2342 $login = apply_filters('pre_user_login', $login);
1851 2343
@@ -1854,93 +2346,88 @@
1854 2346
1855 2347 $reg_author = $wpdb->escape(preg_quote($author));
1856 2348 $author = $wpdb->escape($author);
1857 2349 $email = $wpdb->escape($email);
1858 - $test_email = $wpdb->escape($test_email);
1859 2350 $url = $wpdb->escape($url);
1860 2351
1861 - // Check for an existing author rule....
1862 - if (isset($this->link->settings['map authors']['name'][strtolower(trim($author))])) :
1863 - $author_rule = $this->link->settings['map authors']['name'][strtolower(trim($author))];
1864 - else :
1865 - $author_rule = NULL;
1866 - endif;
1867 -
1868 - // User name is mapped to a particular author. If that author ID exists, use it.
1869 - if (is_numeric($author_rule) and get_userdata((int) $author_rule)) :
1870 - $id = (int) $author_rule;
1871 -
1872 - // User name is filtered out
1873 - elseif ('filter' == $author_rule) :
1874 - $id = NULL;
1875 -
1876 - else :
1877 - // Check the database for an existing author record that might fit
1878 -
2352 + // Look for an existing author record that fits...
2353 + if (!isset($wp_db_version)) :
2354 + #-- WordPress 1.5.x
2355 + $id = $wpdb->get_var(
2356 + "SELECT ID from $wpdb->users
2357 + WHERE
2358 + TRIM(LCASE(user_login)) = TRIM(LCASE('$login')) OR
2359 + (
2360 + LENGTH(TRIM(LCASE(user_email))) > 0
2361 + AND TRIM(LCASE(user_email)) = TRIM(LCASE('$email'))
2362 + ) OR
2363 + TRIM(LCASE(user_firstname)) = TRIM(LCASE('$author')) OR
2364 + TRIM(LCASE(user_nickname)) = TRIM(LCASE('$author')) OR
2365 + TRIM(LCASE(user_nicename)) = TRIM(LCASE('$nice_author')) OR
2366 + TRIM(LCASE(user_description)) = TRIM(LCASE('$author')) OR
2367 + (
2368 + LOWER(user_description)
2369 + RLIKE CONCAT(
2370 + '(^|\\n)a\\.?k\\.?a\\.?( |\\t)*:?( |\\t)*',
2371 + LCASE('$reg_author'),
2372 + '( |\\t|\\r)*(\\n|\$)'
2373 + )
2374 + )
2375 + ");
2376 + elseif ($wp_db_version >= 2966) :
1879 2377 #-- WordPress 2.0+
1880 - if (fwp_test_wp_version(FWP_SCHEMA_HAS_USERMETA)) :
2378 +
2379 + # First try the user core data table.
2380 + $id = $wpdb->get_var(
2381 + "SELECT ID FROM $wpdb->users
2382 + WHERE
2383 + TRIM(LCASE(user_login)) = TRIM(LCASE('$login'))
2384 + OR (
2385 + LENGTH(TRIM(LCASE(user_email))) > 0
2386 + AND TRIM(LCASE(user_email)) = TRIM(LCASE('$email'))
2387 + )
2388 + OR TRIM(LCASE(user_nicename)) = TRIM(LCASE('$nice_author'))
2389 + ");
1881 2390
1882 - // First try the user core data table.
2391 + if (is_null($id)) : # Then look for aliases in the user meta data table
1883 2392 $id = $wpdb->get_var(
1884 - "SELECT ID FROM $wpdb->users
2393 + "SELECT user_id FROM $wpdb->usermeta
1885 2394 WHERE
1886 - TRIM(LCASE(user_login)) = TRIM(LCASE('$login'))
2395 + (meta_key = 'description' AND TRIM(LCASE(meta_value)) = TRIM(LCASE('$author')))
1887 2396 OR (
1888 - LENGTH(TRIM(LCASE(user_email))) > 0
1889 - AND TRIM(LCASE(user_email)) = TRIM(LCASE('$test_email'))
1890 - )
1891 - OR TRIM(LCASE(user_nicename)) = TRIM(LCASE('$nice_author'))
1892 - ");
1893 -
1894 - // If that fails, look for aliases in the user meta data table
1895 - if (is_null($id)) :
1896 - $id = $wpdb->get_var(
1897 - "SELECT user_id FROM $wpdb->usermeta
1898 - WHERE
1899 - (meta_key = 'description' AND TRIM(LCASE(meta_value)) = TRIM(LCASE('$author')))
1900 - OR (
1901 - meta_key = 'description'
1902 - AND TRIM(LCASE(meta_value))
1903 - RLIKE CONCAT(
1904 - '(^|\\n)a\\.?k\\.?a\\.?( |\\t)*:?( |\\t)*',
1905 - TRIM(LCASE('$reg_author')),
1906 - '( |\\t|\\r)*(\\n|\$)'
1907 - )
1908 - )
1909 - ");
1910 - endif;
1911 -
1912 - #-- WordPress 1.5.x
1913 - else :
1914 - $id = $wpdb->get_var(
1915 - "SELECT ID from $wpdb->users
1916 - WHERE
1917 - TRIM(LCASE(user_login)) = TRIM(LCASE('$login')) OR
1918 - (
1919 - LENGTH(TRIM(LCASE(user_email))) > 0
1920 - AND TRIM(LCASE(user_email)) = TRIM(LCASE('$test_email'))
1921 - ) OR
1922 - TRIM(LCASE(user_firstname)) = TRIM(LCASE('$author')) OR
1923 - TRIM(LCASE(user_nickname)) = TRIM(LCASE('$author')) OR
1924 - TRIM(LCASE(user_nicename)) = TRIM(LCASE('$nice_author')) OR
1925 - TRIM(LCASE(user_description)) = TRIM(LCASE('$author')) OR
1926 - (
1927 - LOWER(user_description)
2397 + meta_key = 'description'
2398 + AND TRIM(LCASE(meta_value))
1928 2399 RLIKE CONCAT(
1929 2400 '(^|\\n)a\\.?k\\.?a\\.?( |\\t)*:?( |\\t)*',
1930 - LCASE('$reg_author'),
2401 + TRIM(LCASE('$reg_author')),
1931 2402 '( |\\t|\\r)*(\\n|\$)'
1932 2403 )
1933 2404 )
1934 2405 ");
1935 -
1936 2406 endif;
2407 + endif;
1937 2408
1938 - // ... if you don't find one, then do what you need to do
1939 - if (is_null($id)) :
1940 - if ($unfamiliar_author === 'create') :
2409 + // ... if you don't find one, then do what you need to do
2410 + if (is_null($id)) :
2411 + if ($unfamiliar_author === 'create') :
2412 + if (!isset($wp_db_version)) :
2413 + #-- WordPress 1.5.x
2414 + $wpdb->query (
2415 + "INSERT INTO $wpdb->users
2416 + SET
2417 + ID='0',
2418 + user_login='$login',
2419 + user_firstname='$author',
2420 + user_nickname='$author',
2421 + user_nicename='$nice_author',
2422 + user_description='$author',
2423 + user_email='$email',
2424 + user_url='$url'");
2425 + $id = $wpdb->insert_id;
2426 + elseif ($wp_db_version >= 2966) :
2427 + #-- WordPress 2.0+
1941 2428 $userdata = array();
1942 -
2429 +
1943 2430 #-- user table data
1944 2431 $userdata['ID'] = NULL; // new user
1945 2432 $userdata['user_login'] = $login;
1946 2433 $userdata['user_nicename'] = $nice_author;
@@ -1947,26 +2434,20 @@
1947 2434 $userdata['user_pass'] = substr(md5(uniqid(microtime())), 0, 6); // just something random to lock it up
1948 2435 $userdata['user_email'] = $email;
1949 2436 $userdata['user_url'] = $url;
1950 2437 $userdata['display_name'] = $author;
1951 -
2438 +
1952 2439 $id = wp_insert_user($userdata);
1953 - elseif (is_numeric($unfamiliar_author) and get_userdata((int) $unfamiliar_author)) :
1954 - $id = (int) $unfamiliar_author;
1955 - elseif ($unfamiliar_author === 'default') :
1956 - $id = 1;
1957 2440 endif;
2441 + elseif ($unfamiliar_author === 'default') :
2442 + $id = 1;
1958 2443 endif;
1959 2444 endif;
1960 -
1961 - if ($id) :
1962 - $this->link->settings['map authors']['name'][strtolower(trim($author))] = $id;
1963 - endif;
1964 2445 return $id;
1965 2446 } // function SyndicatedPost::author_id ()
1966 2447
1967 2448 // look up (and create) category ids from a list of categories
1968 - function category_ids ($cats, $unfamiliar_category = 'create', $tags_too = false) {
2449 + function category_ids ($cats, $unfamiliar_category = 'create') {
1969 2450 global $wpdb;
1970 2451
1971 2452 // We need to normalize whitespace because (1) trailing
1972 2453 // whitespace can cause PHP and MySQL not to see eye to eye on
@@ -1975,10 +2456,8 @@
1975 2456 // because I doubt most people want to make a semantic
1976 2457 // distinction between 'Computers' and 'Computers '
1977 2458 $cats = array_map('trim', $cats);
1978 2459
1979 - $tags = array();
1980 -
1981 2460 $cat_ids = array ();
1982 2461 foreach ($cats as $cat_name) :
1983 2462 if (preg_match('/^{#([0-9]+)}$/', $cat_name, $backref)) :
1984 2463 $cat_id = (int) $backref[1];
@@ -1986,9 +2465,9 @@
1986 2465 $cat_ids[] = $cat_id;
1987 2466 elseif (get_category($cat_id)) :
1988 2467 $cat_ids[] = $cat_id;
1989 2468 endif;
1990 - elseif (strlen($cat_name) > 0) :
2469 + else :
1991 2470 $esc = $wpdb->escape($cat_name);
1992 2471 $resc = $wpdb->escape(preg_quote($cat_name));
1993 2472
1994 2473 // WordPress 2.3+
@@ -2006,17 +2485,11 @@
2006 2485 )) :
2007 2486 foreach ($results AS $term) :
2008 2487 $cat_ids[] = (int) $term->term_id;
2009 2488 endforeach;
2010 - elseif ('tag'==$unfamiliar_category) :
2011 - $tags[] = $cat_name;
2012 2489 elseif ('create'===$unfamiliar_category) :
2013 2490 $term = wp_insert_term($cat_name, 'category');
2014 - if (is_wp_error($term)) :
2015 - FeedWordPress::noncritical_bug('term insertion problem', array('cat_name' => $cat_name, 'term' => $term, 'this' => $this), __LINE__);
2016 - else :
2017 - $cat_ids[] = $term['term_id'];
2018 - endif;
2491 + $cat_ids[] = $term['term_id'];
2019 2492 endif;
2020 2493
2021 2494 // WordPress 1.5.x - 2.2.x
2022 2495 else :
@@ -2057,28 +2530,18 @@
2057 2530 $cat_ids = NULL; // Drop the post
2058 2531 else :
2059 2532 $cat_ids = array_unique($cat_ids);
2060 2533 endif;
2061 -
2062 - if ($tags_too) : $ret = array($cat_ids, $tags);
2063 - else : $ret = $cat_ids;
2064 - endif;
2065 -
2066 - return $ret;
2534 + return $cat_ids;
2067 2535 } // function SyndicatedPost::category_ids ()
2068 2536
2069 2537 function use_api ($tag) {
2070 2538 global $wp_db_version;
2071 - switch ($tag) :
2072 - case 'wp_insert_post':
2539 + if ('wp_insert_post'==$tag) :
2073 2540 // Before 2.2, wp_insert_post does too much of the wrong stuff to use it
2074 2541 // In 1.5 it was such a resource hog it would make PHP segfault on big updates
2075 2542 $ret = (isset($wp_db_version) and $wp_db_version > FWP_SCHEMA_21);
2076 - break;
2077 - case 'post_status_pending':
2078 - $ret = (isset($wp_db_version) and $wp_db_version > FWP_SCHEMA_23);
2079 - break;
2080 - endswitch;
2543 + endif;
2081 2544 return $ret;
2082 2545 } // function SyndicatedPost::use_api ()
2083 2546
2084 2547 #### EXTRACT DATA FROM FEED ITEM ####
@@ -2116,18 +2579,14 @@
2116 2579 endif;
2117 2580
2118 2581 # If everything failed, then default to the current time.
2119 2582 if (is_null($epoch)) :
2120 - if (-1 == $default) :
2121 - $epoch = time();
2122 - else :
2123 - $epoch = $default;
2124 - endif;
2583 + $epoch = time();
2125 2584 endif;
2126 2585
2127 2586 return $epoch;
2128 2587 }
2129 - function updated ($fallback = true, $default = -1) {
2588 + function updated ($fallback = true) {
2130 2589 $epoch = null;
2131 2590
2132 2591 # As far as I know, only dcterms and Atom have reliable ways to
2133 2592 # specify when something was *modified* last. If neither is
@@ -2140,27 +2599,19 @@
2140 2599 $epoch = @parse_w3cdtf($this->item['modified']);
2141 2600 elseif (isset($this->item['updated'])): // Atom 1.0
2142 2601 $epoch = @parse_w3cdtf($this->item['updated']);
2143 2602 elseif ($fallback) : // Fall back to issued / dc:date
2144 - $epoch = $this->published(/*fallback=*/ false, /*default=*/ $default);
2603 + $epoch = $this->published(/*fallback=*/ false);
2145 2604 endif;
2146 2605
2147 2606 # If everything failed, then default to the current time.
2148 2607 if (is_null($epoch)) :
2149 - if (-1 == $default) :
2150 - $epoch = time();
2151 - else :
2152 - $epoch = $default;
2153 - endif;
2608 + $epoch = time();
2154 2609 endif;
2155 2610
2156 2611 return $epoch;
2157 2612 }
2158 2613
2159 - function update_hash () {
2160 - return md5(serialize($this->item));
2161 - }
2162 -
2163 2614 function guid () {
2164 2615 $guid = null;
2165 2616 if (isset($this->item['id'])): // Atom 0.3 / 1.0
2166 2617 $guid = $this->item['id'];
@@ -2247,97 +2698,318 @@
2247 2698 endif;
2248 2699
2249 2700 return $author;
2250 2701 } // SyndicatedPost::author()
2702 +} // class SyndicatedPost
2703 +
2704 +# class SyndicatedLink: represents a syndication feed stored within the
2705 +# WordPress database
2706 +#
2707 +# To keep things compact and editable from within WordPress, we use all the
2708 +# links under a particular category in the WordPress "Blogroll" for the list of
2709 +# feeds to syndicate. "Contributors" is the category used by default; you can
2710 +# configure that under Options --> Syndication.
2711 +#
2712 +# Fields used are:
2713 +#
2714 +# * link_rss: the URI of the Atom/RSS feed to syndicate
2715 +#
2716 +# * link_notes: user-configurable options, with keys and values
2717 +# like so:
2718 +#
2719 +# key: value
2720 +# cats: computers\nweb
2721 +# feed/key: value
2722 +#
2723 +# Keys that start with "feed/" are gleaned from the data supplied
2724 +# by the feed itself, and will be overwritten with each update.
2725 +#
2726 +# Values have linebreak characters escaped with C-style
2727 +# backslashes (so, for example, a newline becomes "\n").
2728 +#
2729 +# The value of `cats` is used as a newline-separated list of
2730 +# default categories for any post coming from a particular feed.
2731 +# (In the example above, any posts from this feed will be placed
2732 +# in the "computers" and "web" categories--*in addition to* any
2733 +# categories that may already be applied to the posts.)
2734 +#
2735 +# Values of keys in link_notes are accessible from templates using
2736 +# the function `get_feed_meta($key)` if this plugin is activated.
2737 +
2738 +class SyndicatedLink {
2739 + var $id = null;
2740 + var $link = null;
2741 + var $settings = array ();
2742 + var $magpie = null;
2743 +
2744 + function SyndicatedLink ($link) {
2745 + global $wpdb;
2746 +
2747 + if (is_object($link)) :
2748 + $this->link = $link;
2749 + $this->id = $link->link_id;
2750 + else :
2751 + $this->id = $link;
2752 + if (function_exists('get_bookmark')) : // WP 2.1+
2753 + $this->link = get_bookmark($link);
2754 + else :
2755 + $this->link = $wpdb->get_row("
2756 + SELECT * FROM $wpdb->links
2757 + WHERE (link_id = '".$wpdb->escape($link)."')"
2758 + );
2759 + endif;
2760 + endif;
2761 +
2762 + if (strlen($this->link->link_rss) > 0) :
2763 + // Read off feed settings from link_notes
2764 + $notes = explode("\n", $this->link->link_notes);
2765 + foreach ($notes as $note):
2766 + list($key, $value) = explode(": ", $note, 2);
2251 2767
2252 - var $uri_attrs = array (
2253 - array('a', 'href'),
2254 - array('applet', 'codebase'),
2255 - array('area', 'href'),
2256 - array('blockquote', 'cite'),
2257 - array('body', 'background'),
2258 - array('del', 'cite'),
2259 - array('form', 'action'),
2260 - array('frame', 'longdesc'),
2261 - array('frame', 'src'),
2262 - array('iframe', 'longdesc'),
2263 - array('iframe', 'src'),
2264 - array('head', 'profile'),
2265 - array('img', 'longdesc'),
2266 - array('img', 'src'),
2267 - array('img', 'usemap'),
2268 - array('input', 'src'),
2269 - array('input', 'usemap'),
2270 - array('ins', 'cite'),
2271 - array('link', 'href'),
2272 - array('object', 'classid'),
2273 - array('object', 'codebase'),
2274 - array('object', 'data'),
2275 - array('object', 'usemap'),
2276 - array('q', 'cite'),
2277 - array('script', 'src')
2278 - ); /* var SyndicatedPost::$uri_attrs */
2768 + if (strlen($key) > 0) :
2769 + // Unescape and trim() off the whitespace.
2770 + // Thanks to Ray Lischner for pointing out the
2771 + // need to trim off whitespace.
2772 + $this->settings[$key] = stripcslashes (trim($value));
2773 + endif;
2774 + endforeach;
2279 2775
2280 - var $_base = null;
2776 + // "Magic" feed settings
2777 + $this->settings['link/uri'] = $this->link->link_rss;
2778 + $this->settings['link/name'] = $this->link->link_name;
2779 + $this->settings['link/id'] = $this->link->link_id;
2780 +
2781 + // `hardcode categories` is deprecated in favor of `unfamiliar categories`
2782 + if (
2783 + FeedWordPress::affirmative($this->settings, 'hardcode categories')
2784 + and !isset($this->settings['unfamiliar categories'])
2785 + ) :
2786 + $this->settings['unfamiliar categories'] = 'default';
2787 + endif;
2788 +
2789 + // Set this up automagically for del.icio.us
2790 + if (!isset($this->settings['cat_split']) and false !== strpos($this->link->link_rss, 'del.icio.us')) :
2791 + $this->settings['cat_split'] = '\s'; // Whitespace separates multiple tags in del.icio.us RSS feeds
2792 + endif;
2281 2793
2282 - function resolve_single_relative_uri ($refs) {
2283 - $tag = FeedWordPressHTML::attributeMatch($refs);
2284 - $url = Relative_URI::resolve($tag['value'], $this->_base);
2285 - return $tag['prefix'] . $url . $tag['suffix'];
2286 - } /* function SyndicatedPost::resolve_single_relative_uri() */
2794 + if (isset($this->settings['cats'])):
2795 + $this->settings['cats'] = preg_split(FEEDWORDPRESS_CAT_SEPARATOR_PATTERN, $this->settings['cats']);
2796 + endif;
2797 + endif;
2798 + } // SyndicatedLink::SyndicatedLink ()
2799 +
2800 + function found () {
2801 + return is_object($this->link);
2802 + }
2287 2803
2288 - function resolve_relative_uris ($content, $obj) {
2289 - # The MagpieRSS upgrade has some `xml:base` support baked in.
2290 - # However, sometimes people do silly things, like putting
2291 - # relative URIs out on a production RSS 2.0 feed or other feeds
2292 - # with no good support for `xml:base`. So we'll do our best to
2293 - # try to catch any remaining relative URIs and resolve them as
2294 - # best we can.
2295 - $obj->_base = $obj->item['link']; // Reset the base for resolving relative URIs
2804 + function stale () {
2805 + $stale = true;
2806 + if (isset($this->settings['update/hold']) and ($this->settings['update/hold']=='ping')) :
2807 + $stale = false; // don't update on any timed updates; pings only
2808 + elseif (isset($this->settings['update/hold']) and ($this->settings['update/hold']=='next')) :
2809 + $stale = true; // update on the next timed update
2810 + elseif (!isset($this->settings['update/ttl']) or !isset($this->settings['update/last'])) :
2811 + $stale = true; // initial update
2812 + else :
2813 + $after = ((int) $this->settings['update/last'])
2814 + +((int) $this->settings['update/ttl'] * 60);
2815 + $stale = (time() >= $after);
2816 + endif;
2817 + return $stale;
2818 + }
2296 2819
2297 - foreach ($obj->uri_attrs as $pair) :
2298 - list($tag, $attr) = $pair;
2299 - $pattern = FeedWordPressHTML::attributeRegex($tag, $attr);
2300 - $content = preg_replace_callback (
2301 - $pattern,
2302 - array(&$obj, 'resolve_single_relative_uri'),
2303 - $content
2304 - );
2305 - endforeach;
2820 + function poll () {
2821 + global $wpdb;
2306 2822
2307 - return $content;
2308 - } /* function SyndicatedPost::resolve_relative_uris () */
2823 + $this->magpie = fetch_rss($this->link->link_rss);
2824 + $new_count = NULL;
2309 2825
2310 - var $strip_attrs = array (
2311 - array('[a-z]+', 'target'),
2312 -// array('[a-z]+', 'style'),
2313 -// array('[a-z]+', 'on[a-z]+'),
2314 - );
2826 + if (is_object($this->magpie)) :
2827 + $new_count = array('new' => 0, 'updated' => 0);
2315 2828
2316 - function strip_attribute_from_tag ($refs) {
2317 - $tag = FeedWordPressHTML::attributeMatch($refs);
2318 - return $tag['before_attribute'].$tag['after_attribute'];
2829 + # -- Update Link metadata live from feed
2830 + $channel = $this->magpie->channel;
2831 +
2832 + if (!isset($channel['id'])) :
2833 + $channel['id'] = $this->link->link_rss;
2834 + endif;
2835 +
2836 + $update = array();
2837 + if (!$this->hardcode('url') and isset($channel['link'])) :
2838 + $update[] = "link_url = '".$wpdb->escape($channel['link'])."'";
2839 + endif;
2840 +
2841 + if (!$this->hardcode('name') and isset($channel['title'])) :
2842 + $update[] = "link_name = '".$wpdb->escape($channel['title'])."'";
2843 + endif;
2844 +
2845 + if (!$this->hardcode('description')) :
2846 + if (isset($channel['tagline'])) :
2847 + $update[] = "link_description = '".$wpdb->escape($channel['tagline'])."'";
2848 + elseif (isset($channel['description'])) :
2849 + $update[] = "link_description = '".$wpdb->escape($channel['description'])."'";
2850 + endif;
2851 + endif;
2852 +
2853 + $this->settings = array_merge($this->settings, $this->flatten_array($channel));
2854 +
2855 + $this->settings['update/last'] = time(); $ttl = $this->ttl();
2856 + if (!is_null($ttl)) :
2857 + $this->settings['update/ttl'] = $ttl;
2858 + $this->settings['update/timed'] = 'feed';
2859 + else :
2860 + $this->settings['update/ttl'] = rand(30, 120); // spread over time interval for staggered updates
2861 + $this->settings['update/timed'] = 'automatically';
2862 + endif;
2863 +
2864 + if (!isset($this->settings['update/hold']) or $this->settings['update/hold']!='ping') :
2865 + $this->settings['update/hold'] = 'scheduled';
2866 + endif;
2867 +
2868 + // Copy back without a few things that we don't want to save in the notes
2869 + $to_notes = $this->settings;
2870 +
2871 + if (is_array($to_notes['cats'])) :
2872 + $to_notes['cats'] = implode(FEEDWORDPRESS_CAT_SEPARATOR, $to_notes['cats']);
2873 + endif;
2874 + unset($to_notes['link/id']); unset($to_notes['link/uri']);
2875 + unset($to_notes['link/name']);
2876 + unset($to_notes['hardcode categories']); // Deprecated
2877 +
2878 + $notes = '';
2879 + foreach ($to_notes as $key => $value) :
2880 + $notes .= $key . ": ". addcslashes($value, "\0..\37".'\\') . "\n";
2881 + endforeach;
2882 + $update[] = "link_notes = '".$wpdb->escape($notes)."'";
2883 +
2884 + $update_set = implode(',', $update);
2885 +
2886 + // Update the properties of the link from the feed information
2887 + $result = $wpdb->query("
2888 + UPDATE $wpdb->links
2889 + SET $update_set
2890 + WHERE link_id='$this->id'
2891 + ");
2892 +
2893 + # -- Add new posts from feed and update any updated posts
2894 + if (is_array($this->magpie->items)) :
2895 + foreach ($this->magpie->items as $item) :
2896 + $post =& new SyndicatedPost($item, $this);
2897 + if (!$post->filtered()) :
2898 + $new = $post->store();
2899 + if ( $new !== false ) $new_count[$new]++;
2900 + endif;
2901 + endforeach;
2902 + endif;
2903 + endif;
2904 + return $new_count;
2905 + } /* SyndicatedLink::poll() */
2906 +
2907 + function uri () {
2908 + return (is_object($this->link) ? $this->link->link_rss : NULL);
2319 2909 }
2910 + function homepage () {
2911 + return (isset($this->settings['feed/link']) ? $this->settings['feed/link'] : NULL);
2912 + }
2320 2913
2321 - function sanitize_content ($content, $obj) {
2322 - # This kind of sucks. I intend to replace it with
2323 - # lib_filter sometime soon.
2324 - foreach ($obj->strip_attrs as $pair):
2325 - list($tag,$attr) = $pair;
2326 - $pattern = FeedWordPressHTML::attributeRegex($tag, $attr);
2914 + function ttl () {
2915 + if (is_object($this->magpie)) :
2916 + $channel = $this->magpie->channel;
2917 + else :
2918 + $channel = array();
2919 + endif;
2327 2920
2328 - $content = preg_replace_callback (
2329 - $pattern,
2330 - array(&$obj, 'strip_attribute_from_tag'),
2331 - $content
2921 + if (isset($channel['ttl'])) :
2922 + // "ttl stands for time to live. It's a number of
2923 + // minutes that indicates how long a channel can be
2924 + // cached before refreshing from the source."
2925 + // <http://blogs.law.harvard.edu/tech/rss#ltttlgtSubelementOfLtchannelgt>
2926 + $ret = $channel['ttl'];
2927 + elseif (isset($channel['sy']['updatefrequency']) or isset($channel['sy']['updateperiod'])) :
2928 + $period_minutes = array (
2929 + 'hourly' => 60, /* minutes in an hour */
2930 + 'daily' => 1440, /* minutes in a day */
2931 + 'weekly' => 10080, /* minutes in a week */
2932 + 'monthly' => 43200, /* minutes in a month */
2933 + 'yearly' => 525600, /* minutes in a year */
2332 2934 );
2333 - endforeach;
2334 - return $content;
2335 - }
2336 -} // class SyndicatedPost
2337 2935
2338 -require_once(dirname(__FILE__) . '/syndicatedlink.class.php');
2936 + // "sy:updatePeriod: Describes the period over which the
2937 + // channel format is updated. Acceptable values are:
2938 + // hourly, daily, weekly, monthly, yearly. If omitted,
2939 + // daily is assumed." <http://web.resource.org/rss/1.0/modules/syndication/>
2940 + if (isset($channel['sy']['updateperiod'])) : $period = $channel['sy']['updateperiod'];
2941 + else : $period = 'daily';
2942 + endif;
2943 +
2944 + // "sy:updateFrequency: Used to describe the frequency
2945 + // of updates in relation to the update period. A
2946 + // positive integer indicates how many times in that
2947 + // period the channel is updated. ... If omitted a value
2948 + // of 1 is assumed." <http://web.resource.org/rss/1.0/modules/syndication/>
2949 + if (isset($channel['sy']['updatefrequency'])) : $freq = (int) $channel['sy']['updatefrequency'];
2950 + else : $freq = 1;
2951 + endif;
2952 +
2953 + $ret = (int) ($period_minutes[$period] / $freq);
2954 + else :
2955 + $ret = NULL;
2956 + endif;
2957 + return $ret;
2958 + } /* SyndicatedLink::ttl() */
2339 2959
2960 + // SyndicatedLink:flatten_array (): flatten an array. Useful for
2961 + // hierarchical and namespaced elements.
2962 + //
2963 + // Given an array which may contain array or object elements in it,
2964 + // return a "flattened" array: a one-dimensional array of scalars
2965 + // containing each of the scalar elements contained within the array
2966 + // structure. Thus, for example, if $a['b']['c']['d'] == 'e', then the
2967 + // returned array for FeedWordPress::flatten_array($a) will contain a key
2968 + // $a['feed/b/c/d'] with value 'e'.
2969 + function flatten_array ($arr, $prefix = 'feed/', $separator = '/') {
2970 + $ret = array ();
2971 + if (is_array($arr)) :
2972 + foreach ($arr as $key => $value) :
2973 + if (is_scalar($value)) :
2974 + $ret[$prefix.$key] = $value;
2975 + else :
2976 + $ret = array_merge($ret, $this->flatten_array($value, $prefix.$key.$separator, $separator));
2977 + endif;
2978 + endforeach;
2979 + endif;
2980 + return $ret;
2981 + } // function SyndicatedLink::flatten_array ()
2982 +
2983 + function hardcode ($what) {
2984 + $default = get_option("feedwordpress_hardcode_$what");
2985 + if ( $default === 'yes' ) :
2986 + // If the default is to hardcode, then we want the
2987 + // negation of negative(): TRUE by default and FALSE if
2988 + // the setting is explicitly "no"
2989 + $ret = !FeedWordPress::negative($this->settings, "hardcode $what");
2990 + else :
2991 + // If the default is NOT to hardcode, then we want
2992 + // affirmative(): FALSE by default and TRUE if the
2993 + // setting is explicitly "yes"
2994 + $ret = FeedWordPress::affirmative($this->settings, "hardcode $what");
2995 + endif;
2996 + return $ret;
2997 + } // function SyndicatedLink::hardcode ()
2998 +
2999 + function syndicated_status ($what, $default) {
3000 + global $wpdb;
3001 +
3002 + $ret = get_option("feedwordpress_syndicated_{$what}_status");
3003 + if ( isset($this->settings["$what status"]) ) :
3004 + $ret = $this->settings["$what status"];
3005 + elseif (!$ret) :
3006 + $ret = $default;
3007 + endif;
3008 + return $wpdb->escape(trim(strtolower($ret)));
3009 + } // function SyndicatedLink:syndicated_status ()
3010 +} // class SyndicatedLink
3011 +
2340 3012 ################################################################################
2341 3013 ## XML-RPC HOOKS: accept XML-RPC update pings from Contributors ################
2342 3014 ################################################################################
2343 3015
@@ -2370,9 +3042,8 @@
2370 3042
2371 3043 var $verify = FALSE;
2372 3044
2373 3045 var $_data = NULL;
2374 - var $_error = NULL;
2375 3046 var $_head = NULL;
2376 3047
2377 3048 # -- Recognition patterns
2378 3049 var $_feed_types = array(
@@ -2406,12 +3077,8 @@
2406 3077
2407 3078 // If all that failed, look harder
2408 3079 if (count($href) == 0) $href = $this->_a_href_feeds(FALSE);
2409 3080
2410 - // Our search may turn up duplicate URIs. We only need to do any given URI once.
2411 - // Props to Camilo <http://projects.radgeek.com/2008/12/14/feedwordpress-20081214/#comment-20090122160414>
2412 - $href = array_unique($href);
2413 -
2414 3081 // Verify feeds and resolve relative URIs
2415 3082 foreach ($href as $u) {
2416 3083 $the_uri = Relative_URI::resolve($u, $this->uri);
2417 3084 if ($this->verify) {
@@ -2431,12 +3098,8 @@
2431 3098 $this->_get($uri);
2432 3099 return $this->_data;
2433 3100 }
2434 3101
2435 - function error () {
2436 - return $this->_error;
2437 - }
2438 -
2439 3102 function is_feed ($uri = NULL) {
2440 3103 $data = $this->data($uri);
2441 3104
2442 3105 return (
@@ -2455,23 +3118,23 @@
2455 3118 if ($uri) $this->uri = $uri;
2456 3119
2457 3120 // Is the result not yet cached?
2458 3121 if ($this->_cache_uri !== $this->uri) :
2459 - $headers['Connection'] = 'close';
2460 - $headers['Accept'] = 'application/atom+xml application/rdf+xml application/rss+xml application/xml text/html */*';
2461 - $headers['User-Agent'] = 'feedfinder/1.2 (compatible; PHP FeedFinder) +http://projects.radgeek.com/feedwordpress';
3122 + // Snoopy is an HTTP client in PHP
3123 + $client = new Snoopy();
3124 +
3125 + // Prepare headers and internal settings
3126 + $client->rawheaders['Connection'] = 'close';
3127 + $client->accept = 'application/atom+xml application/rdf+xml application/rss+xml application/xml text/html */*';
3128 + $client->agent = 'feedfinder/1.2 (compatible; PHP FeedFinder) +http://projects.radgeek.com/feedwordpress';
3129 + $client->read_timeout = 25;
3130 +
3131 + // Fetch the HTML or feed
3132 + @$client->fetch($this->uri);
3133 + $this->_data = $client->results;
2462 3134
2463 - // Use function provided by MagpieRSS package
2464 - $client = _fetch_remote_file($this->uri, $headers);
2465 - if (isset($client->error)) :
2466 - $this->_error = $client->error;
2467 - else :
2468 - $this->_error = NULL;
2469 - endif;
2470 - $this->_data = $client->results;
2471 -
2472 - // Kilroy was here
2473 - $this->_cache_uri = $this->uri;
3135 + // Kilroy was here
3136 + $this->_cache_uri = $this->uri;
2474 3137 endif;
2475 3138 } /* FeedFinder::_get () */
2476 3139
2477 3140 function _link_rel_feeds () {
@@ -2732,5 +3395,5 @@
2732 3395 $ret['name'] = NULL; $ret['email'] = NULL;
2733 3396 endif;
2734 3397 return $ret;
2735 3398 }
2736 -
3399 +?>