source: trunk/www.guidonia.net/wp/wp-content/plugins/feedwordpress/feedwordpress.php@ 44

Last change on this file since 44 was 44, checked in by luciano, 14 years ago
File size: 42.8 KB
Line 
1<?php
2/*
3Plugin Name: FeedWordPress
4Plugin URI: http://projects.radgeek.com/feedwordpress
5Description: simple and flexible Atom/RSS syndication for WordPress
6Version: 2009.0707
7Author: Charles Johnson
8Author URI: http://radgeek.com/
9License: GPL
10*/
11
12# This uses code derived from:
13# - wp-rss-aggregate.php by Kellan Elliot-McCrea <kellan@protest.net>
14# - HTTP Navigator 2 by Keyvan Minoukadeh <keyvan@k1m.com>
15# - Ultra-Liberal Feed Finder by Mark Pilgrim <mark@diveintomark.org>
16# according to the terms of the GNU General Public License.
17#
18# INSTALLATION: see readme.txt or <http://projects.radgeek.com/install>
19#
20# 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
24# <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.
28
29# -- Don't change these unless you know what you're doing...
30
31define ('FEEDWORDPRESS_VERSION', '2009.0707');
32define ('FEEDWORDPRESS_AUTHOR_CONTACT', 'http://radgeek.com/contact');
33define ('DEFAULT_SYNDICATION_CATEGORY', 'Contributors');
34
35$feedwordpress_debug = get_option('feedwordpress_debug');
36if (is_string($feedwordpress_debug)) :
37 $feedwordpress_debug = ($feedwordpress_debug == 'yes');
38endif;
39define ('FEEDWORDPRESS_DEBUG', $feedwordpress_debug);
40
41define ('FEEDWORDPRESS_CAT_SEPARATOR_PATTERN', '/[:\n]/');
42define ('FEEDWORDPRESS_CAT_SEPARATOR', "\n");
43
44define ('FEEDVALIDATOR_URI', 'http://feedvalidator.org/check.cgi');
45
46define ('FEEDWORDPRESS_FRESHNESS_INTERVAL', 10*60); // Every ten minutes
47
48define ('FWP_SCHEMA_HAS_USERMETA', 2966);
49define ('FWP_SCHEMA_20', 3308); // Database schema # for WP 2.0
50define ('FWP_SCHEMA_21', 4772); // Database schema # for WP 2.1
51define ('FWP_SCHEMA_23', 5495); // Database schema # for WP 2.3
52define ('FWP_SCHEMA_25', 7558); // Database schema # for WP 2.5
53define ('FWP_SCHEMA_26', 8201); // Database schema # for WP 2.6
54define ('FWP_SCHEMA_27', 9872); // Database schema # for WP 2.7
55define ('FWP_SCHEMA_28', 11548); // Database schema # for WP 2.8
56
57if (FEEDWORDPRESS_DEBUG) :
58 // Help us to pick out errors, if any.
59 ini_set('error_reporting', E_ALL & ~E_NOTICE);
60 ini_set('display_errors', true);
61 define('MAGPIE_DEBUG', true);
62
63 // When testing we don't want cache issues to interfere. But this is
64 // a VERY BAD SETTING for a production server. Webmasters will eat your
65 // face for breakfast if you use it, and the baby Jesus will cry. So
66 // make sure FEEDWORDPRESS_DEBUG is FALSE for any site that will be
67 // used for more than testing purposes!
68 define('MAGPIE_CACHE_AGE', 1);
69else :
70 define('MAGPIE_DEBUG', false);
71endif;
72
73// Note that the rss-functions.php that comes prepackaged with WordPress is
74// old & busted. For the new hotness, drop a copy of rss.php from
75// this archive into wp-includes/rss.php
76
77if (is_readable(ABSPATH . WPINC . '/rss.php')) :
78 require_once (ABSPATH . WPINC . '/rss.php');
79else :
80 require_once (ABSPATH . WPINC . '/rss-functions.php');
81endif;
82
83if (isset($wp_db_version)) :
84 if ($wp_db_version >= FWP_SCHEMA_23) :
85 require_once (ABSPATH . WPINC . '/registration.php'); // for wp_insert_user
86 elseif ($wp_db_version >= FWP_SCHEMA_21) : // WordPress 2.1 and 2.2, but not 2.3
87 require_once (ABSPATH . WPINC . '/registration.php'); // for wp_insert_user
88 require_once (ABSPATH . 'wp-admin/admin-db.php'); // for wp_insert_category
89 elseif ($wp_db_version >= FWP_SCHEMA_20) : // WordPress 2.0
90 require_once (ABSPATH . WPINC . '/registration-functions.php'); // for wp_insert_user
91 require_once (ABSPATH . 'wp-admin/admin-db.php'); // for wp_insert_category
92 endif;
93endif;
94
95require_once(dirname(__FILE__) . '/compatability.php'); // LEGACY API: Replicate or mock up functions for legacy support purposes
96require_once(dirname(__FILE__) . '/feedwordpresshtml.class.php');
97
98// Magic quotes are just about the stupidest thing ever.
99if (is_array($_POST)) :
100 $fwp_post = stripslashes_deep($_POST);
101endif;
102
103// Get the path relative to the plugins directory in which FWP is stored
104preg_match (
105 '|/wp-content/plugins/(.+)$|',
106 dirname(__FILE__),
107 $ref
108);
109
110if (isset($ref[1])) :
111 $fwp_path = $ref[1];
112else : // Something went wrong. Let's just guess.
113 $fwp_path = 'feedwordpress';
114endif;
115
116// If this is a FeedWordPress admin page, queue up scripts for AJAX functions that FWP uses
117// If it is a display page or a non-FeedWordPress admin page, don't.
118if (is_admin() and isset($_REQUEST['page']) and preg_match("|^{$fwp_path}/|", $_REQUEST['page'])) :
119 if (function_exists('wp_enqueue_script')) :
120 if (isset($wp_db_version) and $wp_db_version >= FWP_SCHEMA_25) :
121 wp_enqueue_script('post'); // for magic tag and category boxes
122 wp_enqueue_script('thickbox'); // for fold-up boxes
123 wp_enqueue_script('admin-forms'); // for checkbox selection
124 else :
125 wp_enqueue_script( 'ajaxcat' ); // Provides the handy-dandy new category text box
126 endif;
127 endif;
128 if (function_exists('wp_enqueue_style')) :
129 if (fwp_test_wp_version(FWP_SCHEMA_25)) :
130 wp_enqueue_style('dashboard');
131 endif;
132 endif;
133 if (function_exists('wp_admin_css')) :
134 if (fwp_test_wp_version(FWP_SCHEMA_25)) :
135 wp_admin_css('css/dashboard');
136 endif;
137 endif;
138endif;
139
140if (!FeedWordPress::needs_upgrade()) : // only work if the conditions are safe!
141
142 # Syndicated items are generally received in output-ready (X)HTML and
143 # should not be folded, crumpled, mutilated, or spindled by WordPress
144 # formatting filters. But we don't want to interfere with filters for
145 # any locally-authored posts, either.
146 #
147 # What WordPress should really have is a way for upstream filters to
148 # stop downstream filters from running at all. Since it doesn't, and
149 # since a downstream filter can't access the original copy of the text
150 # that is being filtered, what we will do here is (1) save a copy of the
151 # original text upstream, before any other filters run, and then (2)
152 # retrieve that copy downstream, after all the other filters run, *if*
153 # this is a syndicated post
154
155 add_filter('the_content', 'feedwordpress_preserve_syndicated_content', -10000);
156 add_filter('the_content', 'feedwordpress_restore_syndicated_content', 10000);
157
158 add_action('atom_entry', 'feedwordpress_item_feed_data');
159
160 # Filter in original permalinks if the user wants that
161 add_filter('post_link', 'syndication_permalink', 1);
162
163 # WTF? By default, wp_insert_link runs incoming link_url and link_rss
164 # URIs through default filters that include `wp_kses()`. But `wp_kses()`
165 # just happens to escape any occurrence of & to &amp; -- which just
166 # happens to fuck up any URI with a & to separate GET parameters.
167 remove_filter('pre_link_rss', 'wp_filter_kses');
168 remove_filter('pre_link_url', 'wp_filter_kses');
169
170 # Admin menu
171 add_action('admin_menu', 'fwp_add_pages');
172 add_action('admin_notices', 'fwp_check_debug');
173 add_action('admin_notices', 'fwp_check_magpie');
174
175 # Inbound XML-RPC update methods
176 add_filter('xmlrpc_methods', 'feedwordpress_xmlrpc_hook');
177
178 # Outbound XML-RPC ping reform
179 remove_action('publish_post', 'generic_ping'); // WP 1.5.x
180 remove_action('do_pings', 'do_all_pings', 10, 1); // WP 2.1, 2.2
181 remove_action('publish_post', '_publish_post_hook', 5, 1); // WP 2.3
182
183 add_action('publish_post', 'fwp_publish_post_hook', 5, 1);
184 add_action('do_pings', 'fwp_do_pings', 10, 1);
185 add_action('feedwordpress_update', 'fwp_hold_pings');
186 add_action('feedwordpress_update_complete', 'fwp_release_pings');
187
188 # Hook in logging functions only if the logging option is ON
189 $update_logging = get_option('feedwordpress_update_logging');
190 if ($update_logging == 'yes') :
191 add_action('post_syndicated_item', 'log_feedwordpress_post', 100);
192 add_action('update_syndicated_item', 'log_feedwordpress_update_post', 100);
193 add_action('feedwordpress_update', 'log_feedwordpress_update_feeds', 100);
194 add_action('feedwordpress_check_feed', 'log_feedwordpress_check_feed', 100);
195 add_action('feedwordpress_update_complete', 'log_feedwordpress_update_complete', 100);
196 endif;
197
198 # Cron-less auto-update. Hooray!
199 add_action('init', 'feedwordpress_auto_update');
200 add_action('init', 'feedwordpress_check_for_magpie_fix');
201
202 # Default sanitizers
203 add_filter('syndicated_item_content', array('SyndicatedPost', 'resolve_relative_uris'), 0, 2);
204 add_filter('syndicated_item_content', array('SyndicatedPost', 'sanitize_content'), 0, 2);
205
206else :
207 # Hook in the menus, which will just point to the upgrade interface
208 add_action('admin_menu', 'fwp_add_pages');
209endif; // if (!FeedWordPress::needs_upgrade())
210
211function feedwordpress_check_for_magpie_fix () {
212 if (isset($_POST['action']) and $_POST['action']=='fix_magpie_version') :
213 FeedWordPressCompatibility::validate_http_request(/*action=*/ 'feedwordpress_fix_magpie', /*capability=*/ 'edit_files');
214
215 $back_to = $_SERVER['REQUEST_URI'];
216 if (isset($_POST['ignore'])) :
217 // kill error message by telling it we ignored the upgrade request for this version
218 update_option('feedwordpress_magpie_ignored_upgrade_to', EXPECTED_MAGPIE_VERSION);
219 $ret = 'ignored';
220 elseif (isset($_POST['upgrade'])) :
221 $source = dirname(__FILE__)."/MagpieRSS-upgrade/rss.php";
222 $destination = ABSPATH . WPINC . '/rss.php';
223 $success = @copy($source, $destination);
224 $ret = (int) $success;
225 endif;
226
227 if (strpos($back_to, '?')===false) : $sep = '?';
228 else : $sep = '&';
229 endif;
230
231 header("Location: {$back_to}{$sep}feedwordpress_magpie_fix=".$ret);
232 exit;
233 endif;
234} /* feedwordpress_check_for_magpie_fix() */
235
236function feedwordpress_auto_update () {
237 if (FeedWordPress::stale()) :
238 $feedwordpress =& new FeedWordPress;
239 $feedwordpress->update();
240 endif;
241
242 if (FeedWordPress::update_requested()) :
243 exit;
244 endif;
245} /* feedwordpress_auto_update () */
246
247################################################################################
248## LOGGING FUNCTIONS: log status updates to error_log if you want it ###########
249################################################################################
250
251function log_feedwordpress_post ($id) {
252 $post = wp_get_single_post($id);
253 error_log("[".date('Y-m-d H:i:s')."][feedwordpress] posted "
254 ."'{$post->post_title}' ({$post->post_date})");
255}
256
257function log_feedwordpress_update_post ($id) {
258 $post = wp_get_single_post($id);
259 error_log("[".date('Y-m-d H:i:s')."][feedwordpress] updated "
260 ."'{$post->post_title}' ({$post->post_date})"
261 ." (as of {$post->post_modified})");
262}
263
264function log_feedwordpress_update_feeds ($uri) {
265 error_log("[".date('Y-m-d H:i:s')."][feedwordpress] update('$uri')");
266}
267
268function log_feedwordpress_check_feed ($feed) {
269 $uri = $feed['link/uri']; $name = $feed['link/name'];
270 error_log("[".date('Y-m-d H:i:s')."][feedwordpress] Examining $name <$uri>");
271}
272
273function log_feedwordpress_update_complete ($delta) {
274 $mesg = array();
275 if (isset($delta['new'])) $mesg[] = 'added '.$delta['new'].' new posts';
276 if (isset($delta['updated'])) $mesg[] = 'updated '.$delta['updated'].' existing posts';
277 if (empty($mesg)) $mesg[] = 'nothing changed';
278
279 error_log("[".date('Y-m-d H:i:s')."][feedwordpress] "
280 .(is_null($delta) ? "Error: I don't syndicate that URI"
281 : implode(' and ', $mesg)));
282}
283
284################################################################################
285## TEMPLATE API: functions to make your templates syndication-aware ############
286################################################################################
287
288function is_syndicated () { return (strlen(get_syndication_feed_id()) > 0); }
289
290function get_syndication_source_link ($original = NULL) {
291 if (is_null($original)) : $original = FeedWordPress::use_aggregator_source_data();
292 endif;
293
294 if ($original) : $vals = get_post_custom_values('syndication_source_uri_original');
295 else : $vals = array();
296 endif;
297
298 if (count($vals) == 0) : $vals = get_post_custom_values('syndication_source_uri');
299 endif;
300
301 if (count($vals) > 0) : $ret = $vals[0]; else : $ret = NULL; endif;
302
303 return $ret;
304} /* function get_syndication_source_link() */
305
306function the_syndication_source_link ($original = NULL) { echo get_syndication_source_link($original); }
307
308function get_syndication_source ($original = NULL) {
309 if (is_null($original)) : $original = FeedWordPress::use_aggregator_source_data();
310 endif;
311
312 if ($original) : $vals = get_post_custom_values('syndication_source_original');
313 else : $vals = array();
314 endif;
315
316 if (count($vals) == 0) : $vals = get_post_custom_values('syndication_source');
317 endif;
318
319 if (count($vals) > 0) : $ret = $vals[0]; else : $ret = NULL; endif;
320
321 return $ret;
322} /* function get_syndication_source() */
323
324function the_syndication_source ($original = NULL) { echo get_syndication_source($original); }
325
326function get_syndication_feed ($original = NULL) {
327 if (is_null($original)) : $original = FeedWordPress::use_aggregator_source_data();
328 endif;
329
330 if ($original) : $vals = get_post_custom_values('syndication_feed_original');
331 else : $vals = array();
332 endif;
333
334 if (count($vals) == 0) : $vals = get_post_custom_values('syndication_feed');
335 endif;
336
337 if (count($vals) > 0) : $ret = $vals[0]; else : $ret = NULL; endif;
338
339 return $ret;
340} /* function get_syndication_feed() */
341
342function the_syndication_feed ($original = NULL) { echo get_syndication_feed ($original); }
343
344function get_syndication_feed_guid ($original = NULL) {
345 if (is_null($original)) : $original = FeedWordPress::use_aggregator_source_data();
346 endif;
347
348 if ($original) : $vals = get_post_custom_values('syndication_source_id_original');
349 else : $vals = array();
350 endif;
351
352 if (count($vals) == 0) : $vals = array(get_feed_meta('feed/id'));
353 endif;
354
355 if (count($vals) > 0) : $ret = $vals[0]; else : $ret = NULL; endif;
356
357 return $ret;
358} /* function get_syndication_feed_guid () */
359
360function the_syndication_feed_guid ($original = NULL) { echo get_syndication_feed_guid($original); }
361
362function get_syndication_feed_id () { list($u) = get_post_custom_values('syndication_feed_id'); return $u; }
363function the_syndication_feed_id () { echo get_syndication_feed_id(); }
364
365$feedwordpress_linkcache = array (); // only load links from database once
366
367function get_feed_meta ($key) {
368 global $wpdb, $feedwordpress_linkcache;
369 $feed_id = get_syndication_feed_id();
370
371 $ret = NULL;
372 if (strlen($feed_id) > 0):
373 if (isset($feedwordpress_linkcache[$feed_id])) :
374 $link = $feedwordpress_linkcache[$feed_id];
375 else :
376 $link =& new SyndicatedLink($feed_id);
377 $feedwordpress_linkcache[$feed_id] = $link;
378 endif;
379
380 $ret = $link->settings[$key];
381 endif;
382 return $ret;
383} /* get_feed_meta() */
384
385function get_syndication_permalink () {
386 list($u) = get_post_custom_values('syndication_permalink'); return $u;
387}
388function the_syndication_permalink () {
389 echo get_syndication_permalink();
390}
391
392################################################################################
393## FILTERS: syndication-aware handling of post data for templates and feeds ####
394################################################################################
395
396$feedwordpress_the_syndicated_content = NULL;
397
398function feedwordpress_preserve_syndicated_content ($text) {
399 global $feedwordpress_the_syndicated_content;
400
401 $globalExpose = (get_option('feedwordpress_formatting_filters') == 'yes');
402 $localExpose = get_post_custom_values('_feedwordpress_formatting_filters');
403 $expose = ($globalExpose or ((count($localExpose) > 0) and $localExpose[0]));
404
405 if ( is_syndicated() and !$expose ) :
406 $feedwordpress_the_syndicated_content = $text;
407 else :
408 $feedwordpress_the_syndicated_content = NULL;
409 endif;
410 return $text;
411}
412
413function feedwordpress_restore_syndicated_content ($text) {
414 global $feedwordpress_the_syndicated_content;
415
416 if ( !is_null($feedwordpress_the_syndicated_content) ) :
417 $text = $feedwordpress_the_syndicated_content;
418 endif;
419
420 return $text;
421}
422
423function feedwordpress_item_feed_data () {
424 // In a post context....
425 if (is_syndicated()) :
426?>
427<source>
428 <title><?php the_syndication_source(); ?></title>
429 <link rel="alternate" type="text/html" href="<?php the_syndication_source_link(); ?>" />
430 <link rel="self" href="<?php the_syndication_feed(); ?>" />
431<?php
432 $id = get_syndication_feed_guid();
433 if (strlen($id) > 0) :
434?>
435 <id><?php print $id; ?></id>
436<?php
437 endif;
438 $updated = get_feed_meta('feed/updated');
439 if (strlen($updated) > 0) : ?>
440 <updated><?php print $updated; ?></updated>
441<?php
442 endif;
443?>
444</source>
445<?php
446 endif;
447}
448
449function syndication_permalink ($permalink = '') {
450 if (get_option('feedwordpress_munge_permalink') != 'no'):
451 $uri = get_syndication_permalink();
452 return ((strlen($uri) > 0) ? $uri : $permalink);
453 else:
454 return $permalink;
455 endif;
456} // function syndication_permalink ()
457
458################################################################################
459## ADMIN MENU ADD-ONS: register Dashboard management pages #####################
460################################################################################
461
462function fwp_add_pages () {
463 global $fwp_capability;
464 global $fwp_path;
465
466 $menu = array('Syndicated Sites', 'Syndication', $fwp_capability['manage_links'], $fwp_path.'/syndication.php', NULL);
467 if (fwp_test_wp_version(FWP_SCHEMA_27)) :
468 // add icon parameter
469 $menu[] = WP_PLUGIN_URL.'/'.$fwp_path.'/feedwordpress-tiny.png';
470 endif;
471
472 if (fwp_test_wp_version(FWP_SCHEMA_26)) :
473 $options = __('Settings');
474 $longoptions = __('Syndication Settings');
475 else :
476 $options = __('Options');
477 $longoptions = __('Syndication Options');
478 endif;
479
480 call_user_func_array('add_menu_page', $menu);
481 add_submenu_page($fwp_path.'/syndication.php', 'Syndicated Posts', 'Posts', $fwp_capability['manage_options'], $fwp_path.'/posts-page.php');
482 add_submenu_page($fwp_path.'/syndication.php', 'Syndicated Authors', 'Authors', $fwp_capability['manage_options'], $fwp_path.'/authors-page.php');
483 add_submenu_page($fwp_path.'/syndication.php', 'Categories & Tags', 'Categories & Tags', $fwp_capability['manage_options'], $fwp_path.'/categories-page.php');
484 add_submenu_page($fwp_path.'/syndication.php', $longoptions, $options, $fwp_capability['manage_options'], $fwp_path.'/syndication-options.php');
485
486 add_options_page($longoptions, 'Syndication', $fwp_capability['manage_options'], $fwp_path.'/syndication-options.php');
487} /* function fwp_add_pages () */
488
489function fwp_check_debug () {
490 // This is a horrible fucking kludge that I have to do because the
491 // admin notice code is triggered before the code that updates the
492 // setting.
493 if (isset($_POST['feedwordpress_debug'])) :
494 $feedwordpress_debug = $_POST['feedwordpress_debug'];
495 else :
496 $feedwordpress_debug = get_option('feedwordpress_debug');
497 endif;
498 if ($feedwordpress_debug==='yes') :
499?>
500 <div class="error">
501<p><strong>FeedWordPress warning.</strong> Debugging mode is <strong>ON</strong>.
502While it remains on, FeedWordPress displays many diagnostic error messages,
503warnings, and notices that are ordinarily suppressed, and also turns off all
504caching of feeds. Use with caution: this setting is absolutely inappropriate
505for a production server.</p>
506 </div>
507<?php
508 endif;
509} /* function fwp_check_debug () */
510
511define('EXPECTED_MAGPIE_VERSION', '2009.0618');
512function fwp_check_magpie () {
513 if (isset($_REQUEST['feedwordpress_magpie_fix'])) :
514 if ($_REQUEST['feedwordpress_magpie_fix']=='ignored') :
515?>
516<div class="updated fade">
517<p>O.K., we'll ignore the problem for now. FeedWordPress will not display any
518more error messages.</p>
519</div>
520<?php
521 elseif ((bool) $_REQUEST['feedwordpress_magpie_fix']) :
522?>
523<div class="updated fade">
524<p>Congratulations! Your MagpieRSS has been successfully upgraded to the version
525shipped with FeedWordPress.</p>
526</div>
527<?php
528 else :
529 $source = dirname(__FILE__)."/MagpieRSS-upgrade/rss.php";
530 $destination = ABSPATH . WPINC . '/rss.php';
531 $cmd = "cp '".htmlspecialchars(addslashes($source))."' '".htmlspecialchars(addslashes($destination))."'";
532 $cmd = wordwrap($cmd, /*width=*/ 75, /*break=*/ " \\\n\t");
533
534?>
535<div class="error">
536<p><strong>FeedWordPress was unable to automatically upgrade your copy of MagpieRSS.</strong></p>
537<p>It's likely that you need to change the file permissions on <code><?php print htmlspecialchars($source); ?></code>
538to allow FeedWordPress to overwrite it.</p>
539<p><strong>To perform the upgrade manually,</strong> you can
540use a SFTP or FTP client to upload a copy of <code>rss.php</code> from the
541<code>MagpieRSS-upgrades/</code> directory of your FeedWordPress archive so that
542it overwrites <code><?php print htmlspecialchars($destination); ?></code>. Or,
543if your web host provides shell access, you can issue the following command from
544a command prompt to perform the upgrade:</p>
545<pre>
546<samp>$</samp> <kbd><?php print $cmd; ?></kbd>
547</pre>
548<p><strong>If you've fixed the file permissions,</strong> you can try the
549automatic upgrade again.</p>
550
551<?php feedwordpress_upgrade_old_and_busted_buttons(); ?>
552</div>
553<?php
554 endif;
555 else :
556 $magpie_version = FeedWordPress::magpie_version();
557
558 $ignored = get_option('feedwordpress_magpie_ignored_upgrade_to');
559 if (EXPECTED_MAGPIE_VERSION != $magpie_version and EXPECTED_MAGPIE_VERSION != $ignored) :
560 if (current_user_can('edit_files')) :
561 $youAre = 'you are';
562 $itIsRecommendedThatYou = 'It is <strong>strongly recommended</strong> that you';
563 else :
564 $youAre = 'this site is';
565 $itIsRecommendedThatYou = 'You may want to contact the administrator of the site; it is <strong>strongly recommended</strong> that they';
566 endif;
567 print '<div class="error">';
568?>
569<p style="font-style: italic"><strong>FeedWordPress has detected that <?php print $youAre; ?> currently using a version of
570MagpieRSS other than the upgraded version that ships with this version of FeedWordPress.</strong></p>
571<ul>
572<li><strong>Currently running:</strong> MagpieRSS <?php print $magpie_version; ?></li>
573<li><strong>Version included with FeedWordPress <?php print FEEDWORDPRESS_VERSION; ?>:</strong> MagpieRSS <?php print EXPECTED_MAGPIE_VERSION; ?></li>
574</ul>
575<p><?php print $itIsRecommendedThatYou; ?> install the upgraded
576version of MagpieRSS supplied with FeedWordPress. The version of
577MagpieRSS that ships with WordPress is very old and buggy, and
578encounters a number of errors when trying to parse modern Atom
579and RSS feeds.</p>
580<?php
581 feedwordpress_upgrade_old_and_busted_buttons();
582 print '</div>';
583 endif;
584 endif;
585}
586
587function feedwordpress_upgrade_old_and_busted_buttons() {
588 if (current_user_can('edit_files')) :
589?>
590<form action="" method="post"><div>
591<?php FeedWordPressCompatibility::stamp_nonce('feedwordpress_fix_magpie'); ?>
592<input type="hidden" name="action" value="fix_magpie_version" />
593<input class="button-secondary" type="submit" name="ignore" value="<?php _e('Ignore this problem'); ?>" />
594<input class="button-primary" type="submit" name="upgrade" value="<?php _e('Upgrade'); ?>" />
595</div></form>
596<?php
597 endif;
598}
599
600################################################################################
601## fwp_hold_pings() and fwp_release_pings(): Outbound XML-RPC ping reform ####
602## ... 'coz it's rude to send 500 pings the first time your aggregator runs ####
603################################################################################
604
605$fwp_held_ping = NULL; // NULL: not holding pings yet
606
607function fwp_hold_pings () {
608 global $fwp_held_ping;
609 if (is_null($fwp_held_ping)):
610 $fwp_held_ping = 0; // 0: ready to hold pings; none yet received
611 endif;
612}
613
614function fwp_release_pings () {
615 global $fwp_held_ping;
616 if ($fwp_held_ping):
617 if (function_exists('wp_schedule_single_event')) :
618 wp_schedule_single_event(time(), 'do_pings');
619 else :
620 generic_ping($fwp_held_ping);
621 endif;
622 endif;
623 $fwp_held_ping = NULL; // NULL: not holding pings anymore
624}
625
626function fwp_do_pings () {
627 if (!is_null($fwp_held_ping) and $post_id) : // Defer until we're done updating
628 $fwp_held_ping = $post_id;
629 elseif (function_exists('do_all_pings')) :
630 do_all_pings();
631 else :
632 generic_ping($fwp_held_ping);
633 endif;
634}
635
636function fwp_publish_post_hook ($post_id) {
637 global $fwp_held_ping;
638
639 if (!is_null($fwp_held_ping)) : // Syndicated post. Don't mark with _pingme
640 if ( defined('XMLRPC_REQUEST') )
641 do_action('xmlrpc_publish_post', $post_id);
642 if ( defined('APP_REQUEST') )
643 do_action('app_publish_post', $post_id);
644
645 if ( defined('WP_IMPORTING') )
646 return;
647
648 // Defer sending out pings until we finish updating
649 $fwp_held_ping = $post_id;
650 else :
651 if (function_exists('_publish_post_hook')) : // WordPress 2.3
652 _publish_post_hook($post_id);
653 endif;
654 endif;
655}
656
657################################################################################
658## class FeedWordPress #########################################################
659################################################################################
660
661// class FeedWordPress: handles feed updates and plugs in to the XML-RPC interface
662class FeedWordPress {
663 var $strip_attrs = array (
664 array('[a-z]+', 'style'),
665 array('[a-z]+', 'target'),
666 );
667 var $uri_attrs = array (
668 array('a', 'href'),
669 array('applet', 'codebase'),
670 array('area', 'href'),
671 array('blockquote', 'cite'),
672 array('body', 'background'),
673 array('del', 'cite'),
674 array('form', 'action'),
675 array('frame', 'longdesc'),
676 array('frame', 'src'),
677 array('iframe', 'longdesc'),
678 array('iframe', 'src'),
679 array('head', 'profile'),
680 array('img', 'longdesc'),
681 array('img', 'src'),
682 array('img', 'usemap'),
683 array('input', 'src'),
684 array('input', 'usemap'),
685 array('ins', 'cite'),
686 array('link', 'href'),
687 array('object', 'classid'),
688 array('object', 'codebase'),
689 array('object', 'data'),
690 array('object', 'usemap'),
691 array('q', 'cite'),
692 array('script', 'src')
693 );
694
695 var $feeds = NULL;
696
697 # function FeedWordPress (): Contructor; retrieve a list of feeds
698 function FeedWordPress () {
699 $this->feeds = array ();
700 $links = FeedWordPress::syndicated_links();
701 if ($links): foreach ($links as $link):
702 $this->feeds[] =& new SyndicatedLink($link);
703 endforeach; endif;
704 } // FeedWordPress::FeedWordPress ()
705
706 # function update (): polls for updates on one or more Contributor feeds
707 #
708 # Arguments:
709 # ----------
710 # * $uri (string): either the URI of the feed to poll, the URI of the
711 # (human-readable) website whose feed you want to poll, or NULL.
712 #
713 # If $uri is NULL, then FeedWordPress will poll any feeds that are
714 # ready for polling. It will not poll feeds that are marked as
715 # "Invisible" Links (signifying that the subscription has been
716 # de-activated), or feeds that are not yet stale according to their
717 # TTL setting (which is either set in the feed, or else set
718 # randomly within a window of 30 minutes - 2 hours).
719 #
720 # Returns:
721 # --------
722 # * Normally returns an associative array, with 'new' => the number
723 # of new posts added during the update, and 'updated' => the number
724 # of old posts that were updated during the update. If both numbers
725 # are zero, there was no change since the last poll on that URI.
726 #
727 # * Returns NULL if URI it was passed was not a URI that this
728 # installation of FeedWordPress syndicates.
729 #
730 # Effects:
731 # --------
732 # * One or more feeds are polled for updates
733 #
734 # * If the feed Link does not have a hardcoded name set, its Link
735 # Name is synchronized with the feed's title element
736 #
737 # * If the feed Link does not have a hardcoded URI set, its Link URI
738 # is synchronized with the feed's human-readable link element
739 #
740 # * If the feed Link does not have a hardcoded description set, its
741 # Link Description is synchronized with the feed's description,
742 # tagline, or subtitle element.
743 #
744 # * The time of polling is recorded in the feed's settings, and the
745 # TTL (time until the feed is next available for polling) is set
746 # either from the feed (if it is supplied in the ttl or syndication
747 # module elements) or else from a randomly-generated time window
748 # (between 30 minutes and 2 hours).
749 #
750 # * New posts from the polled feed are added to the WordPress store.
751 #
752 # * Updates to existing posts since the last poll are mirrored in the
753 # WordPress store.
754 #
755 function update ($uri = null, $crash_ts = null) {
756 global $wpdb;
757
758 if (FeedWordPress::needs_upgrade()) : // Will make duplicate posts if we don't hold off
759 return NULL;
760 endif;
761
762 if (!is_null($uri)) :
763 $uri = trim($uri);
764 else : // Update all
765 update_option('feedwordpress_last_update_all', time());
766 endif;
767
768 do_action('feedwordpress_update', $uri);
769
770 if (is_null($crash_ts)) :
771 $crash_dt = (int) get_option('feedwordpress_update_time_limit');
772 if ($crash_dt > 0) :
773 $crash_ts = time() + $crash_dt;
774 else :
775 $crash_ts = NULL;
776 endif;
777 endif;
778
779 // Randomize order for load balancing purposes
780 $feed_set = $this->feeds;
781 shuffle($feed_set);
782
783 // Loop through and check for new posts
784 $delta = NULL;
785 foreach ($feed_set as $feed) :
786 if (!is_null($crash_ts) and (time() > $crash_ts)) : // Check whether we've exceeded the time limit
787 break;
788 endif;
789
790 $pinged_that = (is_null($uri) or in_array($uri, array($feed->uri(), $feed->homepage())));
791
792 if (!is_null($uri)) : // A site-specific ping always updates
793 $timely = true;
794 else :
795 $timely = $feed->stale();
796 endif;
797
798 if ($pinged_that and is_null($delta)) : // If at least one feed was hit for updating...
799 $delta = array('new' => 0, 'updated' => 0); // ... don't return error condition
800 endif;
801
802 if ($pinged_that and $timely) :
803 do_action('feedwordpress_check_feed', $feed->settings);
804 $start_ts = time();
805 $added = $feed->poll($crash_ts);
806 do_action('feedwordpress_check_feed_complete', $feed->settings, $added, time() - $start_ts);
807
808 if (isset($added['new'])) : $delta['new'] += $added['new']; endif;
809 if (isset($added['updated'])) : $delta['updated'] += $added['updated']; endif;
810 endif;
811 endforeach;
812
813 do_action('feedwordpress_update_complete', $delta);
814
815 return $delta;
816 }
817
818 function stale () {
819 if (get_option('feedwordpress_automatic_updates')) :
820 $last = get_option('feedwordpress_last_update_all');
821
822 // If we haven't updated all yet, give it a time window
823 if (false === $last) :
824 $ret = false;
825 update_option('feedwordpress_last_update_all', time());
826
827 // Otherwise, check against freshness interval
828 elseif (is_numeric($last)) : // Expect a timestamp
829 $freshness = get_option('feedwordpress_freshness');
830 if (false === $freshness) : // Use default
831 $freshness = FEEDWORDPRESS_FRESHNESS_INTERVAL;
832 endif;
833 $ret = ( (time() - $last) > $freshness);
834
835 // This should never happen.
836 else :
837 FeedWordPress::critical_bug('FeedWordPress::stale::last', $last, __LINE__);
838 endif;
839
840 // Explicit request for an update (e.g. from a cron job).
841 elseif (FeedWordPress::update_requested()) :
842 $ret = true;
843
844 else :
845 $ret = false;
846 endif;
847 return $ret;
848 } // FeedWordPress::stale()
849
850 function update_requested () {
851 return (isset($_REQUEST['update_feedwordpress']) and $_REQUEST['update_feedwordpress']);
852 } // FeedWordPress::update_requested()
853
854 function syndicate_link ($name, $uri, $rss) {
855 global $wpdb;
856
857 // Get the category ID#
858 $cat_id = FeedWordPress::link_category_id();
859
860 // WordPress gets cranky if there's no homepage URI
861 if (!isset($uri) or strlen($uri)<1) : $uri = $rss; endif;
862
863 if (function_exists('wp_insert_link')) { // WordPress 2.x
864 $link_id = wp_insert_link(array(
865 "link_name" => $name,
866 "link_url" => $uri,
867 "link_category" => (fwp_test_wp_version(0, FWP_SCHEMA_21) ? $cat_id : array($cat_id)),
868 "link_rss" => $rss
869 ));
870 } else { // WordPress 1.5.x
871 $result = $wpdb->query("
872 INSERT INTO $wpdb->links
873 SET
874 link_name = '".$wpdb->escape($name)."',
875 link_url = '".$wpdb->escape($uri)."',
876 link_category = '".$wpdb->escape($cat_id)."',
877 link_rss = '".$wpdb->escape($rss)."'
878 ");
879 $link_id = $wpdb->insert_id;
880 } // if
881 return $link_id;
882 } // function FeedWordPress::syndicate_link()
883
884 function on_unfamiliar ($what = 'author', $override = NULL) {
885 $set = array(
886 'author' => array('create', 'default', 'filter'),
887 'category' => array('create', 'tag', 'default', 'filter'),
888 );
889
890 if (is_string($override)) :
891 $ret = strtolower($override);
892 endif;
893
894 if (!is_numeric($override) and !in_array($ret, $set[$what])) :
895 $ret = get_option('feedwordpress_unfamiliar_'.$what);
896 if (!is_numeric($ret) and !in_array($ret, $set[$what])) :
897 $ret = 'create';
898 endif;
899 endif;
900
901 return $ret;
902 } // function FeedWordPress::on_unfamiliar()
903
904 function null_email_set () {
905 $base = get_option('feedwordpress_null_email_set');
906
907 if ($base===false) :
908 $ret = array('noreply@blogger.com'); // default
909 else :
910 $ret = array_map('strtolower',
911 array_map('trim', explode("\n", $base)));
912 endif;
913 $ret = apply_filters('syndicated_item_author_null_email_set', $ret);
914 return $ret;
915
916 } /* FeedWordPress::null_email_set () */
917
918 function is_null_email ($email) {
919 $ret = in_array(strtolower(trim($email)), FeedWordPress::null_email_set());
920 $ret = apply_filters('syndicated_item_author_is_null_email', $ret, $email);
921 return $ret;
922 } /* FeedWordPress::is_null_email () */
923
924 function use_aggregator_source_data () {
925 $ret = get_option('feedwordpress_use_aggregator_source_data');
926 return apply_filters('syndicated_post_use_aggregator_source_data', ($ret=='yes'));
927 }
928
929 function syndicated_links () {
930 $contributors = FeedWordPress::link_category_id();
931 if (function_exists('get_bookmarks')) :
932 $links = get_bookmarks(array("category" => $contributors));
933 else:
934 $links = get_linkobjects($contributors); // deprecated as of WP 2.1
935 endif;
936 return $links;
937 } // function FeedWordPress::syndicated_links()
938
939 function link_category_id () {
940 global $wpdb, $wp_db_version;
941
942 $cat_id = get_option('feedwordpress_cat_id');
943
944 // If we don't yet *have* the category, we'll have to create it
945 if ($cat_id === false) :
946 $cat = $wpdb->escape(DEFAULT_SYNDICATION_CATEGORY);
947
948 // Look for something with the right name...
949 // -----------------------------------------
950
951 // WordPress 2.3 introduces a new taxonomy/term API
952 if (function_exists('is_term')) :
953 $cat_id = is_term($cat, 'link_category');
954 // WordPress 2.1 and 2.2 use a common table for both link and post categories
955 elseif (fwp_test_wp_version(FWP_SCHEMA_21, FWP_SCHEMA_23)) :
956 $cat_id = $wpdb->get_var("SELECT cat_id FROM {$wpdb->categories} WHERE cat_name='$cat'");
957 // WordPress 1.5 and 2.0.x have a separate table for link categories
958 elseif (fwp_test_wp_version(0, FWP_SCHEMA_21)):
959 $cat_id = $wpdb->get_var("SELECT cat_id FROM {$wpdb->linkcategories} WHERE cat_name='$cat'");
960 // This should never happen.
961 else :
962 FeedWordPress::critical_bug('FeedWordPress::link_category_id::wp_db_version', $wp_db_version, __LINE__);
963 endif;
964
965 // If you still can't find anything, make it for yourself.
966 // -------------------------------------------------------
967 if (!$cat_id) :
968 // WordPress 2.3+ term/taxonomy API
969 if (function_exists('wp_insert_term')) :
970 $term = wp_insert_term($cat, 'link_category');
971 $cat_id = $term['term_id'];
972 // WordPress 2.1, 2.2 category API. By the way, why the fuck is this API function only available in a wp-admin module?
973 elseif (function_exists('wp_insert_category') and !fwp_test_wp_version(FWP_SCHEMA_20, FWP_SCHEMA_21)) :
974 $cat_id = wp_insert_category(array('cat_name' => $cat));
975 // WordPress 1.5 and 2.0.x
976 elseif (fwp_test_wp_version(0, FWP_SCHEMA_21)) :
977 $result = $wpdb->query("
978 INSERT INTO $wpdb->linkcategories
979 SET
980 cat_id = 0,
981 cat_name='$cat',
982 show_images='N',
983 show_description='N',
984 show_rating='N',
985 show_updated='N',
986 sort_order='name'
987 ");
988 $cat_id = $wpdb->insert_id;
989 // This should never happen.
990 else :
991 FeedWordPress::critical_bug('FeedWordPress::link_category_id::wp_db_version', $wp_db_version, __LINE__);
992 endif;
993 endif;
994
995 update_option('feedwordpress_cat_id', $cat_id);
996 endif;
997 return $cat_id;
998 } // function FeedWordPress::link_category_id()
999
1000 # Upgrades and maintenance...
1001 function needs_upgrade () {
1002 global $wpdb;
1003 $fwp_db_version = get_option('feedwordpress_version');
1004 $ret = false; // innocent until proven guilty
1005 if (!$fwp_db_version or $fwp_db_version < FEEDWORDPRESS_VERSION) :
1006 // This is an older version or a fresh install. Does it
1007 // require a database upgrade or database initialization?
1008 if ($fwp_db_version <= 0.96) :
1009 // Yes. Check to see whether this is a fresh install or an upgrade.
1010 $syn = $wpdb->get_col("
1011 SELECT post_id
1012 FROM $wpdb->postmeta
1013 WHERE meta_key = 'syndication_feed'
1014 ");
1015 if (count($syn) > 0) : // contains at least one syndicated post
1016 $ret = true;
1017 else : // fresh install; brand it as ours
1018 update_option('feedwordpress_version', FEEDWORDPRESS_VERSION);
1019 endif;
1020 elseif ($fwp_db_version < 2009.0707) :
1021 // We need to clear out any busted AJAX crap
1022 if (fwp_test_wp_version(FWP_SCHEMA_HAS_USERMETA)) :
1023 $wpdb->query("
1024 DELETE FROM $wpdb->usermeta
1025 WHERE LOCATE('feedwordpress', meta_key)
1026 AND LOCATE('box', meta_key);
1027 ");
1028 endif;
1029 update_option('feedwordpress_version', FEEDWORDPRESS_VERSION);
1030 else :
1031 // No. Just brand it with the new version.
1032 update_option('feedwordpress_version', FEEDWORDPRESS_VERSION);
1033 endif;
1034 endif;
1035 return $ret;
1036 }
1037
1038 function upgrade_database ($from = NULL) {
1039 global $wpdb;
1040
1041 if (is_null($from) or $from <= 0.96) : $from = 0.96; endif;
1042
1043 switch ($from) :
1044 case 0.96: // account for changes to syndication custom values and guid
1045 echo "<p>Upgrading database from {$from} to ".FEEDWORDPRESS_VERSION."...</p>\n";
1046
1047 $cat_id = FeedWordPress::link_category_id();
1048
1049 // Avoid duplicates
1050 $wpdb->query("DELETE FROM `{$wpdb->postmeta}` WHERE meta_key = 'syndication_feed_id'");
1051
1052 // Look up all the link IDs
1053 $wpdb->query("
1054 CREATE TEMPORARY TABLE tmp_custom_values
1055 SELECT
1056 NULL AS meta_id,
1057 post_id,
1058 'syndication_feed_id' AS meta_key,
1059 link_id AS meta_value
1060 FROM `{$wpdb->postmeta}`, `{$wpdb->links}`
1061 WHERE
1062 meta_key='syndication_feed'
1063 AND meta_value=link_rss
1064 AND link_category = {$cat_id}
1065 ");
1066
1067 // Now attach them to their posts
1068 $wpdb->query("INSERT INTO `{$wpdb->postmeta}` SELECT * FROM tmp_custom_values");
1069
1070 // And clean up after ourselves.
1071 $wpdb->query("DROP TABLE tmp_custom_values");
1072
1073 // Now fix the guids to avoid duplicate posts
1074 echo "<ul>";
1075 foreach ($this->feeds as $feed) :
1076 echo "<li>Fixing post meta-data for <cite>".$feed['link/name']."</cite> &#8230; "; flush();
1077 $rss = @fetch_rss($feed['link/uri']);
1078 if (is_array($rss->items)) :
1079 foreach ($rss->items as $item) :
1080 $guid = $wpdb->escape(FeedWordPress::guid($item, $feed)); // new GUID algorithm
1081 $link = $wpdb->escape($item['link']);
1082
1083 $wpdb->query("
1084 UPDATE `{$wpdb->posts}` SET guid='{$guid}' WHERE guid='{$link}'
1085 ");
1086 endforeach;
1087 endif;
1088 echo "<strong>complete.</strong></li>\n";
1089 endforeach;
1090 echo "</ul>\n";
1091
1092 // Mark the upgrade as successful.
1093 update_option('feedwordpress_version', FEEDWORDPRESS_VERSION);
1094 endswitch;
1095 echo "<p>Upgrade complete. FeedWordPress is now ready to use again.</p>";
1096 } /* FeedWordPress::upgrade_database() */
1097
1098 function create_guid_index () {
1099 global $wpdb;
1100
1101 $wpdb->query("
1102 CREATE INDEX {$wpdb->posts}_guid_idx ON {$wpdb->posts}(guid)
1103 ");
1104 } /* FeedWordPress::create_guid_index () */
1105
1106 function magpie_version () {
1107 if (!defined('MAGPIE_VERSION')) : $magpie_version = $GLOBALS['wp_version'].'-default';
1108 else : $magpie_version = MAGPIE_VERSION;
1109 endif;
1110 return $magpie_version;
1111 }
1112
1113 # Utility functions for handling text settings
1114 function negative ($f, $setting) {
1115 $nego = array ('n', 'no', 'f', 'false');
1116 return (isset($f[$setting]) and in_array(strtolower($f[$setting]), $nego));
1117 }
1118
1119 function affirmative ($f, $setting) {
1120 $affirmo = array ('y', 'yes', 't', 'true', 1);
1121 return (isset($f[$setting]) and in_array(strtolower($f[$setting]), $affirmo));
1122 }
1123
1124
1125 # Internal debugging functions
1126 function critical_bug ($varname, $var, $line) {
1127 global $wp_version;
1128
1129 if (defined('MAGPIE_VERSION')) : $mv = MAGPIE_VERSION;
1130 else : $mv = 'WordPress '.$wp_version.' default.';
1131 endif;
1132
1133 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>';
1134 echo "\n<plaintext>";
1135 echo "Triggered at line # ".$line."\n";
1136 echo "FeedWordPress version: ".FEEDWORDPRESS_VERSION."\n";
1137 echo "MagpieRSS version: {$mv}\n";
1138 echo "WordPress version: {$wp_version}\n";
1139 echo "PHP version: ".phpversion()."\n";
1140 echo "\n";
1141 echo $varname.": "; var_dump($var); echo "\n";
1142 die;
1143 }
1144
1145 function noncritical_bug ($varname, $var, $line) {
1146 if (FEEDWORDPRESS_DEBUG) : // halt only when we are doing debugging
1147 FeedWordPress::critical_bug($varname, $var, $line);
1148 endif;
1149 }
1150} // class FeedWordPress
1151
1152require_once(dirname(__FILE__) . '/syndicatedpost.class.php');
1153require_once(dirname(__FILE__) . '/syndicatedlink.class.php');
1154
1155################################################################################
1156## XML-RPC HOOKS: accept XML-RPC update pings from Contributors ################
1157################################################################################
1158
1159function feedwordpress_xmlrpc_hook ($args = array ()) {
1160 $args['weblogUpdates.ping'] = 'feedwordpress_pong';
1161 return $args;
1162}
1163
1164function feedwordpress_pong ($args) {
1165 $feedwordpress =& new FeedWordPress;
1166 $delta = @$feedwordpress->update($args[1]);
1167 if (is_null($delta)):
1168 return array('flerror' => true, 'message' => "Sorry. I don't syndicate <$args[1]>.");
1169 else:
1170 $mesg = array();
1171 if (isset($delta['new'])) { $mesg[] = ' '.$delta['new'].' new posts were syndicated'; }
1172 if (isset($delta['updated'])) { $mesg[] = ' '.$delta['updated'].' existing posts were updated'; }
1173
1174 return array('flerror' => false, 'message' => "Thanks for the ping.".implode(' and', $mesg));
1175 endif;
1176}
1177
1178# The upgraded MagpieRSS also uses this class. So if we have it loaded
1179# in, don't load it again.
1180if (!class_exists('Relative_URI')) {
1181 require_once(dirname(__FILE__) . '/relative_uri.class.php');
1182}
1183
1184// take your best guess at the realname and e-mail, given a string
1185define('FWP_REGEX_EMAIL_ADDY', '([^@"(<\s]+@[^"@(<\s]+\.[^"@(<\s]+)');
1186define('FWP_REGEX_EMAIL_NAME', '("([^"]*)"|([^"<(]+\S))');
1187define('FWP_REGEX_EMAIL_POSTFIX_NAME', '/^\s*'.FWP_REGEX_EMAIL_ADDY."\s+\(".FWP_REGEX_EMAIL_NAME.'\)\s*$/');
1188define('FWP_REGEX_EMAIL_PREFIX_NAME', '/^\s*'.FWP_REGEX_EMAIL_NAME.'\s*<'.FWP_REGEX_EMAIL_ADDY.'>\s*$/');
1189define('FWP_REGEX_EMAIL_JUST_ADDY', '/^\s*'.FWP_REGEX_EMAIL_ADDY.'\s*$/');
1190define('FWP_REGEX_EMAIL_JUST_NAME', '/^\s*'.FWP_REGEX_EMAIL_NAME.'\s*$/');
1191
1192function parse_email_with_realname ($email) {
1193 if (preg_match(FWP_REGEX_EMAIL_POSTFIX_NAME, $email, $matches)) :
1194 ($ret['name'] = $matches[3]) or ($ret['name'] = $matches[2]);
1195 $ret['email'] = $matches[1];
1196 elseif (preg_match(FWP_REGEX_EMAIL_PREFIX_NAME, $email, $matches)) :
1197 ($ret['name'] = $matches[2]) or ($ret['name'] = $matches[3]);
1198 $ret['email'] = $matches[4];
1199 elseif (preg_match(FWP_REGEX_EMAIL_JUST_ADDY, $email, $matches)) :
1200 $ret['name'] = NULL; $ret['email'] = $matches[1];
1201 elseif (preg_match(FWP_REGEX_EMAIL_JUST_NAME, $email, $matches)) :
1202 $ret['email'] = NULL;
1203 ($ret['name'] = $matches[2]) or ($ret['name'] = $matches[3]);
1204 else :
1205 $ret['name'] = NULL; $ret['email'] = NULL;
1206 endif;
1207 return $ret;
1208}
1209
Note: See TracBrowser for help on using the repository browser.