Version Description
FILTERS AND ADD-ONS: A number of new hooks for filters and add-ons to further customize the behavior of FWP have been added.
COMPATIBILITY/BUGFIX: Many users saw odd characters, especially "n," appearing in posts in versions of WordPress from 3.6 on, due to a change in when the API expects HTML data for posts to be slashed and when it does not. This has been fixed, so that the junk characters should no longer appear, regardless of your version of WordPress.
BUGFIX: A bug preventing FWP from saving categories assigned under Syndication > Categories & Tags has been fixed.
BUGFIX: Post-editing related metaboxes should now show up when you edit items of any post type, including custom types, not only normal WordPress posts.
BUGFIX: A bug in the admin UI that caused the "Alternative Feeds" / "Find Feeds" box to throw a permissions error has been fixed.
BUGFIX: A bug preventing proper mapping of categories and other terms in 2013.0504 has been fixed.
BUGFIX: A number of small fixes contributed through Github by Flynsarmy should eliminate PHP warnings for many users on several methods that are called as static methods within FeedWordPress.
Release Info
Developer | radgeek |
Plugin | FeedWordPress |
Version | 2014.0805 |
Comparing to | |
See all releases |
Code changes from version 2013.0504 to 2014.0805
- admin-ui.php +110 -95
- btc-qr-64px.png +0 -0
- categories-page.php +47 -45
- compatability.php +15 -15
- diagnostics-page.php +38 -36
- externals/myphp/myphp.class.php +65 -4
- feeds-page.php +4 -4
- feedwordpie.class.php +4 -2
- feedwordpress-elements.css +4 -2
- feedwordpress-walker-category-checklist.class.php +5 -5
- feedwordpress.php +639 -354
- feedwordpress_file.class.php +9 -13
- feedwordpresshtml.class.php +5 -5
- feedwordpresslocalpost.class.php +41 -3
- feedwordpressrpc.class.php +2 -5
- feedwordpresssyndicationpage.class.php +44 -11
- inspectpostmeta.class.php +3 -7
- magpiefromsimplepie.class.php +1 -1
- magpiemocklink.class.php +5 -5
- paypal-donation-64px.png +0 -0
- performance-page.php +7 -42
- readme.txt +38 -4
- syndicatedlink.class.php +276 -102
- syndicatedpost.class.php +451 -324
- syndicatedpostterm.class.php +215 -0
- syndicationdataqueries.class.php +15 -39
@@ -28,7 +28,7 @@ class FeedWordPressAdminPage {
|
|
28 |
$slug = preg_replace('/FeedWordPress(.*)Page/', '$1', get_class($this));
|
29 |
return strtolower($slug);
|
30 |
}
|
31 |
-
|
32 |
function pagename ($context = NULL) {
|
33 |
if (is_null($context)) :
|
34 |
$context = 'default';
|
@@ -50,7 +50,7 @@ class FeedWordPressAdminPage {
|
|
50 |
elseif ($this->save_requested_in($post)) : // User mashed Save Changes
|
51 |
$this->save_settings($post);
|
52 |
endif;
|
53 |
-
do_action($this->dispatch.'_post', $post, $this);
|
54 |
}
|
55 |
|
56 |
function update_feed () {
|
@@ -58,22 +58,25 @@ class FeedWordPressAdminPage {
|
|
58 |
|
59 |
add_action('feedwordpress_check_feed', 'update_feeds_mention');
|
60 |
add_action('feedwordpress_check_feed_complete', 'update_feeds_finish', 10, 3);
|
61 |
-
|
62 |
print '<div class="updated">';
|
63 |
print "<ul>";
|
64 |
$uri = $this->link->uri();
|
|
|
|
|
|
|
|
|
|
|
|
|
65 |
$delta = $feedwordpress->update($uri);
|
66 |
print "</ul>";
|
67 |
|
68 |
if (!is_null($delta)) :
|
69 |
-
|
70 |
-
if (isset($delta['new'])) : $mesg[] = ' '.$delta['new'].' new posts were syndicated'; endif;
|
71 |
-
if (isset($delta['updated'])) : $mesg[] = ' '.$delta['updated'].' existing posts were updated'; endif;
|
72 |
-
echo "<p><strong>Update complete.</strong>".implode(' and', $mesg)."</p>";
|
73 |
echo "\n"; flush();
|
74 |
else :
|
75 |
-
$
|
76 |
-
echo "<p><strong>Error:</strong> There was a problem updating <a href=\"$
|
77 |
endif;
|
78 |
print "</div>\n";
|
79 |
remove_action('feedwordpress_check_feed', 'update_feeds_mention');
|
@@ -87,7 +90,7 @@ class FeedWordPressAdminPage {
|
|
87 |
// Save settings
|
88 |
$this->link->save_settings(/*reload=*/ true);
|
89 |
$this->updated = true;
|
90 |
-
|
91 |
// Reset, reload
|
92 |
$link_id = $this->link->id;
|
93 |
unset($this->link);
|
@@ -118,7 +121,7 @@ class FeedWordPressAdminPage {
|
|
118 |
endif;
|
119 |
|
120 |
if ($this->for_feed_settings()) : // Check feed-specific setting first; fall back to global
|
121 |
-
if (!$params['fallback']) : $global_name = NULL; endif;
|
122 |
$ret = $this->link->setting($feed_name, $global_name, $fallback_value, $params['default']);
|
123 |
else : // Check global setting
|
124 |
$ret = get_option($global_name, $fallback_value);
|
@@ -134,7 +137,7 @@ class FeedWordPressAdminPage {
|
|
134 |
$feed_name = $names['feed'];
|
135 |
$global_name = 'feedwordpress_'.$names['global'];
|
136 |
endif;
|
137 |
-
|
138 |
if ($this->for_feed_settings()) : // Update feed-specific setting
|
139 |
$this->link->update_setting($feed_name, $value, $default);
|
140 |
else : // Update global setting
|
@@ -148,7 +151,7 @@ class FeedWordPressAdminPage {
|
|
148 |
function update_requested_in ($post) {
|
149 |
return (isset($post['update']) and (strlen($post['update']) > 0));
|
150 |
}
|
151 |
-
|
152 |
/*static*/ function submitted_link_id () {
|
153 |
global $fwp_post;
|
154 |
|
@@ -166,7 +169,7 @@ class FeedWordPressAdminPage {
|
|
166 |
$link_id = MyPHP::request('save_link_id');
|
167 |
endif;
|
168 |
endforeach;
|
169 |
-
|
170 |
if (is_null($link_id) and isset($_REQUEST['link_id'])) :
|
171 |
$link_id = MyPHP::request('link_id');
|
172 |
endif;
|
@@ -212,7 +215,7 @@ class FeedWordPressAdminPage {
|
|
212 |
function meta_box_context () {
|
213 |
return $this->context;
|
214 |
} /* FeedWordPressAdminPage::meta_box_context () */
|
215 |
-
|
216 |
/**
|
217 |
* Outputs JavaScript to fix AJAX toggles settings.
|
218 |
*
|
@@ -252,7 +255,7 @@ class FeedWordPressAdminPage {
|
|
252 |
$link_id = NULL;
|
253 |
if (is_object($link)) :
|
254 |
if (method_exists($link, 'found')) :
|
255 |
-
// Is this a SyndicatedLink object?
|
256 |
if ($link->found()) :
|
257 |
$link_id = $link->link->link_id;
|
258 |
endif;
|
@@ -284,14 +287,14 @@ class FeedWordPressAdminPage {
|
|
284 |
'subscription' => $this->link,
|
285 |
));
|
286 |
$sub = $params['subscription'];
|
287 |
-
|
288 |
$links = array(
|
289 |
"Feed" => array('page' => 'feeds-page.php', 'long' => 'Feeds & Updates'),
|
290 |
"Posts" => array('page' => 'posts-page.php', 'long' => 'Posts & Links'),
|
291 |
"Authors" => array('page' => 'authors-page.php', 'long' => 'Authors'),
|
292 |
'Categories' => array('page' => 'categories-page.php', 'long' => 'Categories & Tags'),
|
293 |
);
|
294 |
-
|
295 |
$link_id = NULL;
|
296 |
if (is_object($sub)) :
|
297 |
if (method_exists($sub, 'found')) :
|
@@ -302,40 +305,40 @@ class FeedWordPressAdminPage {
|
|
302 |
$link_id = $sub->link_id;
|
303 |
endif;
|
304 |
endif;
|
305 |
-
|
306 |
print $params['before']; $first = true;
|
307 |
foreach ($links as $label => $link) :
|
308 |
if (!$first) : print $params['between']; endif;
|
309 |
-
|
310 |
if (isset($link['url'])) : MyPHP::url($link['url'], array("link_id" => $link_id));
|
311 |
else : $url = $this->admin_page_href($link['page'], array(), $sub);
|
312 |
endif;
|
313 |
$url = esc_html($url);
|
314 |
-
|
315 |
if ($link['page']==basename($this->filename)) :
|
316 |
print "<strong>";
|
317 |
else :
|
318 |
print "<a href=\"${url}\">";
|
319 |
endif;
|
320 |
-
|
321 |
if ($params['long']) : print esc_html(__($link['long']));
|
322 |
else : print esc_html(__($label));
|
323 |
endif;
|
324 |
-
|
325 |
if ($link['page']==basename($this->filename)) :
|
326 |
print "</strong>";
|
327 |
else :
|
328 |
print "</a>";
|
329 |
endif;
|
330 |
-
|
331 |
$first = false;
|
332 |
endforeach;
|
333 |
print $params['after'];
|
334 |
} /* FeedWordPressAdminPage::display_feed_settings_page_links */
|
335 |
-
|
336 |
function display_feed_select_dropdown() {
|
337 |
$links = FeedWordPress::syndicated_links();
|
338 |
-
|
339 |
?>
|
340 |
<div id="fwpfs-container"><ul class="subsubsub">
|
341 |
<li><select name="link_id" class="fwpfs" style="max-width: 20.0em;">
|
@@ -353,14 +356,14 @@ class FeedWordPressAdminPage {
|
|
353 |
'after' => '</li>',
|
354 |
'subscription' => $this->link,
|
355 |
));
|
356 |
-
|
357 |
if ($this->for_feed_settings()) :
|
358 |
?>
|
359 |
<li><input class="button" type="submit" name="update" value="Update Now" /></li>
|
360 |
<?php
|
361 |
endif;
|
362 |
?>
|
363 |
-
</ul>
|
364 |
</div>
|
365 |
<?php
|
366 |
} /* FeedWordPressAdminPage::display_feed_select_dropdown() */
|
@@ -385,7 +388,7 @@ class FeedWordPressAdminPage {
|
|
385 |
$this->mesg = $this->updated;
|
386 |
endif;
|
387 |
endif;
|
388 |
-
|
389 |
if (!is_null($this->mesg)) :
|
390 |
?>
|
391 |
<div class="updated">
|
@@ -408,12 +411,12 @@ class FeedWordPressAdminPage {
|
|
408 |
<?php
|
409 |
endif;
|
410 |
} /* FeedWordPressAdminPage::display_settings_scope_message () */
|
411 |
-
|
412 |
/*static*/ function has_link () { return true; }
|
413 |
|
414 |
function form_action ($filename = NULL) {
|
415 |
global $fwp_path;
|
416 |
-
|
417 |
if (is_null($filename)) :
|
418 |
$filename = basename($this->filename);
|
419 |
endif;
|
@@ -451,7 +454,7 @@ class FeedWordPressAdminPage {
|
|
451 |
$this->pagename('settings-update'),
|
452 |
$this->update_message()
|
453 |
);
|
454 |
-
|
455 |
$this->open_sheet($this->pagename('open-sheet'));
|
456 |
?>
|
457 |
<div id="post-body">
|
@@ -464,7 +467,7 @@ class FeedWordPressAdminPage {
|
|
464 |
$id = 'feedwordpress_'.$method;
|
465 |
$title = $row;
|
466 |
endif;
|
467 |
-
|
468 |
add_meta_box(
|
469 |
/*id=*/ $id,
|
470 |
/*title=*/ $title,
|
@@ -493,7 +496,7 @@ class FeedWordPressAdminPage {
|
|
493 |
$this->ajax_interface_js();
|
494 |
?>
|
495 |
</script>
|
496 |
-
|
497 |
<?php
|
498 |
add_action(
|
499 |
FeedWordPressCompatibility::bottom_script_hook($this->filename),
|
@@ -535,14 +538,14 @@ class FeedWordPressAdminPage {
|
|
535 |
endif;
|
536 |
?>
|
537 |
</div>
|
538 |
-
|
539 |
<div id="poststuff">
|
540 |
<?php
|
541 |
} /* FeedWordPressAdminPage::open_sheet () */
|
542 |
-
|
543 |
function close_sheet () {
|
544 |
?>
|
545 |
-
|
546 |
</div> <!-- id="poststuff" -->
|
547 |
<?php
|
548 |
if (!is_null($this->dispatch)) :
|
@@ -551,51 +554,51 @@ class FeedWordPressAdminPage {
|
|
551 |
endif;
|
552 |
?>
|
553 |
</div> <!-- class="wrap" -->
|
554 |
-
|
555 |
<?php
|
556 |
} /* FeedWordPressAdminPage::close_sheet () */
|
557 |
-
|
558 |
function setting_radio_control ($localName, $globalName, $options, $params = array()) {
|
559 |
global $fwp_path;
|
560 |
-
|
561 |
if (isset($params['filename'])) : $filename = $params['filename'];
|
562 |
else : $filename = basename($this->filename);
|
563 |
endif;
|
564 |
-
|
565 |
if (isset($params['site-wide-url'])) : $href = $params['site-wide-url'];
|
566 |
else : $href = $this->admin_page_href($filename);
|
567 |
endif;
|
568 |
-
|
569 |
if (isset($params['setting-default'])) : $settingDefault = $params['setting-default'];
|
570 |
else : $settingDefault = NULL;
|
571 |
endif;
|
572 |
-
|
573 |
if (isset($params['global-setting-default'])) : $globalSettingDefault = $params['global-setting-default'];
|
574 |
else : $globalSettingDefault = $settingDefault;
|
575 |
endif;
|
576 |
|
577 |
-
$globalSetting = get_option('feedwordpress_'.$globalName, $globalSettingDefault);
|
578 |
if ($this->for_feed_settings()) :
|
579 |
$setting = $this->link->setting($localName, NULL, $settingDefault);
|
580 |
else :
|
581 |
$setting = $globalSetting;
|
582 |
endif;
|
583 |
-
|
584 |
if (isset($params['offer-site-wide'])) : $offerSiteWide = $params['offer-site-wide'];
|
585 |
else : $offerSiteWide = $this->for_feed_settings();
|
586 |
endif;
|
587 |
-
|
588 |
// This allows us to provide an alternative set of human-readable
|
589 |
// labels for each potential value. For use in Currently: line.
|
590 |
if (isset($params['labels'])) : $labels = $params['labels'];
|
591 |
elseif (is_callable($options)) : $labels = NULL;
|
592 |
else : $labels = $options;
|
593 |
endif;
|
594 |
-
|
595 |
if (isset($params['input-name'])) : $inputName = $params['input-name'];
|
596 |
else : $inputName = $globalName;
|
597 |
endif;
|
598 |
-
|
599 |
if (isset($params['default-input-id'])) : $defaultInputId = $params['default-input-id'];
|
600 |
else : $defaultInputId = NULL;
|
601 |
endif;
|
@@ -604,7 +607,7 @@ class FeedWordPressAdminPage {
|
|
604 |
elseif (!is_null($defaultInputId)) : $defaultInputIdNo = $defaultInputId.'-no';
|
605 |
else : $defaultInputIdNo = NULL;
|
606 |
endif;
|
607 |
-
|
608 |
// This allows us to either include the site-default setting as
|
609 |
// one of the options within the radio box, or else as a simple
|
610 |
// yes/no toggle that controls whether or not to check another
|
@@ -622,7 +625,7 @@ class FeedWordPressAdminPage {
|
|
622 |
: 'site-default'
|
623 |
);
|
624 |
endif;
|
625 |
-
|
626 |
$settingDefaulted = (is_null($setting) or ($settingDefault === $setting));
|
627 |
|
628 |
if (!is_callable($options)) :
|
@@ -630,7 +633,7 @@ class FeedWordPressAdminPage {
|
|
630 |
if ($settingDefaulted) :
|
631 |
$checked[$defaultInputValue] = ' checked="checked"';
|
632 |
endif;
|
633 |
-
|
634 |
foreach ($options as $value => $label) :
|
635 |
if ($setting == $value) :
|
636 |
$checked[$value] = ' checked="checked"';
|
@@ -647,7 +650,7 @@ class FeedWordPressAdminPage {
|
|
647 |
else :
|
648 |
$defaulted['yes'] = (isset($checked[$defaultInputValue]) ? $checked[$defaultInputValue] : '');
|
649 |
endif;
|
650 |
-
|
651 |
if (isset($params['defaulted'])) :
|
652 |
$defaulted['yes'] = ($params['defaulted'] ? ' checked="checked"' : '');
|
653 |
$defaulted['no'] = ($params['defaulted'] ? '' : ' checked="checked"');
|
@@ -674,7 +677,7 @@ class FeedWordPressAdminPage {
|
|
674 |
print $labels[$globalSetting];
|
675 |
endif; ?></strong> (<a href="<?php print $href; ?>">change</a>)</span></li>
|
676 |
</ul></td>
|
677 |
-
|
678 |
<td class="equals second inactive">
|
679 |
<?php if ($defaultInputName != $inputName) : ?>
|
680 |
<ul class="options">
|
@@ -686,7 +689,7 @@ class FeedWordPressAdminPage {
|
|
686 |
<?php _e('Do something different with this feed.'); ?></label>
|
687 |
<?php endif;
|
688 |
endif;
|
689 |
-
|
690 |
// Let's spit out the controls here.
|
691 |
if (is_callable($options)) :
|
692 |
// Method call to print out options list
|
@@ -703,7 +706,7 @@ class FeedWordPressAdminPage {
|
|
703 |
</ul> <!-- class="options" -->
|
704 |
<?php
|
705 |
endif;
|
706 |
-
|
707 |
if ($offerSiteWide) :
|
708 |
if ($defaultInputName != $inputName) :
|
709 |
// Close the <li> and <ul class="options"> we opened above
|
@@ -712,7 +715,7 @@ class FeedWordPressAdminPage {
|
|
712 |
</ul> <!-- class="options" -->
|
713 |
<?php
|
714 |
endif;
|
715 |
-
|
716 |
// Close off the twofer table that we opened up above.
|
717 |
?>
|
718 |
</td></tr>
|
@@ -721,7 +724,7 @@ class FeedWordPressAdminPage {
|
|
721 |
<?php
|
722 |
endif;
|
723 |
} /* FeedWordPressAdminPage::setting_radio_control () */
|
724 |
-
|
725 |
function save_button ($caption = NULL) {
|
726 |
if (is_null($caption)) : $caption = __('Save Changes'); endif;
|
727 |
?>
|
@@ -732,6 +735,18 @@ class FeedWordPressAdminPage {
|
|
732 |
}
|
733 |
} /* class FeedWordPressAdminPage */
|
734 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
735 |
function fwp_authors_single_submit ($link = NULL) {
|
736 |
?>
|
737 |
<div class="submitbox" id="submitlink">
|
@@ -772,13 +787,13 @@ function fwp_tags_box ($tags, $object, $params = array()) {
|
|
772 |
'id' => NULL,
|
773 |
'box_title' => __('Post Tags'),
|
774 |
));
|
775 |
-
|
776 |
if (!is_array($tags)) : $tags = array(); endif;
|
777 |
-
|
778 |
$tax_name = $params['taxonomy'];
|
779 |
$taxonomy = get_taxonomy($params['taxonomy']);
|
780 |
$disabled = (!current_user_can($taxonomy->cap->assign_terms) ? 'disabled="disabled"' : '');
|
781 |
-
|
782 |
$desc = "<p style=\"font-size:smaller;font-style:bold;margin:0\">Tag $object as...</p>";
|
783 |
|
784 |
if (is_null($params['textarea_name'])) :
|
@@ -793,11 +808,11 @@ function fwp_tags_box ($tags, $object, $params = array()) {
|
|
793 |
if (is_null($params['input_name'])) :
|
794 |
$params['input_name'] = "newtag[$tax_name]";
|
795 |
endif;
|
796 |
-
|
797 |
if (is_null($params['id'])) :
|
798 |
$params['id'] = $tax_name;
|
799 |
endif;
|
800 |
-
|
801 |
print $desc;
|
802 |
$helps = __('Separate tags with commas.');
|
803 |
$box['title'] = __('Tags');
|
@@ -807,7 +822,7 @@ function fwp_tags_box ($tags, $object, $params = array()) {
|
|
807 |
<div class="nojs-tags hide-if-js">
|
808 |
<p><?php echo $taxonomy->labels->add_or_remove_items; ?></p>
|
809 |
<textarea name="<?php echo $params['textarea_name']; ?>" class="the-tags" id="<?php echo $params['textarea_id']; ?>"><?php echo esc_attr(implode(",", $tags)); ?></textarea></div>
|
810 |
-
|
811 |
<?php if ( current_user_can($taxonomy->cap->assign_terms) ) :?>
|
812 |
<div class="ajaxtag hide-if-no-js">
|
813 |
<label class="screen-reader-text" for="<?php echo $params['input_id']; ?>"><?php echo $params['box_title']; ?></label>
|
@@ -818,7 +833,7 @@ function fwp_tags_box ($tags, $object, $params = array()) {
|
|
818 |
<p class="howto"><?php echo esc_attr( $taxonomy->labels->separate_items_with_commas ); ?></p>
|
819 |
<?php endif; ?>
|
820 |
</div>
|
821 |
-
|
822 |
<div class="tagchecklist"></div>
|
823 |
</div>
|
824 |
<?php if ( current_user_can($taxonomy->cap->assign_terms) ) : ?>
|
@@ -869,7 +884,7 @@ function fwp_category_box ($checked, $object, $tags = array(), $params = array()
|
|
869 |
<p id="<?php print $idPrefix; ?><?php print $taxonomy; ?>-add" class="category-add wp-hidden-child">
|
870 |
<?php
|
871 |
$newcat = 'new'.$taxonomy;
|
872 |
-
|
873 |
?>
|
874 |
<label class="screen-reader-text" for="<?php print $idPrefix; ?>new<?php print $taxonomy; ?>"><?php _e('Add New Category'); ?></label>
|
875 |
<input
|
@@ -877,7 +892,7 @@ function fwp_category_box ($checked, $object, $tags = array(), $params = array()
|
|
877 |
class="new<?php print $taxonomy; ?> form-required form-input-tip"
|
878 |
aria-required="true"
|
879 |
tabindex="3"
|
880 |
-
type="text" name="<?php print $newcat; ?>"
|
881 |
value="<?php _e( 'New category name' ); ?>"
|
882 |
/>
|
883 |
<label class="screen-reader-text" for="<?php print $idPrefix; ?>new<?php print $taxonomy; ?>-parent"><?php _e('Parent Category:'); ?></label>
|
@@ -926,7 +941,7 @@ function fwp_author_list () {
|
|
926 |
global $wpdb;
|
927 |
$ret = array();
|
928 |
|
929 |
-
$users =
|
930 |
if (is_array($users)) :
|
931 |
foreach ($users as $user) :
|
932 |
$id = (int) $user->ID;
|
@@ -940,9 +955,9 @@ function fwp_author_list () {
|
|
940 |
}
|
941 |
|
942 |
class FeedWordPressSettingsUI {
|
943 |
-
function is_admin () {
|
944 |
global $fwp_path;
|
945 |
-
|
946 |
$admin_page = false; // Innocent until proven guilty
|
947 |
if (isset($_REQUEST['page'])) :
|
948 |
$admin_page = (
|
@@ -952,18 +967,18 @@ class FeedWordPressSettingsUI {
|
|
952 |
endif;
|
953 |
return $admin_page;
|
954 |
}
|
955 |
-
|
956 |
-
function admin_scripts () {
|
957 |
global $fwp_path;
|
958 |
-
|
959 |
wp_enqueue_script('post'); // for magic tag and category boxes
|
960 |
wp_enqueue_script('admin-forms'); // for checkbox selection
|
961 |
-
|
962 |
wp_register_script('feedwordpress-elements', WP_PLUGIN_URL.'/'.$fwp_path.'/feedwordpress-elements.js');
|
963 |
wp_enqueue_script('feedwordpress-elements');
|
964 |
}
|
965 |
|
966 |
-
function admin_styles () {
|
967 |
?>
|
968 |
<style type="text/css">
|
969 |
#feedwordpress-admin-feeds .link-rss-params-remove .x, .feedwordpress-admin .remove-it .x {
|
@@ -985,7 +1000,7 @@ class FeedWordPressSettingsUI {
|
|
985 |
background-position:0 top;
|
986 |
background-repeat:repeat-x;
|
987 |
}
|
988 |
-
|
989 |
.update-results {
|
990 |
max-width: 100%;
|
991 |
overflow: auto;
|
@@ -994,8 +1009,8 @@ class FeedWordPressSettingsUI {
|
|
994 |
</style>
|
995 |
<?php
|
996 |
} /* FeedWordPressSettingsUI::admin_styles () */
|
997 |
-
|
998 |
-
|
999 |
if (function_exists('wp_nonce_field')) :
|
1000 |
echo "<form style='display: none' method='get' action=''>\n<p>\n";
|
1001 |
wp_nonce_field( 'closedpostboxes', 'closedpostboxesnonce', false );
|
@@ -1004,24 +1019,24 @@ class FeedWordPressSettingsUI {
|
|
1004 |
endif;
|
1005 |
} /* FeedWordPressSettingsUI::ajax_nonce_fields () */
|
1006 |
|
1007 |
-
|
1008 |
?>
|
1009 |
<script type="text/javascript">
|
1010 |
-
jQuery(document).ready( function($) {
|
1011 |
// In case someone got here first...
|
1012 |
$('.postbox h3, .postbox .handlediv').unbind('click');
|
1013 |
$('.postbox h3 a').unbind('click');
|
1014 |
$('.hide-postbox-tog').unbind('click');
|
1015 |
$('.columns-prefs input[type="radio"]').unbind('click');
|
1016 |
$('.meta-box-sortables').sortable('destroy');
|
1017 |
-
|
1018 |
postboxes.add_postbox_toggles('<?php print $context; ?>');
|
1019 |
} );
|
1020 |
</script>
|
1021 |
<?php
|
1022 |
} /* FeedWordPressSettingsUI::fix_toggles_js () */
|
1023 |
-
|
1024 |
-
function magic_input_tip_js ($id) {
|
1025 |
if (!preg_match('/^[.#]/', $id)) :
|
1026 |
$id = '#'.$id;
|
1027 |
endif;
|
@@ -1038,7 +1053,7 @@ class FeedWordPressSettingsUI {
|
|
1038 |
inputBox.blur(function() {
|
1039 |
if ( this.value == '' )
|
1040 |
jQuery(this).val( this.defaultValue ).addClass( 'form-input-tip' );
|
1041 |
-
});
|
1042 |
} );
|
1043 |
</script>
|
1044 |
<?php
|
@@ -1056,10 +1071,10 @@ function fwp_insert_new_user ($newuser_name) {
|
|
1056 |
$userdata['user_nicename'] = apply_filters('pre_user_nicename', sanitize_title($newuser_name));
|
1057 |
$userdata['display_name'] = $newuser_name;
|
1058 |
$userdata['user_pass'] = substr(md5(uniqid(microtime())), 0, 6); // just something random to lock it up
|
1059 |
-
|
1060 |
$blahUrl = get_bloginfo('url'); $url = parse_url($blahUrl);
|
1061 |
$userdata['user_email'] = substr(md5(uniqid(microtime())), 0, 6).'@'.$url['host'];
|
1062 |
-
|
1063 |
$newuser_id = wp_insert_user($userdata);
|
1064 |
$ret = $newuser_id; // Either a numeric ID or a WP_Error object
|
1065 |
else :
|
@@ -1081,7 +1096,7 @@ function fwp_add_meta_box ($id, $title, $callback, $page, $context = 'advanced',
|
|
1081 |
|
1082 |
function fwp_do_meta_boxes($page, $context, $object) {
|
1083 |
$ret = do_meta_boxes($page, $context, $object);
|
1084 |
-
|
1085 |
// Avoid JavaScript error from WordPress 2.5 bug
|
1086 |
?>
|
1087 |
<div style="display: none">
|
@@ -1096,7 +1111,7 @@ function fwp_remove_meta_box($id, $page, $context) {
|
|
1096 |
} /* function fwp_remove_meta_box() */
|
1097 |
|
1098 |
function fwp_syndication_manage_page_links_table_rows ($links, $page, $visible = 'Y') {
|
1099 |
-
|
1100 |
$subscribed = ('Y' == strtoupper($visible));
|
1101 |
if ($subscribed or (count($links) > 0)) :
|
1102 |
?>
|
@@ -1112,7 +1127,7 @@ function fwp_syndication_manage_page_links_table_rows ($links, $page, $visible =
|
|
1112 |
|
1113 |
<tbody>
|
1114 |
<?php
|
1115 |
-
$alt_row = true;
|
1116 |
if (count($links) > 0):
|
1117 |
foreach ($links as $link):
|
1118 |
$trClass = array();
|
@@ -1130,7 +1145,7 @@ function fwp_syndication_manage_page_links_table_rows ($links, $page, $visible =
|
|
1130 |
if (is_null($sLink->setting('update/error'))) :
|
1131 |
$errorsSince = '';
|
1132 |
if (!is_null($sLink->setting('link/item count'))) :
|
1133 |
-
$N = $sLink->setting('link/item count');
|
1134 |
$fileSizeLines[] = sprintf((($N==1) ? __('%d item') : __('%d items')), $N);
|
1135 |
endif;
|
1136 |
|
@@ -1141,7 +1156,7 @@ function fwp_syndication_manage_page_links_table_rows ($links, $page, $visible =
|
|
1141 |
$trClass[] = 'feed-error';
|
1142 |
|
1143 |
$theError = unserialize($sLink->setting('update/error'));
|
1144 |
-
|
1145 |
$errorsSince = "<div class=\"returning-errors\">"
|
1146 |
."<p><strong>Returning errors</strong> since "
|
1147 |
.fwp_time_elapsed($theError['since'])
|
@@ -1155,7 +1170,7 @@ function fwp_syndication_manage_page_links_table_rows ($links, $page, $visible =
|
|
1155 |
endif;
|
1156 |
|
1157 |
$nextUpdate = "<div style='max-width: 30.0em; font-size: 0.9em;'><div style='font-style:italic;'>";
|
1158 |
-
|
1159 |
$ttl = $sLink->setting('update/ttl');
|
1160 |
if (is_numeric($ttl)) :
|
1161 |
$next = $sLink->setting('update/last') + $sLink->setting('update/fudge') + ((int) $ttl * 60);
|
@@ -1178,7 +1193,7 @@ function fwp_syndication_manage_page_links_table_rows ($links, $page, $visible =
|
|
1178 |
else :
|
1179 |
$lastUpdated .= gmdate('F j', $next + (get_option('gmt_offset') * 3600));
|
1180 |
endif;
|
1181 |
-
|
1182 |
$nextUpdate .= "Scheduled to be checked for updates every ".$ttl." minute".(($ttl!=1)?"s":"")."</div><div style='size:0.9em; margin-top: 0.5em'> This update schedule was requested by the feed provider";
|
1183 |
if ($sLink->setting('update/xml')) :
|
1184 |
$nextUpdate .= " using a standard <code style=\"font-size: inherit; padding: 0; background: transparent\"><".$sLink->setting('update/xml')."></code> element";
|
@@ -1194,11 +1209,11 @@ function fwp_syndication_manage_page_links_table_rows ($links, $page, $visible =
|
|
1194 |
if (count($fileSizeLines) > 0) :
|
1195 |
$fileSize = '<div>'.implode(" / ", $fileSizeLines)."</div>";
|
1196 |
endif;
|
1197 |
-
|
1198 |
unset($sLink);
|
1199 |
-
|
1200 |
$alt_row = !$alt_row;
|
1201 |
-
|
1202 |
if ($alt_row) :
|
1203 |
$trClass[] = 'alternate';
|
1204 |
endif;
|
28 |
$slug = preg_replace('/FeedWordPress(.*)Page/', '$1', get_class($this));
|
29 |
return strtolower($slug);
|
30 |
}
|
31 |
+
|
32 |
function pagename ($context = NULL) {
|
33 |
if (is_null($context)) :
|
34 |
$context = 'default';
|
50 |
elseif ($this->save_requested_in($post)) : // User mashed Save Changes
|
51 |
$this->save_settings($post);
|
52 |
endif;
|
53 |
+
do_action($this->dispatch.'_post', $post, $this);
|
54 |
}
|
55 |
|
56 |
function update_feed () {
|
58 |
|
59 |
add_action('feedwordpress_check_feed', 'update_feeds_mention');
|
60 |
add_action('feedwordpress_check_feed_complete', 'update_feeds_finish', 10, 3);
|
61 |
+
|
62 |
print '<div class="updated">';
|
63 |
print "<ul>";
|
64 |
$uri = $this->link->uri();
|
65 |
+
$displayUrl = $uri;
|
66 |
+
|
67 |
+
// check for effects of an effective-url filter
|
68 |
+
$effectiveUrl = $link->uri(array('fetch' => true));
|
69 |
+
if ($uri != $effectiveUrl) : $displayUrl .= ' | ' . $effectiveUrl; endif;
|
70 |
+
|
71 |
$delta = $feedwordpress->update($uri);
|
72 |
print "</ul>";
|
73 |
|
74 |
if (!is_null($delta)) :
|
75 |
+
echo "<p><strong>Update complete.</strong>".fwp_update_set_results_message($delta)."</p>";
|
|
|
|
|
|
|
76 |
echo "\n"; flush();
|
77 |
else :
|
78 |
+
$effectiveUrl = esc_html($effectiveUrl);
|
79 |
+
echo "<p><strong>Error:</strong> There was a problem updating <a href=\"$effectiveUrl\">$displayUrl</a></p>\n";
|
80 |
endif;
|
81 |
print "</div>\n";
|
82 |
remove_action('feedwordpress_check_feed', 'update_feeds_mention');
|
90 |
// Save settings
|
91 |
$this->link->save_settings(/*reload=*/ true);
|
92 |
$this->updated = true;
|
93 |
+
|
94 |
// Reset, reload
|
95 |
$link_id = $this->link->id;
|
96 |
unset($this->link);
|
121 |
endif;
|
122 |
|
123 |
if ($this->for_feed_settings()) : // Check feed-specific setting first; fall back to global
|
124 |
+
if (!$params['fallback']) : $global_name = NULL; endif;
|
125 |
$ret = $this->link->setting($feed_name, $global_name, $fallback_value, $params['default']);
|
126 |
else : // Check global setting
|
127 |
$ret = get_option($global_name, $fallback_value);
|
137 |
$feed_name = $names['feed'];
|
138 |
$global_name = 'feedwordpress_'.$names['global'];
|
139 |
endif;
|
140 |
+
|
141 |
if ($this->for_feed_settings()) : // Update feed-specific setting
|
142 |
$this->link->update_setting($feed_name, $value, $default);
|
143 |
else : // Update global setting
|
151 |
function update_requested_in ($post) {
|
152 |
return (isset($post['update']) and (strlen($post['update']) > 0));
|
153 |
}
|
154 |
+
|
155 |
/*static*/ function submitted_link_id () {
|
156 |
global $fwp_post;
|
157 |
|
169 |
$link_id = MyPHP::request('save_link_id');
|
170 |
endif;
|
171 |
endforeach;
|
172 |
+
|
173 |
if (is_null($link_id) and isset($_REQUEST['link_id'])) :
|
174 |
$link_id = MyPHP::request('link_id');
|
175 |
endif;
|
215 |
function meta_box_context () {
|
216 |
return $this->context;
|
217 |
} /* FeedWordPressAdminPage::meta_box_context () */
|
218 |
+
|
219 |
/**
|
220 |
* Outputs JavaScript to fix AJAX toggles settings.
|
221 |
*
|
255 |
$link_id = NULL;
|
256 |
if (is_object($link)) :
|
257 |
if (method_exists($link, 'found')) :
|
258 |
+
// Is this a SyndicatedLink object?
|
259 |
if ($link->found()) :
|
260 |
$link_id = $link->link->link_id;
|
261 |
endif;
|
287 |
'subscription' => $this->link,
|
288 |
));
|
289 |
$sub = $params['subscription'];
|
290 |
+
|
291 |
$links = array(
|
292 |
"Feed" => array('page' => 'feeds-page.php', 'long' => 'Feeds & Updates'),
|
293 |
"Posts" => array('page' => 'posts-page.php', 'long' => 'Posts & Links'),
|
294 |
"Authors" => array('page' => 'authors-page.php', 'long' => 'Authors'),
|
295 |
'Categories' => array('page' => 'categories-page.php', 'long' => 'Categories & Tags'),
|
296 |
);
|
297 |
+
|
298 |
$link_id = NULL;
|
299 |
if (is_object($sub)) :
|
300 |
if (method_exists($sub, 'found')) :
|
305 |
$link_id = $sub->link_id;
|
306 |
endif;
|
307 |
endif;
|
308 |
+
|
309 |
print $params['before']; $first = true;
|
310 |
foreach ($links as $label => $link) :
|
311 |
if (!$first) : print $params['between']; endif;
|
312 |
+
|
313 |
if (isset($link['url'])) : MyPHP::url($link['url'], array("link_id" => $link_id));
|
314 |
else : $url = $this->admin_page_href($link['page'], array(), $sub);
|
315 |
endif;
|
316 |
$url = esc_html($url);
|
317 |
+
|
318 |
if ($link['page']==basename($this->filename)) :
|
319 |
print "<strong>";
|
320 |
else :
|
321 |
print "<a href=\"${url}\">";
|
322 |
endif;
|
323 |
+
|
324 |
if ($params['long']) : print esc_html(__($link['long']));
|
325 |
else : print esc_html(__($label));
|
326 |
endif;
|
327 |
+
|
328 |
if ($link['page']==basename($this->filename)) :
|
329 |
print "</strong>";
|
330 |
else :
|
331 |
print "</a>";
|
332 |
endif;
|
333 |
+
|
334 |
$first = false;
|
335 |
endforeach;
|
336 |
print $params['after'];
|
337 |
} /* FeedWordPressAdminPage::display_feed_settings_page_links */
|
338 |
+
|
339 |
function display_feed_select_dropdown() {
|
340 |
$links = FeedWordPress::syndicated_links();
|
341 |
+
|
342 |
?>
|
343 |
<div id="fwpfs-container"><ul class="subsubsub">
|
344 |
<li><select name="link_id" class="fwpfs" style="max-width: 20.0em;">
|
356 |
'after' => '</li>',
|
357 |
'subscription' => $this->link,
|
358 |
));
|
359 |
+
|
360 |
if ($this->for_feed_settings()) :
|
361 |
?>
|
362 |
<li><input class="button" type="submit" name="update" value="Update Now" /></li>
|
363 |
<?php
|
364 |
endif;
|
365 |
?>
|
366 |
+
</ul>
|
367 |
</div>
|
368 |
<?php
|
369 |
} /* FeedWordPressAdminPage::display_feed_select_dropdown() */
|
388 |
$this->mesg = $this->updated;
|
389 |
endif;
|
390 |
endif;
|
391 |
+
|
392 |
if (!is_null($this->mesg)) :
|
393 |
?>
|
394 |
<div class="updated">
|
411 |
<?php
|
412 |
endif;
|
413 |
} /* FeedWordPressAdminPage::display_settings_scope_message () */
|
414 |
+
|
415 |
/*static*/ function has_link () { return true; }
|
416 |
|
417 |
function form_action ($filename = NULL) {
|
418 |
global $fwp_path;
|
419 |
+
|
420 |
if (is_null($filename)) :
|
421 |
$filename = basename($this->filename);
|
422 |
endif;
|
454 |
$this->pagename('settings-update'),
|
455 |
$this->update_message()
|
456 |
);
|
457 |
+
|
458 |
$this->open_sheet($this->pagename('open-sheet'));
|
459 |
?>
|
460 |
<div id="post-body">
|
467 |
$id = 'feedwordpress_'.$method;
|
468 |
$title = $row;
|
469 |
endif;
|
470 |
+
|
471 |
add_meta_box(
|
472 |
/*id=*/ $id,
|
473 |
/*title=*/ $title,
|
496 |
$this->ajax_interface_js();
|
497 |
?>
|
498 |
</script>
|
499 |
+
|
500 |
<?php
|
501 |
add_action(
|
502 |
FeedWordPressCompatibility::bottom_script_hook($this->filename),
|
538 |
endif;
|
539 |
?>
|
540 |
</div>
|
541 |
+
|
542 |
<div id="poststuff">
|
543 |
<?php
|
544 |
} /* FeedWordPressAdminPage::open_sheet () */
|
545 |
+
|
546 |
function close_sheet () {
|
547 |
?>
|
548 |
+
|
549 |
</div> <!-- id="poststuff" -->
|
550 |
<?php
|
551 |
if (!is_null($this->dispatch)) :
|
554 |
endif;
|
555 |
?>
|
556 |
</div> <!-- class="wrap" -->
|
557 |
+
|
558 |
<?php
|
559 |
} /* FeedWordPressAdminPage::close_sheet () */
|
560 |
+
|
561 |
function setting_radio_control ($localName, $globalName, $options, $params = array()) {
|
562 |
global $fwp_path;
|
563 |
+
|
564 |
if (isset($params['filename'])) : $filename = $params['filename'];
|
565 |
else : $filename = basename($this->filename);
|
566 |
endif;
|
567 |
+
|
568 |
if (isset($params['site-wide-url'])) : $href = $params['site-wide-url'];
|
569 |
else : $href = $this->admin_page_href($filename);
|
570 |
endif;
|
571 |
+
|
572 |
if (isset($params['setting-default'])) : $settingDefault = $params['setting-default'];
|
573 |
else : $settingDefault = NULL;
|
574 |
endif;
|
575 |
+
|
576 |
if (isset($params['global-setting-default'])) : $globalSettingDefault = $params['global-setting-default'];
|
577 |
else : $globalSettingDefault = $settingDefault;
|
578 |
endif;
|
579 |
|
580 |
+
$globalSetting = get_option('feedwordpress_'.$globalName, $globalSettingDefault);
|
581 |
if ($this->for_feed_settings()) :
|
582 |
$setting = $this->link->setting($localName, NULL, $settingDefault);
|
583 |
else :
|
584 |
$setting = $globalSetting;
|
585 |
endif;
|
586 |
+
|
587 |
if (isset($params['offer-site-wide'])) : $offerSiteWide = $params['offer-site-wide'];
|
588 |
else : $offerSiteWide = $this->for_feed_settings();
|
589 |
endif;
|
590 |
+
|
591 |
// This allows us to provide an alternative set of human-readable
|
592 |
// labels for each potential value. For use in Currently: line.
|
593 |
if (isset($params['labels'])) : $labels = $params['labels'];
|
594 |
elseif (is_callable($options)) : $labels = NULL;
|
595 |
else : $labels = $options;
|
596 |
endif;
|
597 |
+
|
598 |
if (isset($params['input-name'])) : $inputName = $params['input-name'];
|
599 |
else : $inputName = $globalName;
|
600 |
endif;
|
601 |
+
|
602 |
if (isset($params['default-input-id'])) : $defaultInputId = $params['default-input-id'];
|
603 |
else : $defaultInputId = NULL;
|
604 |
endif;
|
607 |
elseif (!is_null($defaultInputId)) : $defaultInputIdNo = $defaultInputId.'-no';
|
608 |
else : $defaultInputIdNo = NULL;
|
609 |
endif;
|
610 |
+
|
611 |
// This allows us to either include the site-default setting as
|
612 |
// one of the options within the radio box, or else as a simple
|
613 |
// yes/no toggle that controls whether or not to check another
|
625 |
: 'site-default'
|
626 |
);
|
627 |
endif;
|
628 |
+
|
629 |
$settingDefaulted = (is_null($setting) or ($settingDefault === $setting));
|
630 |
|
631 |
if (!is_callable($options)) :
|
633 |
if ($settingDefaulted) :
|
634 |
$checked[$defaultInputValue] = ' checked="checked"';
|
635 |
endif;
|
636 |
+
|
637 |
foreach ($options as $value => $label) :
|
638 |
if ($setting == $value) :
|
639 |
$checked[$value] = ' checked="checked"';
|
650 |
else :
|
651 |
$defaulted['yes'] = (isset($checked[$defaultInputValue]) ? $checked[$defaultInputValue] : '');
|
652 |
endif;
|
653 |
+
|
654 |
if (isset($params['defaulted'])) :
|
655 |
$defaulted['yes'] = ($params['defaulted'] ? ' checked="checked"' : '');
|
656 |
$defaulted['no'] = ($params['defaulted'] ? '' : ' checked="checked"');
|
677 |
print $labels[$globalSetting];
|
678 |
endif; ?></strong> (<a href="<?php print $href; ?>">change</a>)</span></li>
|
679 |
</ul></td>
|
680 |
+
|
681 |
<td class="equals second inactive">
|
682 |
<?php if ($defaultInputName != $inputName) : ?>
|
683 |
<ul class="options">
|
689 |
<?php _e('Do something different with this feed.'); ?></label>
|
690 |
<?php endif;
|
691 |
endif;
|
692 |
+
|
693 |
// Let's spit out the controls here.
|
694 |
if (is_callable($options)) :
|
695 |
// Method call to print out options list
|
706 |
</ul> <!-- class="options" -->
|
707 |
<?php
|
708 |
endif;
|
709 |
+
|
710 |
if ($offerSiteWide) :
|
711 |
if ($defaultInputName != $inputName) :
|
712 |
// Close the <li> and <ul class="options"> we opened above
|
715 |
</ul> <!-- class="options" -->
|
716 |
<?php
|
717 |
endif;
|
718 |
+
|
719 |
// Close off the twofer table that we opened up above.
|
720 |
?>
|
721 |
</td></tr>
|
724 |
<?php
|
725 |
endif;
|
726 |
} /* FeedWordPressAdminPage::setting_radio_control () */
|
727 |
+
|
728 |
function save_button ($caption = NULL) {
|
729 |
if (is_null($caption)) : $caption = __('Save Changes'); endif;
|
730 |
?>
|
735 |
}
|
736 |
} /* class FeedWordPressAdminPage */
|
737 |
|
738 |
+
function fwp_update_set_results_message ($delta, $joiner = ';') {
|
739 |
+
$mesg = array();
|
740 |
+
if (isset($delta['new'])) : $mesg[] = ' '.$delta['new'].' new posts were syndicated'; endif;
|
741 |
+
if (isset($delta['updated']) and ($delta['updated'] != 0)) : $mesg[] = ' '.$delta['updated'].' existing posts were updated'; endif;
|
742 |
+
if (isset($delta['stored']) and ($delta['stored'] != 0)) : $mesg[] = ' '.$delta['stored'].' alternate versions of existing posts were stored for reference'; endif;
|
743 |
+
|
744 |
+
if (!is_null($joiner)) :
|
745 |
+
$mesg = implode($joiner, $mesg);
|
746 |
+
endif;
|
747 |
+
return $mesg;
|
748 |
+
} /* function fwp_update_set_results_message () */
|
749 |
+
|
750 |
function fwp_authors_single_submit ($link = NULL) {
|
751 |
?>
|
752 |
<div class="submitbox" id="submitlink">
|
787 |
'id' => NULL,
|
788 |
'box_title' => __('Post Tags'),
|
789 |
));
|
790 |
+
|
791 |
if (!is_array($tags)) : $tags = array(); endif;
|
792 |
+
|
793 |
$tax_name = $params['taxonomy'];
|
794 |
$taxonomy = get_taxonomy($params['taxonomy']);
|
795 |
$disabled = (!current_user_can($taxonomy->cap->assign_terms) ? 'disabled="disabled"' : '');
|
796 |
+
|
797 |
$desc = "<p style=\"font-size:smaller;font-style:bold;margin:0\">Tag $object as...</p>";
|
798 |
|
799 |
if (is_null($params['textarea_name'])) :
|
808 |
if (is_null($params['input_name'])) :
|
809 |
$params['input_name'] = "newtag[$tax_name]";
|
810 |
endif;
|
811 |
+
|
812 |
if (is_null($params['id'])) :
|
813 |
$params['id'] = $tax_name;
|
814 |
endif;
|
815 |
+
|
816 |
print $desc;
|
817 |
$helps = __('Separate tags with commas.');
|
818 |
$box['title'] = __('Tags');
|
822 |
<div class="nojs-tags hide-if-js">
|
823 |
<p><?php echo $taxonomy->labels->add_or_remove_items; ?></p>
|
824 |
<textarea name="<?php echo $params['textarea_name']; ?>" class="the-tags" id="<?php echo $params['textarea_id']; ?>"><?php echo esc_attr(implode(",", $tags)); ?></textarea></div>
|
825 |
+
|
826 |
<?php if ( current_user_can($taxonomy->cap->assign_terms) ) :?>
|
827 |
<div class="ajaxtag hide-if-no-js">
|
828 |
<label class="screen-reader-text" for="<?php echo $params['input_id']; ?>"><?php echo $params['box_title']; ?></label>
|
833 |
<p class="howto"><?php echo esc_attr( $taxonomy->labels->separate_items_with_commas ); ?></p>
|
834 |
<?php endif; ?>
|
835 |
</div>
|
836 |
+
|
837 |
<div class="tagchecklist"></div>
|
838 |
</div>
|
839 |
<?php if ( current_user_can($taxonomy->cap->assign_terms) ) : ?>
|
884 |
<p id="<?php print $idPrefix; ?><?php print $taxonomy; ?>-add" class="category-add wp-hidden-child">
|
885 |
<?php
|
886 |
$newcat = 'new'.$taxonomy;
|
887 |
+
|
888 |
?>
|
889 |
<label class="screen-reader-text" for="<?php print $idPrefix; ?>new<?php print $taxonomy; ?>"><?php _e('Add New Category'); ?></label>
|
890 |
<input
|
892 |
class="new<?php print $taxonomy; ?> form-required form-input-tip"
|
893 |
aria-required="true"
|
894 |
tabindex="3"
|
895 |
+
type="text" name="<?php print $newcat; ?>"
|
896 |
value="<?php _e( 'New category name' ); ?>"
|
897 |
/>
|
898 |
<label class="screen-reader-text" for="<?php print $idPrefix; ?>new<?php print $taxonomy; ?>-parent"><?php _e('Parent Category:'); ?></label>
|
941 |
global $wpdb;
|
942 |
$ret = array();
|
943 |
|
944 |
+
$users = get_users();
|
945 |
if (is_array($users)) :
|
946 |
foreach ($users as $user) :
|
947 |
$id = (int) $user->ID;
|
955 |
}
|
956 |
|
957 |
class FeedWordPressSettingsUI {
|
958 |
+
static function is_admin () {
|
959 |
global $fwp_path;
|
960 |
+
|
961 |
$admin_page = false; // Innocent until proven guilty
|
962 |
if (isset($_REQUEST['page'])) :
|
963 |
$admin_page = (
|
967 |
endif;
|
968 |
return $admin_page;
|
969 |
}
|
970 |
+
|
971 |
+
static function admin_scripts () {
|
972 |
global $fwp_path;
|
973 |
+
|
974 |
wp_enqueue_script('post'); // for magic tag and category boxes
|
975 |
wp_enqueue_script('admin-forms'); // for checkbox selection
|
976 |
+
|
977 |
wp_register_script('feedwordpress-elements', WP_PLUGIN_URL.'/'.$fwp_path.'/feedwordpress-elements.js');
|
978 |
wp_enqueue_script('feedwordpress-elements');
|
979 |
}
|
980 |
|
981 |
+
static function admin_styles () {
|
982 |
?>
|
983 |
<style type="text/css">
|
984 |
#feedwordpress-admin-feeds .link-rss-params-remove .x, .feedwordpress-admin .remove-it .x {
|
1000 |
background-position:0 top;
|
1001 |
background-repeat:repeat-x;
|
1002 |
}
|
1003 |
+
|
1004 |
.update-results {
|
1005 |
max-width: 100%;
|
1006 |
overflow: auto;
|
1009 |
</style>
|
1010 |
<?php
|
1011 |
} /* FeedWordPressSettingsUI::admin_styles () */
|
1012 |
+
|
1013 |
+
static function ajax_nonce_fields () {
|
1014 |
if (function_exists('wp_nonce_field')) :
|
1015 |
echo "<form style='display: none' method='get' action=''>\n<p>\n";
|
1016 |
wp_nonce_field( 'closedpostboxes', 'closedpostboxesnonce', false );
|
1019 |
endif;
|
1020 |
} /* FeedWordPressSettingsUI::ajax_nonce_fields () */
|
1021 |
|
1022 |
+
static function fix_toggles_js ($context) {
|
1023 |
?>
|
1024 |
<script type="text/javascript">
|
1025 |
+
jQuery(document).ready( function($) {
|
1026 |
// In case someone got here first...
|
1027 |
$('.postbox h3, .postbox .handlediv').unbind('click');
|
1028 |
$('.postbox h3 a').unbind('click');
|
1029 |
$('.hide-postbox-tog').unbind('click');
|
1030 |
$('.columns-prefs input[type="radio"]').unbind('click');
|
1031 |
$('.meta-box-sortables').sortable('destroy');
|
1032 |
+
|
1033 |
postboxes.add_postbox_toggles('<?php print $context; ?>');
|
1034 |
} );
|
1035 |
</script>
|
1036 |
<?php
|
1037 |
} /* FeedWordPressSettingsUI::fix_toggles_js () */
|
1038 |
+
|
1039 |
+
static function magic_input_tip_js ($id) {
|
1040 |
if (!preg_match('/^[.#]/', $id)) :
|
1041 |
$id = '#'.$id;
|
1042 |
endif;
|
1053 |
inputBox.blur(function() {
|
1054 |
if ( this.value == '' )
|
1055 |
jQuery(this).val( this.defaultValue ).addClass( 'form-input-tip' );
|
1056 |
+
});
|
1057 |
} );
|
1058 |
</script>
|
1059 |
<?php
|
1071 |
$userdata['user_nicename'] = apply_filters('pre_user_nicename', sanitize_title($newuser_name));
|
1072 |
$userdata['display_name'] = $newuser_name;
|
1073 |
$userdata['user_pass'] = substr(md5(uniqid(microtime())), 0, 6); // just something random to lock it up
|
1074 |
+
|
1075 |
$blahUrl = get_bloginfo('url'); $url = parse_url($blahUrl);
|
1076 |
$userdata['user_email'] = substr(md5(uniqid(microtime())), 0, 6).'@'.$url['host'];
|
1077 |
+
|
1078 |
$newuser_id = wp_insert_user($userdata);
|
1079 |
$ret = $newuser_id; // Either a numeric ID or a WP_Error object
|
1080 |
else :
|
1096 |
|
1097 |
function fwp_do_meta_boxes($page, $context, $object) {
|
1098 |
$ret = do_meta_boxes($page, $context, $object);
|
1099 |
+
|
1100 |
// Avoid JavaScript error from WordPress 2.5 bug
|
1101 |
?>
|
1102 |
<div style="display: none">
|
1111 |
} /* function fwp_remove_meta_box() */
|
1112 |
|
1113 |
function fwp_syndication_manage_page_links_table_rows ($links, $page, $visible = 'Y') {
|
1114 |
+
|
1115 |
$subscribed = ('Y' == strtoupper($visible));
|
1116 |
if ($subscribed or (count($links) > 0)) :
|
1117 |
?>
|
1127 |
|
1128 |
<tbody>
|
1129 |
<?php
|
1130 |
+
$alt_row = true;
|
1131 |
if (count($links) > 0):
|
1132 |
foreach ($links as $link):
|
1133 |
$trClass = array();
|
1145 |
if (is_null($sLink->setting('update/error'))) :
|
1146 |
$errorsSince = '';
|
1147 |
if (!is_null($sLink->setting('link/item count'))) :
|
1148 |
+
$N = $sLink->setting('link/item count');
|
1149 |
$fileSizeLines[] = sprintf((($N==1) ? __('%d item') : __('%d items')), $N);
|
1150 |
endif;
|
1151 |
|
1156 |
$trClass[] = 'feed-error';
|
1157 |
|
1158 |
$theError = unserialize($sLink->setting('update/error'));
|
1159 |
+
|
1160 |
$errorsSince = "<div class=\"returning-errors\">"
|
1161 |
."<p><strong>Returning errors</strong> since "
|
1162 |
.fwp_time_elapsed($theError['since'])
|
1170 |
endif;
|
1171 |
|
1172 |
$nextUpdate = "<div style='max-width: 30.0em; font-size: 0.9em;'><div style='font-style:italic;'>";
|
1173 |
+
|
1174 |
$ttl = $sLink->setting('update/ttl');
|
1175 |
if (is_numeric($ttl)) :
|
1176 |
$next = $sLink->setting('update/last') + $sLink->setting('update/fudge') + ((int) $ttl * 60);
|
1193 |
else :
|
1194 |
$lastUpdated .= gmdate('F j', $next + (get_option('gmt_offset') * 3600));
|
1195 |
endif;
|
1196 |
+
|
1197 |
$nextUpdate .= "Scheduled to be checked for updates every ".$ttl." minute".(($ttl!=1)?"s":"")."</div><div style='size:0.9em; margin-top: 0.5em'> This update schedule was requested by the feed provider";
|
1198 |
if ($sLink->setting('update/xml')) :
|
1199 |
$nextUpdate .= " using a standard <code style=\"font-size: inherit; padding: 0; background: transparent\"><".$sLink->setting('update/xml')."></code> element";
|
1209 |
if (count($fileSizeLines) > 0) :
|
1210 |
$fileSize = '<div>'.implode(" / ", $fileSizeLines)."</div>";
|
1211 |
endif;
|
1212 |
+
|
1213 |
unset($sLink);
|
1214 |
+
|
1215 |
$alt_row = !$alt_row;
|
1216 |
+
|
1217 |
if ($alt_row) :
|
1218 |
$trClass[] = 'alternate';
|
1219 |
endif;
|
Binary file
|
@@ -6,7 +6,7 @@ class FeedWordPressCategoriesPage extends FeedWordPressAdminPage {
|
|
6 |
if (is_numeric($link) and -1 == $link) :
|
7 |
$link = $this->submitted_link();
|
8 |
endif;
|
9 |
-
|
10 |
FeedWordPressAdminPage::FeedWordPressAdminPage('feedwordpresscategories', $link);
|
11 |
$this->dispatch = 'feedwordpress_admin_page_categories';
|
12 |
$this->pagenames = array(
|
@@ -16,7 +16,7 @@ class FeedWordPressCategoriesPage extends FeedWordPressAdminPage {
|
|
16 |
);
|
17 |
$this->filename = __FILE__;
|
18 |
}
|
19 |
-
|
20 |
function unfamiliar_category_label ($name) {
|
21 |
if (preg_match('/^create:(.*)$/', $name, $refs)) :
|
22 |
$tax = get_taxonomy($refs[1]);
|
@@ -24,11 +24,11 @@ class FeedWordPressCategoriesPage extends FeedWordPressAdminPage {
|
|
24 |
endif;
|
25 |
return $name;
|
26 |
}
|
27 |
-
|
28 |
-
|
29 |
function feed_categories_box ($page, $box = NULL) {
|
30 |
$link = $page->link;
|
31 |
-
|
32 |
$globalPostType = get_option('feedwordpress_syndicated_post_type', 'post');
|
33 |
if ($this->for_feed_settings()) :
|
34 |
$post_type = $link->setting('syndicated post type', 'syndicated_post_type', 'post');
|
@@ -42,7 +42,7 @@ class FeedWordPressCategoriesPage extends FeedWordPressAdminPage {
|
|
42 |
$tagLikeTaxonomies = array();
|
43 |
foreach ($taxonomies as $tax) :
|
44 |
$taxonomy = get_taxonomy($tax);
|
45 |
-
|
46 |
if (!$taxonomy->hierarchical) :
|
47 |
$tagLikeTaxonomies[] = $tax;
|
48 |
endif;
|
@@ -62,12 +62,12 @@ class FeedWordPressCategoriesPage extends FeedWordPressAdminPage {
|
|
62 |
);
|
63 |
endforeach;
|
64 |
endforeach;
|
65 |
-
|
66 |
foreach ($unmatched as $what => $um) :
|
67 |
$unmatched[$what]['null'] = array('label' => __('Don\'t create any matching terms'));
|
68 |
$unmatchedRadio[$what]['null'] = '';
|
69 |
endforeach;
|
70 |
-
|
71 |
$globalUnmatched = array(
|
72 |
'category' => FeedWordPress::on_unfamiliar('category'),
|
73 |
'post_tag' => FeedWordPress::on_unfamiliar('post_tag'),
|
@@ -77,21 +77,21 @@ class FeedWordPressCategoriesPage extends FeedWordPressAdminPage {
|
|
77 |
if ($value=='tag') : $value = 'create:post_tag'; endif;
|
78 |
$globalUnmatched[$what] = $value;
|
79 |
endforeach;
|
80 |
-
|
81 |
$globalMatch['cats'] = get_option('feedwordpress_match_cats', $taxonomies);
|
82 |
$globalMatch['tags'] = get_option('feedwordpress_match_tags', $tagLikeTaxonomies);
|
83 |
$globalMatch['filter'] = get_option('feedwordpress_match_filter', array());
|
84 |
-
|
85 |
$globalMatchLabels = array();
|
86 |
$nothingDoing = array('cats' => "won't try to match", 'tags' => "won't try to match", "filter" => "won't filter");
|
87 |
-
|
88 |
foreach ($globalMatch as $what => $domain) :
|
89 |
$labels = array(); $domain = array_filter($domain, 'remove_dummy_zero');
|
90 |
foreach ($domain as $tax) :
|
91 |
$tax = get_taxonomy($tax);
|
92 |
$labels[] = $tax->labels->name;
|
93 |
endforeach;
|
94 |
-
|
95 |
if (count($labels) > 0) :
|
96 |
$globalMatchLabels[$what] = implode(", ", $labels);
|
97 |
else :
|
@@ -126,30 +126,30 @@ class FeedWordPressCategoriesPage extends FeedWordPressAdminPage {
|
|
126 |
$unmatchedDefault[$what] = $opts[0];
|
127 |
$unmatchedColumns[$what] = array();
|
128 |
endif;
|
129 |
-
|
130 |
$ucKey[$what] = $link->setting("unfamiliar $what", NULL, NULL);
|
131 |
endforeach;
|
132 |
-
|
133 |
$match['cats'] = $this->link->setting('match/cats', NULL, NULL);
|
134 |
$match['tags'] = $this->link->setting('match/tags', NULL, NULL);
|
135 |
$match['filter'] = $this->link->setting('match/filter', NULL, NULL);
|
136 |
else :
|
137 |
foreach ($unmatched as $what => $um) :
|
138 |
-
$ucKey[$what] = FeedWordPress::on_unfamiliar($what);
|
139 |
endforeach;
|
140 |
|
141 |
$match = $globalMatch;
|
142 |
endif;
|
143 |
-
|
144 |
foreach ($ucKey as $what => $uck) :
|
145 |
if ($uck == 'tag') : $uck = 'create:post_tag'; endif;
|
146 |
if ($uck == 'create') : $uck = 'create:category'; endif;
|
147 |
-
|
148 |
if (!is_string($uck)) :
|
149 |
$uck = $unmatchedDefault[$what];
|
150 |
endif;
|
151 |
$ucKey[$what] = $uck;
|
152 |
-
|
153 |
if (!array_key_exists($uck, $unmatchedRadio[$what])) :
|
154 |
$obsoleteLi = array(
|
155 |
$uck => array(
|
@@ -159,12 +159,12 @@ class FeedWordPressCategoriesPage extends FeedWordPressAdminPage {
|
|
159 |
$unmatched[$what] = array_merge($obsoleteLi, $unmatched[$what]);
|
160 |
$unmatchedRadio[$what][$uck] = ' disabled="disabled"';
|
161 |
endif;
|
162 |
-
|
163 |
$unmatchedRadio[$what][$uck] .= ' checked="checked"';
|
164 |
-
|
165 |
$unmatchedColumns[$what][] = $unmatched[$what];
|
166 |
endforeach;
|
167 |
-
|
168 |
$defaulted = array();
|
169 |
foreach ($match as $what => $set) :
|
170 |
$defaulted[$what] = false;
|
@@ -175,7 +175,7 @@ class FeedWordPressCategoriesPage extends FeedWordPressAdminPage {
|
|
175 |
$match[$what] = $globalMatch[$what];
|
176 |
endif;
|
177 |
endif;
|
178 |
-
|
179 |
if (!$defaulted[$what] or $this->for_feed_settings()) :
|
180 |
foreach ($set as $against) :
|
181 |
if (array_key_exists($against, $matchUl[$what])) :
|
@@ -350,7 +350,7 @@ least one local <strong><?php $l = $li['labels']; print $l->singular_name; ?></s
|
|
350 |
<?php if ($page->for_feed_settings()) : ?>
|
351 |
<tr>
|
352 |
<th scope="row">Multiple categories:</th>
|
353 |
-
<td>
|
354 |
<input type="text" size="20" id="cat_split" name="cat_split" value="<?php if (isset($link->settings['cat_split'])) : echo htmlspecialchars($link->settings['cat_split']); endif; ?>" />
|
355 |
<p class="setting-description">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
|
356 |
categories in a single category element. The regular expression should match
|
@@ -376,9 +376,11 @@ blank.</p></td>
|
|
376 |
'post_tag' => 'tags',
|
377 |
);
|
378 |
}
|
379 |
-
|
380 |
function categories_box ($page, $box = NULL) {
|
381 |
$link = $page->link;
|
|
|
|
|
382 |
|
383 |
if ($this->for_feed_settings()) :
|
384 |
$post_type = $link->setting('syndicated post type', 'syndicated_post_type', 'post');
|
@@ -417,7 +419,7 @@ blank.</p></td>
|
|
417 |
$add_global_categories = $link->setting("add/$tax", NULL, 'yes');
|
418 |
$checked = array('yes' => '', 'no' => '');
|
419 |
$checked[$add_global_categories] = ' checked="checked"';
|
420 |
-
|
421 |
if (isset($setting_map[$tax])) :
|
422 |
$setting = $setting_map[$tax];
|
423 |
$cats = $link->setting($setting, NULL, NULL);
|
@@ -430,7 +432,7 @@ blank.</p></td>
|
|
430 |
else :
|
431 |
$cats = $globalCats;
|
432 |
endif;
|
433 |
-
|
434 |
if ($page->for_feed_settings()) :
|
435 |
?>
|
436 |
<table class="twofer">
|
@@ -439,17 +441,17 @@ blank.</p></td>
|
|
439 |
<td class="primary">
|
440 |
<?php
|
441 |
endif;
|
442 |
-
|
443 |
-
$dogs =
|
444 |
|
445 |
if ($taxonomy->hierarchical) : // Use a category-style checkbox
|
446 |
fwp_category_box($dogs, 'all '.$page->these_posts_phrase(), /*tags=*/ array(), /*params=*/ array('taxonomy' => $tax));
|
447 |
else : // Use a tag-style edit box
|
448 |
fwp_tags_box($cats, 'all '.$page->these_posts_phrase(), /*params=*/ array('taxonomy' => $tax));
|
449 |
endif;
|
450 |
-
|
451 |
-
$globalDogs =
|
452 |
-
|
453 |
$siteWideHref = $this->admin_page_href(basename(__FILE__));
|
454 |
|
455 |
if ($page->for_feed_settings()) :
|
@@ -472,7 +474,7 @@ blank.</p></td>
|
|
472 |
Should <?php print $page->these_posts_phrase(); ?> be assigned
|
473 |
these <?php print $taxonomy->labels->name; ?> from the <a href="<?php print esc_html($siteWideHref); ?>">site-wide settings</a>, in
|
474 |
addition to the feed-specific <?php print $taxonomy->labels->name; ?> you set up here?</p>
|
475 |
-
|
476 |
<ul class="settings">
|
477 |
<li><p><label><input type="radio" name="add_global[<?php print $tax; ?>]" value="yes" <?php print $checked['yes']; ?> /> Yes. Place <?php print $page->these_posts_phrase(); ?> under all these categories.</label></p></li>
|
478 |
<li><p><label><input type="radio" name="add_global[<?php print $tax; ?>]" value="no" <?php print $checked['no']; ?> /> No. Only use the categories I set up on the left. Do not use the global defaults for <?php print $page->these_posts_phrase(); ?></label></p></li>
|
@@ -493,7 +495,7 @@ blank.</p></td>
|
|
493 |
</table>
|
494 |
<?php
|
495 |
} /* FeedWordPressCategoriesPage::categories_box () */
|
496 |
-
|
497 |
function save_settings ($post) {
|
498 |
if (isset($post['match_categories'])) :
|
499 |
foreach ($post['match_categories'] as $what => $set) :
|
@@ -504,7 +506,7 @@ blank.</p></td>
|
|
504 |
and $post['match_default'][$what]=='yes') :
|
505 |
$set = NULL; // Defaulted!
|
506 |
endif;
|
507 |
-
|
508 |
$this->update_setting("match/$what", $set, NULL);
|
509 |
endforeach;
|
510 |
endif;
|
@@ -512,9 +514,9 @@ blank.</p></td>
|
|
512 |
$settingMap = $this->term_setting_map();
|
513 |
|
514 |
$saveTerms = array(); $separateSaveTerms = array('category' => array(), 'post_tag' => array());
|
515 |
-
|
516 |
if (!isset($post['tax_input'])) : $post['tax_input'] = array(); endif;
|
517 |
-
|
518 |
// Merge in data from older-notation category check boxes
|
519 |
if (isset($post['post_category'])) :
|
520 |
// Just merging in for processing below.
|
@@ -537,7 +539,7 @@ blank.</p></td>
|
|
537 |
$saveTerms[$tax] = explode(",", $terms);
|
538 |
endif;
|
539 |
$saveTerms[$tax] = array_map('trim', $saveTerms[$tax]);
|
540 |
-
|
541 |
if (isset($optionMap[$tax])) :
|
542 |
$separateSaveTerms[$tax] = $saveTerms[$tax];
|
543 |
unset($saveTerms[$tax]);
|
@@ -546,10 +548,10 @@ blank.</p></td>
|
|
546 |
|
547 |
if (isset($post['post_category'])) :
|
548 |
foreach ($post['post_category'] as $cat) :
|
549 |
-
$separateSaveTerms['category'][] = '{category#'.$cat.'}';
|
550 |
endforeach;
|
551 |
endif;
|
552 |
-
|
553 |
// Unmatched categories and tags
|
554 |
foreach (array('category', 'post_tag') as $what) :
|
555 |
if (isset($post["unfamiliar_{$what}"])) :
|
@@ -560,7 +562,7 @@ blank.</p></td>
|
|
560 |
);
|
561 |
endif;
|
562 |
endforeach;
|
563 |
-
|
564 |
// Categories and Tags
|
565 |
foreach ($separateSaveTerms as $tax => $terms) :
|
566 |
if ($this->for_feed_settings()) :
|
@@ -573,7 +575,7 @@ blank.</p></td>
|
|
573 |
endif;
|
574 |
endif;
|
575 |
endforeach;
|
576 |
-
|
577 |
// Other terms
|
578 |
$this->update_setting(array('feed'=>'terms', 'global'=>'syndication_terms'), $saveTerms, array());
|
579 |
|
@@ -582,7 +584,7 @@ blank.</p></td>
|
|
582 |
if (isset($post['cat_split'])) :
|
583 |
$this->link->update_setting('cat_split', trim($post['cat_split']), '');
|
584 |
endif;
|
585 |
-
|
586 |
// Treat global terms (cats, tags, etc.) as additional,
|
587 |
// or as defaults to be overridden and replaced?
|
588 |
if (isset($post['add_global'])) :
|
@@ -593,18 +595,18 @@ blank.</p></td>
|
|
593 |
endif;
|
594 |
parent::save_settings($post);
|
595 |
} /* FeedWordPressCategoriesPage::save_settings() */
|
596 |
-
|
597 |
function display () {
|
598 |
////////////////////////////////////////////////
|
599 |
// Display settings boxes //////////////////////
|
600 |
////////////////////////////////////////////////
|
601 |
-
|
602 |
$this->boxes_by_methods = array(
|
603 |
'feed_categories_box' => __('Feed Categories & Tags'),
|
604 |
'categories_box' => array('title' => __('Categories'), 'id' => 'categorydiv'),
|
605 |
);
|
606 |
|
607 |
-
parent::display();
|
608 |
}
|
609 |
}
|
610 |
|
6 |
if (is_numeric($link) and -1 == $link) :
|
7 |
$link = $this->submitted_link();
|
8 |
endif;
|
9 |
+
|
10 |
FeedWordPressAdminPage::FeedWordPressAdminPage('feedwordpresscategories', $link);
|
11 |
$this->dispatch = 'feedwordpress_admin_page_categories';
|
12 |
$this->pagenames = array(
|
16 |
);
|
17 |
$this->filename = __FILE__;
|
18 |
}
|
19 |
+
|
20 |
function unfamiliar_category_label ($name) {
|
21 |
if (preg_match('/^create:(.*)$/', $name, $refs)) :
|
22 |
$tax = get_taxonomy($refs[1]);
|
24 |
endif;
|
25 |
return $name;
|
26 |
}
|
27 |
+
|
28 |
+
|
29 |
function feed_categories_box ($page, $box = NULL) {
|
30 |
$link = $page->link;
|
31 |
+
|
32 |
$globalPostType = get_option('feedwordpress_syndicated_post_type', 'post');
|
33 |
if ($this->for_feed_settings()) :
|
34 |
$post_type = $link->setting('syndicated post type', 'syndicated_post_type', 'post');
|
42 |
$tagLikeTaxonomies = array();
|
43 |
foreach ($taxonomies as $tax) :
|
44 |
$taxonomy = get_taxonomy($tax);
|
45 |
+
|
46 |
if (!$taxonomy->hierarchical) :
|
47 |
$tagLikeTaxonomies[] = $tax;
|
48 |
endif;
|
62 |
);
|
63 |
endforeach;
|
64 |
endforeach;
|
65 |
+
|
66 |
foreach ($unmatched as $what => $um) :
|
67 |
$unmatched[$what]['null'] = array('label' => __('Don\'t create any matching terms'));
|
68 |
$unmatchedRadio[$what]['null'] = '';
|
69 |
endforeach;
|
70 |
+
|
71 |
$globalUnmatched = array(
|
72 |
'category' => FeedWordPress::on_unfamiliar('category'),
|
73 |
'post_tag' => FeedWordPress::on_unfamiliar('post_tag'),
|
77 |
if ($value=='tag') : $value = 'create:post_tag'; endif;
|
78 |
$globalUnmatched[$what] = $value;
|
79 |
endforeach;
|
80 |
+
|
81 |
$globalMatch['cats'] = get_option('feedwordpress_match_cats', $taxonomies);
|
82 |
$globalMatch['tags'] = get_option('feedwordpress_match_tags', $tagLikeTaxonomies);
|
83 |
$globalMatch['filter'] = get_option('feedwordpress_match_filter', array());
|
84 |
+
|
85 |
$globalMatchLabels = array();
|
86 |
$nothingDoing = array('cats' => "won't try to match", 'tags' => "won't try to match", "filter" => "won't filter");
|
87 |
+
|
88 |
foreach ($globalMatch as $what => $domain) :
|
89 |
$labels = array(); $domain = array_filter($domain, 'remove_dummy_zero');
|
90 |
foreach ($domain as $tax) :
|
91 |
$tax = get_taxonomy($tax);
|
92 |
$labels[] = $tax->labels->name;
|
93 |
endforeach;
|
94 |
+
|
95 |
if (count($labels) > 0) :
|
96 |
$globalMatchLabels[$what] = implode(", ", $labels);
|
97 |
else :
|
126 |
$unmatchedDefault[$what] = $opts[0];
|
127 |
$unmatchedColumns[$what] = array();
|
128 |
endif;
|
129 |
+
|
130 |
$ucKey[$what] = $link->setting("unfamiliar $what", NULL, NULL);
|
131 |
endforeach;
|
132 |
+
|
133 |
$match['cats'] = $this->link->setting('match/cats', NULL, NULL);
|
134 |
$match['tags'] = $this->link->setting('match/tags', NULL, NULL);
|
135 |
$match['filter'] = $this->link->setting('match/filter', NULL, NULL);
|
136 |
else :
|
137 |
foreach ($unmatched as $what => $um) :
|
138 |
+
$ucKey[$what] = FeedWordPress::on_unfamiliar($what);
|
139 |
endforeach;
|
140 |
|
141 |
$match = $globalMatch;
|
142 |
endif;
|
143 |
+
|
144 |
foreach ($ucKey as $what => $uck) :
|
145 |
if ($uck == 'tag') : $uck = 'create:post_tag'; endif;
|
146 |
if ($uck == 'create') : $uck = 'create:category'; endif;
|
147 |
+
|
148 |
if (!is_string($uck)) :
|
149 |
$uck = $unmatchedDefault[$what];
|
150 |
endif;
|
151 |
$ucKey[$what] = $uck;
|
152 |
+
|
153 |
if (!array_key_exists($uck, $unmatchedRadio[$what])) :
|
154 |
$obsoleteLi = array(
|
155 |
$uck => array(
|
159 |
$unmatched[$what] = array_merge($obsoleteLi, $unmatched[$what]);
|
160 |
$unmatchedRadio[$what][$uck] = ' disabled="disabled"';
|
161 |
endif;
|
162 |
+
|
163 |
$unmatchedRadio[$what][$uck] .= ' checked="checked"';
|
164 |
+
|
165 |
$unmatchedColumns[$what][] = $unmatched[$what];
|
166 |
endforeach;
|
167 |
+
|
168 |
$defaulted = array();
|
169 |
foreach ($match as $what => $set) :
|
170 |
$defaulted[$what] = false;
|
175 |
$match[$what] = $globalMatch[$what];
|
176 |
endif;
|
177 |
endif;
|
178 |
+
|
179 |
if (!$defaulted[$what] or $this->for_feed_settings()) :
|
180 |
foreach ($set as $against) :
|
181 |
if (array_key_exists($against, $matchUl[$what])) :
|
350 |
<?php if ($page->for_feed_settings()) : ?>
|
351 |
<tr>
|
352 |
<th scope="row">Multiple categories:</th>
|
353 |
+
<td>
|
354 |
<input type="text" size="20" id="cat_split" name="cat_split" value="<?php if (isset($link->settings['cat_split'])) : echo htmlspecialchars($link->settings['cat_split']); endif; ?>" />
|
355 |
<p class="setting-description">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
|
356 |
categories in a single category element. The regular expression should match
|
376 |
'post_tag' => 'tags',
|
377 |
);
|
378 |
}
|
379 |
+
|
380 |
function categories_box ($page, $box = NULL) {
|
381 |
$link = $page->link;
|
382 |
+
$dummy = null;
|
383 |
+
$syndicatedlink = new SyndicatedLink($dummy);
|
384 |
|
385 |
if ($this->for_feed_settings()) :
|
386 |
$post_type = $link->setting('syndicated post type', 'syndicated_post_type', 'post');
|
419 |
$add_global_categories = $link->setting("add/$tax", NULL, 'yes');
|
420 |
$checked = array('yes' => '', 'no' => '');
|
421 |
$checked[$add_global_categories] = ' checked="checked"';
|
422 |
+
|
423 |
if (isset($setting_map[$tax])) :
|
424 |
$setting = $setting_map[$tax];
|
425 |
$cats = $link->setting($setting, NULL, NULL);
|
432 |
else :
|
433 |
$cats = $globalCats;
|
434 |
endif;
|
435 |
+
|
436 |
if ($page->for_feed_settings()) :
|
437 |
?>
|
438 |
<table class="twofer">
|
441 |
<td class="primary">
|
442 |
<?php
|
443 |
endif;
|
444 |
+
|
445 |
+
$dogs = $syndicatedlink->category_ids(/*post=*/ NULL, $cats, /*unfamiliar=*/ NULL, /*taxonomies=*/ array($tax));
|
446 |
|
447 |
if ($taxonomy->hierarchical) : // Use a category-style checkbox
|
448 |
fwp_category_box($dogs, 'all '.$page->these_posts_phrase(), /*tags=*/ array(), /*params=*/ array('taxonomy' => $tax));
|
449 |
else : // Use a tag-style edit box
|
450 |
fwp_tags_box($cats, 'all '.$page->these_posts_phrase(), /*params=*/ array('taxonomy' => $tax));
|
451 |
endif;
|
452 |
+
|
453 |
+
$globalDogs = $syndicatedlink->category_ids(/*post=*/ NULL, $globalCats, /*unfamiliar=*/ 'create:'.$tax, /*taxonomies=*/ array($tax));
|
454 |
+
|
455 |
$siteWideHref = $this->admin_page_href(basename(__FILE__));
|
456 |
|
457 |
if ($page->for_feed_settings()) :
|
474 |
Should <?php print $page->these_posts_phrase(); ?> be assigned
|
475 |
these <?php print $taxonomy->labels->name; ?> from the <a href="<?php print esc_html($siteWideHref); ?>">site-wide settings</a>, in
|
476 |
addition to the feed-specific <?php print $taxonomy->labels->name; ?> you set up here?</p>
|
477 |
+
|
478 |
<ul class="settings">
|
479 |
<li><p><label><input type="radio" name="add_global[<?php print $tax; ?>]" value="yes" <?php print $checked['yes']; ?> /> Yes. Place <?php print $page->these_posts_phrase(); ?> under all these categories.</label></p></li>
|
480 |
<li><p><label><input type="radio" name="add_global[<?php print $tax; ?>]" value="no" <?php print $checked['no']; ?> /> No. Only use the categories I set up on the left. Do not use the global defaults for <?php print $page->these_posts_phrase(); ?></label></p></li>
|
495 |
</table>
|
496 |
<?php
|
497 |
} /* FeedWordPressCategoriesPage::categories_box () */
|
498 |
+
|
499 |
function save_settings ($post) {
|
500 |
if (isset($post['match_categories'])) :
|
501 |
foreach ($post['match_categories'] as $what => $set) :
|
506 |
and $post['match_default'][$what]=='yes') :
|
507 |
$set = NULL; // Defaulted!
|
508 |
endif;
|
509 |
+
|
510 |
$this->update_setting("match/$what", $set, NULL);
|
511 |
endforeach;
|
512 |
endif;
|
514 |
$settingMap = $this->term_setting_map();
|
515 |
|
516 |
$saveTerms = array(); $separateSaveTerms = array('category' => array(), 'post_tag' => array());
|
517 |
+
|
518 |
if (!isset($post['tax_input'])) : $post['tax_input'] = array(); endif;
|
519 |
+
|
520 |
// Merge in data from older-notation category check boxes
|
521 |
if (isset($post['post_category'])) :
|
522 |
// Just merging in for processing below.
|
539 |
$saveTerms[$tax] = explode(",", $terms);
|
540 |
endif;
|
541 |
$saveTerms[$tax] = array_map('trim', $saveTerms[$tax]);
|
542 |
+
|
543 |
if (isset($optionMap[$tax])) :
|
544 |
$separateSaveTerms[$tax] = $saveTerms[$tax];
|
545 |
unset($saveTerms[$tax]);
|
548 |
|
549 |
if (isset($post['post_category'])) :
|
550 |
foreach ($post['post_category'] as $cat) :
|
551 |
+
$separateSaveTerms['category'][] = '{category#'.$cat.'}';
|
552 |
endforeach;
|
553 |
endif;
|
554 |
+
|
555 |
// Unmatched categories and tags
|
556 |
foreach (array('category', 'post_tag') as $what) :
|
557 |
if (isset($post["unfamiliar_{$what}"])) :
|
562 |
);
|
563 |
endif;
|
564 |
endforeach;
|
565 |
+
|
566 |
// Categories and Tags
|
567 |
foreach ($separateSaveTerms as $tax => $terms) :
|
568 |
if ($this->for_feed_settings()) :
|
575 |
endif;
|
576 |
endif;
|
577 |
endforeach;
|
578 |
+
|
579 |
// Other terms
|
580 |
$this->update_setting(array('feed'=>'terms', 'global'=>'syndication_terms'), $saveTerms, array());
|
581 |
|
584 |
if (isset($post['cat_split'])) :
|
585 |
$this->link->update_setting('cat_split', trim($post['cat_split']), '');
|
586 |
endif;
|
587 |
+
|
588 |
// Treat global terms (cats, tags, etc.) as additional,
|
589 |
// or as defaults to be overridden and replaced?
|
590 |
if (isset($post['add_global'])) :
|
595 |
endif;
|
596 |
parent::save_settings($post);
|
597 |
} /* FeedWordPressCategoriesPage::save_settings() */
|
598 |
+
|
599 |
function display () {
|
600 |
////////////////////////////////////////////////
|
601 |
// Display settings boxes //////////////////////
|
602 |
////////////////////////////////////////////////
|
603 |
+
|
604 |
$this->boxes_by_methods = array(
|
605 |
'feed_categories_box' => __('Feed Categories & Tags'),
|
606 |
'categories_box' => array('title' => __('Categories'), 'id' => 'categorydiv'),
|
607 |
);
|
608 |
|
609 |
+
parent::display();
|
610 |
}
|
611 |
}
|
612 |
|
@@ -15,9 +15,9 @@ class FeedWordPressCompatibility {
|
|
15 |
* @return bool TRUE if within the range of versions, FALSE if too low
|
16 |
* or too high.
|
17 |
*/
|
18 |
-
|
19 |
global $wp_db_version;
|
20 |
-
|
21 |
$ver = (isset($wp_db_version) ? $wp_db_version : 0);
|
22 |
$good = ($ver >= $floor);
|
23 |
if (!is_null($ceiling)) :
|
@@ -26,7 +26,7 @@ class FeedWordPressCompatibility {
|
|
26 |
return $good;
|
27 |
} /* FeedWordPressCompatibility::test_version() */
|
28 |
|
29 |
-
|
30 |
global $wpdb;
|
31 |
|
32 |
// WordPress 2.3+ term/taxonomy API
|
@@ -45,12 +45,12 @@ class FeedWordPressCompatibility {
|
|
45 |
else :
|
46 |
$cat_id = $term;
|
47 |
endif;
|
48 |
-
|
49 |
// Return newly-created category ID
|
50 |
return $cat_id;
|
51 |
} /* FeedWordPressCompatibility::insert_link_category () */
|
52 |
|
53 |
-
|
54 |
global $wpdb;
|
55 |
|
56 |
$cat_id = NULL;
|
@@ -65,11 +65,11 @@ class FeedWordPressCompatibility {
|
|
65 |
else :
|
66 |
$cat_id = $the_term;
|
67 |
endif;
|
68 |
-
|
69 |
return $cat_id;
|
70 |
} /* FeedWordPressCompatibility::link_category_id () */
|
71 |
|
72 |
-
|
73 |
// Only worry about this if we're using a method with significant side-effects
|
74 |
if (strtoupper($_SERVER['REQUEST_METHOD']) == 'POST') :
|
75 |
// Limit post by user capabilities
|
@@ -87,15 +87,15 @@ class FeedWordPressCompatibility {
|
|
87 |
endif;
|
88 |
endif;
|
89 |
} /* FeedWordPressCompatibility::validate_http_request() */
|
90 |
-
|
91 |
-
|
92 |
// stamp form with hidden fields for a nonce in WP 2.0.3 & later
|
93 |
if (function_exists('wp_nonce_field')) :
|
94 |
wp_nonce_field($action);
|
95 |
endif;
|
96 |
} /* FeedWordPressCompatibility::stamp_nonce() */
|
97 |
-
|
98 |
-
|
99 |
global $fwp_path;
|
100 |
|
101 |
$hook = 'admin_footer-'.$fwp_path.'/'.basename($filename);
|
@@ -125,11 +125,11 @@ if (!function_exists('set_post_field')) {
|
|
125 |
* Included under terms of GPL from WordPress Ticket #10946 <http://core.trac.wordpress.org/attachment/ticket/10946/post.php.diff>
|
126 |
*/
|
127 |
function set_post_field ($field, $value, $post_id) {
|
128 |
-
global $wpdb;
|
129 |
|
130 |
$post_id = absint($post_id);
|
131 |
// sigh ... when FWP is active, I need to avoid avoid_kses_munge
|
132 |
-
// $value = sanitize_post_field($field, $value, $post_id, 'db');
|
133 |
return $wpdb->update($wpdb->posts, array($field => $value), array('ID' => $post_id));
|
134 |
} /* function set_post_field () */
|
135 |
|
@@ -145,10 +145,10 @@ function fwp_category_checklist ($post_id = 0, $descendents_and_self = 0, $selec
|
|
145 |
$prefix = (isset($params['prefix']) ? $params['prefix'] : '');
|
146 |
$taxonomy = (isset($params['taxonomy']) ? $params['taxonomy'] : 'category');
|
147 |
endif;
|
148 |
-
|
149 |
$walker = new FeedWordPress_Walker_Category_Checklist($params);
|
150 |
$walker->set_prefix($prefix);
|
151 |
-
$walker->set_taxonomy($taxonomy);
|
152 |
wp_terms_checklist(/*post_id=*/ $post_id, array(
|
153 |
'taxonomy' => $taxonomy,
|
154 |
'descendents_and_self' => $descendents_and_self,
|
15 |
* @return bool TRUE if within the range of versions, FALSE if too low
|
16 |
* or too high.
|
17 |
*/
|
18 |
+
static function test_version ($floor, $ceiling = null) {
|
19 |
global $wp_db_version;
|
20 |
+
|
21 |
$ver = (isset($wp_db_version) ? $wp_db_version : 0);
|
22 |
$good = ($ver >= $floor);
|
23 |
if (!is_null($ceiling)) :
|
26 |
return $good;
|
27 |
} /* FeedWordPressCompatibility::test_version() */
|
28 |
|
29 |
+
static function insert_link_category ($name) {
|
30 |
global $wpdb;
|
31 |
|
32 |
// WordPress 2.3+ term/taxonomy API
|
45 |
else :
|
46 |
$cat_id = $term;
|
47 |
endif;
|
48 |
+
|
49 |
// Return newly-created category ID
|
50 |
return $cat_id;
|
51 |
} /* FeedWordPressCompatibility::insert_link_category () */
|
52 |
|
53 |
+
static function link_category_id ($value, $key = 'cat_name') {
|
54 |
global $wpdb;
|
55 |
|
56 |
$cat_id = NULL;
|
65 |
else :
|
66 |
$cat_id = $the_term;
|
67 |
endif;
|
68 |
+
|
69 |
return $cat_id;
|
70 |
} /* FeedWordPressCompatibility::link_category_id () */
|
71 |
|
72 |
+
static function validate_http_request ($action = -1, $capability = null) {
|
73 |
// Only worry about this if we're using a method with significant side-effects
|
74 |
if (strtoupper($_SERVER['REQUEST_METHOD']) == 'POST') :
|
75 |
// Limit post by user capabilities
|
87 |
endif;
|
88 |
endif;
|
89 |
} /* FeedWordPressCompatibility::validate_http_request() */
|
90 |
+
|
91 |
+
static function stamp_nonce ($action = -1) {
|
92 |
// stamp form with hidden fields for a nonce in WP 2.0.3 & later
|
93 |
if (function_exists('wp_nonce_field')) :
|
94 |
wp_nonce_field($action);
|
95 |
endif;
|
96 |
} /* FeedWordPressCompatibility::stamp_nonce() */
|
97 |
+
|
98 |
+
static function bottom_script_hook ($filename) {
|
99 |
global $fwp_path;
|
100 |
|
101 |
$hook = 'admin_footer-'.$fwp_path.'/'.basename($filename);
|
125 |
* Included under terms of GPL from WordPress Ticket #10946 <http://core.trac.wordpress.org/attachment/ticket/10946/post.php.diff>
|
126 |
*/
|
127 |
function set_post_field ($field, $value, $post_id) {
|
128 |
+
global $wpdb;
|
129 |
|
130 |
$post_id = absint($post_id);
|
131 |
// sigh ... when FWP is active, I need to avoid avoid_kses_munge
|
132 |
+
// $value = sanitize_post_field($field, $value, $post_id, 'db');
|
133 |
return $wpdb->update($wpdb->posts, array($field => $value), array('ID' => $post_id));
|
134 |
} /* function set_post_field () */
|
135 |
|
145 |
$prefix = (isset($params['prefix']) ? $params['prefix'] : '');
|
146 |
$taxonomy = (isset($params['taxonomy']) ? $params['taxonomy'] : 'category');
|
147 |
endif;
|
148 |
+
|
149 |
$walker = new FeedWordPress_Walker_Category_Checklist($params);
|
150 |
$walker->set_prefix($prefix);
|
151 |
+
$walker->set_taxonomy($taxonomy);
|
152 |
wp_terms_checklist(/*post_id=*/ $post_id, array(
|
153 |
'taxonomy' => $taxonomy,
|
154 |
'descendents_and_self' => $descendents_and_self,
|
@@ -7,7 +7,7 @@ class FeedWordPressDiagnosticsPage extends FeedWordPressAdminPage {
|
|
7 |
FeedWordPressAdminPage::FeedWordPressAdminPage('feedwordpressdiagnosticspage');
|
8 |
$this->dispatch = 'feedwordpress_diagnostics';
|
9 |
$this->filename = __FILE__;
|
10 |
-
|
11 |
$this->test_html = array();
|
12 |
add_action('feedwordpress_diagnostics_do_http_test', array($this, 'do_http_test'), 10, 1);
|
13 |
}
|
@@ -17,15 +17,15 @@ class FeedWordPressDiagnosticsPage extends FeedWordPressAdminPage {
|
|
17 |
function display () {
|
18 |
global $wpdb, $wp_db_version, $fwp_path;
|
19 |
global $fwp_post;
|
20 |
-
|
21 |
if (FeedWordPress::needs_upgrade()) :
|
22 |
fwp_upgrade_page();
|
23 |
return;
|
24 |
endif;
|
25 |
-
|
26 |
// If this is a POST, validate source and user credentials
|
27 |
FeedWordPressCompatibility::validate_http_request(/*action=*/ 'feedwordpress_diagnostics', /*capability=*/ 'manage_options');
|
28 |
-
|
29 |
if (strtoupper($_SERVER['REQUEST_METHOD'])=='POST') :
|
30 |
$this->accept_POST($fwp_post);
|
31 |
do_action('feedwordpress_admin_page_diagnostics_save', $fwp_post, $this);
|
@@ -47,7 +47,7 @@ class FeedWordPressDiagnosticsPage extends FeedWordPressAdminPage {
|
|
47 |
'updates_box' => __('Updates'),
|
48 |
'tests_box' => __('Diagnostic Tests'),
|
49 |
);
|
50 |
-
|
51 |
foreach ($boxes_by_methods as $method => $title) :
|
52 |
add_meta_box(
|
53 |
/*id=*/ 'feedwordpress_'.$method,
|
@@ -76,13 +76,13 @@ class FeedWordPressDiagnosticsPage extends FeedWordPressAdminPage {
|
|
76 |
or isset($post['feedwordpress_diagnostics_do'])) :
|
77 |
update_option('feedwordpress_debug', $post['feedwordpress_debug']);
|
78 |
update_option('feedwordpress_secret_key', $post['feedwordpress_secret_key']);
|
79 |
-
|
80 |
if (!isset($post['diagnostics_output'])
|
81 |
or !is_array($post['diagnostics_output'])) :
|
82 |
$post['diagnostics_output'] = array();
|
83 |
endif;
|
84 |
update_option('feedwordpress_diagnostics_output', $post['diagnostics_output']);
|
85 |
-
|
86 |
if (!isset($post['diagnostics_show'])
|
87 |
or !is_array($post['diagnostics_show'])) :
|
88 |
$post['diagnostics_show'] = array();
|
@@ -95,7 +95,7 @@ class FeedWordPressDiagnosticsPage extends FeedWordPressAdminPage {
|
|
95 |
else :
|
96 |
delete_option('feedwordpress_diagnostics_persistent_errors_hours');
|
97 |
endif;
|
98 |
-
|
99 |
if (in_array('email', $post['diagnostics_output'])) :
|
100 |
$ded = $post['diagnostics_email_destination'];
|
101 |
if ('mailto'==$ded) :
|
@@ -106,18 +106,18 @@ class FeedWordPressDiagnosticsPage extends FeedWordPressAdminPage {
|
|
106 |
else :
|
107 |
delete_option('feedwordpress_diagnostics_email_destination');
|
108 |
endif;
|
109 |
-
|
110 |
if (isset($post['feedwordpress_diagnostics_do'])) :
|
111 |
foreach ($post['feedwordpress_diagnostics_do'] as $do => $value) :
|
112 |
do_action('feedwordpress_diagnostics_do_'.$do, $post);
|
113 |
endforeach;
|
114 |
endif;
|
115 |
-
|
116 |
$this->updated = true; // Default update message
|
117 |
endif;
|
118 |
} /* FeedWordPressDiagnosticsPage::accept_POST () */
|
119 |
|
120 |
-
function info_box ($page, $box = NULL) {
|
121 |
global $feedwordpress;
|
122 |
global $wp_version;
|
123 |
$link_category_id = FeedWordPress::link_category_id();
|
@@ -147,7 +147,7 @@ class FeedWordPressDiagnosticsPage extends FeedWordPressAdminPage {
|
|
147 |
</ul>
|
148 |
</td>
|
149 |
</tr>
|
150 |
-
|
151 |
<tr>
|
152 |
<th scope="row">Link Category:</th>
|
153 |
<td><?php if (!is_wp_error($link_category_id)) :
|
@@ -168,13 +168,13 @@ class FeedWordPressDiagnosticsPage extends FeedWordPressAdminPage {
|
|
168 |
<?php $data = $link_category_id->get_error_data(); if (!empty($data)) : ?>
|
169 |
<tr>
|
170 |
<th scope="row">Auxiliary Data:</th>
|
171 |
-
<td><pre><?php print esc_html(
|
172 |
</tr>
|
173 |
<?php endif; ?>
|
174 |
</table>
|
175 |
<?php endif; ?></td>
|
176 |
</tr>
|
177 |
-
|
178 |
<tr>
|
179 |
<th scope="row"><?php _e('Secret Key:'); ?></th>
|
180 |
<td><input type="text" name="feedwordpress_secret_key" value="<?php print esc_attr($feedwordpress->secret_key()); ?>" />
|
@@ -186,13 +186,13 @@ class FeedWordPressDiagnosticsPage extends FeedWordPressAdminPage {
|
|
186 |
|
187 |
<?php
|
188 |
} /* FeedWordPressDiagnosticsPage::info_box () */
|
189 |
-
|
190 |
-
function diagnostics_box ($page, $box = NULL) {
|
191 |
$settings = array();
|
192 |
$settings['debug'] = (get_option('feedwordpress_debug')=='yes');
|
193 |
|
194 |
$diagnostics_output = get_option('feedwordpress_diagnostics_output', array());
|
195 |
-
|
196 |
$users = fwp_author_list();
|
197 |
|
198 |
$ded = get_option('feedwordpress_diagnostics_email_destination', 'admins');
|
@@ -202,7 +202,7 @@ class FeedWordPressDiagnosticsPage extends FeedWordPressAdminPage {
|
|
202 |
else :
|
203 |
$ded_addy = NULL;
|
204 |
endif;
|
205 |
-
|
206 |
// Hey ho, let's go...
|
207 |
?>
|
208 |
<table class="edit-form">
|
@@ -255,16 +255,16 @@ testing but absolutely inappropriate for a production server.</p>
|
|
255 |
'mailto',
|
256 |
'inline'
|
257 |
);
|
258 |
-
} );
|
259 |
</script>
|
260 |
<?php
|
261 |
} /* FeedWordPressDiagnosticsPage::diagnostics_box () */
|
262 |
-
|
263 |
-
|
264 |
$hours = get_option('feedwordpress_diagnostics_persistent_errors_hours', 2);
|
265 |
$fields = apply_filters('feedwordpress_diagnostics', array(
|
266 |
'Update Diagnostics' => array(
|
267 |
-
'update_schedule:check' => 'whenever a FeedWordPress checks in on the update schedule',
|
268 |
'updated_feeds' => 'as each feed is checked for updates',
|
269 |
'updated_feeds:errors:persistent' => 'when attempts to update a feed have resulted in errors</label> <label>for at least <input type="number" min="1" max="360" step="1" name="diagnostics_persistent_error_hours" value="'.$hours.'" /> hours',
|
270 |
'updated_feeds:errors' => 'any time FeedWordPress encounters any errors while checking a feed for updates',
|
@@ -276,15 +276,17 @@ testing but absolutely inappropriate for a production server.</p>
|
|
276 |
'Syndicated Post Details' => array(
|
277 |
'feed_items:freshness' => 'as FeedWordPress decides whether to treat an item as a new post, an update, or a duplicate of an existing post',
|
278 |
'feed_items:rejected' => 'when FeedWordPress rejects a post without syndicating it',
|
|
|
279 |
'syndicated_posts:meta_data' => 'as syndication meta-data is added on the post',
|
280 |
),
|
281 |
'Advanced Diagnostics' => array(
|
282 |
'feed_items:freshness:reasons' => 'explaining the reason that a post was treated as an update to an existing post',
|
283 |
-
'feed_items:freshness:sql' => 'when FeedWordPress issues the SQL query it uses to decide whether to treat items as new, updates, or duplicates',
|
|
|
284 |
'syndicated_posts:static_meta_data' => 'providing meta-data about syndicated posts in the Edit Posts interface',
|
285 |
),
|
286 |
), $page);
|
287 |
-
|
288 |
foreach ($fields as $section => $items) :
|
289 |
foreach ($items as $key => $label) :
|
290 |
$checked[$key] = '';
|
@@ -317,8 +319,8 @@ testing but absolutely inappropriate for a production server.</p>
|
|
317 |
</table>
|
318 |
<?php
|
319 |
} /* FeedWordPressDiagnosticsPage::updates_box () */
|
320 |
-
|
321 |
-
function tests_box ($page, $box = NULL) {
|
322 |
?>
|
323 |
<script type="text/javascript">
|
324 |
function clone_http_test_args_keyvalue_prototype () {
|
@@ -327,7 +329,7 @@ function clone_http_test_args_keyvalue_prototype () {
|
|
327 |
newRow.find('.http_test_args_key').attr('name', 'http_test_args_key['+next+']').val('');
|
328 |
newRow.find('.http_test_args_value').attr('name', 'http_test_args_value['+next+']').val('');
|
329 |
|
330 |
-
newRow.appendTo('#http-test-args');
|
331 |
return false;
|
332 |
}
|
333 |
</script>
|
@@ -354,7 +356,7 @@ function clone_http_test_args_keyvalue_prototype () {
|
|
354 |
<td><a href="#http-test-args" onclick="return clone_http_test_args_keyvalue_prototype();">+ Add</a></td>
|
355 |
</tr>
|
356 |
</table>
|
357 |
-
|
358 |
<?php if (isset($page->test_html['http_test'])) : ?>
|
359 |
<div style="position: relative">
|
360 |
<div style="width: 100%; overflow: scroll; background-color: #eed">
|
@@ -370,10 +372,10 @@ function clone_http_test_args_keyvalue_prototype () {
|
|
370 |
} /* FeedWordPressDiagnosticsPage::tests_box () */
|
371 |
|
372 |
var $test_html;
|
373 |
-
function do_http_test ($post) {
|
374 |
if (isset($post['http_test_url']) and isset($post['http_test_method'])) :
|
375 |
$url = $post['http_test_url'];
|
376 |
-
|
377 |
$args = array();
|
378 |
if (isset($post['http_test_args_key'])) :
|
379 |
foreach ($post['http_test_args_key'] as $idx => $name) :
|
@@ -384,21 +386,21 @@ function clone_http_test_args_keyvalue_prototype () {
|
|
384 |
and isset($post['http_test_args_value'][$idx])) :
|
385 |
$value = $post['http_test_args_value'][$idx];
|
386 |
endif;
|
387 |
-
|
388 |
if (preg_match('/^javascript:(.*)$/i', $value, $refs)) :
|
389 |
-
if (function_exists('json_decode')) :
|
390 |
$json_value = json_decode($refs[1]);
|
391 |
if (!is_null($json_value)) :
|
392 |
$value = $json_value;
|
393 |
endif;
|
394 |
endif;
|
395 |
endif;
|
396 |
-
|
397 |
$args[$name] = $value;
|
398 |
endif;
|
399 |
endforeach;
|
400 |
endif;
|
401 |
-
|
402 |
switch ($post['http_test_method']) :
|
403 |
case 'wp_remote_request' :
|
404 |
$out = wp_remote_request($url, $args);
|
@@ -408,10 +410,10 @@ function clone_http_test_args_keyvalue_prototype () {
|
|
408 |
break;
|
409 |
endswitch;
|
410 |
|
411 |
-
$this->test_html['http_test'] = esc_html(
|
412 |
endif;
|
413 |
} /* FeedWordPressDiagnosticsPage::do_http_test () */
|
414 |
-
|
415 |
} /* class FeedWordPressDiagnosticsPage */
|
416 |
|
417 |
$diagnosticsPage = new FeedWordPressDiagnosticsPage;
|
7 |
FeedWordPressAdminPage::FeedWordPressAdminPage('feedwordpressdiagnosticspage');
|
8 |
$this->dispatch = 'feedwordpress_diagnostics';
|
9 |
$this->filename = __FILE__;
|
10 |
+
|
11 |
$this->test_html = array();
|
12 |
add_action('feedwordpress_diagnostics_do_http_test', array($this, 'do_http_test'), 10, 1);
|
13 |
}
|
17 |
function display () {
|
18 |
global $wpdb, $wp_db_version, $fwp_path;
|
19 |
global $fwp_post;
|
20 |
+
|
21 |
if (FeedWordPress::needs_upgrade()) :
|
22 |
fwp_upgrade_page();
|
23 |
return;
|
24 |
endif;
|
25 |
+
|
26 |
// If this is a POST, validate source and user credentials
|
27 |
FeedWordPressCompatibility::validate_http_request(/*action=*/ 'feedwordpress_diagnostics', /*capability=*/ 'manage_options');
|
28 |
+
|
29 |
if (strtoupper($_SERVER['REQUEST_METHOD'])=='POST') :
|
30 |
$this->accept_POST($fwp_post);
|
31 |
do_action('feedwordpress_admin_page_diagnostics_save', $fwp_post, $this);
|
47 |
'updates_box' => __('Updates'),
|
48 |
'tests_box' => __('Diagnostic Tests'),
|
49 |
);
|
50 |
+
|
51 |
foreach ($boxes_by_methods as $method => $title) :
|
52 |
add_meta_box(
|
53 |
/*id=*/ 'feedwordpress_'.$method,
|
76 |
or isset($post['feedwordpress_diagnostics_do'])) :
|
77 |
update_option('feedwordpress_debug', $post['feedwordpress_debug']);
|
78 |
update_option('feedwordpress_secret_key', $post['feedwordpress_secret_key']);
|
79 |
+
|
80 |
if (!isset($post['diagnostics_output'])
|
81 |
or !is_array($post['diagnostics_output'])) :
|
82 |
$post['diagnostics_output'] = array();
|
83 |
endif;
|
84 |
update_option('feedwordpress_diagnostics_output', $post['diagnostics_output']);
|
85 |
+
|
86 |
if (!isset($post['diagnostics_show'])
|
87 |
or !is_array($post['diagnostics_show'])) :
|
88 |
$post['diagnostics_show'] = array();
|
95 |
else :
|
96 |
delete_option('feedwordpress_diagnostics_persistent_errors_hours');
|
97 |
endif;
|
98 |
+
|
99 |
if (in_array('email', $post['diagnostics_output'])) :
|
100 |
$ded = $post['diagnostics_email_destination'];
|
101 |
if ('mailto'==$ded) :
|
106 |
else :
|
107 |
delete_option('feedwordpress_diagnostics_email_destination');
|
108 |
endif;
|
109 |
+
|
110 |
if (isset($post['feedwordpress_diagnostics_do'])) :
|
111 |
foreach ($post['feedwordpress_diagnostics_do'] as $do => $value) :
|
112 |
do_action('feedwordpress_diagnostics_do_'.$do, $post);
|
113 |
endforeach;
|
114 |
endif;
|
115 |
+
|
116 |
$this->updated = true; // Default update message
|
117 |
endif;
|
118 |
} /* FeedWordPressDiagnosticsPage::accept_POST () */
|
119 |
|
120 |
+
static function info_box ($page, $box = NULL) {
|
121 |
global $feedwordpress;
|
122 |
global $wp_version;
|
123 |
$link_category_id = FeedWordPress::link_category_id();
|
147 |
</ul>
|
148 |
</td>
|
149 |
</tr>
|
150 |
+
|
151 |
<tr>
|
152 |
<th scope="row">Link Category:</th>
|
153 |
<td><?php if (!is_wp_error($link_category_id)) :
|
168 |
<?php $data = $link_category_id->get_error_data(); if (!empty($data)) : ?>
|
169 |
<tr>
|
170 |
<th scope="row">Auxiliary Data:</th>
|
171 |
+
<td><pre><?php print esc_html(MyPHP::val($link_category_id->get_error_data())); ?></pre></td>
|
172 |
</tr>
|
173 |
<?php endif; ?>
|
174 |
</table>
|
175 |
<?php endif; ?></td>
|
176 |
</tr>
|
177 |
+
|
178 |
<tr>
|
179 |
<th scope="row"><?php _e('Secret Key:'); ?></th>
|
180 |
<td><input type="text" name="feedwordpress_secret_key" value="<?php print esc_attr($feedwordpress->secret_key()); ?>" />
|
186 |
|
187 |
<?php
|
188 |
} /* FeedWordPressDiagnosticsPage::info_box () */
|
189 |
+
|
190 |
+
static function diagnostics_box ($page, $box = NULL) {
|
191 |
$settings = array();
|
192 |
$settings['debug'] = (get_option('feedwordpress_debug')=='yes');
|
193 |
|
194 |
$diagnostics_output = get_option('feedwordpress_diagnostics_output', array());
|
195 |
+
|
196 |
$users = fwp_author_list();
|
197 |
|
198 |
$ded = get_option('feedwordpress_diagnostics_email_destination', 'admins');
|
202 |
else :
|
203 |
$ded_addy = NULL;
|
204 |
endif;
|
205 |
+
|
206 |
// Hey ho, let's go...
|
207 |
?>
|
208 |
<table class="edit-form">
|
255 |
'mailto',
|
256 |
'inline'
|
257 |
);
|
258 |
+
} );
|
259 |
</script>
|
260 |
<?php
|
261 |
} /* FeedWordPressDiagnosticsPage::diagnostics_box () */
|
262 |
+
|
263 |
+
static function updates_box ($page, $box = NULL) {
|
264 |
$hours = get_option('feedwordpress_diagnostics_persistent_errors_hours', 2);
|
265 |
$fields = apply_filters('feedwordpress_diagnostics', array(
|
266 |
'Update Diagnostics' => array(
|
267 |
+
'update_schedule:check' => 'whenever a FeedWordPress checks in on the update schedule',
|
268 |
'updated_feeds' => 'as each feed is checked for updates',
|
269 |
'updated_feeds:errors:persistent' => 'when attempts to update a feed have resulted in errors</label> <label>for at least <input type="number" min="1" max="360" step="1" name="diagnostics_persistent_error_hours" value="'.$hours.'" /> hours',
|
270 |
'updated_feeds:errors' => 'any time FeedWordPress encounters any errors while checking a feed for updates',
|
276 |
'Syndicated Post Details' => array(
|
277 |
'feed_items:freshness' => 'as FeedWordPress decides whether to treat an item as a new post, an update, or a duplicate of an existing post',
|
278 |
'feed_items:rejected' => 'when FeedWordPress rejects a post without syndicating it',
|
279 |
+
'syndicated_posts:categories' => 'as categories, tags, and other terms are added on the post',
|
280 |
'syndicated_posts:meta_data' => 'as syndication meta-data is added on the post',
|
281 |
),
|
282 |
'Advanced Diagnostics' => array(
|
283 |
'feed_items:freshness:reasons' => 'explaining the reason that a post was treated as an update to an existing post',
|
284 |
+
'feed_items:freshness:sql' => 'when FeedWordPress issues the SQL query it uses to decide whether to treat items as new, updates, or duplicates',
|
285 |
+
'syndicated_posts:categories:test' => 'as FeedWordPress checks for the familiarity of feed categories and tags',
|
286 |
'syndicated_posts:static_meta_data' => 'providing meta-data about syndicated posts in the Edit Posts interface',
|
287 |
),
|
288 |
), $page);
|
289 |
+
|
290 |
foreach ($fields as $section => $items) :
|
291 |
foreach ($items as $key => $label) :
|
292 |
$checked[$key] = '';
|
319 |
</table>
|
320 |
<?php
|
321 |
} /* FeedWordPressDiagnosticsPage::updates_box () */
|
322 |
+
|
323 |
+
static function tests_box ($page, $box = NULL) {
|
324 |
?>
|
325 |
<script type="text/javascript">
|
326 |
function clone_http_test_args_keyvalue_prototype () {
|
329 |
newRow.find('.http_test_args_key').attr('name', 'http_test_args_key['+next+']').val('');
|
330 |
newRow.find('.http_test_args_value').attr('name', 'http_test_args_value['+next+']').val('');
|
331 |
|
332 |
+
newRow.appendTo('#http-test-args');
|
333 |
return false;
|
334 |
}
|
335 |
</script>
|
356 |
<td><a href="#http-test-args" onclick="return clone_http_test_args_keyvalue_prototype();">+ Add</a></td>
|
357 |
</tr>
|
358 |
</table>
|
359 |
+
|
360 |
<?php if (isset($page->test_html['http_test'])) : ?>
|
361 |
<div style="position: relative">
|
362 |
<div style="width: 100%; overflow: scroll; background-color: #eed">
|
372 |
} /* FeedWordPressDiagnosticsPage::tests_box () */
|
373 |
|
374 |
var $test_html;
|
375 |
+
static function do_http_test ($post) {
|
376 |
if (isset($post['http_test_url']) and isset($post['http_test_method'])) :
|
377 |
$url = $post['http_test_url'];
|
378 |
+
|
379 |
$args = array();
|
380 |
if (isset($post['http_test_args_key'])) :
|
381 |
foreach ($post['http_test_args_key'] as $idx => $name) :
|
386 |
and isset($post['http_test_args_value'][$idx])) :
|
387 |
$value = $post['http_test_args_value'][$idx];
|
388 |
endif;
|
389 |
+
|
390 |
if (preg_match('/^javascript:(.*)$/i', $value, $refs)) :
|
391 |
+
if (function_exists('json_decode')) :
|
392 |
$json_value = json_decode($refs[1]);
|
393 |
if (!is_null($json_value)) :
|
394 |
$value = $json_value;
|
395 |
endif;
|
396 |
endif;
|
397 |
endif;
|
398 |
+
|
399 |
$args[$name] = $value;
|
400 |
endif;
|
401 |
endforeach;
|
402 |
endif;
|
403 |
+
|
404 |
switch ($post['http_test_method']) :
|
405 |
case 'wp_remote_request' :
|
406 |
$out = wp_remote_request($url, $args);
|
410 |
break;
|
411 |
endswitch;
|
412 |
|
413 |
+
$this->test_html['http_test'] = esc_html(MyPHP::val($out));
|
414 |
endif;
|
415 |
} /* FeedWordPressDiagnosticsPage::do_http_test () */
|
416 |
+
|
417 |
} /* class FeedWordPressDiagnosticsPage */
|
418 |
|
419 |
$diagnosticsPage = new FeedWordPressDiagnosticsPage;
|
@@ -1,7 +1,23 @@
|
|
1 |
<?php
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
if (!class_exists('MyPHP')) :
|
3 |
class MyPHP {
|
4 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5 |
static public function param ($key, $default = NULL, $type = 'REQUEST') {
|
6 |
// PHP 5.4 introduces "just-in-time" initialization of
|
7 |
// $GLOBALS. Which seems to me largely to defeat the
|
@@ -26,14 +42,40 @@ if (!class_exists('MyPHP')) :
|
|
26 |
return $ret;
|
27 |
} /* MyPHP::param () */
|
28 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
29 |
static function post ($key, $default = NULL) {
|
30 |
return self::param($key, $default, 'POST');
|
31 |
} /*MyPHP::post () */
|
32 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
33 |
static function get ($key, $default = NULL) {
|
34 |
return self::param($key, $default, "GET");
|
35 |
} /* MyPHP::get () */
|
36 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
37 |
static function request ($key, $default = NULL) {
|
38 |
return self::param($key, $default, "REQUEST");
|
39 |
} /* MyPHP::request () */
|
@@ -82,7 +124,26 @@ if (!class_exists('MyPHP')) :
|
|
82 |
endforeach;
|
83 |
return implode("&", $getQuery);
|
84 |
} /* MyPHP::to_http_post () */
|
85 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
86 |
endif;
|
87 |
-
|
88 |
-
|
1 |
<?php
|
2 |
+
/**
|
3 |
+
* MyPHP: handy general utility functions, for things that PHP should do, but
|
4 |
+
* doesn't do (yet).
|
5 |
+
*
|
6 |
+
* @package MyPHP
|
7 |
+
* @version 2014.0805
|
8 |
+
*/
|
9 |
if (!class_exists('MyPHP')) :
|
10 |
class MyPHP {
|
11 |
+
/**
|
12 |
+
* MyPHP::param: For dealing with HTTP GET/POST parameters sent
|
13 |
+
* to us as input.
|
14 |
+
*
|
15 |
+
* @param string $key The name of the GET/POST parameter
|
16 |
+
* @param mixed $default Default to return if parameter is unset
|
17 |
+
* @param string $type 'GET', 'POST' or 'REQUEST' (=both GET and POST)
|
18 |
+
* @return mixed The value of the named parameter, or the fallback
|
19 |
+
* in $default if there is no value set for that param name.
|
20 |
+
*/
|
21 |
static public function param ($key, $default = NULL, $type = 'REQUEST') {
|
22 |
// PHP 5.4 introduces "just-in-time" initialization of
|
23 |
// $GLOBALS. Which seems to me largely to defeat the
|
42 |
return $ret;
|
43 |
} /* MyPHP::param () */
|
44 |
|
45 |
+
/**
|
46 |
+
* MyPHP::post: For dealing with HTTP POST parameters sent as input
|
47 |
+
*
|
48 |
+
* @param string $key The name of the POST parameter
|
49 |
+
* @param mixed $default Default to return if parameter is unset
|
50 |
+
* @return mixed The value of the named parameter, or the fallback
|
51 |
+
* in $default if there is no value set for that param name.
|
52 |
+
*/
|
53 |
static function post ($key, $default = NULL) {
|
54 |
return self::param($key, $default, 'POST');
|
55 |
} /*MyPHP::post () */
|
56 |
|
57 |
+
/**
|
58 |
+
* MyPHP::post: For dealing with HTTP GET parameters sent as input
|
59 |
+
*
|
60 |
+
* @param string $key The name of the GET parameter
|
61 |
+
* @param mixed $default Default to return if parameter is unset
|
62 |
+
* @return mixed The value of the named parameter, or the fallback
|
63 |
+
* in $default if there is no value set for that param name.
|
64 |
+
*/
|
65 |
static function get ($key, $default = NULL) {
|
66 |
return self::param($key, $default, "GET");
|
67 |
} /* MyPHP::get () */
|
68 |
|
69 |
+
/**
|
70 |
+
* MyPHP::request: For dealing with HTTP GET/POST parameters
|
71 |
+
* sent as input. This method checks both GET parameters and POST
|
72 |
+
* parameters and will return values from either.
|
73 |
+
*
|
74 |
+
* @param string $key The name of the GET/POST parameter
|
75 |
+
* @param mixed $default Default to return if parameter is unset
|
76 |
+
* @return mixed The value of the named parameter, or the fallback
|
77 |
+
* in $default if there is no value set for that param name.
|
78 |
+
*/
|
79 |
static function request ($key, $default = NULL) {
|
80 |
return self::param($key, $default, "REQUEST");
|
81 |
} /* MyPHP::request () */
|
124 |
endforeach;
|
125 |
return implode("&", $getQuery);
|
126 |
} /* MyPHP::to_http_post () */
|
127 |
+
|
128 |
+
/**
|
129 |
+
* MyPHP::val(): Captures the output of var_dump() to a string,
|
130 |
+
* with some optional filtering removing newlines and replacing
|
131 |
+
* them with spaces) applied.
|
132 |
+
*
|
133 |
+
* @param mixed $v Value to dump to a string representation
|
134 |
+
* @param bool $no_newlines Whether to filter out newline chars
|
135 |
+
*
|
136 |
+
* @return string
|
137 |
+
*/
|
138 |
+
static function val ($v, $no_newlines = false) {
|
139 |
+
ob_start();
|
140 |
+
var_dump($v);
|
141 |
+
$out = ob_get_contents(); ob_end_clean();
|
142 |
+
|
143 |
+
if ($no_newlines) :
|
144 |
+
$out = preg_replace('/\s+/', " ", $out);
|
145 |
+
endif;
|
146 |
+
return $out;
|
147 |
+
} /* MyPHP::val () */
|
148 |
+
} /* class MyPHP */
|
149 |
endif;
|
|
|
|
@@ -901,7 +901,7 @@ class FeedWordPressFeedsPage extends FeedWordPressAdminPage {
|
|
901 |
$feed_version = '';
|
902 |
endif;
|
903 |
?>
|
904 |
-
<form<?php print $form_class; ?> action="<?php $this->form_action('syndication.php'); ?>" method="post">
|
905 |
<div class="inside"><?php FeedWordPressCompatibility::stamp_nonce('feedwordpress_switchfeed'); ?>
|
906 |
|
907 |
<?php
|
@@ -1034,7 +1034,7 @@ class FeedWordPressFeedsPage extends FeedWordPressAdminPage {
|
|
1034 |
|
1035 |
print "<h4>".__("HTTP Transport").":</h4>\n";
|
1036 |
print "<ol>\n";
|
1037 |
-
print "<li>".
|
1038 |
print "</ol>\n";
|
1039 |
endif;
|
1040 |
|
@@ -1069,9 +1069,9 @@ class FeedWordPressFeedsPage extends FeedWordPressAdminPage {
|
|
1069 |
$alt = $params['alt'];
|
1070 |
|
1071 |
?>
|
1072 |
-
<form action="<?php $this->form_action(); ?>" method="post">
|
1073 |
<div class="inside"><?php
|
1074 |
-
FeedWordPressCompatibility::stamp_nonce(
|
1075 |
?>
|
1076 |
<fieldset class="alt"
|
1077 |
<?php if (!$alt): ?>style="margin: 1.0em 3.0em; font-size: smaller;"<?php endif; ?>>
|
901 |
$feed_version = '';
|
902 |
endif;
|
903 |
?>
|
904 |
+
<form<?php print $form_class; ?> action="<?php print $this->form_action('syndication.php'); ?>" method="post">
|
905 |
<div class="inside"><?php FeedWordPressCompatibility::stamp_nonce('feedwordpress_switchfeed'); ?>
|
906 |
|
907 |
<?php
|
1034 |
|
1035 |
print "<h4>".__("HTTP Transport").":</h4>\n";
|
1036 |
print "<ol>\n";
|
1037 |
+
print "<li>".MyPHP::val($transport)."</li>\n";
|
1038 |
print "</ol>\n";
|
1039 |
endif;
|
1040 |
|
1069 |
$alt = $params['alt'];
|
1070 |
|
1071 |
?>
|
1072 |
+
<form action="<?php print $this->form_action('syndication.php'); ?>" method="post">
|
1073 |
<div class="inside"><?php
|
1074 |
+
FeedWordPressCompatibility::stamp_nonce('feedwordpress_feeds');
|
1075 |
?>
|
1076 |
<fieldset class="alt"
|
1077 |
<?php if (!$alt): ?>style="margin: 1.0em 3.0em; font-size: smaller;"<?php endif; ?>>
|
@@ -10,7 +10,7 @@ class FeedWordPie extends SimplePie {
|
|
10 |
|
11 |
// Get URL with relevant parameters attached.
|
12 |
// Credentials will be handled further down.
|
13 |
-
$new_url = $url->uri(array('add_params' => true));
|
14 |
|
15 |
// Store for reference.
|
16 |
$this->subscription = $url->id();
|
@@ -43,10 +43,12 @@ class FeedWordPie extends SimplePie {
|
|
43 |
}
|
44 |
|
45 |
function get_feed_tags ($namespace, $tag) {
|
|
|
|
|
46 |
// Allow filters to filter SimplePie handling
|
47 |
return apply_filters(
|
48 |
'feedwordpie_get_feed_tags',
|
49 |
-
|
50 |
$namespace,
|
51 |
$tag,
|
52 |
$this
|
10 |
|
11 |
// Get URL with relevant parameters attached.
|
12 |
// Credentials will be handled further down.
|
13 |
+
$new_url = $url->uri(array('add_params' => true, 'fetch' => true));
|
14 |
|
15 |
// Store for reference.
|
16 |
$this->subscription = $url->id();
|
43 |
}
|
44 |
|
45 |
function get_feed_tags ($namespace, $tag) {
|
46 |
+
$tags = parent::get_feed_tags($namespace, $tag);
|
47 |
+
|
48 |
// Allow filters to filter SimplePie handling
|
49 |
return apply_filters(
|
50 |
'feedwordpie_get_feed_tags',
|
51 |
+
$tags,
|
52 |
$namespace,
|
53 |
$tag,
|
54 |
$this
|
@@ -330,7 +330,7 @@ table.twofer td.secondary { padding-left: 10px; width: 30%; }
|
|
330 |
}
|
331 |
#feedwordpress-admin-syndication .update-form.with-donation {
|
332 |
margin-right: 50%;
|
333 |
-
min-height:
|
334 |
}
|
335 |
#feedwordpress-admin-syndication .donation-form,
|
336 |
#feedwordpress-admin-syndication .donation-thanks {
|
@@ -468,4 +468,6 @@ table.twofer td.secondary { padding-left: 10px; width: 30%; }
|
|
468 |
padding: 10px;
|
469 |
}
|
470 |
|
471 |
-
|
|
|
|
330 |
}
|
331 |
#feedwordpress-admin-syndication .update-form.with-donation {
|
332 |
margin-right: 50%;
|
333 |
+
min-height: 355px;
|
334 |
}
|
335 |
#feedwordpress-admin-syndication .donation-form,
|
336 |
#feedwordpress-admin-syndication .donation-thanks {
|
468 |
padding: 10px;
|
469 |
}
|
470 |
|
471 |
+
.hovered-component .hover-on { display: none; }
|
472 |
+
.hovered-component:hover .hover-on { display: inline; }
|
473 |
+
.hovered-component:hover .hover-on.pop-over { display: block; position: absolute; }
|
@@ -15,12 +15,12 @@ class FeedWordPress_Walker_Category_Checklist extends Walker_Category_Checklist
|
|
15 |
var $checkbox_name = NULL;
|
16 |
function FeedWordPress_Walker_Category_Checklist ($params = array()) {
|
17 |
$this->set_taxonomy('category');
|
18 |
-
|
19 |
if (isset($params['checkbox_name'])) :
|
20 |
$this->checkbox_name = $params['checkbox_name'];
|
21 |
endif;
|
22 |
}
|
23 |
-
|
24 |
function set_prefix ($prefix) {
|
25 |
$this->prefix = $prefix;
|
26 |
}
|
@@ -28,11 +28,11 @@ class FeedWordPress_Walker_Category_Checklist extends Walker_Category_Checklist
|
|
28 |
$this->taxonomy = $taxonomy;
|
29 |
}
|
30 |
|
31 |
-
function start_el
|
32 |
extract($args);
|
33 |
if ( empty($taxonomy) ) :
|
34 |
$taxonomy = 'category';
|
35 |
-
endif;
|
36 |
|
37 |
if (!is_null($this->checkbox_name)) :
|
38 |
$name = $this->checkbox_name;
|
@@ -41,7 +41,7 @@ class FeedWordPress_Walker_Category_Checklist extends Walker_Category_Checklist
|
|
41 |
else :
|
42 |
$name = 'tax_input['.$taxonomy.']';
|
43 |
endif;
|
44 |
-
|
45 |
$unit = array();
|
46 |
if (strlen($this->prefix) > 0) :
|
47 |
$unit[] = $this->prefix;
|
15 |
var $checkbox_name = NULL;
|
16 |
function FeedWordPress_Walker_Category_Checklist ($params = array()) {
|
17 |
$this->set_taxonomy('category');
|
18 |
+
|
19 |
if (isset($params['checkbox_name'])) :
|
20 |
$this->checkbox_name = $params['checkbox_name'];
|
21 |
endif;
|
22 |
}
|
23 |
+
|
24 |
function set_prefix ($prefix) {
|
25 |
$this->prefix = $prefix;
|
26 |
}
|
28 |
$this->taxonomy = $taxonomy;
|
29 |
}
|
30 |
|
31 |
+
function start_el( &$output, $category, $depth = 0, $args = array(), $current_object_id = 0 ) {
|
32 |
extract($args);
|
33 |
if ( empty($taxonomy) ) :
|
34 |
$taxonomy = 'category';
|
35 |
+
endif;
|
36 |
|
37 |
if (!is_null($this->checkbox_name)) :
|
38 |
$name = $this->checkbox_name;
|
41 |
else :
|
42 |
$name = 'tax_input['.$taxonomy.']';
|
43 |
endif;
|
44 |
+
|
45 |
$unit = array();
|
46 |
if (strlen($this->prefix) > 0) :
|
47 |
$unit[] = $this->prefix;
|
@@ -3,7 +3,7 @@
|
|
3 |
Plugin Name: FeedWordPress
|
4 |
Plugin URI: http://feedwordpress.radgeek.com/
|
5 |
Description: simple and flexible Atom/RSS syndication for WordPress
|
6 |
-
Version:
|
7 |
Author: Charles Johnson
|
8 |
Author URI: http://radgeek.com/
|
9 |
License: GPL
|
@@ -11,7 +11,7 @@ License: GPL
|
|
11 |
|
12 |
/**
|
13 |
* @package FeedWordPress
|
14 |
-
* @version
|
15 |
*/
|
16 |
|
17 |
# This uses code derived from:
|
@@ -27,17 +27,18 @@ License: GPL
|
|
27 |
# USAGE: once FeedWordPress is installed, you manage just about everything from
|
28 |
# the WordPress Dashboard, under the Syndication menu. To keep fresh content
|
29 |
# coming in as it becomes available, you'll have to either check for updates
|
30 |
-
# manually, or set up one of the automatically-scheduled update methods. See
|
31 |
# <http://feedwordpress.radgeek.com/wiki/quick-start/> for some details.
|
32 |
|
33 |
# -- Don't change these unless you know what you're doing...
|
34 |
|
35 |
-
define ('FEEDWORDPRESS_VERSION', '
|
36 |
define ('FEEDWORDPRESS_AUTHOR_CONTACT', 'http://radgeek.com/contact');
|
37 |
|
38 |
if (!defined('FEEDWORDPRESS_BLEG')) :
|
39 |
define ('FEEDWORDPRESS_BLEG', true);
|
40 |
endif;
|
|
|
41 |
|
42 |
// Defaults
|
43 |
define ('DEFAULT_SYNDICATION_CATEGORY', 'Contributors');
|
@@ -70,9 +71,9 @@ if (FEEDWORDPRESS_DEBUG) :
|
|
70 |
// Help us to pick out errors, if any.
|
71 |
ini_set('error_reporting', E_ALL & ~E_NOTICE);
|
72 |
ini_set('display_errors', true);
|
73 |
-
|
74 |
// When testing we don't want cache issues to interfere. But this is
|
75 |
-
// a VERY BAD SETTING for a production server. Webmasters will eat your
|
76 |
// face for breakfast if you use it, and the baby Jesus will cry. So
|
77 |
// make sure FEEDWORDPRESS_DEBUG is FALSE for any site that will be
|
78 |
// used for more than testing purposes!
|
@@ -101,11 +102,11 @@ if (!function_exists('wp_insert_user')) :
|
|
101 |
require_once (ABSPATH . WPINC . '/registration.php'); // for wp_insert_user
|
102 |
endif;
|
103 |
|
104 |
-
$dir = dirname(__FILE__);
|
105 |
require_once("${dir}/externals/myphp/myphp.class.php");
|
106 |
require_once("${dir}/admin-ui.php");
|
107 |
require_once("${dir}/feedwordpresssyndicationpage.class.php");
|
108 |
-
require_once("${dir}/compatability.php"); // Legacy API
|
109 |
require_once("${dir}/syndicatedpost.class.php");
|
110 |
require_once("${dir}/syndicatedlink.class.php");
|
111 |
require_once("${dir}/feedwordpresshtml.class.php");
|
@@ -141,7 +142,8 @@ else : // Something went wrong. Let's just guess.
|
|
141 |
$fwp_path = 'feedwordpress';
|
142 |
endif;
|
143 |
|
144 |
-
|
|
|
145 |
|
146 |
# Syndicated items are generally received in output-ready (X)HTML and
|
147 |
# should not be folded, crumpled, mutilated, or spindled by WordPress
|
@@ -158,18 +160,18 @@ if (!FeedWordPress::needs_upgrade()) : // only work if the conditions are safe!
|
|
158 |
|
159 |
add_filter('the_content', 'feedwordpress_preserve_syndicated_content', -10000);
|
160 |
add_filter('the_content', 'feedwordpress_restore_syndicated_content', 10000);
|
161 |
-
|
162 |
add_action('atom_entry', 'feedwordpress_item_feed_data');
|
163 |
-
|
164 |
# Filter in original permalinks if the user wants that
|
165 |
add_filter('post_link', 'syndication_permalink', /*priority=*/ 1, /*arguments=*/ 3);
|
166 |
add_filter('post_type_link', 'syndication_permalink', /*priority=*/ 1, /*arguments=*/ 4);
|
167 |
-
|
168 |
# When foreign URLs are used for permalinks in feeds or display
|
169 |
# contexts, they need to be escaped properly.
|
170 |
add_filter('the_permalink', 'syndication_permalink_escaped');
|
171 |
add_filter('the_permalink_rss', 'syndication_permalink_escaped');
|
172 |
-
|
173 |
add_filter('post_comments_feed_link', 'syndication_comments_feed_link');
|
174 |
|
175 |
# WTF? By default, wp_insert_link runs incoming link_url and link_rss
|
@@ -178,17 +180,17 @@ if (!FeedWordPress::needs_upgrade()) : // only work if the conditions are safe!
|
|
178 |
# happens to fuck up any URI with a & to separate GET parameters.
|
179 |
remove_filter('pre_link_rss', 'wp_filter_kses');
|
180 |
remove_filter('pre_link_url', 'wp_filter_kses');
|
181 |
-
|
182 |
# Admin menu
|
183 |
-
add_action('admin_init', array(
|
184 |
add_action('admin_menu', 'fwp_add_pages');
|
185 |
add_action('admin_notices', 'fwp_check_debug');
|
186 |
|
187 |
add_action('admin_menu', 'feedwordpress_add_post_edit_controls');
|
188 |
add_action('save_post', 'feedwordpress_save_post_edit_controls');
|
189 |
|
190 |
-
add_action('admin_footer', array(
|
191 |
-
|
192 |
# Inbound XML-RPC update methods
|
193 |
$feedwordpressRPC = new FeedWordPressRPC;
|
194 |
|
@@ -206,24 +208,25 @@ if (!FeedWordPress::needs_upgrade()) : // only work if the conditions are safe!
|
|
206 |
|
207 |
add_action('wp_footer', 'debug_out_feedwordpress_footer', -100);
|
208 |
add_action('admin_footer', 'debug_out_feedwordpress_footer', -100);
|
209 |
-
|
210 |
-
$feedwordpress = new FeedWordPress;
|
211 |
|
212 |
# Cron-less auto-update. Hooray!
|
213 |
$autoUpdateHook = $feedwordpress->automatic_update_hook();
|
214 |
if (!is_null($autoUpdateHook)) :
|
215 |
add_action($autoUpdateHook, array($feedwordpress, 'auto_update'));
|
216 |
endif;
|
217 |
-
|
218 |
add_action('init', array($feedwordpress, 'init'));
|
219 |
add_action('shutdown', array($feedwordpress, 'email_diagnostic_log'));
|
|
|
220 |
add_action('wp_dashboard_setup', array($feedwordpress, 'dashboard_setup'));
|
221 |
|
222 |
# Default sanitizers
|
223 |
add_filter('syndicated_item_content', array('SyndicatedPost', 'resolve_relative_uris'), 0, 2);
|
224 |
add_filter('syndicated_item_content', array('SyndicatedPost', 'sanitize_content'), 0, 2);
|
225 |
|
226 |
-
add_action('plugins_loaded', array(
|
|
|
|
|
227 |
else :
|
228 |
# Hook in the menus, which will just point to the upgrade interface
|
229 |
add_action('admin_menu', 'fwp_add_pages');
|
@@ -238,6 +241,10 @@ class FeedWordPressDiagnostic {
|
|
238 |
$wpError = $error['object'];
|
239 |
$url = $link->uri();
|
240 |
|
|
|
|
|
|
|
|
|
241 |
$mesgs = $wpError->get_error_messages();
|
242 |
foreach ($mesgs as $mesg) :
|
243 |
$mesg = esc_html($mesg);
|
@@ -245,7 +252,7 @@ class FeedWordPressDiagnostic {
|
|
245 |
'updated_feeds:errors',
|
246 |
"Feed Error: [${url}] update returned error: $mesg"
|
247 |
);
|
248 |
-
|
249 |
$hours = get_option('feedwordpress_diagnostics_persistent_errors_hours', 2);
|
250 |
$span = ($error['ts'] - $error['since']);
|
251 |
|
@@ -311,8 +318,8 @@ function debug_out_feedwordpress_footer () {
|
|
311 |
* displaying a post.
|
312 |
*
|
313 |
* @param int $id The post to check for syndicated status. Defaults to the current post in a Loop context.
|
314 |
-
* @return bool TRUE if the post's meta-data indicates it was syndicated; FALSE otherwise
|
315 |
-
*/
|
316 |
function is_syndicated ($id = NULL) {
|
317 |
$p = new FeedWordPressLocalPost($id);
|
318 |
return $p->is_syndicated();
|
@@ -320,12 +327,12 @@ function is_syndicated ($id = NULL) {
|
|
320 |
|
321 |
function feedwordpress_display_url ($url, $before = 60, $after = 0) {
|
322 |
$bits = parse_url($url);
|
323 |
-
|
324 |
// Strip out crufty subdomains
|
325 |
if (isset($bits['host'])) :
|
326 |
$bits['host'] = preg_replace('/^www[0-9]*\./i', '', $bits['host']);
|
327 |
endif;
|
328 |
-
|
329 |
// Reassemble bit-by-bit with minimum of crufty elements
|
330 |
$url = (isset($bits['user'])?$bits['user'].'@':'')
|
331 |
.(isset($bits['host'])?$bits['host']:'')
|
@@ -334,7 +341,7 @@ function feedwordpress_display_url ($url, $before = 60, $after = 0) {
|
|
334 |
.(isset($bits['query'])?'?'.$bits['query']:'');
|
335 |
|
336 |
if (strlen($url) > ($before+$after)) :
|
337 |
-
$url = substr($url, 0, $before).'
|
338 |
endif;
|
339 |
|
340 |
return $url;
|
@@ -433,7 +440,7 @@ function the_syndication_permalink ($id = NULL) {
|
|
433 |
*/
|
434 |
function get_local_permalink ($id = NULL) {
|
435 |
global $feedwordpress_the_original_permalink;
|
436 |
-
|
437 |
// get permalink, and thus activate filter and force global to be filled
|
438 |
// with original URL.
|
439 |
$url = get_permalink($id);
|
@@ -476,7 +483,7 @@ function feedwordpress_preserve_syndicated_content ($text) {
|
|
476 |
|
477 |
function feedwordpress_restore_syndicated_content ($text) {
|
478 |
global $feedwordpress_the_syndicated_content;
|
479 |
-
|
480 |
if ( !is_null($feedwordpress_the_syndicated_content) ) :
|
481 |
$text = $feedwordpress_the_syndicated_content;
|
482 |
endif;
|
@@ -531,7 +538,7 @@ function feedwordpress_item_feed_data () {
|
|
531 |
function syndication_permalink ($permalink = '', $post = null, $leavename = false, $sample = false) {
|
532 |
global $id;
|
533 |
global $feedwordpress_the_original_permalink;
|
534 |
-
|
535 |
// Save the local permalink in case we need to retrieve it later.
|
536 |
$feedwordpress_the_original_permalink = $permalink;
|
537 |
|
@@ -581,11 +588,11 @@ function syndication_permalink_escaped ($permalink) {
|
|
581 |
$permalink = esc_html($permalink);
|
582 |
endif;
|
583 |
return $permalink;
|
584 |
-
} /* function syndication_permalink_escaped() */
|
585 |
|
586 |
/**
|
587 |
* syndication_comments_feed_link: Escape XML special characters in comments
|
588 |
-
* feed links
|
589 |
*
|
590 |
* @param string $link
|
591 |
* @return string
|
@@ -602,7 +609,7 @@ function syndication_comments_feed_link ($link) {
|
|
602 |
// that value here.
|
603 |
$source = get_syndication_feed_object();
|
604 |
$replacement = NULL;
|
605 |
-
|
606 |
if ($source->setting('munge comments feed links', 'munge_comments_feed_links', 'yes') != 'no') :
|
607 |
$commentFeeds = get_post_custom_values('wfw:commentRSS');
|
608 |
if (
|
@@ -611,14 +618,14 @@ function syndication_comments_feed_link ($link) {
|
|
611 |
and (strlen($commentFeeds[0]) > 0)
|
612 |
) :
|
613 |
$replacement = $commentFeeds[0];
|
614 |
-
|
615 |
// This is a foreign link; WordPress can't vouch for its not
|
616 |
// having any entities that need to be &-escaped. So we'll do it
|
617 |
// here.
|
618 |
$replacement = esc_html($replacement);
|
619 |
endif;
|
620 |
endif;
|
621 |
-
|
622 |
if (is_null($replacement)) :
|
623 |
// Q: How can we get the proper feed format, since the
|
624 |
// format is, stupidly, not passed to the filter?
|
@@ -642,7 +649,7 @@ function syndication_comments_feed_link ($link) {
|
|
642 |
// comments feed link is never munged by FWP.
|
643 |
endif;
|
644 |
endif;
|
645 |
-
|
646 |
if (!is_null($replacement)) : $link = $replacement; endif;
|
647 |
endif;
|
648 |
return $link;
|
@@ -654,11 +661,11 @@ function syndication_comments_feed_link ($link) {
|
|
654 |
|
655 |
function fwp_add_pages () {
|
656 |
global $feedwordpress;
|
657 |
-
|
658 |
$menu_cap = FeedWordPress::menu_cap();
|
659 |
$settings_cap = FeedWordPress::menu_cap(/*sub=*/ true);
|
660 |
$syndicationMenu = FeedWordPress::path('syndication.php');
|
661 |
-
|
662 |
add_menu_page(
|
663 |
'Syndicated Sites', 'Syndication',
|
664 |
$menu_cap,
|
@@ -708,7 +715,7 @@ function fwp_add_pages () {
|
|
708 |
$syndicationMenu, 'FeedWordPress Diagnostics', 'Diagnostics',
|
709 |
$settings_cap, FeedWordPress::path('diagnostics-page.php')
|
710 |
);
|
711 |
-
|
712 |
add_filter('page_row_actions', array($feedwordpress, 'row_actions'), 10, 2);
|
713 |
add_filter('post_row_actions', array($feedwordpress, 'row_actions'), 10, 2);
|
714 |
} /* function fwp_add_pages () */
|
@@ -779,7 +786,7 @@ function fwp_publish_post_hook ($post_id) {
|
|
779 |
do_action('xmlrpc_publish_post', $post_id);
|
780 |
if ( defined('APP_REQUEST') )
|
781 |
do_action('app_publish_post', $post_id);
|
782 |
-
|
783 |
if ( defined('WP_IMPORTING') )
|
784 |
return;
|
785 |
|
@@ -797,18 +804,29 @@ function fwp_publish_post_hook ($post_id) {
|
|
797 |
global $inspectPostMeta;
|
798 |
|
799 |
// Put in Manual Editing checkbox
|
800 |
-
|
801 |
|
802 |
add_filter('user_can_richedit', array($feedwordpress, 'user_can_richedit'), 1000, 1);
|
803 |
-
|
804 |
if (FeedWordPress::diagnostic_on('syndicated_posts:static_meta_data')) :
|
805 |
$inspectPostMeta = new InspectPostMeta;
|
806 |
endif;
|
807 |
-
} // function
|
808 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
809 |
function feedwordpress_post_edit_controls () {
|
810 |
global $post;
|
811 |
-
|
812 |
$frozen_values = get_post_custom_values('_syndication_freeze_updates', $post->ID);
|
813 |
$frozen_post = (count($frozen_values) > 0 and 'yes' == $frozen_values[0]);
|
814 |
|
@@ -817,47 +835,71 @@ function fwp_publish_post_hook ($post_id) {
|
|
817 |
<p>This is a syndicated post, which originally appeared at
|
818 |
<cite><?php print esc_html(get_syndication_source(NULL, $post->ID)); ?></cite>.
|
819 |
<a href="<?php print esc_html(get_syndication_permalink($post->ID)); ?>">View original post</a>.</p>
|
|
|
|
|
820 |
|
821 |
<p><input type="hidden" name="feedwordpress_noncename" id="feedwordpress_noncename" value="<?php print wp_create_nonce(plugin_basename(__FILE__)); ?>" />
|
822 |
<label><input type="checkbox" name="freeze_updates" value="yes" <?php if ($frozen_post) : ?>checked="checked"<?php endif; ?> /> <strong>Manual editing.</strong>
|
823 |
If set, FeedWordPress will not overwrite the changes you make manually
|
824 |
to this post, if the syndicated content is updated on the
|
825 |
feed.</label></p>
|
|
|
|
|
|
|
826 |
<?php
|
827 |
else :
|
828 |
?>
|
829 |
<p>This post was created locally at this website.</p>
|
830 |
<?php
|
831 |
endif;
|
832 |
-
}
|
833 |
|
834 |
function feedwordpress_save_post_edit_controls ( $post_id ) {
|
835 |
global $post;
|
836 |
-
|
837 |
if (!isset($_POST['feedwordpress_noncename']) or !wp_verify_nonce($_POST['feedwordpress_noncename'], plugin_basename(__FILE__))) :
|
838 |
return $post_id;
|
839 |
endif;
|
840 |
-
|
841 |
// Verify if this is an auto save routine. If it is our form has
|
842 |
// not been submitted, so we don't want to do anything.
|
843 |
if ( defined('DOING_AUTOSAVE') and DOING_AUTOSAVE ) :
|
844 |
return $post_id;
|
845 |
endif;
|
|
|
|
|
|
|
|
|
|
|
|
|
846 |
|
847 |
// Check permissions
|
848 |
-
|
|
|
|
|
|
|
|
|
|
|
849 |
return $post_id;
|
850 |
endif;
|
851 |
|
852 |
// OK, we're golden. Now let's save some data.
|
853 |
if (isset($_POST['freeze_updates'])) :
|
|
|
854 |
update_post_meta($post_id, '_syndication_freeze_updates', $_POST['freeze_updates']);
|
855 |
$ret = $_POST['freeze_updates'];
|
|
|
|
|
|
|
|
|
|
|
|
|
856 |
else :
|
857 |
delete_post_meta($post_id, '_syndication_freeze_updates');
|
858 |
$ret = NULL;
|
859 |
endif;
|
860 |
-
|
|
|
|
|
861 |
return $ret;
|
862 |
} // function feedwordpress_save_edit_controls
|
863 |
|
@@ -902,16 +944,19 @@ class FeedWordPress {
|
|
902 |
var $feeds = NULL;
|
903 |
var $feedurls = NULL;
|
904 |
var $httpauth = NULL;
|
905 |
-
|
906 |
-
|
907 |
-
|
|
|
|
|
|
|
908 |
$this->feeds = array ();
|
909 |
$this->feedurls = array();
|
910 |
$links = FeedWordPress::syndicated_links();
|
911 |
if ($links): foreach ($links as $link):
|
912 |
$id = intval($link->link_id);
|
913 |
$url = $link->link_rss;
|
914 |
-
|
915 |
// Store for later reference.
|
916 |
$this->feeds[$id] = $id;
|
917 |
if (strlen($url) > 0) :
|
@@ -919,20 +964,37 @@ class FeedWordPress {
|
|
919 |
endif;
|
920 |
endforeach; endif;
|
921 |
|
|
|
|
|
922 |
$this->httpauth = new FeedWordPressHTTPAuthenticator;
|
923 |
-
}
|
924 |
|
925 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
926 |
return (isset($this->feedurls[$id]) or isset($this->feeds[$id]));
|
927 |
} /* FeedWordPress::subscribed () */
|
928 |
-
|
929 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
930 |
$sub = NULL;
|
931 |
-
|
932 |
if (is_string($which) and isset($this->feedurls[$which])) :
|
933 |
$which = $this->feedurls[$which];
|
934 |
endif;
|
935 |
-
|
936 |
if (isset($this->feeds[$which])) :
|
937 |
$sub = $this->feeds[$which];
|
938 |
endif;
|
@@ -950,10 +1012,10 @@ class FeedWordPress {
|
|
950 |
$this->feeds[$which] = $link;
|
951 |
$sub = $link;
|
952 |
endif;
|
953 |
-
|
954 |
return $sub;
|
955 |
} /* FeedWordPress::subscription () */
|
956 |
-
|
957 |
# function update (): polls for updates on one or more Contributor feeds
|
958 |
#
|
959 |
# Arguments:
|
@@ -999,17 +1061,17 @@ class FeedWordPress {
|
|
999 |
# (between 30 minutes and 2 hours).
|
1000 |
#
|
1001 |
# * New posts from the polled feed are added to the WordPress store.
|
1002 |
-
#
|
1003 |
# * Updates to existing posts since the last poll are mirrored in the
|
1004 |
# WordPress store.
|
1005 |
#
|
1006 |
-
function update ($uri = null, $crash_ts = null) {
|
1007 |
global $wpdb;
|
1008 |
|
1009 |
if (FeedWordPress::needs_upgrade()) : // Will make duplicate posts if we don't hold off
|
1010 |
return NULL;
|
1011 |
endif;
|
1012 |
-
|
1013 |
if (!is_null($uri) and $uri != '*') :
|
1014 |
$uri = trim($uri);
|
1015 |
else : // Update all
|
@@ -1028,7 +1090,7 @@ class FeedWordPress {
|
|
1028 |
if (is_null($crash_ts)) :
|
1029 |
$crash_ts = $this->crash_ts();
|
1030 |
endif;
|
1031 |
-
|
1032 |
// Randomize order for load balancing purposes
|
1033 |
$feed_set = array_keys($this->feeds);
|
1034 |
shuffle($feed_set);
|
@@ -1045,8 +1107,8 @@ class FeedWordPress {
|
|
1045 |
), $uri);
|
1046 |
|
1047 |
$feed_set = apply_filters('feedwordpress_update_feeds', $feed_set, $uri);
|
1048 |
-
|
1049 |
-
|
1050 |
// Loop through and check for new posts
|
1051 |
$delta = NULL; $remaining = $max_polls;
|
1052 |
foreach ($feed_set as $feed_id) :
|
@@ -1057,13 +1119,13 @@ class FeedWordPress {
|
|
1057 |
if (
|
1058 |
// Over time limit?
|
1059 |
(!is_null($crash_ts) and (time() > $crash_ts))
|
1060 |
-
|
1061 |
// Over feed count?
|
1062 |
-
or ($remaining == 0)
|
1063 |
) :
|
1064 |
break;
|
1065 |
endif;
|
1066 |
-
|
1067 |
$pinged_that = (is_null($uri) or ($uri=='*') or in_array($uri, array($feed->uri(), $feed->homepage())));
|
1068 |
|
1069 |
if (!is_null($uri)) : // A site-specific ping always updates
|
@@ -1072,8 +1134,10 @@ class FeedWordPress {
|
|
1072 |
$timely = $feed->stale();
|
1073 |
endif;
|
1074 |
|
1075 |
-
|
1076 |
-
|
|
|
|
|
1077 |
endif;
|
1078 |
|
1079 |
if ($pinged_that and $timely) :
|
@@ -1085,18 +1149,18 @@ class FeedWordPress {
|
|
1085 |
do_action('feedwordpress_check_feed_complete', $feed->settings, $added, time() - $start_ts);
|
1086 |
|
1087 |
if (is_array($added)) : // Success
|
1088 |
-
|
1089 |
-
|
|
|
1090 |
endif;
|
1091 |
endif;
|
1092 |
endforeach;
|
1093 |
|
1094 |
do_action('feedwordpress_update_complete', $delta);
|
1095 |
-
|
1096 |
return $delta;
|
1097 |
-
}
|
1098 |
|
1099 |
-
function crash_ts ($default = NULL) {
|
1100 |
$crash_dt = (int) get_option('feedwordpress_update_time_limit', 0);
|
1101 |
if ($crash_dt > 0) :
|
1102 |
$crash_ts = time() + $crash_dt;
|
@@ -1104,32 +1168,23 @@ class FeedWordPress {
|
|
1104 |
$crash_ts = $default;
|
1105 |
endif;
|
1106 |
return $crash_ts;
|
1107 |
-
}
|
1108 |
-
|
1109 |
-
function secret_key () {
|
1110 |
$secret = get_option('feedwordpress_secret_key', false);
|
1111 |
if (!$secret) : // Generate random key.
|
1112 |
$secret = substr(md5(uniqid(microtime())), 0, 6);
|
1113 |
update_option('feedwordpress_secret_key', $secret);
|
1114 |
endif;
|
1115 |
return $secret;
|
1116 |
-
}
|
1117 |
-
|
1118 |
-
function has_secret () {
|
1119 |
-
return (
|
1120 |
-
}
|
1121 |
|
1122 |
-
// Utility function so I don't have to repeat myself w/ 1,000,003 isset()'s
|
1123 |
-
function by_request ($param, $eq = NULL) {
|
1124 |
-
$match = false;
|
1125 |
-
if (isset($_REQUEST[$param])) :
|
1126 |
-
$match = (is_null($eq) ? $_REQUEST[$param] : ($eq==$_REQUEST[$param]));
|
1127 |
-
endif;
|
1128 |
-
return $match;
|
1129 |
-
}
|
1130 |
-
|
1131 |
var $update_hooked = NULL;
|
1132 |
-
function automatic_update_hook ($params = array()) {
|
1133 |
$params = wp_parse_args($params, array( // Defaults
|
1134 |
'setting only' => false,
|
1135 |
));
|
@@ -1140,51 +1195,53 @@ class FeedWordPress {
|
|
1140 |
if (
|
1141 |
!$params['setting only']
|
1142 |
and $this->has_secret()
|
1143 |
-
and
|
1144 |
) :
|
1145 |
-
$hook =
|
1146 |
$method = 'URL parameter';
|
1147 |
endif;
|
1148 |
-
|
1149 |
$exact = $hook; // Before munging
|
1150 |
-
|
1151 |
if (!!$hook) :
|
1152 |
if ($hook != 'init') : // Constrain values.
|
1153 |
$hook = 'shutdown';
|
1154 |
endif;
|
1155 |
endif;
|
1156 |
-
|
1157 |
if ($hook) :
|
1158 |
$this->update_hooked = "Initiating an AUTOMATIC CHECK FOR UPDATES ON PAGE LOAD ".$hook." due to ".$method." = ".trim($this->val($exact));
|
1159 |
endif;
|
1160 |
-
|
1161 |
-
return $hook;
|
1162 |
-
}
|
1163 |
-
|
|
|
1164 |
$last = get_option('feedwordpress_last_update_all');
|
1165 |
-
if ($this->has_secret() and
|
1166 |
$last = 1; // A long, long time ago.
|
1167 |
-
elseif ($this->has_secret() and
|
1168 |
-
$last =
|
1169 |
endif;
|
1170 |
return $last;
|
1171 |
-
}
|
1172 |
-
|
1173 |
-
|
1174 |
-
|
1175 |
-
|
1176 |
-
|
|
|
1177 |
if (!is_null($this->automatic_update_hook())) :
|
1178 |
// Do our best to avoid possible simultaneous
|
1179 |
// updates by getting up-to-the-minute settings.
|
1180 |
-
|
1181 |
$last = $this->last_update_all();
|
1182 |
-
|
1183 |
// If we haven't updated all yet, give it a time window
|
1184 |
if (false === $last) :
|
1185 |
$ret = false;
|
1186 |
update_option('feedwordpress_last_update_all', time());
|
1187 |
-
|
1188 |
// Otherwise, check against freshness interval
|
1189 |
elseif (is_numeric($last)) : // Expect a timestamp
|
1190 |
$freshness = get_option('feedwordpress_freshness');
|
@@ -1192,7 +1249,7 @@ class FeedWordPress {
|
|
1192 |
$freshness = FEEDWORDPRESS_FRESHNESS_INTERVAL;
|
1193 |
endif;
|
1194 |
$ret = ( (time() - $last) > $freshness );
|
1195 |
-
|
1196 |
// This should never happen.
|
1197 |
else :
|
1198 |
FeedWordPress::critical_bug('FeedWordPress::stale::last', $last, __LINE__, __FILE__);
|
@@ -1202,7 +1259,7 @@ class FeedWordPress {
|
|
1202 |
$ret = false;
|
1203 |
endif;
|
1204 |
return $ret;
|
1205 |
-
}
|
1206 |
|
1207 |
static function admin_init () {
|
1208 |
// WordPress 3.5+ compat: the WP devs are in the midst of removing Links from the WordPress core. Eventually we'll have to deal
|
@@ -1211,34 +1268,200 @@ class FeedWordPress {
|
|
1211 |
if (!intval(get_option('link_manager_enabled', false))) :
|
1212 |
update_option('link_manager_enabled', true);
|
1213 |
endif;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1214 |
} /* FeedWordPress::admin_init() */
|
1215 |
|
1216 |
-
function admin_api () {
|
1217 |
// This sucks, but WordPress doesn't give us any other way to
|
1218 |
// easily invoke a permanent-delete from a plugged in post
|
1219 |
// actions link. So we create a magic parameter, and when this
|
1220 |
// magic parameter is activated, the WordPress trashcan is
|
1221 |
// temporarily de-activated.
|
1222 |
-
|
1223 |
if (MyPHP::request('fwp_post_delete')=='nuke') :
|
1224 |
// Get post ID #
|
1225 |
$post_id = MyPHP::request('post');
|
1226 |
if (!$post_id) :
|
1227 |
$post_id = MyPHP::request('post_ID');
|
1228 |
endif;
|
1229 |
-
|
1230 |
// Make sure we've got the right nonce and all that.
|
1231 |
check_admin_referer('delete-post_' . $post_id);
|
1232 |
-
|
1233 |
// If so, disable the trashcan.
|
1234 |
define('EMPTY_TRASH_DAYS', 0);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1235 |
endif;
|
|
|
|
|
|
|
|
|
1236 |
|
|
|
1237 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1238 |
|
1239 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1240 |
global $fwp_path;
|
1241 |
-
|
1242 |
// If this is a FeedWordPress admin page, queue up scripts for AJAX
|
1243 |
// functions that FWP uses. If it is a display page or a non-FWP admin
|
1244 |
// page, don't.
|
@@ -1246,19 +1469,21 @@ class FeedWordPress {
|
|
1246 |
if (FeedWordPressSettingsUI::is_admin()) :
|
1247 |
// For JavaScript that needs to be generated dynamically
|
1248 |
add_action('admin_print_scripts', array('FeedWordPressSettingsUI', 'admin_scripts'));
|
1249 |
-
|
1250 |
// For CSS that needs to be generated dynamically.
|
1251 |
add_action('admin_print_styles', array('FeedWordPressSettingsUI', 'admin_styles'));
|
1252 |
-
|
1253 |
wp_enqueue_style('dashboard');
|
1254 |
wp_enqueue_style('feedwordpress-elements');
|
1255 |
-
|
1256 |
/*if (function_exists('wp_admin_css')) :
|
1257 |
wp_admin_css('css/dashboard');
|
1258 |
endif;*/
|
1259 |
endif;
|
1260 |
|
1261 |
-
//
|
|
|
|
|
1262 |
register_post_status('fwpretired', array(
|
1263 |
'label' => _x('Retired', 'post'),
|
1264 |
'label_count' => _n_noop('Retired <span class="count">(%s)</span>', 'Retired <span class="count">(%s)</span>'),
|
@@ -1268,6 +1493,15 @@ class FeedWordPress {
|
|
1268 |
'show_in_admin_all_list' => false,
|
1269 |
'show_in_admin_status_list' => true,
|
1270 |
));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1271 |
add_action(
|
1272 |
/*hook=*/ 'template_redirect',
|
1273 |
/*function=*/ array($this, 'redirect_retired'),
|
@@ -1277,15 +1511,15 @@ class FeedWordPress {
|
|
1277 |
add_action('wp_ajax_fwp_feeds', array($this, 'fwp_feeds'));
|
1278 |
add_action('wp_ajax_fwp_feedcontents', array($this, 'fwp_feedcontents'));
|
1279 |
add_action('wp_ajax_fwp_xpathtest', array($this, 'fwp_xpathtest'));
|
1280 |
-
|
1281 |
$this->clear_cache_magic_url();
|
1282 |
$this->update_magic_url();
|
1283 |
} /* FeedWordPress::init() */
|
1284 |
-
|
1285 |
-
function fwp_feeds () {
|
1286 |
$feeds = array();
|
1287 |
$feed_ids = $this->feeds;
|
1288 |
-
|
1289 |
foreach ($feed_ids as $id) :
|
1290 |
$sub = $this->subscription($id);
|
1291 |
$feeds[] = array(
|
@@ -1295,18 +1529,18 @@ class FeedWordPress {
|
|
1295 |
);
|
1296 |
endforeach;
|
1297 |
|
1298 |
-
header("Content-Type: application/json");
|
1299 |
echo json_encode($feeds);
|
1300 |
exit;
|
1301 |
-
}
|
1302 |
|
1303 |
-
function fwp_feedcontents () {
|
1304 |
$feed_id = MyPHP::request('feed_id');
|
1305 |
-
|
1306 |
// Let's load up some data from the feed . . .
|
1307 |
$feed = $this->subscription($feed_id);
|
1308 |
$posts = $feed->live_posts();
|
1309 |
-
|
1310 |
if (is_wp_error($posts)) :
|
1311 |
header("HTTP/1.1 502 Bad Gateway");
|
1312 |
$result = $posts;
|
@@ -1315,7 +1549,7 @@ class FeedWordPress {
|
|
1315 |
|
1316 |
foreach ($posts as $post) :
|
1317 |
$p = new SyndicatedPost($post, $feed);
|
1318 |
-
|
1319 |
$result[] = array(
|
1320 |
"post_title" => $p->entry->get_title(),
|
1321 |
"post_link" => $p->permalink(),
|
@@ -1324,42 +1558,42 @@ class FeedWordPress {
|
|
1324 |
);
|
1325 |
endforeach;
|
1326 |
endif;
|
1327 |
-
|
1328 |
header("Content-Type: application/json");
|
1329 |
-
|
1330 |
echo json_encode($result);
|
1331 |
-
|
1332 |
// This is an AJAX request, so close it out thus.
|
1333 |
die;
|
1334 |
} /* FeedWordPress::fwp_feedcontents () */
|
1335 |
-
|
1336 |
-
function fwp_xpathtest () {
|
1337 |
$xpath = MyPHP::request('xpath');
|
1338 |
$feed_id = MyPHP::request('feed_id');
|
1339 |
$post_id = MyPHP::request('post_id');
|
1340 |
-
|
1341 |
$expr = new FeedWordPressParsedPostMeta($xpath);
|
1342 |
-
|
1343 |
// Let's load up some data from the feed . . .
|
1344 |
$feed = $this->subscription($feed_id);
|
1345 |
$posts = $feed->live_posts();
|
1346 |
-
|
1347 |
if (!is_wp_error($posts)) :
|
1348 |
if (strlen($post_id) == 0) :
|
1349 |
$post = $posts[0];
|
1350 |
else :
|
1351 |
$post = null;
|
1352 |
-
|
1353 |
foreach ($posts as $p) :
|
1354 |
if ($p->get_id() == $post_id) :
|
1355 |
$post = $p;
|
1356 |
endif;
|
1357 |
endforeach;
|
1358 |
endif;
|
1359 |
-
|
1360 |
$post = new SyndicatedPost($post, $feed);
|
1361 |
$meta = $expr->do_substitutions($post);
|
1362 |
-
|
1363 |
$result = array(
|
1364 |
"post_title" => $post->entry->get_title(),
|
1365 |
"post_link" => $post->permalink(),
|
@@ -1374,24 +1608,27 @@ class FeedWordPress {
|
|
1374 |
"post_id" => $post_id,
|
1375 |
"results" => $posts
|
1376 |
);
|
1377 |
-
|
1378 |
header("HTTP/1.1 503 Bad Gateway");
|
1379 |
endif;
|
1380 |
-
|
1381 |
header("Content-Type: application/json");
|
1382 |
-
|
1383 |
echo json_encode($result);
|
1384 |
-
|
1385 |
// This is an AJAX request, so close it out thus.
|
1386 |
die;
|
1387 |
} /* FeedWordPress::fwp_xpathtest () */
|
1388 |
-
|
1389 |
-
function redirect_retired () {
|
1390 |
global $wp_query;
|
1391 |
if (is_singular()) :
|
1392 |
-
if (
|
|
|
|
|
|
|
1393 |
do_action('feedwordpress_redirect_retired', $wp_query->post);
|
1394 |
-
|
1395 |
if (!($template = get_404_template())) :
|
1396 |
$template = get_index_template();
|
1397 |
endif;
|
@@ -1402,48 +1639,73 @@ class FeedWordPress {
|
|
1402 |
exit;
|
1403 |
endif;
|
1404 |
endif;
|
1405 |
-
}
|
1406 |
-
|
1407 |
-
function row_actions ($actions, $post) {
|
1408 |
if (is_syndicated($post->ID)) :
|
1409 |
$link = get_delete_post_link($post->ID, '', true);
|
1410 |
-
$
|
|
|
|
|
|
|
1411 |
|
1412 |
-
$
|
1413 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1414 |
|
1415 |
$keys = array_keys($actions);
|
1416 |
$links = array();
|
1417 |
foreach ($keys as $key) :
|
1418 |
$links[$key] = $actions[$key];
|
1419 |
-
|
1420 |
if ('trash'==$key) :
|
1421 |
-
|
1422 |
-
|
1423 |
// Placeholder.
|
|
|
|
|
|
|
1424 |
$links['delete'] = '';
|
1425 |
endif;
|
1426 |
endforeach;
|
1427 |
-
|
1428 |
-
|
|
|
|
|
|
|
1429 |
|
1430 |
$actions = $links;
|
1431 |
endif;
|
1432 |
return $actions;
|
1433 |
-
}
|
1434 |
-
|
1435 |
-
function dashboard_setup () {
|
1436 |
$see_it = FeedWordPress::menu_cap();
|
1437 |
-
|
1438 |
if (current_user_can($see_it)) :
|
1439 |
// Get the stylesheet
|
1440 |
wp_enqueue_style('feedwordpress-elements');
|
1441 |
-
|
1442 |
$widget_id = 'feedwordpress_dashboard';
|
1443 |
$widget_name = __('Syndicated Sources');
|
1444 |
$column = 'side';
|
1445 |
$priority = 'core';
|
1446 |
-
|
1447 |
// I would love to use wp_add_dashboard_widget() here and save
|
1448 |
// myself some trouble. But WP 3 does not yet have any way to
|
1449 |
// push a dashboard widget onto the side, or to give it a default
|
@@ -1457,57 +1719,57 @@ class FeedWordPress {
|
|
1457 |
/*priority=*/ $priority
|
1458 |
);
|
1459 |
/*control_callback= array($this, 'dashboard_control') */
|
1460 |
-
|
1461 |
// This is kind of rude, I know, but the dashboard widget isn't
|
1462 |
// worth much if users don't know that it exists, and I don't
|
1463 |
// know of any better way to reorder the boxen.
|
1464 |
//
|
1465 |
// Gleefully ripped off of codex.wordpress.org/Dashboard_Widgets_API
|
1466 |
-
|
1467 |
// Globalize the metaboxes array, this holds all the widgets for wp-admin
|
1468 |
global $wp_meta_boxes;
|
1469 |
-
|
1470 |
-
// Get the regular dashboard widgets array
|
1471 |
// (which has our new widget already but at the end)
|
1472 |
-
|
1473 |
$normal_dashboard = $wp_meta_boxes['dashboard'][$column][$priority];
|
1474 |
-
|
1475 |
// Backup and delete our new dashbaord widget from the end of the array
|
1476 |
if (isset($normal_dashboard[$widget_id])) :
|
1477 |
$backup = array();
|
1478 |
$backup[$widget_id] = $normal_dashboard[$widget_id];
|
1479 |
unset($normal_dashboard[$widget_id]);
|
1480 |
-
|
1481 |
// Merge the two arrays together so our widget is at the
|
1482 |
// beginning
|
1483 |
$sorted_dashboard = array_merge($backup, $normal_dashboard);
|
1484 |
-
|
1485 |
-
// Save the sorted array back into the original metaboxes
|
1486 |
$wp_meta_boxes['dashboard'][$column][$priority] = $sorted_dashboard;
|
1487 |
endif;
|
1488 |
endif;
|
1489 |
} /* FeedWordPress::dashboard_setup () */
|
1490 |
-
|
1491 |
-
function dashboard () {
|
1492 |
$syndicationPage = new FeedWordPressSyndicationPage(dirname(__FILE__).'/syndication.php');
|
1493 |
$syndicationPage->dashboard_box($syndicationPage);
|
1494 |
} /* FeedWordPress::dashboard () */
|
1495 |
|
1496 |
-
function user_can_richedit ($rich_edit) {
|
1497 |
|
1498 |
$post = new FeedWordPressLocalPost;
|
1499 |
-
|
1500 |
if (!$post->is_exposed_to_formatting_filters()) :
|
1501 |
// Disable visual editor and only allow operations
|
1502 |
// directly on HTML if post is bypassing fmt filters
|
1503 |
-
$rich_edit = false;
|
1504 |
endif;
|
1505 |
-
|
1506 |
return $rich_edit;
|
1507 |
|
1508 |
} /* FeedWordPress::user_can_richedit () */
|
1509 |
-
|
1510 |
-
function update_magic_url () {
|
1511 |
global $wpdb;
|
1512 |
|
1513 |
// Explicit update request in the HTTP request (e.g. from a cron job)
|
@@ -1515,7 +1777,7 @@ class FeedWordPress {
|
|
1515 |
$this->update_hooked = "Initiating a CRON JOB CHECK-IN ON UPDATE SCHEDULE due to URL parameter = ".trim($this->val($_REQUEST['update_feedwordpress']));
|
1516 |
|
1517 |
$this->update($this->update_requested_url());
|
1518 |
-
|
1519 |
if (FEEDWORDPRESS_DEBUG and count($wpdb->queries) > 0) :
|
1520 |
$mysqlTime = 0.0;
|
1521 |
$byTime = array();
|
@@ -1523,58 +1785,58 @@ class FeedWordPress {
|
|
1523 |
$time = $query[1] * 1000000.0;
|
1524 |
$mysqlTime += $query[1];
|
1525 |
if (!isset($byTime[$time])) : $byTime[$time] = array(); endif;
|
1526 |
-
$byTime[$time][] = $query[0]. ' // STACK: ' . $query[2];
|
1527 |
endforeach;
|
1528 |
krsort($byTime);
|
1529 |
-
|
1530 |
foreach ($byTime as $time => $querySet) :
|
1531 |
foreach ($querySet as $query) :
|
1532 |
print "[".(sprintf('%4.4f', $time/1000.0)) . "ms] $query\n";
|
1533 |
endforeach;
|
1534 |
endforeach;
|
1535 |
-
echo
|
1536 |
endif;
|
1537 |
-
|
1538 |
debug_out_feedwordpress_footer();
|
1539 |
-
|
1540 |
// Magic URL should return nothing but a 200 OK header packet
|
1541 |
// when successful.
|
1542 |
exit;
|
1543 |
endif;
|
1544 |
} /* FeedWordPress::magic_update_url () */
|
1545 |
|
1546 |
-
function clear_cache_magic_url () {
|
1547 |
if ($this->clear_cache_requested()) :
|
1548 |
$this->clear_cache();
|
1549 |
endif;
|
1550 |
} /* FeedWordPress::clear_cache_magic_url() */
|
1551 |
-
|
1552 |
-
function clear_cache_requested () {
|
1553 |
return MyPHP::request('clear_cache');
|
1554 |
} /* FeedWordPress::clear_cache_requested() */
|
1555 |
|
1556 |
-
function update_requested () {
|
1557 |
-
return
|
1558 |
-
}
|
1559 |
|
1560 |
-
function update_requested_url () {
|
1561 |
$ret = null;
|
1562 |
-
|
1563 |
if (($_REQUEST['update_feedwordpress']=='*')
|
1564 |
or (preg_match('|^http://.*|i', $_REQUEST['update_feedwordpress']))) :
|
1565 |
$ret = $_REQUEST['update_feedwordpress'];
|
1566 |
endif;
|
1567 |
|
1568 |
return $ret;
|
1569 |
-
}
|
1570 |
|
1571 |
-
function auto_update () {
|
1572 |
if ($this->stale()) :
|
1573 |
$this->update();
|
1574 |
endif;
|
1575 |
} /* FeedWordPress::auto_update () */
|
1576 |
|
1577 |
-
function find_link ($uri, $field = 'link_rss') {
|
1578 |
global $wpdb;
|
1579 |
|
1580 |
$unslashed = untrailingslashit($uri);
|
@@ -1583,11 +1845,40 @@ class FeedWordPress {
|
|
1583 |
SELECT link_id FROM $wpdb->links WHERE $field IN ('%s', '%s')
|
1584 |
LIMIT 1", $unslashed, $slashed
|
1585 |
));
|
1586 |
-
|
1587 |
return $link_id;
|
1588 |
} /* FeedWordPress::find_link () */
|
1589 |
|
1590 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1591 |
// Get the category ID#
|
1592 |
$cat_id = FeedWordPress::link_category_id();
|
1593 |
if (!is_wp_error($cat_id)) :
|
@@ -1598,21 +1889,21 @@ class FeedWordPress {
|
|
1598 |
|
1599 |
// WordPress gets cranky if there's no homepage URI
|
1600 |
if (!is_string($uri) or strlen($uri)<1) : $uri = $rss; endif;
|
1601 |
-
|
1602 |
// Check if this feed URL is already being syndicated.
|
1603 |
-
$link_id = wp_insert_link(array(
|
1604 |
"link_id" => FeedWordPress::find_link($rss), // insert if nothing was found; else update
|
1605 |
"link_rss" => $rss,
|
1606 |
"link_name" => $name,
|
1607 |
"link_url" => $uri,
|
1608 |
"link_category" => $link_category,
|
1609 |
"link_visible" => 'Y', // reactivate if inactivated
|
1610 |
-
));
|
1611 |
|
1612 |
return $link_id;
|
1613 |
} /* function FeedWordPress::syndicate_link() */
|
1614 |
|
1615 |
-
|
1616 |
$ret = get_option("feedwordpress_syndicated_{$what}_status");
|
1617 |
if (!$ret) :
|
1618 |
$ret = $default;
|
@@ -1620,17 +1911,17 @@ class FeedWordPress {
|
|
1620 |
return $ret;
|
1621 |
} /* FeedWordPress::syndicated_status() */
|
1622 |
|
1623 |
-
function on_unfamiliar ($what = 'author') {
|
1624 |
switch ($what) :
|
1625 |
case 'category' : $suffix = ':category'; break;
|
1626 |
case 'post_tag' : $suffix = ':post_tag'; break;
|
1627 |
default: $suffix = '';
|
1628 |
endswitch;
|
1629 |
-
|
1630 |
return get_option('feedwordpress_unfamiliar_'.$what, 'create'.$suffix);
|
1631 |
} // function FeedWordPress::on_unfamiliar()
|
1632 |
|
1633 |
-
function null_email_set () {
|
1634 |
$base = get_option('feedwordpress_null_email_set');
|
1635 |
|
1636 |
if ($base===false) :
|
@@ -1644,16 +1935,16 @@ class FeedWordPress {
|
|
1644 |
|
1645 |
} /* FeedWordPress::null_email_set () */
|
1646 |
|
1647 |
-
function is_null_email ($email) {
|
1648 |
$ret = in_array(strtolower(trim($email)), FeedWordPress::null_email_set());
|
1649 |
$ret = apply_filters('syndicated_item_author_is_null_email', $ret, $email);
|
1650 |
return $ret;
|
1651 |
} /* FeedWordPress::is_null_email () */
|
1652 |
|
1653 |
-
function use_aggregator_source_data () {
|
1654 |
$ret = get_option('feedwordpress_use_aggregator_source_data');
|
1655 |
return apply_filters('syndicated_post_use_aggregator_source_data', ($ret=='yes'));
|
1656 |
-
}
|
1657 |
|
1658 |
/**
|
1659 |
* FeedWordPress::munge_permalinks: check whether or not FeedWordPress
|
@@ -1662,11 +1953,11 @@ class FeedWordPress {
|
|
1662 |
*
|
1663 |
* @return bool TRUE if FeedWordPress SHOULD rewrite permalinks; FALSE otherwise
|
1664 |
*/
|
1665 |
-
|
1666 |
return (get_option('feedwordpress_munge_permalink', /*default=*/ 'yes') != 'no');
|
1667 |
} /* FeedWordPress::munge_permalinks() */
|
1668 |
|
1669 |
-
function syndicated_links ($args = array()) {
|
1670 |
$contributors = FeedWordPress::link_category_id();
|
1671 |
if (!is_wp_error($contributors)) :
|
1672 |
$links = get_bookmarks(array_merge(
|
@@ -1678,13 +1969,13 @@ class FeedWordPress {
|
|
1678 |
endif;
|
1679 |
|
1680 |
return $links;
|
1681 |
-
}
|
1682 |
|
1683 |
-
function link_category_id () {
|
1684 |
global $wpdb, $wp_db_version;
|
1685 |
|
1686 |
$cat_id = get_option('feedwordpress_cat_id');
|
1687 |
-
|
1688 |
// If we don't yet have the category ID stored, search by name
|
1689 |
if (!$cat_id) :
|
1690 |
$cat_id = FeedWordPressCompatibility::link_category_id(DEFAULT_SYNDICATION_CATEGORY);
|
@@ -1698,7 +1989,7 @@ class FeedWordPress {
|
|
1698 |
else :
|
1699 |
$cat_id = FeedWordPressCompatibility::link_category_id((int) $cat_id, 'cat_id');
|
1700 |
endif;
|
1701 |
-
|
1702 |
// If we could not find an appropriate link category,
|
1703 |
// make a new one for ourselves.
|
1704 |
if (!$cat_id) :
|
@@ -1710,45 +2001,35 @@ class FeedWordPress {
|
|
1710 |
endif;
|
1711 |
|
1712 |
return $cat_id;
|
1713 |
-
}
|
1714 |
|
1715 |
# Upgrades and maintenance...
|
1716 |
-
function needs_upgrade () {
|
|
|
1717 |
global $wpdb;
|
1718 |
-
$fwp_db_version = get_option('feedwordpress_version');
|
1719 |
$ret = false; // innocent until proven guilty
|
1720 |
-
if (
|
1721 |
-
// This is an older version or a fresh install. Does it
|
1722 |
-
// require a database upgrade or database initialization?
|
1723 |
-
if ($fwp_db_version <= 0.96) :
|
1724 |
-
// Yes. Check to see whether this is a fresh install or an upgrade.
|
1725 |
-
$syn = $wpdb->get_col("
|
1726 |
-
SELECT post_id
|
1727 |
-
FROM $wpdb->postmeta
|
1728 |
-
WHERE meta_key = 'syndication_feed'
|
1729 |
-
");
|
1730 |
-
if (count($syn) > 0) : // contains at least one syndicated post
|
1731 |
-
$ret = true;
|
1732 |
-
else : // fresh install; brand it as ours
|
1733 |
-
update_option('feedwordpress_version', FEEDWORDPRESS_VERSION);
|
1734 |
-
endif;
|
1735 |
-
elseif ($fwp_db_version < 2009.0707) :
|
1736 |
-
// We need to clear out any busted AJAX crap
|
1737 |
-
$wpdb->query("
|
1738 |
-
DELETE FROM $wpdb->usermeta
|
1739 |
-
WHERE LOCATE('feedwordpress', meta_key)
|
1740 |
-
AND LOCATE('box', meta_key);
|
1741 |
-
");
|
1742 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1743 |
update_option('feedwordpress_version', FEEDWORDPRESS_VERSION);
|
|
|
1744 |
elseif ($fwp_db_version < 2010.0814) :
|
|
|
1745 |
// Change in terminology.
|
1746 |
if (get_option('feedwordpress_unfamiliar_category', 'create')=='default') :
|
1747 |
update_option('feedwordpress_unfamiliar_category', 'null');
|
1748 |
endif;
|
1749 |
foreach (FeedWordPress::syndicated_links() as $link) :
|
1750 |
$sub = new SyndicatedLink($link);
|
1751 |
-
|
1752 |
$remap_uf = array(
|
1753 |
'default' => 'null',
|
1754 |
'filter' => 'null',
|
@@ -1765,34 +2046,38 @@ class FeedWordPress {
|
|
1765 |
endif;
|
1766 |
endforeach;
|
1767 |
endif;
|
1768 |
-
|
1769 |
if (isset($sub->settings['add global categories'])) :
|
1770 |
$sub->settings['add/category'] = $sub->settings['add global categories'];
|
1771 |
unset($sub->settings['add global categories']);
|
1772 |
endif;
|
1773 |
-
|
1774 |
$sub->save_settings(/*reload=*/ true);
|
1775 |
endforeach;
|
1776 |
update_option('feedwordpress_version', FEEDWORDPRESS_VERSION);
|
|
|
1777 |
else :
|
1778 |
-
|
|
|
1779 |
update_option('feedwordpress_version', FEEDWORDPRESS_VERSION);
|
|
|
1780 |
endif;
|
|
|
1781 |
endif;
|
1782 |
return $ret;
|
1783 |
-
}
|
1784 |
|
1785 |
-
function upgrade_database ($from = NULL) {
|
1786 |
global $wpdb;
|
1787 |
|
1788 |
if (is_null($from) or $from <= 0.96) : $from = 0.96; endif;
|
1789 |
|
1790 |
switch ($from) :
|
1791 |
case 0.96:
|
1792 |
-
|
1793 |
-
|
1794 |
-
|
1795 |
-
|
1796 |
|
1797 |
// Mark the upgrade as successful.
|
1798 |
update_option('feedwordpress_version', FEEDWORDPRESS_VERSION);
|
@@ -1800,9 +2085,9 @@ class FeedWordPress {
|
|
1800 |
echo "<p>Upgrade complete. FeedWordPress is now ready to use again.</p>";
|
1801 |
} /* FeedWordPress::upgrade_database() */
|
1802 |
|
1803 |
-
function has_guid_index () {
|
1804 |
global $wpdb;
|
1805 |
-
|
1806 |
$found = false; // Guilty until proven innocent.
|
1807 |
|
1808 |
$results = $wpdb->get_results("
|
@@ -1818,41 +2103,42 @@ class FeedWordPress {
|
|
1818 |
endif;
|
1819 |
return $found;
|
1820 |
} /* FeedWordPress::has_guid_index () */
|
1821 |
-
|
1822 |
-
function create_guid_index () {
|
1823 |
global $wpdb;
|
1824 |
-
|
1825 |
$wpdb->query("
|
1826 |
CREATE INDEX {$wpdb->posts}_guid_idx ON {$wpdb->posts}(guid)
|
1827 |
");
|
1828 |
} /* FeedWordPress::create_guid_index () */
|
1829 |
-
|
1830 |
-
function remove_guid_index () {
|
1831 |
global $wpdb;
|
1832 |
-
|
1833 |
$wpdb->query("
|
1834 |
DROP INDEX {$wpdb->posts}_guid_idx ON {$wpdb->posts}
|
1835 |
");
|
1836 |
}
|
1837 |
|
1838 |
-
|
1839 |
return apply_filters(
|
1840 |
'feedwordpress_fetch_timeout',
|
1841 |
intval(get_option('feedwordpress_fetch_timeout', FEEDWORDPRESS_FETCH_TIMEOUT_DEFAULT))
|
1842 |
);
|
1843 |
}
|
1844 |
-
|
1845 |
-
|
1846 |
if (is_wp_error($url)) :
|
1847 |
// Let's bounce.
|
1848 |
return $url;
|
1849 |
endif;
|
1850 |
-
|
1851 |
$force_feed = true; // Default
|
1852 |
|
1853 |
-
// Allow user to change default feed-fetch timeout with a global setting.
|
|
|
1854 |
$timeout = FeedWordPress::fetch_timeout();
|
1855 |
-
|
1856 |
if (!is_array($params)) :
|
1857 |
$force_feed = $params;
|
1858 |
else : // Parameter array
|
@@ -1860,11 +2146,11 @@ class FeedWordPress {
|
|
1860 |
'force_feed' => $force_feed,
|
1861 |
'timeout' => $timeout
|
1862 |
), $params);
|
1863 |
-
|
1864 |
extract($args);
|
1865 |
endif;
|
1866 |
$timeout = intval($timeout);
|
1867 |
-
|
1868 |
$pie_class = apply_filters('feedwordpress_simplepie_class', 'FeedWordPie');
|
1869 |
$cache_class = apply_filters('feedwordpress_cache_class', 'WP_Feed_Cache');
|
1870 |
$file_class = apply_filters('feedwordpress_file_class', 'FeedWordPress_File');
|
@@ -1876,7 +2162,7 @@ class FeedWordPress {
|
|
1876 |
$feed->set_feed_url($url);
|
1877 |
$feed->set_cache_class($cache_class);
|
1878 |
$feed->set_timeout($timeout);
|
1879 |
-
|
1880 |
$feed->set_content_type_sniffer_class($sniffer_class);
|
1881 |
$feed->set_file_class($file_class);
|
1882 |
$feed->set_parser_class($parser_class);
|
@@ -1885,7 +2171,7 @@ class FeedWordPress {
|
|
1885 |
$feed->set_cache_duration(FeedWordPress::cache_duration($params));
|
1886 |
$feed->init();
|
1887 |
$feed->handle_content_type();
|
1888 |
-
|
1889 |
if ($feed->error()) :
|
1890 |
$ret = new WP_Error('simplepie-error', $feed->error());
|
1891 |
else :
|
@@ -1893,10 +2179,10 @@ class FeedWordPress {
|
|
1893 |
endif;
|
1894 |
return $ret;
|
1895 |
} /* FeedWordPress::fetch () */
|
1896 |
-
|
1897 |
-
function clear_cache () {
|
1898 |
global $wpdb;
|
1899 |
-
|
1900 |
// Just in case, clear out any old MagpieRSS cache records.
|
1901 |
$magpies = $wpdb->query("
|
1902 |
DELETE FROM {$wpdb->options}
|
@@ -1919,11 +2205,11 @@ class FeedWordPress {
|
|
1919 |
return ($magpies + $simplepies);
|
1920 |
} /* FeedWordPress::clear_cache () */
|
1921 |
|
1922 |
-
function cache_duration ($params = array()) {
|
1923 |
$params = wp_parse_args($params, array(
|
1924 |
"cache" => true,
|
1925 |
));
|
1926 |
-
|
1927 |
$duration = NULL;
|
1928 |
if (!$params['cache']) :
|
1929 |
$duration = 0;
|
@@ -1932,7 +2218,8 @@ class FeedWordPress {
|
|
1932 |
endif;
|
1933 |
return $duration;
|
1934 |
}
|
1935 |
-
|
|
|
1936 |
// Check for explicit setting of a lifetime duration
|
1937 |
if (defined('FEEDWORDPRESS_CACHE_LIFETIME')) :
|
1938 |
$duration = FEEDWORDPRESS_CACHE_LIFETIME;
|
@@ -1941,32 +2228,32 @@ class FeedWordPress {
|
|
1941 |
elseif (defined('FEEDWORDPRESS_CACHE_AGE')) :
|
1942 |
$duration = FEEDWORDPRESS_CACHE_AGE;
|
1943 |
endif;
|
1944 |
-
|
1945 |
// Fall back to WordPress default
|
1946 |
return $duration;
|
1947 |
} /* FeedWordPress::cache_lifetime () */
|
1948 |
|
1949 |
# Utility functions for handling text settings
|
1950 |
-
function negative ($f, $setting) {
|
1951 |
$nego = array ('n', 'no', 'f', 'false');
|
1952 |
return (isset($f[$setting]) and in_array(strtolower($f[$setting]), $nego));
|
1953 |
-
}
|
1954 |
|
1955 |
-
function affirmative ($f, $setting) {
|
1956 |
$affirmo = array ('y', 'yes', 't', 'true', 1);
|
1957 |
return (isset($f[$setting]) and in_array(strtolower($f[$setting]), $affirmo));
|
1958 |
-
}
|
1959 |
|
1960 |
# Internal debugging functions
|
1961 |
-
function critical_bug ($varname, $var, $line, $file = NULL) {
|
1962 |
global $wp_version;
|
1963 |
-
|
1964 |
if (!is_null($file)) :
|
1965 |
$location = "line # ${line} of ".basename($file);
|
1966 |
else :
|
1967 |
$location = "line # ${line}";
|
1968 |
endif;
|
1969 |
-
|
1970 |
print '<p><strong>Critical error:</strong> 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>';
|
1971 |
print "\n<plaintext>";
|
1972 |
print "Triggered at ${location}\n";
|
@@ -1976,31 +2263,24 @@ class FeedWordPress {
|
|
1976 |
print "Error data: ";
|
1977 |
print $varname.": "; var_dump($var); echo "\n";
|
1978 |
die;
|
1979 |
-
}
|
1980 |
-
|
1981 |
-
function noncritical_bug ($varname, $var, $line, $file = NULL) {
|
1982 |
if (FEEDWORDPRESS_DEBUG) : // halt only when we are doing debugging
|
1983 |
FeedWordPress::critical_bug($varname, $var, $line, $file);
|
1984 |
endif;
|
1985 |
-
}
|
1986 |
-
|
1987 |
-
function val ($v, $no_newlines = false) {
|
1988 |
-
|
1989 |
-
var_dump($v);
|
1990 |
-
$out = ob_get_contents(); ob_end_clean();
|
1991 |
-
|
1992 |
-
if ($no_newlines) :
|
1993 |
-
$out = preg_replace('/\s+/', " ", $out);
|
1994 |
-
endif;
|
1995 |
-
return $out;
|
1996 |
} /* FeedWordPress::val () */
|
1997 |
|
1998 |
-
function diagnostic_on ($level) {
|
1999 |
$show = get_option('feedwordpress_diagnostics_show', array());
|
2000 |
return (in_array($level, $show));
|
2001 |
} /* FeedWordPress::diagnostic_on () */
|
2002 |
|
2003 |
-
function diagnostic ($level, $out, $persist = NULL, $since = NULL, $mostRecent = NULL) {
|
2004 |
global $feedwordpress_admin_footer;
|
2005 |
|
2006 |
$output = get_option('feedwordpress_diagnostics_output', array());
|
@@ -2013,7 +2293,7 @@ class FeedWordPress {
|
|
2013 |
switch ($method) :
|
2014 |
case 'echo' :
|
2015 |
if (!FeedWordPress::update_requested()) :
|
2016 |
-
echo "<div><pre><strong>Diag".str_repeat('====', $diagnostic_nesting-1).'|</strong> '.$out."</pre></div
|
2017 |
endif;
|
2018 |
break;
|
2019 |
case 'echo_in_cronjob' :
|
@@ -2028,7 +2308,7 @@ class FeedWordPress {
|
|
2028 |
error_log(FeedWordPress::log_prefix().' '.$out);
|
2029 |
break;
|
2030 |
case 'email' :
|
2031 |
-
|
2032 |
if (is_null($persist)) :
|
2033 |
$sect = 'occurrent';
|
2034 |
$hook = (isset($dlog['mesg'][$sect]) ? count($dlog['mesg'][$sect]) : 0);
|
@@ -2038,56 +2318,58 @@ class FeedWordPress {
|
|
2038 |
$hook = md5($level."\n".$persist);
|
2039 |
$line = array("Since" => $since, "Message" => $out, "Most Recent" => $mostRecent);
|
2040 |
endif;
|
2041 |
-
|
2042 |
if (!isset($dlog['mesg'])) : $dlog['mesg'] = array(); endif;
|
2043 |
if (!isset($dlog['mesg'][$sect])) : $dlog['mesg'][$sect] = array(); endif;
|
2044 |
-
|
2045 |
$dlog['mesg'][$sect][$hook] = $line;
|
2046 |
endswitch;
|
2047 |
endforeach;
|
2048 |
endif;
|
2049 |
-
|
2050 |
-
update_option('feedwordpress_diagnostics_log', $dlog);
|
2051 |
} /* FeedWordPress::diagnostic () */
|
2052 |
-
|
2053 |
-
function email_diagnostics_override () {
|
2054 |
return ($this->has_secret() and isset($_REQUEST['feedwordpress_email_diagnostics']) and !!$_REQUEST['feedwordpress_email_diagnostics']);
|
2055 |
-
}
|
2056 |
-
|
|
|
2057 |
$ret = false;
|
2058 |
if ($this->email_diagnostics_override()
|
2059 |
or (isset($dlog['schedule']) and isset($dlog['schedule']['last']))) :
|
2060 |
$ret = true;
|
2061 |
endif;
|
2062 |
return $ret;
|
2063 |
-
}
|
2064 |
-
|
|
|
2065 |
$ret = false;
|
2066 |
if ($this->email_diagnostics_override()
|
2067 |
or (time() > ($dlog['schedule']['last'] + $dlog['schedule']['freq']))) :
|
2068 |
$ret = true;
|
2069 |
endif;
|
2070 |
return $ret;
|
2071 |
-
}
|
2072 |
-
|
2073 |
-
function email_diagnostic_log ($params = array()) {
|
2074 |
$params = wp_parse_args($params, array(
|
2075 |
"force" => false,
|
2076 |
));
|
2077 |
|
2078 |
$dlog = get_option('feedwordpress_diagnostics_log', array());
|
2079 |
-
|
2080 |
if ($this->has_emailed_diagnostics($dlog)) :
|
2081 |
if ($this->ready_to_email_diagnostics($dlog)) :
|
2082 |
// No news is good news; only send if
|
2083 |
// there are some messages to send.
|
2084 |
$body = NULL;
|
2085 |
if (!isset($dlog['mesg'])) : $dlog['mesg'] = array(); endif;
|
2086 |
-
|
2087 |
foreach ($dlog['mesg'] as $sect => $mesgs) :
|
2088 |
if (count($mesgs) > 0) :
|
2089 |
if (is_null($body)) : $body = ''; endif;
|
2090 |
-
|
2091 |
$paradigm = reset($mesgs);
|
2092 |
$body .= "<h2>".ucfirst($sect)." issues</h2>\n"
|
2093 |
."<table>\n"
|
@@ -2097,7 +2379,7 @@ class FeedWordPress {
|
|
2097 |
endforeach;
|
2098 |
$body .= "</tr></thead>\n"
|
2099 |
."<tbody>\n";
|
2100 |
-
|
2101 |
foreach ($mesgs as $line) :
|
2102 |
$body .= "<tr>\n";
|
2103 |
foreach ($line as $col => $cell) :
|
@@ -2109,11 +2391,11 @@ class FeedWordPress {
|
|
2109 |
endforeach;
|
2110 |
$body .= "</tr>\n";
|
2111 |
endforeach;
|
2112 |
-
|
2113 |
$body .= "</tbody>\n</table>\n\n";
|
2114 |
endif;
|
2115 |
endforeach;
|
2116 |
-
|
2117 |
$body = apply_filters('feedwordpress_diagnostic_email_body', $body, $dlog);
|
2118 |
if (!is_null($body)) :
|
2119 |
$home = feedwordpress_display_url(get_bloginfo('url'));
|
@@ -2148,12 +2430,12 @@ EOMAIL;
|
|
2148 |
// e-mail address
|
2149 |
if (preg_match('/^mailto:(.*)$/', $ded, $ref)) :
|
2150 |
$recipients = array($ref[1]);
|
2151 |
-
|
2152 |
// userid
|
2153 |
elseif (preg_match('/^user:(.*)$/', $ded, $ref)) :
|
2154 |
$userdata = get_userdata((int) $ref[1]);
|
2155 |
$recipients = array($userdata->user_email);
|
2156 |
-
|
2157 |
// admins
|
2158 |
else :
|
2159 |
$recipients = FeedWordPressDiagnostic::admin_emails();
|
@@ -2176,17 +2458,17 @@ EOMAIL;
|
|
2176 |
endif;
|
2177 |
$head = apply_filters('feedwordpress_diagnostic_email_headers', $head);
|
2178 |
|
2179 |
-
foreach ($recipients as $email) :
|
2180 |
add_filter('wp_mail_content_type', array('FeedWordPress', 'allow_html_mail'));
|
2181 |
wp_mail($email, $subj, $body, $head);
|
2182 |
remove_filter('wp_mail_content_type', array('FeedWordPress', 'allow_html_mail'));
|
2183 |
endforeach;
|
2184 |
endif;
|
2185 |
-
|
2186 |
// Clear the logs
|
2187 |
$dlog['mesg']['persistent'] = array();
|
2188 |
$dlog['mesg']['occurrent'] = array();
|
2189 |
-
|
2190 |
// Set schedule for next update
|
2191 |
$dlog['schedule']['last'] = time();
|
2192 |
endif;
|
@@ -2196,22 +2478,22 @@ EOMAIL;
|
|
2196 |
'last' => time(),
|
2197 |
);
|
2198 |
endif;
|
2199 |
-
|
2200 |
update_option('feedwordpress_diagnostics_log', $dlog);
|
2201 |
} /* FeedWordPress::email_diagnostic_log () */
|
2202 |
-
|
2203 |
-
function allow_html_mail () {
|
2204 |
return 'text/html';
|
2205 |
} /* FeedWordPress::allow_html_mail () */
|
2206 |
|
2207 |
-
function admin_footer () {
|
2208 |
global $feedwordpress_admin_footer;
|
2209 |
foreach ($feedwordpress_admin_footer as $line) :
|
2210 |
echo '<div><pre>'.$line.'</pre></div>';
|
2211 |
endforeach;
|
2212 |
} /* FeedWordPress::admin_footer () */
|
2213 |
-
|
2214 |
-
function log_prefix ($date = false) {
|
2215 |
$home = get_bloginfo('url');
|
2216 |
$prefix = '['.feedwordpress_display_url($home).'] [feedwordpress] ';
|
2217 |
if ($date) :
|
@@ -2219,8 +2501,8 @@ EOMAIL;
|
|
2219 |
endif;
|
2220 |
return $prefix;
|
2221 |
} /* FeedWordPress::log_prefix () */
|
2222 |
-
|
2223 |
-
function menu_cap ($sub = false) {
|
2224 |
if ($sub) :
|
2225 |
$cap = apply_filters('feedwordpress_menu_settings_capacity', 'manage_options');
|
2226 |
else :
|
@@ -2228,26 +2510,29 @@ EOMAIL;
|
|
2228 |
endif;
|
2229 |
return $cap;
|
2230 |
} /* FeedWordPress::menu_cap () */
|
2231 |
-
|
2232 |
-
function path ($filename = '') {
|
2233 |
global $fwp_path;
|
2234 |
-
|
2235 |
$path = $fwp_path;
|
2236 |
if (strlen($filename) > 0) :
|
2237 |
$path .= '/'.$filename;
|
2238 |
endif;
|
2239 |
return $path;
|
2240 |
-
}
|
2241 |
-
|
2242 |
// These are superceded by MyPHP::param/post/get/request, but kept
|
2243 |
// here for backward compatibility.
|
2244 |
-
|
|
|
2245 |
return MyPHP::param($key, $default, $type);
|
2246 |
-
}
|
2247 |
-
|
|
|
2248 |
return MyPHP::post($key, $default);
|
2249 |
-
}
|
2250 |
-
|
|
|
2251 |
|
2252 |
$feedwordpress_admin_footer = array();
|
2253 |
|
3 |
Plugin Name: FeedWordPress
|
4 |
Plugin URI: http://feedwordpress.radgeek.com/
|
5 |
Description: simple and flexible Atom/RSS syndication for WordPress
|
6 |
+
Version: 2014.0805
|
7 |
Author: Charles Johnson
|
8 |
Author URI: http://radgeek.com/
|
9 |
License: GPL
|
11 |
|
12 |
/**
|
13 |
* @package FeedWordPress
|
14 |
+
* @version 2014.0805
|
15 |
*/
|
16 |
|
17 |
# This uses code derived from:
|
27 |
# USAGE: once FeedWordPress is installed, you manage just about everything from
|
28 |
# the WordPress Dashboard, under the Syndication menu. To keep fresh content
|
29 |
# coming in as it becomes available, you'll have to either check for updates
|
30 |
+
# manually, or set up one of the automatically-scheduled update methods. See
|
31 |
# <http://feedwordpress.radgeek.com/wiki/quick-start/> for some details.
|
32 |
|
33 |
# -- Don't change these unless you know what you're doing...
|
34 |
|
35 |
+
define ('FEEDWORDPRESS_VERSION', '2014.0805');
|
36 |
define ('FEEDWORDPRESS_AUTHOR_CONTACT', 'http://radgeek.com/contact');
|
37 |
|
38 |
if (!defined('FEEDWORDPRESS_BLEG')) :
|
39 |
define ('FEEDWORDPRESS_BLEG', true);
|
40 |
endif;
|
41 |
+
define('FEEDWORDPRESS_BLEG_BTC', '1FN3Q4VSR4jV7unRjaknVQVe5ky88ktPHS');
|
42 |
|
43 |
// Defaults
|
44 |
define ('DEFAULT_SYNDICATION_CATEGORY', 'Contributors');
|
71 |
// Help us to pick out errors, if any.
|
72 |
ini_set('error_reporting', E_ALL & ~E_NOTICE);
|
73 |
ini_set('display_errors', true);
|
74 |
+
|
75 |
// When testing we don't want cache issues to interfere. But this is
|
76 |
+
// a VERY BAD SETTING for a production server. Webmasters will eat your
|
77 |
// face for breakfast if you use it, and the baby Jesus will cry. So
|
78 |
// make sure FEEDWORDPRESS_DEBUG is FALSE for any site that will be
|
79 |
// used for more than testing purposes!
|
102 |
require_once (ABSPATH . WPINC . '/registration.php'); // for wp_insert_user
|
103 |
endif;
|
104 |
|
105 |
+
$dir = dirname(__FILE__);
|
106 |
require_once("${dir}/externals/myphp/myphp.class.php");
|
107 |
require_once("${dir}/admin-ui.php");
|
108 |
require_once("${dir}/feedwordpresssyndicationpage.class.php");
|
109 |
+
require_once("${dir}/compatability.php"); // Legacy API
|
110 |
require_once("${dir}/syndicatedpost.class.php");
|
111 |
require_once("${dir}/syndicatedlink.class.php");
|
112 |
require_once("${dir}/feedwordpresshtml.class.php");
|
142 |
$fwp_path = 'feedwordpress';
|
143 |
endif;
|
144 |
|
145 |
+
$feedwordpress = new FeedWordPress;
|
146 |
+
if (!$feedwordpress->needs_upgrade()) : // only work if the conditions are safe!
|
147 |
|
148 |
# Syndicated items are generally received in output-ready (X)HTML and
|
149 |
# should not be folded, crumpled, mutilated, or spindled by WordPress
|
160 |
|
161 |
add_filter('the_content', 'feedwordpress_preserve_syndicated_content', -10000);
|
162 |
add_filter('the_content', 'feedwordpress_restore_syndicated_content', 10000);
|
163 |
+
|
164 |
add_action('atom_entry', 'feedwordpress_item_feed_data');
|
165 |
+
|
166 |
# Filter in original permalinks if the user wants that
|
167 |
add_filter('post_link', 'syndication_permalink', /*priority=*/ 1, /*arguments=*/ 3);
|
168 |
add_filter('post_type_link', 'syndication_permalink', /*priority=*/ 1, /*arguments=*/ 4);
|
169 |
+
|
170 |
# When foreign URLs are used for permalinks in feeds or display
|
171 |
# contexts, they need to be escaped properly.
|
172 |
add_filter('the_permalink', 'syndication_permalink_escaped');
|
173 |
add_filter('the_permalink_rss', 'syndication_permalink_escaped');
|
174 |
+
|
175 |
add_filter('post_comments_feed_link', 'syndication_comments_feed_link');
|
176 |
|
177 |
# WTF? By default, wp_insert_link runs incoming link_url and link_rss
|
180 |
# happens to fuck up any URI with a & to separate GET parameters.
|
181 |
remove_filter('pre_link_rss', 'wp_filter_kses');
|
182 |
remove_filter('pre_link_url', 'wp_filter_kses');
|
183 |
+
|
184 |
# Admin menu
|
185 |
+
add_action('admin_init', array($feedwordpress, 'admin_init'));
|
186 |
add_action('admin_menu', 'fwp_add_pages');
|
187 |
add_action('admin_notices', 'fwp_check_debug');
|
188 |
|
189 |
add_action('admin_menu', 'feedwordpress_add_post_edit_controls');
|
190 |
add_action('save_post', 'feedwordpress_save_post_edit_controls');
|
191 |
|
192 |
+
add_action('admin_footer', array($feedwordpress, 'admin_footer'));
|
193 |
+
|
194 |
# Inbound XML-RPC update methods
|
195 |
$feedwordpressRPC = new FeedWordPressRPC;
|
196 |
|
208 |
|
209 |
add_action('wp_footer', 'debug_out_feedwordpress_footer', -100);
|
210 |
add_action('admin_footer', 'debug_out_feedwordpress_footer', -100);
|
|
|
|
|
211 |
|
212 |
# Cron-less auto-update. Hooray!
|
213 |
$autoUpdateHook = $feedwordpress->automatic_update_hook();
|
214 |
if (!is_null($autoUpdateHook)) :
|
215 |
add_action($autoUpdateHook, array($feedwordpress, 'auto_update'));
|
216 |
endif;
|
217 |
+
|
218 |
add_action('init', array($feedwordpress, 'init'));
|
219 |
add_action('shutdown', array($feedwordpress, 'email_diagnostic_log'));
|
220 |
+
add_action('shutdown', array($feedwordpress, 'feedwordpress_cleanup'));
|
221 |
add_action('wp_dashboard_setup', array($feedwordpress, 'dashboard_setup'));
|
222 |
|
223 |
# Default sanitizers
|
224 |
add_filter('syndicated_item_content', array('SyndicatedPost', 'resolve_relative_uris'), 0, 2);
|
225 |
add_filter('syndicated_item_content', array('SyndicatedPost', 'sanitize_content'), 0, 2);
|
226 |
|
227 |
+
add_action('plugins_loaded', array($feedwordpress, 'admin_api'));
|
228 |
+
add_action('all_admin_notices', array($feedwordpress, 'all_admin_notices'));
|
229 |
+
|
230 |
else :
|
231 |
# Hook in the menus, which will just point to the upgrade interface
|
232 |
add_action('admin_menu', 'fwp_add_pages');
|
241 |
$wpError = $error['object'];
|
242 |
$url = $link->uri();
|
243 |
|
244 |
+
// check for effects of an effective-url filter
|
245 |
+
$effectiveUrl = $link->uri(array('fetch' => true));
|
246 |
+
if ($url != $effectiveUrl) : $url .= ' | ' . $effectiveUrl; endif;
|
247 |
+
|
248 |
$mesgs = $wpError->get_error_messages();
|
249 |
foreach ($mesgs as $mesg) :
|
250 |
$mesg = esc_html($mesg);
|
252 |
'updated_feeds:errors',
|
253 |
"Feed Error: [${url}] update returned error: $mesg"
|
254 |
);
|
255 |
+
|
256 |
$hours = get_option('feedwordpress_diagnostics_persistent_errors_hours', 2);
|
257 |
$span = ($error['ts'] - $error['since']);
|
258 |
|
318 |
* displaying a post.
|
319 |
*
|
320 |
* @param int $id The post to check for syndicated status. Defaults to the current post in a Loop context.
|
321 |
+
* @return bool TRUE if the post's meta-data indicates it was syndicated; FALSE otherwise
|
322 |
+
*/
|
323 |
function is_syndicated ($id = NULL) {
|
324 |
$p = new FeedWordPressLocalPost($id);
|
325 |
return $p->is_syndicated();
|
327 |
|
328 |
function feedwordpress_display_url ($url, $before = 60, $after = 0) {
|
329 |
$bits = parse_url($url);
|
330 |
+
|
331 |
// Strip out crufty subdomains
|
332 |
if (isset($bits['host'])) :
|
333 |
$bits['host'] = preg_replace('/^www[0-9]*\./i', '', $bits['host']);
|
334 |
endif;
|
335 |
+
|
336 |
// Reassemble bit-by-bit with minimum of crufty elements
|
337 |
$url = (isset($bits['user'])?$bits['user'].'@':'')
|
338 |
.(isset($bits['host'])?$bits['host']:'')
|
341 |
.(isset($bits['query'])?'?'.$bits['query']:'');
|
342 |
|
343 |
if (strlen($url) > ($before+$after)) :
|
344 |
+
$url = substr($url, 0, $before).'.'.substr($url, 0 - $after, $after);
|
345 |
endif;
|
346 |
|
347 |
return $url;
|
440 |
*/
|
441 |
function get_local_permalink ($id = NULL) {
|
442 |
global $feedwordpress_the_original_permalink;
|
443 |
+
|
444 |
// get permalink, and thus activate filter and force global to be filled
|
445 |
// with original URL.
|
446 |
$url = get_permalink($id);
|
483 |
|
484 |
function feedwordpress_restore_syndicated_content ($text) {
|
485 |
global $feedwordpress_the_syndicated_content;
|
486 |
+
|
487 |
if ( !is_null($feedwordpress_the_syndicated_content) ) :
|
488 |
$text = $feedwordpress_the_syndicated_content;
|
489 |
endif;
|
538 |
function syndication_permalink ($permalink = '', $post = null, $leavename = false, $sample = false) {
|
539 |
global $id;
|
540 |
global $feedwordpress_the_original_permalink;
|
541 |
+
|
542 |
// Save the local permalink in case we need to retrieve it later.
|
543 |
$feedwordpress_the_original_permalink = $permalink;
|
544 |
|
588 |
$permalink = esc_html($permalink);
|
589 |
endif;
|
590 |
return $permalink;
|
591 |
+
} /* function syndication_permalink_escaped() */
|
592 |
|
593 |
/**
|
594 |
* syndication_comments_feed_link: Escape XML special characters in comments
|
595 |
+
* feed links
|
596 |
*
|
597 |
* @param string $link
|
598 |
* @return string
|
609 |
// that value here.
|
610 |
$source = get_syndication_feed_object();
|
611 |
$replacement = NULL;
|
612 |
+
|
613 |
if ($source->setting('munge comments feed links', 'munge_comments_feed_links', 'yes') != 'no') :
|
614 |
$commentFeeds = get_post_custom_values('wfw:commentRSS');
|
615 |
if (
|
618 |
and (strlen($commentFeeds[0]) > 0)
|
619 |
) :
|
620 |
$replacement = $commentFeeds[0];
|
621 |
+
|
622 |
// This is a foreign link; WordPress can't vouch for its not
|
623 |
// having any entities that need to be &-escaped. So we'll do it
|
624 |
// here.
|
625 |
$replacement = esc_html($replacement);
|
626 |
endif;
|
627 |
endif;
|
628 |
+
|
629 |
if (is_null($replacement)) :
|
630 |
// Q: How can we get the proper feed format, since the
|
631 |
// format is, stupidly, not passed to the filter?
|
649 |
// comments feed link is never munged by FWP.
|
650 |
endif;
|
651 |
endif;
|
652 |
+
|
653 |
if (!is_null($replacement)) : $link = $replacement; endif;
|
654 |
endif;
|
655 |
return $link;
|
661 |
|
662 |
function fwp_add_pages () {
|
663 |
global $feedwordpress;
|
664 |
+
|
665 |
$menu_cap = FeedWordPress::menu_cap();
|
666 |
$settings_cap = FeedWordPress::menu_cap(/*sub=*/ true);
|
667 |
$syndicationMenu = FeedWordPress::path('syndication.php');
|
668 |
+
|
669 |
add_menu_page(
|
670 |
'Syndicated Sites', 'Syndication',
|
671 |
$menu_cap,
|
715 |
$syndicationMenu, 'FeedWordPress Diagnostics', 'Diagnostics',
|
716 |
$settings_cap, FeedWordPress::path('diagnostics-page.php')
|
717 |
);
|
718 |
+
|
719 |
add_filter('page_row_actions', array($feedwordpress, 'row_actions'), 10, 2);
|
720 |
add_filter('post_row_actions', array($feedwordpress, 'row_actions'), 10, 2);
|
721 |
} /* function fwp_add_pages () */
|
786 |
do_action('xmlrpc_publish_post', $post_id);
|
787 |
if ( defined('APP_REQUEST') )
|
788 |
do_action('app_publish_post', $post_id);
|
789 |
+
|
790 |
if ( defined('WP_IMPORTING') )
|
791 |
return;
|
792 |
|
804 |
global $inspectPostMeta;
|
805 |
|
806 |
// Put in Manual Editing checkbox
|
807 |
+
add_action('add_meta_boxes', 'feedwordpress_post_add_meta_boxes', 10, 2);
|
808 |
|
809 |
add_filter('user_can_richedit', array($feedwordpress, 'user_can_richedit'), 1000, 1);
|
810 |
+
|
811 |
if (FeedWordPress::diagnostic_on('syndicated_posts:static_meta_data')) :
|
812 |
$inspectPostMeta = new InspectPostMeta;
|
813 |
endif;
|
814 |
+
} // function feedwordpress_add_post_edit_controls ()
|
815 |
+
|
816 |
+
function feedwordpress_post_add_meta_boxes ($post_type, $post) {
|
817 |
+
add_meta_box(
|
818 |
+
'feedwordpress-post-controls',
|
819 |
+
__('Syndication'),
|
820 |
+
'feedwordpress_post_edit_controls',
|
821 |
+
$post_type,
|
822 |
+
'side',
|
823 |
+
'high'
|
824 |
+
);
|
825 |
+
}
|
826 |
+
|
827 |
function feedwordpress_post_edit_controls () {
|
828 |
global $post;
|
829 |
+
|
830 |
$frozen_values = get_post_custom_values('_syndication_freeze_updates', $post->ID);
|
831 |
$frozen_post = (count($frozen_values) > 0 and 'yes' == $frozen_values[0]);
|
832 |
|
835 |
<p>This is a syndicated post, which originally appeared at
|
836 |
<cite><?php print esc_html(get_syndication_source(NULL, $post->ID)); ?></cite>.
|
837 |
<a href="<?php print esc_html(get_syndication_permalink($post->ID)); ?>">View original post</a>.</p>
|
838 |
+
|
839 |
+
<?php do_action('feedwordpress_post_edit_controls_pre', $post); ?>
|
840 |
|
841 |
<p><input type="hidden" name="feedwordpress_noncename" id="feedwordpress_noncename" value="<?php print wp_create_nonce(plugin_basename(__FILE__)); ?>" />
|
842 |
<label><input type="checkbox" name="freeze_updates" value="yes" <?php if ($frozen_post) : ?>checked="checked"<?php endif; ?> /> <strong>Manual editing.</strong>
|
843 |
If set, FeedWordPress will not overwrite the changes you make manually
|
844 |
to this post, if the syndicated content is updated on the
|
845 |
feed.</label></p>
|
846 |
+
|
847 |
+
<?php do_action('feedwordpress_post_edit_controls', $post); ?>
|
848 |
+
|
849 |
<?php
|
850 |
else :
|
851 |
?>
|
852 |
<p>This post was created locally at this website.</p>
|
853 |
<?php
|
854 |
endif;
|
855 |
+
} /* function feedwordpress_post_edit_controls () */
|
856 |
|
857 |
function feedwordpress_save_post_edit_controls ( $post_id ) {
|
858 |
global $post;
|
|
|
859 |
if (!isset($_POST['feedwordpress_noncename']) or !wp_verify_nonce($_POST['feedwordpress_noncename'], plugin_basename(__FILE__))) :
|
860 |
return $post_id;
|
861 |
endif;
|
862 |
+
|
863 |
// Verify if this is an auto save routine. If it is our form has
|
864 |
// not been submitted, so we don't want to do anything.
|
865 |
if ( defined('DOING_AUTOSAVE') and DOING_AUTOSAVE ) :
|
866 |
return $post_id;
|
867 |
endif;
|
868 |
+
|
869 |
+
// The data in $_POST is for applying only to the post actually
|
870 |
+
// in the edit window, i.e. $post
|
871 |
+
if ($post_id != $post->ID) :
|
872 |
+
return $post_id;
|
873 |
+
endif;
|
874 |
|
875 |
// Check permissions
|
876 |
+
$cap[0] = 'edit_post';
|
877 |
+
$cap[1] = 'edit_' . $_POST['post_type'];
|
878 |
+
if (
|
879 |
+
!current_user_can( $cap[0], $post_id )
|
880 |
+
and !current_user_can( $cap[1], $post_id )
|
881 |
+
) :
|
882 |
return $post_id;
|
883 |
endif;
|
884 |
|
885 |
// OK, we're golden. Now let's save some data.
|
886 |
if (isset($_POST['freeze_updates'])) :
|
887 |
+
|
888 |
update_post_meta($post_id, '_syndication_freeze_updates', $_POST['freeze_updates']);
|
889 |
$ret = $_POST['freeze_updates'];
|
890 |
+
|
891 |
+
// If you make manual edits through the WordPress editing
|
892 |
+
// UI then they should be run through normal WP formatting
|
893 |
+
// filters.
|
894 |
+
update_post_meta($post_id, '_feedwordpress_formatting_filters', 'yes');
|
895 |
+
|
896 |
else :
|
897 |
delete_post_meta($post_id, '_syndication_freeze_updates');
|
898 |
$ret = NULL;
|
899 |
endif;
|
900 |
+
|
901 |
+
do_action('feedwordpress_save_edit_controls', $post_id);
|
902 |
+
|
903 |
return $ret;
|
904 |
} // function feedwordpress_save_edit_controls
|
905 |
|
944 |
var $feeds = NULL;
|
945 |
var $feedurls = NULL;
|
946 |
var $httpauth = NULL;
|
947 |
+
|
948 |
+
/**
|
949 |
+
* FeedWordPress::__construct (): Construct FeedWordPress singleton object
|
950 |
+
* and retrieves a list of feeds for later reference.
|
951 |
+
*/
|
952 |
+
public function __construct () {
|
953 |
$this->feeds = array ();
|
954 |
$this->feedurls = array();
|
955 |
$links = FeedWordPress::syndicated_links();
|
956 |
if ($links): foreach ($links as $link):
|
957 |
$id = intval($link->link_id);
|
958 |
$url = $link->link_rss;
|
959 |
+
|
960 |
// Store for later reference.
|
961 |
$this->feeds[$id] = $id;
|
962 |
if (strlen($url) > 0) :
|
964 |
endif;
|
965 |
endforeach; endif;
|
966 |
|
967 |
+
add_filter('feedwordpress_update_complete', array($this, 'process_retirements'), 1000, 1);
|
968 |
+
|
969 |
$this->httpauth = new FeedWordPressHTTPAuthenticator;
|
970 |
+
} /* FeedWordPress::__construct () */
|
971 |
|
972 |
+
/**
|
973 |
+
* FeedWordPress::subscribed (): Check whether a feed is currently in the
|
974 |
+
* subscription list for FeedWordPress.
|
975 |
+
*
|
976 |
+
* @param mixed $id Numeric ID of a WordPress link object or URL of a feed
|
977 |
+
* @return bool TRUE if currently subscribed; FALSE otherwise.
|
978 |
+
*/
|
979 |
+
public function subscribed ($id) {
|
980 |
return (isset($this->feedurls[$id]) or isset($this->feeds[$id]));
|
981 |
} /* FeedWordPress::subscribed () */
|
982 |
+
|
983 |
+
/**
|
984 |
+
* FeedWordPress::subscription (): Get the SyndicatedLink object for a
|
985 |
+
* given URL or numeric ID, if we have either an active subscription to
|
986 |
+
* it; or a de-activated subscription.
|
987 |
+
*
|
988 |
+
* @param mixed $which Numeric ID for a WordPress link object or string URL for a feed
|
989 |
+
* @return mixed SyndicatedLink object if subscription is found; NULL if not
|
990 |
+
*/
|
991 |
+
public function subscription ($which) {
|
992 |
$sub = NULL;
|
993 |
+
|
994 |
if (is_string($which) and isset($this->feedurls[$which])) :
|
995 |
$which = $this->feedurls[$which];
|
996 |
endif;
|
997 |
+
|
998 |
if (isset($this->feeds[$which])) :
|
999 |
$sub = $this->feeds[$which];
|
1000 |
endif;
|
1012 |
$this->feeds[$which] = $link;
|
1013 |
$sub = $link;
|
1014 |
endif;
|
1015 |
+
|
1016 |
return $sub;
|
1017 |
} /* FeedWordPress::subscription () */
|
1018 |
+
|
1019 |
# function update (): polls for updates on one or more Contributor feeds
|
1020 |
#
|
1021 |
# Arguments:
|
1061 |
# (between 30 minutes and 2 hours).
|
1062 |
#
|
1063 |
# * New posts from the polled feed are added to the WordPress store.
|
1064 |
+
#
|
1065 |
# * Updates to existing posts since the last poll are mirrored in the
|
1066 |
# WordPress store.
|
1067 |
#
|
1068 |
+
public function update ($uri = null, $crash_ts = null) {
|
1069 |
global $wpdb;
|
1070 |
|
1071 |
if (FeedWordPress::needs_upgrade()) : // Will make duplicate posts if we don't hold off
|
1072 |
return NULL;
|
1073 |
endif;
|
1074 |
+
|
1075 |
if (!is_null($uri) and $uri != '*') :
|
1076 |
$uri = trim($uri);
|
1077 |
else : // Update all
|
1090 |
if (is_null($crash_ts)) :
|
1091 |
$crash_ts = $this->crash_ts();
|
1092 |
endif;
|
1093 |
+
|
1094 |
// Randomize order for load balancing purposes
|
1095 |
$feed_set = array_keys($this->feeds);
|
1096 |
shuffle($feed_set);
|
1107 |
), $uri);
|
1108 |
|
1109 |
$feed_set = apply_filters('feedwordpress_update_feeds', $feed_set, $uri);
|
1110 |
+
|
1111 |
+
|
1112 |
// Loop through and check for new posts
|
1113 |
$delta = NULL; $remaining = $max_polls;
|
1114 |
foreach ($feed_set as $feed_id) :
|
1119 |
if (
|
1120 |
// Over time limit?
|
1121 |
(!is_null($crash_ts) and (time() > $crash_ts))
|
1122 |
+
|
1123 |
// Over feed count?
|
1124 |
+
or ($remaining == 0)
|
1125 |
) :
|
1126 |
break;
|
1127 |
endif;
|
1128 |
+
|
1129 |
$pinged_that = (is_null($uri) or ($uri=='*') or in_array($uri, array($feed->uri(), $feed->homepage())));
|
1130 |
|
1131 |
if (!is_null($uri)) : // A site-specific ping always updates
|
1134 |
$timely = $feed->stale();
|
1135 |
endif;
|
1136 |
|
1137 |
+
// If at least one feed was hit for updating...
|
1138 |
+
if ($pinged_that and is_null($delta)) :
|
1139 |
+
// ... don't return error condition
|
1140 |
+
$delta = array('new' => 0, 'updated' => 0, 'stored' => 0);
|
1141 |
endif;
|
1142 |
|
1143 |
if ($pinged_that and $timely) :
|
1149 |
do_action('feedwordpress_check_feed_complete', $feed->settings, $added, time() - $start_ts);
|
1150 |
|
1151 |
if (is_array($added)) : // Success
|
1152 |
+
foreach ($added as $key => $count) :
|
1153 |
+
$delta[$key] += $added[$key];
|
1154 |
+
endforeach;
|
1155 |
endif;
|
1156 |
endif;
|
1157 |
endforeach;
|
1158 |
|
1159 |
do_action('feedwordpress_update_complete', $delta);
|
|
|
1160 |
return $delta;
|
1161 |
+
} /* FeedWordPress::update () */
|
1162 |
|
1163 |
+
public function crash_ts ($default = NULL) {
|
1164 |
$crash_dt = (int) get_option('feedwordpress_update_time_limit', 0);
|
1165 |
if ($crash_dt > 0) :
|
1166 |
$crash_ts = time() + $crash_dt;
|
1168 |
$crash_ts = $default;
|
1169 |
endif;
|
1170 |
return $crash_ts;
|
1171 |
+
} /* FeedWordPress::crash_ts () */
|
1172 |
+
|
1173 |
+
public function secret_key () {
|
1174 |
$secret = get_option('feedwordpress_secret_key', false);
|
1175 |
if (!$secret) : // Generate random key.
|
1176 |
$secret = substr(md5(uniqid(microtime())), 0, 6);
|
1177 |
update_option('feedwordpress_secret_key', $secret);
|
1178 |
endif;
|
1179 |
return $secret;
|
1180 |
+
} /* FeedWordPress::secret_key () */
|
1181 |
+
|
1182 |
+
public function has_secret () {
|
1183 |
+
return (MyPHP::request('feedwordpress_key')==$this->secret_key());
|
1184 |
+
} /* FeedWordPress::has_secret () */
|
1185 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1186 |
var $update_hooked = NULL;
|
1187 |
+
public function automatic_update_hook ($params = array()) {
|
1188 |
$params = wp_parse_args($params, array( // Defaults
|
1189 |
'setting only' => false,
|
1190 |
));
|
1195 |
if (
|
1196 |
!$params['setting only']
|
1197 |
and $this->has_secret()
|
1198 |
+
and MyPHP::request('automatic_update')
|
1199 |
) :
|
1200 |
+
$hook = MyPHP::request('automatic_update');
|
1201 |
$method = 'URL parameter';
|
1202 |
endif;
|
1203 |
+
|
1204 |
$exact = $hook; // Before munging
|
1205 |
+
|
1206 |
if (!!$hook) :
|
1207 |
if ($hook != 'init') : // Constrain values.
|
1208 |
$hook = 'shutdown';
|
1209 |
endif;
|
1210 |
endif;
|
1211 |
+
|
1212 |
if ($hook) :
|
1213 |
$this->update_hooked = "Initiating an AUTOMATIC CHECK FOR UPDATES ON PAGE LOAD ".$hook." due to ".$method." = ".trim($this->val($exact));
|
1214 |
endif;
|
1215 |
+
|
1216 |
+
return $hook;
|
1217 |
+
} /* FeedWordPress::automatic_update_hook () */
|
1218 |
+
|
1219 |
+
public function last_update_all () {
|
1220 |
$last = get_option('feedwordpress_last_update_all');
|
1221 |
+
if ($this->has_secret() and MyPHP::request('automatic_update')) :
|
1222 |
$last = 1; // A long, long time ago.
|
1223 |
+
elseif ($this->has_secret() and MyPHP::request('last_update_all')) :
|
1224 |
+
$last = MyPHP::request('last_update_all');
|
1225 |
endif;
|
1226 |
return $last;
|
1227 |
+
} /* FeedWordPress::last_update_all () */
|
1228 |
+
|
1229 |
+
public function force_update_all () {
|
1230 |
+
return ($this->has_secret() and MyPHP::request('force_update_feeds'));
|
1231 |
+
} /* FeedWordPress::force_update_all () */
|
1232 |
+
|
1233 |
+
public function stale () {
|
1234 |
if (!is_null($this->automatic_update_hook())) :
|
1235 |
// Do our best to avoid possible simultaneous
|
1236 |
// updates by getting up-to-the-minute settings.
|
1237 |
+
|
1238 |
$last = $this->last_update_all();
|
1239 |
+
|
1240 |
// If we haven't updated all yet, give it a time window
|
1241 |
if (false === $last) :
|
1242 |
$ret = false;
|
1243 |
update_option('feedwordpress_last_update_all', time());
|
1244 |
+
|
1245 |
// Otherwise, check against freshness interval
|
1246 |
elseif (is_numeric($last)) : // Expect a timestamp
|
1247 |
$freshness = get_option('feedwordpress_freshness');
|
1249 |
$freshness = FEEDWORDPRESS_FRESHNESS_INTERVAL;
|
1250 |
endif;
|
1251 |
$ret = ( (time() - $last) > $freshness );
|
1252 |
+
|
1253 |
// This should never happen.
|
1254 |
else :
|
1255 |
FeedWordPress::critical_bug('FeedWordPress::stale::last', $last, __LINE__, __FILE__);
|
1259 |
$ret = false;
|
1260 |
endif;
|
1261 |
return $ret;
|
1262 |
+
} /* FeedWordPress::stale() */
|
1263 |
|
1264 |
static function admin_init () {
|
1265 |
// WordPress 3.5+ compat: the WP devs are in the midst of removing Links from the WordPress core. Eventually we'll have to deal
|
1268 |
if (!intval(get_option('link_manager_enabled', false))) :
|
1269 |
update_option('link_manager_enabled', true);
|
1270 |
endif;
|
1271 |
+
|
1272 |
+
if (defined('FEEDWORDPRESS_PREPARE_TO_ZAP') and FEEDWORDPRESS_PREPARE_TO_ZAP) :
|
1273 |
+
$post_id = FEEDWORDPRESS_PREPARE_TO_ZAP;
|
1274 |
+
$sendback = wp_get_referer();
|
1275 |
+
if (
|
1276 |
+
! $sendback
|
1277 |
+
or strpos( $sendback, 'post.php' ) !== false
|
1278 |
+
or strpos( $sendback, 'post-new.php' ) !== false
|
1279 |
+
) :
|
1280 |
+
if ( 'attachment' == $post_type ) :
|
1281 |
+
$sendback = admin_url( 'upload.php' );
|
1282 |
+
else :
|
1283 |
+
$sendback = admin_url( 'edit.php' );
|
1284 |
+
$sendback .= ( ! empty( $post_type ) ) ? '?post_type=' . $post_type : '';
|
1285 |
+
endif;
|
1286 |
+
else :
|
1287 |
+
$sendback = remove_query_arg( array('trashed', 'untrashed', 'deleted', 'zapped', 'unzapped', 'ids'), $sendback );
|
1288 |
+
endif;
|
1289 |
+
|
1290 |
+
// Make sure we have a post corresponding to this ID.
|
1291 |
+
$post = $post_type = $post_type_object = null;
|
1292 |
+
if ( $post_id ) :
|
1293 |
+
$post = get_post( $post_id );
|
1294 |
+
endif;
|
1295 |
+
|
1296 |
+
if ( $post ) :
|
1297 |
+
$post_type = $post->post_type;
|
1298 |
+
endif;
|
1299 |
+
$p = get_post($post_id);
|
1300 |
+
|
1301 |
+
if ( ! $post ) :
|
1302 |
+
wp_die( __( 'The item you are trying to zap no longer exists.' ) );
|
1303 |
+
endif;
|
1304 |
+
|
1305 |
+
if ( ! current_user_can( 'delete_post', $post_id ) ) :
|
1306 |
+
wp_die( __( 'You are not allowed to zap this item.' ) );
|
1307 |
+
endif;
|
1308 |
+
|
1309 |
+
if ( $user_id = wp_check_post_lock( $post_id ) ) :
|
1310 |
+
$user = get_userdata( $user_id );
|
1311 |
+
wp_die( sprintf( __( 'You cannot retire this item. %s is currently editing.' ), $user->display_name ) );
|
1312 |
+
endif;
|
1313 |
+
|
1314 |
+
if (MyPHP::request('fwp_post_delete')=='zap') :
|
1315 |
+
FeedWordPress::diagnostic('syndicated_posts', 'Zapping existing post # '.$p->ID.' "'.$p->post_title.'" due to user request.');
|
1316 |
+
|
1317 |
+
$old_status = $post->post_status;
|
1318 |
+
|
1319 |
+
set_post_field('post_status', 'fwpzapped', $post_id);
|
1320 |
+
wp_transition_post_status('fwpzapped', $old_status, $post);
|
1321 |
+
|
1322 |
+
# Set up the post to have its content blanked on
|
1323 |
+
# next update if you do not undo the zapping.
|
1324 |
+
add_post_meta($post_id, '_feedwordpress_zapped_blank_me', 1, /*unique=*/ true);
|
1325 |
+
add_post_meta($post_id, '_feedwordpress_zapped_blank_old_status', $old_status, /*unique=*/ true);
|
1326 |
+
|
1327 |
+
wp_redirect( add_query_arg( array('zapped' => 1, 'ids' => $post_id), $sendback ) );
|
1328 |
+
|
1329 |
+
else :
|
1330 |
+
$old_status = get_post_meta($post_id, '_feedwordpress_zapped_blank_old_status', /*single=*/ true);
|
1331 |
+
|
1332 |
+
set_post_field('post_status', $old_status, $post_id);
|
1333 |
+
wp_transition_post_status($old_status, 'fwpzapped', $post);
|
1334 |
+
|
1335 |
+
# O.K., make sure this post does not get blanked
|
1336 |
+
delete_post_meta($post_id, '_feedwordpress_zapped_blank_me');
|
1337 |
+
delete_post_meta($post_id, '_feedwordpress_zapped_blank_old_status');
|
1338 |
+
|
1339 |
+
wp_redirect( add_query_arg( array('unzapped' => 1, 'ids' => $post_id), $sendback ) );
|
1340 |
+
|
1341 |
+
endif;
|
1342 |
+
|
1343 |
+
// Intercept, don't pass on.
|
1344 |
+
exit;
|
1345 |
+
endif;
|
1346 |
} /* FeedWordPress::admin_init() */
|
1347 |
|
1348 |
+
public function admin_api () {
|
1349 |
// This sucks, but WordPress doesn't give us any other way to
|
1350 |
// easily invoke a permanent-delete from a plugged in post
|
1351 |
// actions link. So we create a magic parameter, and when this
|
1352 |
// magic parameter is activated, the WordPress trashcan is
|
1353 |
// temporarily de-activated.
|
1354 |
+
|
1355 |
if (MyPHP::request('fwp_post_delete')=='nuke') :
|
1356 |
// Get post ID #
|
1357 |
$post_id = MyPHP::request('post');
|
1358 |
if (!$post_id) :
|
1359 |
$post_id = MyPHP::request('post_ID');
|
1360 |
endif;
|
1361 |
+
|
1362 |
// Make sure we've got the right nonce and all that.
|
1363 |
check_admin_referer('delete-post_' . $post_id);
|
1364 |
+
|
1365 |
// If so, disable the trashcan.
|
1366 |
define('EMPTY_TRASH_DAYS', 0);
|
1367 |
+
|
1368 |
+
elseif (MyPHP::request('fwp_post_delete')=='zap' OR MyPHP::request('fwp_post_delete') == 'unzap') :
|
1369 |
+
// Get post ID #
|
1370 |
+
$post_id = MyPHP::request('post');
|
1371 |
+
if (!$post_id) :
|
1372 |
+
$post_id = MyPHP::request('post_ID');
|
1373 |
+
endif;
|
1374 |
+
|
1375 |
+
// Make sure we've got the right nonce and all that
|
1376 |
+
check_admin_referer('delete-post_' . $post_id);
|
1377 |
+
|
1378 |
+
// If so, get ready to intercept the call a little
|
1379 |
+
// further down the line.
|
1380 |
+
|
1381 |
+
define('FEEDWORDPRESS_PREPARE_TO_ZAP', $post_id);
|
1382 |
+
|
1383 |
+
endif;
|
1384 |
+
|
1385 |
+
} /* FeedWordPress::admin_api () */
|
1386 |
+
|
1387 |
+
public function all_admin_notices () {
|
1388 |
+
if (MyPHP::request('zapped')) :
|
1389 |
+
$n = intval(MyPHP::request('zapped'));
|
1390 |
+
?>
|
1391 |
+
<div id="message" class="updated"><p><?php print $n; ?> syndicated item<?php print ($n!=1?'s':''); ?> zapped. <strong>These items will not be re-syndicated.</strong> If this was a mistake, you must <strong>immediately</strong> Un-Zap them in the Zapped items section to avoid losing the data.</p></div>
|
1392 |
+
<?php
|
1393 |
+
endif;
|
1394 |
+
|
1395 |
+
if (MyPHP::request('unzapped')) :
|
1396 |
+
$n = intval(MyPHP::request('unzapped'));
|
1397 |
+
?>
|
1398 |
+
<div id="message" class="updated"><p><?php print $n; ?> syndicated item<?php print ($n!=1?'s':'') ?> un-zapped and restored to normal.</p></div>
|
1399 |
+
<?php
|
1400 |
endif;
|
1401 |
+
} /* FeedWordPress::all_admin_notices () */
|
1402 |
+
|
1403 |
+
public function process_retirements ($delta) {
|
1404 |
+
update_option('feedwordpress_process_zaps', 1);
|
1405 |
|
1406 |
+
return $delta;
|
1407 |
}
|
1408 |
+
|
1409 |
+
public function feedwordpress_cleanup () {
|
1410 |
+
if (get_option('feedwordpress_process_zaps', null)) :
|
1411 |
+
$q = new WP_Query(array(
|
1412 |
+
'fields' => '_synfrom',
|
1413 |
+
'post_status' => 'fwpzapped',
|
1414 |
+
'ignore_sticky_posts' => true,
|
1415 |
+
'meta_key' => '_feedwordpress_zapped_blank_me',
|
1416 |
+
'meta_value' => 1,
|
1417 |
+
));
|
1418 |
+
|
1419 |
+
if ($q->have_posts()) :
|
1420 |
+
foreach ($q->posts as $p) :
|
1421 |
|
1422 |
+
$post_id = $p->ID;
|
1423 |
+
$revisions = wp_get_post_revisions($post_id, array("check_enabled" => false));
|
1424 |
+
|
1425 |
+
# Now nuke the content of the post & its revisions
|
1426 |
+
set_post_field('post_content', '', $post_id);
|
1427 |
+
set_post_field('post_excerpt', '', $post_id);
|
1428 |
+
|
1429 |
+
foreach ($revisions as $rev) :
|
1430 |
+
set_post_field('post_content', '', $rev->ID);
|
1431 |
+
set_post_field('post_excerpt', '', $rev->ID);
|
1432 |
+
endforeach;
|
1433 |
+
|
1434 |
+
# Un-tag it for blanking.
|
1435 |
+
delete_post_meta($p->ID, '_feedwordpress_zapped_blank_me');
|
1436 |
+
|
1437 |
+
# Don't remove old_status indicator. A later
|
1438 |
+
# update from the feed may cause us to once
|
1439 |
+
# again have some content so we can un-zap.
|
1440 |
+
|
1441 |
+
endforeach;
|
1442 |
+
endif;
|
1443 |
+
|
1444 |
+
$q = new WP_Query(array(
|
1445 |
+
'fields' => '_synfrom',
|
1446 |
+
'post_status' => 'fwpzapped',
|
1447 |
+
'ignore_sticky_posts' => true,
|
1448 |
+
'meta_key' => '_feedwordpress_zapped_blank_me',
|
1449 |
+
'meta_value' => 2,
|
1450 |
+
));
|
1451 |
+
|
1452 |
+
if ($q->have_posts()) :
|
1453 |
+
foreach ($q->posts as $p) :
|
1454 |
+
update_post_meta($p->ID, '_feedwordpress_zapped_blank_me', 1);
|
1455 |
+
endforeach;
|
1456 |
+
endif;
|
1457 |
+
|
1458 |
+
update_option('feedwordpress_process_zaps', 0);
|
1459 |
+
endif;
|
1460 |
+
} /* FeedWordPress::feedwordpress_cleanup () */
|
1461 |
+
|
1462 |
+
public function init () {
|
1463 |
global $fwp_path;
|
1464 |
+
|
1465 |
// If this is a FeedWordPress admin page, queue up scripts for AJAX
|
1466 |
// functions that FWP uses. If it is a display page or a non-FWP admin
|
1467 |
// page, don't.
|
1469 |
if (FeedWordPressSettingsUI::is_admin()) :
|
1470 |
// For JavaScript that needs to be generated dynamically
|
1471 |
add_action('admin_print_scripts', array('FeedWordPressSettingsUI', 'admin_scripts'));
|
1472 |
+
|
1473 |
// For CSS that needs to be generated dynamically.
|
1474 |
add_action('admin_print_styles', array('FeedWordPressSettingsUI', 'admin_styles'));
|
1475 |
+
|
1476 |
wp_enqueue_style('dashboard');
|
1477 |
wp_enqueue_style('feedwordpress-elements');
|
1478 |
+
|
1479 |
/*if (function_exists('wp_admin_css')) :
|
1480 |
wp_admin_css('css/dashboard');
|
1481 |
endif;*/
|
1482 |
endif;
|
1483 |
|
1484 |
+
// These are a special post statuses for hiding posts that have
|
1485 |
+
// expired from the feed or been marked for permanent zapping by
|
1486 |
+
// the FWP admin.
|
1487 |
register_post_status('fwpretired', array(
|
1488 |
'label' => _x('Retired', 'post'),
|
1489 |
'label_count' => _n_noop('Retired <span class="count">(%s)</span>', 'Retired <span class="count">(%s)</span>'),
|
1493 |
'show_in_admin_all_list' => false,
|
1494 |
'show_in_admin_status_list' => true,
|
1495 |
));
|
1496 |
+
register_post_status('fwpzapped', array(
|
1497 |
+
'label' => _x('Zapped', 'post'),
|
1498 |
+
'label_count' => _n_noop('Zapped <span class="count">(%s)</span>', 'Retired <span class="count">(%s)</span>'),
|
1499 |
+
'exclude_from_search' => true,
|
1500 |
+
'public' => false,
|
1501 |
+
'publicly_queryable' => false,
|
1502 |
+
'show_in_admin_all_list' => false,
|
1503 |
+
'show_in_admin_status_list' => true,
|
1504 |
+
));
|
1505 |
add_action(
|
1506 |
/*hook=*/ 'template_redirect',
|
1507 |
/*function=*/ array($this, 'redirect_retired'),
|
1511 |
add_action('wp_ajax_fwp_feeds', array($this, 'fwp_feeds'));
|
1512 |
add_action('wp_ajax_fwp_feedcontents', array($this, 'fwp_feedcontents'));
|
1513 |
add_action('wp_ajax_fwp_xpathtest', array($this, 'fwp_xpathtest'));
|
1514 |
+
|
1515 |
$this->clear_cache_magic_url();
|
1516 |
$this->update_magic_url();
|
1517 |
} /* FeedWordPress::init() */
|
1518 |
+
|
1519 |
+
public function fwp_feeds () {
|
1520 |
$feeds = array();
|
1521 |
$feed_ids = $this->feeds;
|
1522 |
+
|
1523 |
foreach ($feed_ids as $id) :
|
1524 |
$sub = $this->subscription($id);
|
1525 |
$feeds[] = array(
|
1529 |
);
|
1530 |
endforeach;
|
1531 |
|
1532 |
+
header("Content-Type: application/json");
|
1533 |
echo json_encode($feeds);
|
1534 |
exit;
|
1535 |
+
} /* FeedWordPress::fwp_feeds () */
|
1536 |
|
1537 |
+
public function fwp_feedcontents () {
|
1538 |
$feed_id = MyPHP::request('feed_id');
|
1539 |
+
|
1540 |
// Let's load up some data from the feed . . .
|
1541 |
$feed = $this->subscription($feed_id);
|
1542 |
$posts = $feed->live_posts();
|
1543 |
+
|
1544 |
if (is_wp_error($posts)) :
|
1545 |
header("HTTP/1.1 502 Bad Gateway");
|
1546 |
$result = $posts;
|
1549 |
|
1550 |
foreach ($posts as $post) :
|
1551 |
$p = new SyndicatedPost($post, $feed);
|
1552 |
+
|
1553 |
$result[] = array(
|
1554 |
"post_title" => $p->entry->get_title(),
|
1555 |
"post_link" => $p->permalink(),
|
1558 |
);
|
1559 |
endforeach;
|
1560 |
endif;
|
1561 |
+
|
1562 |
header("Content-Type: application/json");
|
1563 |
+
|
1564 |
echo json_encode($result);
|
1565 |
+
|
1566 |
// This is an AJAX request, so close it out thus.
|
1567 |
die;
|
1568 |
} /* FeedWordPress::fwp_feedcontents () */
|
1569 |
+
|
1570 |
+
public function fwp_xpathtest () {
|
1571 |
$xpath = MyPHP::request('xpath');
|
1572 |
$feed_id = MyPHP::request('feed_id');
|
1573 |
$post_id = MyPHP::request('post_id');
|
1574 |
+
|
1575 |
$expr = new FeedWordPressParsedPostMeta($xpath);
|
1576 |
+
|
1577 |
// Let's load up some data from the feed . . .
|
1578 |
$feed = $this->subscription($feed_id);
|
1579 |
$posts = $feed->live_posts();
|
1580 |
+
|
1581 |
if (!is_wp_error($posts)) :
|
1582 |
if (strlen($post_id) == 0) :
|
1583 |
$post = $posts[0];
|
1584 |
else :
|
1585 |
$post = null;
|
1586 |
+
|
1587 |
foreach ($posts as $p) :
|
1588 |
if ($p->get_id() == $post_id) :
|
1589 |
$post = $p;
|
1590 |
endif;
|
1591 |
endforeach;
|
1592 |
endif;
|
1593 |
+
|
1594 |
$post = new SyndicatedPost($post, $feed);
|
1595 |
$meta = $expr->do_substitutions($post);
|
1596 |
+
|
1597 |
$result = array(
|
1598 |
"post_title" => $post->entry->get_title(),
|
1599 |
"post_link" => $post->permalink(),
|
1608 |
"post_id" => $post_id,
|
1609 |
"results" => $posts
|
1610 |
);
|
1611 |
+
|
1612 |
header("HTTP/1.1 503 Bad Gateway");
|
1613 |
endif;
|
1614 |
+
|
1615 |
header("Content-Type: application/json");
|
1616 |
+
|
1617 |
echo json_encode($result);
|
1618 |
+
|
1619 |
// This is an AJAX request, so close it out thus.
|
1620 |
die;
|
1621 |
} /* FeedWordPress::fwp_xpathtest () */
|
1622 |
+
|
1623 |
+
public function redirect_retired () {
|
1624 |
global $wp_query;
|
1625 |
if (is_singular()) :
|
1626 |
+
if (
|
1627 |
+
'fwpretired'==$wp_query->post->post_status
|
1628 |
+
or 'fwpzapped'==$wp_query->post->post_status
|
1629 |
+
) :
|
1630 |
do_action('feedwordpress_redirect_retired', $wp_query->post);
|
1631 |
+
|
1632 |
if (!($template = get_404_template())) :
|
1633 |
$template = get_index_template();
|
1634 |
endif;
|
1639 |
exit;
|
1640 |
endif;
|
1641 |
endif;
|
1642 |
+
} /* FeedWordPress::redirect_retired () */
|
1643 |
+
|
1644 |
+
public function row_actions ($actions, $post) {
|
1645 |
if (is_syndicated($post->ID)) :
|
1646 |
$link = get_delete_post_link($post->ID, '', true);
|
1647 |
+
$eraseLink = MyPHP::url($link, array("fwp_post_delete" => "nuke"));
|
1648 |
+
|
1649 |
+
$caption = apply_filters('feedwordpress_ui_erase_link_caption', __('Erase the record of this post (will be re-syndicated if it still appears on the feed).'));
|
1650 |
+
$linktext = apply_filters('feedwordpress_ui_erase_link_text', __('Erase/Resyndicate'));
|
1651 |
|
1652 |
+
$retireClass = NULL;
|
1653 |
+
if ($post->post_status == 'fwpzapped') :
|
1654 |
+
if (count(get_post_meta($post->ID, '_feedwordpress_zapped_blank_me')) > 0) :
|
1655 |
+
$retireCap = 'Un-Zap this syndicated post (so it will appear on the site again)';
|
1656 |
+
$retireText = 'Un-Zap & Restore';
|
1657 |
+
$retireLink = MyPHP::url($link, array("fwp_post_delete" => "unzap"));
|
1658 |
+
else :
|
1659 |
+
// No Un-Zap link for posts that have
|
1660 |
+
// been blanked. You'll just have to
|
1661 |
+
// Erase and hope you can resyndicate...
|
1662 |
+
$retireLink = NULL;
|
1663 |
+
endif;
|
1664 |
+
else :
|
1665 |
+
$retireCap = apply_filters('feedwordpress_ui_zap_link_caption', __('Zap this syndicated post (so it will not be re-syndicated if it still appears on the feed).'));
|
1666 |
+
$retireText = apply_filters('feedwordpress_ui_zap_link_text', __('Zap/Don’t Resyndicate'));
|
1667 |
+
$retireLink = MyPHP::url($link, array("fwp_post_delete" => "zap"));
|
1668 |
+
$retireClass = 'submitdelete';
|
1669 |
+
endif;
|
1670 |
|
1671 |
$keys = array_keys($actions);
|
1672 |
$links = array();
|
1673 |
foreach ($keys as $key) :
|
1674 |
$links[$key] = $actions[$key];
|
1675 |
+
|
1676 |
if ('trash'==$key) :
|
1677 |
+
#$links[$key] = "<a class='submitdelete' title='" . esc_attr( __( 'Move this item to the Trash (will NOT be re-syndicated)' ) ) . "' href='" . get_delete_post_link( $post->ID ) . "'>" . __( 'Trash' ) . "</a>";
|
1678 |
+
|
1679 |
// Placeholder.
|
1680 |
+
if (!is_null($retireLink)) :
|
1681 |
+
$links['zap trash'] = '';
|
1682 |
+
endif;
|
1683 |
$links['delete'] = '';
|
1684 |
endif;
|
1685 |
endforeach;
|
1686 |
+
|
1687 |
+
if (!is_null($retireLink)) :
|
1688 |
+
$links['zap trash'] = '<a class="'.esc_attr($retireClass).'" title="'.esc_attr(__($retireCap)).'" href="' . $retireLink . '">' . __($retireText) . '</a>';
|
1689 |
+
endif;
|
1690 |
+
$links['delete'] = '<a class="submitdelete" title="'.esc_attr(__($caption)).'" href="' . $eraseLink . '">' . __($linktext) . '</a>';
|
1691 |
|
1692 |
$actions = $links;
|
1693 |
endif;
|
1694 |
return $actions;
|
1695 |
+
} /* FeedWordPress::row_actions () */
|
1696 |
+
|
1697 |
+
public function dashboard_setup () {
|
1698 |
$see_it = FeedWordPress::menu_cap();
|
1699 |
+
|
1700 |
if (current_user_can($see_it)) :
|
1701 |
// Get the stylesheet
|
1702 |
wp_enqueue_style('feedwordpress-elements');
|
1703 |
+
|
1704 |
$widget_id = 'feedwordpress_dashboard';
|
1705 |
$widget_name = __('Syndicated Sources');
|
1706 |
$column = 'side';
|
1707 |
$priority = 'core';
|
1708 |
+
|
1709 |
// I would love to use wp_add_dashboard_widget() here and save
|
1710 |
// myself some trouble. But WP 3 does not yet have any way to
|
1711 |
// push a dashboard widget onto the side, or to give it a default
|
1719 |
/*priority=*/ $priority
|
1720 |
);
|
1721 |
/*control_callback= array($this, 'dashboard_control') */
|
1722 |
+
|
1723 |
// This is kind of rude, I know, but the dashboard widget isn't
|
1724 |
// worth much if users don't know that it exists, and I don't
|
1725 |
// know of any better way to reorder the boxen.
|
1726 |
//
|
1727 |
// Gleefully ripped off of codex.wordpress.org/Dashboard_Widgets_API
|
1728 |
+
|
1729 |
// Globalize the metaboxes array, this holds all the widgets for wp-admin
|
1730 |
global $wp_meta_boxes;
|
1731 |
+
|
1732 |
+
// Get the regular dashboard widgets array
|
1733 |
// (which has our new widget already but at the end)
|
1734 |
+
|
1735 |
$normal_dashboard = $wp_meta_boxes['dashboard'][$column][$priority];
|
1736 |
+
|
1737 |
// Backup and delete our new dashbaord widget from the end of the array
|
1738 |
if (isset($normal_dashboard[$widget_id])) :
|
1739 |
$backup = array();
|
1740 |
$backup[$widget_id] = $normal_dashboard[$widget_id];
|
1741 |
unset($normal_dashboard[$widget_id]);
|
1742 |
+
|
1743 |
// Merge the two arrays together so our widget is at the
|
1744 |
// beginning
|
1745 |
$sorted_dashboard = array_merge($backup, $normal_dashboard);
|
1746 |
+
|
1747 |
+
// Save the sorted array back into the original metaboxes
|
1748 |
$wp_meta_boxes['dashboard'][$column][$priority] = $sorted_dashboard;
|
1749 |
endif;
|
1750 |
endif;
|
1751 |
} /* FeedWordPress::dashboard_setup () */
|
1752 |
+
|
1753 |
+
public function dashboard () {
|
1754 |
$syndicationPage = new FeedWordPressSyndicationPage(dirname(__FILE__).'/syndication.php');
|
1755 |
$syndicationPage->dashboard_box($syndicationPage);
|
1756 |
} /* FeedWordPress::dashboard () */
|
1757 |
|
1758 |
+
public function user_can_richedit ($rich_edit) {
|
1759 |
|
1760 |
$post = new FeedWordPressLocalPost;
|
1761 |
+
|
1762 |
if (!$post->is_exposed_to_formatting_filters()) :
|
1763 |
// Disable visual editor and only allow operations
|
1764 |
// directly on HTML if post is bypassing fmt filters
|
1765 |
+
# $rich_edit = false;
|
1766 |
endif;
|
1767 |
+
|
1768 |
return $rich_edit;
|
1769 |
|
1770 |
} /* FeedWordPress::user_can_richedit () */
|
1771 |
+
|
1772 |
+
public function update_magic_url () {
|
1773 |
global $wpdb;
|
1774 |
|
1775 |
// Explicit update request in the HTTP request (e.g. from a cron job)
|
1777 |
$this->update_hooked = "Initiating a CRON JOB CHECK-IN ON UPDATE SCHEDULE due to URL parameter = ".trim($this->val($_REQUEST['update_feedwordpress']));
|
1778 |
|
1779 |
$this->update($this->update_requested_url());
|
1780 |
+
|
1781 |
if (FEEDWORDPRESS_DEBUG and count($wpdb->queries) > 0) :
|
1782 |
$mysqlTime = 0.0;
|
1783 |
$byTime = array();
|
1785 |
$time = $query[1] * 1000000.0;
|
1786 |
$mysqlTime += $query[1];
|
1787 |
if (!isset($byTime[$time])) : $byTime[$time] = array(); endif;
|
1788 |
+
$byTime[$time][] = $query[0]. ' // STACK: ' . $query[2];
|
1789 |
endforeach;
|
1790 |
krsort($byTime);
|
1791 |
+
|
1792 |
foreach ($byTime as $time => $querySet) :
|
1793 |
foreach ($querySet as $query) :
|
1794 |
print "[".(sprintf('%4.4f', $time/1000.0)) . "ms] $query\n";
|
1795 |
endforeach;
|
1796 |
endforeach;
|
1797 |
+
echo self::log_prefix()."$wpdb->num_queries queries. $mysqlTime seconds in MySQL. Total of "; timer_stop(1); print " seconds.";
|
1798 |
endif;
|
1799 |
+
|
1800 |
debug_out_feedwordpress_footer();
|
1801 |
+
|
1802 |
// Magic URL should return nothing but a 200 OK header packet
|
1803 |
// when successful.
|
1804 |
exit;
|
1805 |
endif;
|
1806 |
} /* FeedWordPress::magic_update_url () */
|
1807 |
|
1808 |
+
public function clear_cache_magic_url () {
|
1809 |
if ($this->clear_cache_requested()) :
|
1810 |
$this->clear_cache();
|
1811 |
endif;
|
1812 |
} /* FeedWordPress::clear_cache_magic_url() */
|
1813 |
+
|
1814 |
+
public function clear_cache_requested () {
|
1815 |
return MyPHP::request('clear_cache');
|
1816 |
} /* FeedWordPress::clear_cache_requested() */
|
1817 |
|
1818 |
+
public function update_requested () {
|
1819 |
+
return MyPHP::request('update_feedwordpress');
|
1820 |
+
} /* FeedWordPress::update_requested() */
|
1821 |
|
1822 |
+
public function update_requested_url () {
|
1823 |
$ret = null;
|
1824 |
+
|
1825 |
if (($_REQUEST['update_feedwordpress']=='*')
|
1826 |
or (preg_match('|^http://.*|i', $_REQUEST['update_feedwordpress']))) :
|
1827 |
$ret = $_REQUEST['update_feedwordpress'];
|
1828 |
endif;
|
1829 |
|
1830 |
return $ret;
|
1831 |
+
} /* FeedWordPress::update_requested_url() */
|
1832 |
|
1833 |
+
public function auto_update () {
|
1834 |
if ($this->stale()) :
|
1835 |
$this->update();
|
1836 |
endif;
|
1837 |
} /* FeedWordPress::auto_update () */
|
1838 |
|
1839 |
+
public static function find_link ($uri, $field = 'link_rss') {
|
1840 |
global $wpdb;
|
1841 |
|
1842 |
$unslashed = untrailingslashit($uri);
|
1845 |
SELECT link_id FROM $wpdb->links WHERE $field IN ('%s', '%s')
|
1846 |
LIMIT 1", $unslashed, $slashed
|
1847 |
));
|
1848 |
+
|
1849 |
return $link_id;
|
1850 |
} /* FeedWordPress::find_link () */
|
1851 |
|
1852 |
+
/**
|
1853 |
+
* FeedWordPress:syndicate_link(): add or update a feed subscription
|
1854 |
+
*
|
1855 |
+
* Add a new subscription to, or update an existing subscription in,
|
1856 |
+
* FWP's list of subscribed feeds.
|
1857 |
+
*
|
1858 |
+
* Postcondition: If $rss is the URL of a feed not yet on FWP's list of
|
1859 |
+
* subscribed feeds, then a new subscription will be added, using $name
|
1860 |
+
* as its initial title and $uri as its initial homepage URL (normally
|
1861 |
+
* these will be updated with new values taken from the feed, the first
|
1862 |
+
* time the new feed is checked for syndicated content, unless feed
|
1863 |
+
* settings prevent this). If $rss is the URL of a feed that is already
|
1864 |
+
* on FWP's list of subscribed feeds, then that feed will be updated to
|
1865 |
+
* use the title provided in $name and the homepage URL in $uri
|
1866 |
+
*
|
1867 |
+
* @param string $name The human-readable title of the feed (for example, "Rad Geek People's Daily")
|
1868 |
+
* @param string $uri The URI for the human-readable homepage associated with the feed (for example, <http://radgeek.com/>)
|
1869 |
+
* @param string $rss The URI for the feed itself (for example, <http://radgeek.com/feed/>)
|
1870 |
+
*
|
1871 |
+
* @return mixed Returns an int with the numeric ID of the new
|
1872 |
+
* subscription's wp_links record if successful or a WP_Error object
|
1873 |
+
* if wp_insert_link() failed.
|
1874 |
+
*
|
1875 |
+
* @uses FeedWordPress::link_category_id()
|
1876 |
+
* @uses FeedWordPress::find_link()
|
1877 |
+
* @uses is_wp_error()
|
1878 |
+
* @uses wp_insert_link()
|
1879 |
+
*
|
1880 |
+
*/
|
1881 |
+
public static function syndicate_link ($name, $uri, $rss) {
|
1882 |
// Get the category ID#
|
1883 |
$cat_id = FeedWordPress::link_category_id();
|
1884 |
if (!is_wp_error($cat_id)) :
|
1889 |
|
1890 |
// WordPress gets cranky if there's no homepage URI
|
1891 |
if (!is_string($uri) or strlen($uri)<1) : $uri = $rss; endif;
|
1892 |
+
|
1893 |
// Check if this feed URL is already being syndicated.
|
1894 |
+
$link_id = wp_insert_link(/*linkdata=*/ array(
|
1895 |
"link_id" => FeedWordPress::find_link($rss), // insert if nothing was found; else update
|
1896 |
"link_rss" => $rss,
|
1897 |
"link_name" => $name,
|
1898 |
"link_url" => $uri,
|
1899 |
"link_category" => $link_category,
|
1900 |
"link_visible" => 'Y', // reactivate if inactivated
|
1901 |
+
), /*wp_error=*/ true);
|
1902 |
|
1903 |
return $link_id;
|
1904 |
} /* function FeedWordPress::syndicate_link() */
|
1905 |
|
1906 |
+
static function syndicated_status ($what, $default) {
|
1907 |
$ret = get_option("feedwordpress_syndicated_{$what}_status");
|
1908 |
if (!$ret) :
|
1909 |
$ret = $default;
|
1911 |
return $ret;
|
1912 |
} /* FeedWordPress::syndicated_status() */
|
1913 |
|
1914 |
+
public static function on_unfamiliar ($what = 'author') {
|
1915 |
switch ($what) :
|
1916 |
case 'category' : $suffix = ':category'; break;
|
1917 |
case 'post_tag' : $suffix = ':post_tag'; break;
|
1918 |
default: $suffix = '';
|
1919 |
endswitch;
|
1920 |
+
|
1921 |
return get_option('feedwordpress_unfamiliar_'.$what, 'create'.$suffix);
|
1922 |
} // function FeedWordPress::on_unfamiliar()
|
1923 |
|
1924 |
+
public static function null_email_set () {
|
1925 |
$base = get_option('feedwordpress_null_email_set');
|
1926 |
|
1927 |
if ($base===false) :
|
1935 |
|
1936 |
} /* FeedWordPress::null_email_set () */
|
1937 |
|
1938 |
+
public static function is_null_email ($email) {
|
1939 |
$ret = in_array(strtolower(trim($email)), FeedWordPress::null_email_set());
|
1940 |
$ret = apply_filters('syndicated_item_author_is_null_email', $ret, $email);
|
1941 |
return $ret;
|
1942 |
} /* FeedWordPress::is_null_email () */
|
1943 |
|
1944 |
+
public static function use_aggregator_source_data () {
|
1945 |
$ret = get_option('feedwordpress_use_aggregator_source_data');
|
1946 |
return apply_filters('syndicated_post_use_aggregator_source_data', ($ret=='yes'));
|
1947 |
+
} /* FeedWordPress::use_aggregator_source_data () */
|
1948 |
|
1949 |
/**
|
1950 |
* FeedWordPress::munge_permalinks: check whether or not FeedWordPress
|
1953 |
*
|
1954 |
* @return bool TRUE if FeedWordPress SHOULD rewrite permalinks; FALSE otherwise
|
1955 |
*/
|
1956 |
+
static function munge_permalinks () {
|
1957 |
return (get_option('feedwordpress_munge_permalink', /*default=*/ 'yes') != 'no');
|
1958 |
} /* FeedWordPress::munge_permalinks() */
|
1959 |
|
1960 |
+
public static function syndicated_links ($args = array()) {
|
1961 |
$contributors = FeedWordPress::link_category_id();
|
1962 |
if (!is_wp_error($contributors)) :
|
1963 |
$links = get_bookmarks(array_merge(
|
1969 |
endif;
|
1970 |
|
1971 |
return $links;
|
1972 |
+
} /* FeedWordPress::syndicated_links() */
|
1973 |
|
1974 |
+
public static function link_category_id () {
|
1975 |
global $wpdb, $wp_db_version;
|
1976 |
|
1977 |
$cat_id = get_option('feedwordpress_cat_id');
|
1978 |
+
|
1979 |
// If we don't yet have the category ID stored, search by name
|
1980 |
if (!$cat_id) :
|
1981 |
$cat_id = FeedWordPressCompatibility::link_category_id(DEFAULT_SYNDICATION_CATEGORY);
|
1989 |
else :
|
1990 |
$cat_id = FeedWordPressCompatibility::link_category_id((int) $cat_id, 'cat_id');
|
1991 |
endif;
|
1992 |
+
|
1993 |
// If we could not find an appropriate link category,
|
1994 |
// make a new one for ourselves.
|
1995 |
if (!$cat_id) :
|
2001 |
endif;
|
2002 |
|
2003 |
return $cat_id;
|
2004 |
+
} /* FeedWordPress::link_category_id() */
|
2005 |
|
2006 |
# Upgrades and maintenance...
|
2007 |
+
static function needs_upgrade () {
|
2008 |
+
|
2009 |
global $wpdb;
|
2010 |
+
$fwp_db_version = get_option('feedwordpress_version', NULL);
|
2011 |
$ret = false; // innocent until proven guilty
|
2012 |
+
if (is_null($fwp_db_version) or ($fwp_db_version < FEEDWORDPRESS_VERSION)) :
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2013 |
|
2014 |
+
// This is an older version or a fresh install. Does it require a database
|
2015 |
+
// upgrade or database initialization?
|
2016 |
+
|
2017 |
+
if (is_null($fwp_db_version)) :
|
2018 |
+
|
2019 |
+
// Fresh install; brand it as ours. Or possibly a version of FWP
|
2020 |
+
// from before 0.96. But I'm no longer supporting upgrade paths
|
2021 |
+
// for versions from the previous decade. Sorry.
|
2022 |
update_option('feedwordpress_version', FEEDWORDPRESS_VERSION);
|
2023 |
+
|
2024 |
elseif ($fwp_db_version < 2010.0814) :
|
2025 |
+
|
2026 |
// Change in terminology.
|
2027 |
if (get_option('feedwordpress_unfamiliar_category', 'create')=='default') :
|
2028 |
update_option('feedwordpress_unfamiliar_category', 'null');
|
2029 |
endif;
|
2030 |
foreach (FeedWordPress::syndicated_links() as $link) :
|
2031 |
$sub = new SyndicatedLink($link);
|
2032 |
+
|
2033 |
$remap_uf = array(
|
2034 |
'default' => 'null',
|
2035 |
'filter' => 'null',
|
2046 |
endif;
|
2047 |
endforeach;
|
2048 |
endif;
|
2049 |
+
|
2050 |
if (isset($sub->settings['add global categories'])) :
|
2051 |
$sub->settings['add/category'] = $sub->settings['add global categories'];
|
2052 |
unset($sub->settings['add global categories']);
|
2053 |
endif;
|
2054 |
+
|
2055 |
$sub->save_settings(/*reload=*/ true);
|
2056 |
endforeach;
|
2057 |
update_option('feedwordpress_version', FEEDWORDPRESS_VERSION);
|
2058 |
+
|
2059 |
else :
|
2060 |
+
|
2061 |
+
// No upgrade needed. Just brand it with the new version.
|
2062 |
update_option('feedwordpress_version', FEEDWORDPRESS_VERSION);
|
2063 |
+
|
2064 |
endif;
|
2065 |
+
|
2066 |
endif;
|
2067 |
return $ret;
|
2068 |
+
} /* FeedWordPress::needs_upgrade () */
|
2069 |
|
2070 |
+
static function upgrade_database ($from = NULL) {
|
2071 |
global $wpdb;
|
2072 |
|
2073 |
if (is_null($from) or $from <= 0.96) : $from = 0.96; endif;
|
2074 |
|
2075 |
switch ($from) :
|
2076 |
case 0.96:
|
2077 |
+
// Dropping legacy upgrade code. If anyone is still
|
2078 |
+
// using 0.96 and just now decided to upgrade, well, I'm
|
2079 |
+
// sorry about that. You'll just have to cope with a few
|
2080 |
+
// duplicate posts.
|
2081 |
|
2082 |
// Mark the upgrade as successful.
|
2083 |
update_option('feedwordpress_version', FEEDWORDPRESS_VERSION);
|
2085 |
echo "<p>Upgrade complete. FeedWordPress is now ready to use again.</p>";
|
2086 |
} /* FeedWordPress::upgrade_database() */
|
2087 |
|
2088 |
+
public static function has_guid_index () {
|
2089 |
global $wpdb;
|
2090 |
+
|
2091 |
$found = false; // Guilty until proven innocent.
|
2092 |
|
2093 |
$results = $wpdb->get_results("
|
2103 |
endif;
|
2104 |
return $found;
|
2105 |
} /* FeedWordPress::has_guid_index () */
|
2106 |
+
|
2107 |
+
public static function create_guid_index () {
|
2108 |
global $wpdb;
|
2109 |
+
|
2110 |
$wpdb->query("
|
2111 |
CREATE INDEX {$wpdb->posts}_guid_idx ON {$wpdb->posts}(guid)
|
2112 |
");
|
2113 |
} /* FeedWordPress::create_guid_index () */
|
2114 |
+
|
2115 |
+
public static function remove_guid_index () {
|
2116 |
global $wpdb;
|
2117 |
+
|
2118 |
$wpdb->query("
|
2119 |
DROP INDEX {$wpdb->posts}_guid_idx ON {$wpdb->posts}
|
2120 |
");
|
2121 |
}
|
2122 |
|
2123 |
+
static function fetch_timeout () {
|
2124 |
return apply_filters(
|
2125 |
'feedwordpress_fetch_timeout',
|
2126 |
intval(get_option('feedwordpress_fetch_timeout', FEEDWORDPRESS_FETCH_TIMEOUT_DEFAULT))
|
2127 |
);
|
2128 |
}
|
2129 |
+
|
2130 |
+
static function fetch ($url, $params = array()) {
|
2131 |
if (is_wp_error($url)) :
|
2132 |
// Let's bounce.
|
2133 |
return $url;
|
2134 |
endif;
|
2135 |
+
|
2136 |
$force_feed = true; // Default
|
2137 |
|
2138 |
+
// Allow user to change default feed-fetch timeout with a global setting.
|
2139 |
+
// Props Erigami Scholey-Fuller <http://www.piepalace.ca/blog/2010/11/feedwordpress-broke-my-heart.html>
|
2140 |
$timeout = FeedWordPress::fetch_timeout();
|
2141 |
+
|
2142 |
if (!is_array($params)) :
|
2143 |
$force_feed = $params;
|
2144 |
else : // Parameter array
|
2146 |
'force_feed' => $force_feed,
|
2147 |
'timeout' => $timeout
|
2148 |
), $params);
|
2149 |
+
|
2150 |
extract($args);
|
2151 |
endif;
|
2152 |
$timeout = intval($timeout);
|
2153 |
+
|
2154 |
$pie_class = apply_filters('feedwordpress_simplepie_class', 'FeedWordPie');
|
2155 |
$cache_class = apply_filters('feedwordpress_cache_class', 'WP_Feed_Cache');
|
2156 |
$file_class = apply_filters('feedwordpress_file_class', 'FeedWordPress_File');
|
2162 |
$feed->set_feed_url($url);
|
2163 |
$feed->set_cache_class($cache_class);
|
2164 |
$feed->set_timeout($timeout);
|
2165 |
+
|
2166 |
$feed->set_content_type_sniffer_class($sniffer_class);
|
2167 |
$feed->set_file_class($file_class);
|
2168 |
$feed->set_parser_class($parser_class);
|
2171 |
$feed->set_cache_duration(FeedWordPress::cache_duration($params));
|
2172 |
$feed->init();
|
2173 |
$feed->handle_content_type();
|
2174 |
+
|
2175 |
if ($feed->error()) :
|
2176 |
$ret = new WP_Error('simplepie-error', $feed->error());
|
2177 |
else :
|
2179 |
endif;
|
2180 |
return $ret;
|
2181 |
} /* FeedWordPress::fetch () */
|
2182 |
+
|
2183 |
+
public function clear_cache () {
|
2184 |
global $wpdb;
|
2185 |
+
|
2186 |
// Just in case, clear out any old MagpieRSS cache records.
|
2187 |
$magpies = $wpdb->query("
|
2188 |
DELETE FROM {$wpdb->options}
|
2205 |
return ($magpies + $simplepies);
|
2206 |
} /* FeedWordPress::clear_cache () */
|
2207 |
|
2208 |
+
static public function cache_duration ($params = array()) {
|
2209 |
$params = wp_parse_args($params, array(
|
2210 |
"cache" => true,
|
2211 |
));
|
2212 |
+
|
2213 |
$duration = NULL;
|
2214 |
if (!$params['cache']) :
|
2215 |
$duration = 0;
|
2218 |
endif;
|
2219 |
return $duration;
|
2220 |
}
|
2221 |
+
|
2222 |
+
static public function cache_lifetime ($duration) {
|
2223 |
// Check for explicit setting of a lifetime duration
|
2224 |
if (defined('FEEDWORDPRESS_CACHE_LIFETIME')) :
|
2225 |
$duration = FEEDWORDPRESS_CACHE_LIFETIME;
|
2228 |
elseif (defined('FEEDWORDPRESS_CACHE_AGE')) :
|
2229 |
$duration = FEEDWORDPRESS_CACHE_AGE;
|
2230 |
endif;
|
2231 |
+
|
2232 |
// Fall back to WordPress default
|
2233 |
return $duration;
|
2234 |
} /* FeedWordPress::cache_lifetime () */
|
2235 |
|
2236 |
# Utility functions for handling text settings
|
2237 |
+
static function negative ($f, $setting) {
|
2238 |
$nego = array ('n', 'no', 'f', 'false');
|
2239 |
return (isset($f[$setting]) and in_array(strtolower($f[$setting]), $nego));
|
2240 |
+
} /* FeedWordPress::negative () */
|
2241 |
|
2242 |
+
static function affirmative ($f, $setting) {
|
2243 |
$affirmo = array ('y', 'yes', 't', 'true', 1);
|
2244 |
return (isset($f[$setting]) and in_array(strtolower($f[$setting]), $affirmo));
|
2245 |
+
} /* FeedWordPress::affirmative () */
|
2246 |
|
2247 |
# Internal debugging functions
|
2248 |
+
static function critical_bug ($varname, $var, $line, $file = NULL) {
|
2249 |
global $wp_version;
|
2250 |
+
|
2251 |
if (!is_null($file)) :
|
2252 |
$location = "line # ${line} of ".basename($file);
|
2253 |
else :
|
2254 |
$location = "line # ${line}";
|
2255 |
endif;
|
2256 |
+
|
2257 |
print '<p><strong>Critical error:</strong> 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>';
|
2258 |
print "\n<plaintext>";
|
2259 |
print "Triggered at ${location}\n";
|
2263 |
print "Error data: ";
|
2264 |
print $varname.": "; var_dump($var); echo "\n";
|
2265 |
die;
|
2266 |
+
} /* FeedWordPress::critical_bug () */
|
2267 |
+
|
2268 |
+
static function noncritical_bug ($varname, $var, $line, $file = NULL) {
|
2269 |
if (FEEDWORDPRESS_DEBUG) : // halt only when we are doing debugging
|
2270 |
FeedWordPress::critical_bug($varname, $var, $line, $file);
|
2271 |
endif;
|
2272 |
+
} /* FeedWordPress::noncritical_bug () */
|
2273 |
+
|
2274 |
+
static function val ($v, $no_newlines = false) {
|
2275 |
+
return MyPHP::val($v, $no_newlines);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2276 |
} /* FeedWordPress::val () */
|
2277 |
|
2278 |
+
static function diagnostic_on ($level) {
|
2279 |
$show = get_option('feedwordpress_diagnostics_show', array());
|
2280 |
return (in_array($level, $show));
|
2281 |
} /* FeedWordPress::diagnostic_on () */
|
2282 |
|
2283 |
+
static function diagnostic ($level, $out, $persist = NULL, $since = NULL, $mostRecent = NULL) {
|
2284 |
global $feedwordpress_admin_footer;
|
2285 |
|
2286 |
$output = get_option('feedwordpress_diagnostics_output', array());
|
2293 |
switch ($method) :
|
2294 |
case 'echo' :
|
2295 |
if (!FeedWordPress::update_requested()) :
|
2296 |
+
echo "<div><pre><strong>Diag".str_repeat('====', $diagnostic_nesting-1).'|</strong> '.$out."</pre></div>\n";
|
2297 |
endif;
|
2298 |
break;
|
2299 |
case 'echo_in_cronjob' :
|
2308 |
error_log(FeedWordPress::log_prefix().' '.$out);
|
2309 |
break;
|
2310 |
case 'email' :
|
2311 |
+
|
2312 |
if (is_null($persist)) :
|
2313 |
$sect = 'occurrent';
|
2314 |
$hook = (isset($dlog['mesg'][$sect]) ? count($dlog['mesg'][$sect]) : 0);
|
2318 |
$hook = md5($level."\n".$persist);
|
2319 |
$line = array("Since" => $since, "Message" => $out, "Most Recent" => $mostRecent);
|
2320 |
endif;
|
2321 |
+
|
2322 |
if (!isset($dlog['mesg'])) : $dlog['mesg'] = array(); endif;
|
2323 |
if (!isset($dlog['mesg'][$sect])) : $dlog['mesg'][$sect] = array(); endif;
|
2324 |
+
|
2325 |
$dlog['mesg'][$sect][$hook] = $line;
|
2326 |
endswitch;
|
2327 |
endforeach;
|
2328 |
endif;
|
2329 |
+
|
2330 |
+
update_option('feedwordpress_diagnostics_log', $dlog);
|
2331 |
} /* FeedWordPress::diagnostic () */
|
2332 |
+
|
2333 |
+
public function email_diagnostics_override () {
|
2334 |
return ($this->has_secret() and isset($_REQUEST['feedwordpress_email_diagnostics']) and !!$_REQUEST['feedwordpress_email_diagnostics']);
|
2335 |
+
} /* FeedWordPress::email_diagnostics_override () */
|
2336 |
+
|
2337 |
+
public function has_emailed_diagnostics ($dlog) {
|
2338 |
$ret = false;
|
2339 |
if ($this->email_diagnostics_override()
|
2340 |
or (isset($dlog['schedule']) and isset($dlog['schedule']['last']))) :
|
2341 |
$ret = true;
|
2342 |
endif;
|
2343 |
return $ret;
|
2344 |
+
} /* FeedWordPress::has_emailed_diagnostics () */
|
2345 |
+
|
2346 |
+
public function ready_to_email_diagnostics ($dlog) {
|
2347 |
$ret = false;
|
2348 |
if ($this->email_diagnostics_override()
|
2349 |
or (time() > ($dlog['schedule']['last'] + $dlog['schedule']['freq']))) :
|
2350 |
$ret = true;
|
2351 |
endif;
|
2352 |
return $ret;
|
2353 |
+
} /* FeedWordPress::ready_to_email_diagnostics () */
|
2354 |
+
|
2355 |
+
public function email_diagnostic_log ($params = array()) {
|
2356 |
$params = wp_parse_args($params, array(
|
2357 |
"force" => false,
|
2358 |
));
|
2359 |
|
2360 |
$dlog = get_option('feedwordpress_diagnostics_log', array());
|
2361 |
+
|
2362 |
if ($this->has_emailed_diagnostics($dlog)) :
|
2363 |
if ($this->ready_to_email_diagnostics($dlog)) :
|
2364 |
// No news is good news; only send if
|
2365 |
// there are some messages to send.
|
2366 |
$body = NULL;
|
2367 |
if (!isset($dlog['mesg'])) : $dlog['mesg'] = array(); endif;
|
2368 |
+
|
2369 |
foreach ($dlog['mesg'] as $sect => $mesgs) :
|
2370 |
if (count($mesgs) > 0) :
|
2371 |
if (is_null($body)) : $body = ''; endif;
|
2372 |
+
|
2373 |
$paradigm = reset($mesgs);
|
2374 |
$body .= "<h2>".ucfirst($sect)." issues</h2>\n"
|
2375 |
."<table>\n"
|
2379 |
endforeach;
|
2380 |
$body .= "</tr></thead>\n"
|
2381 |
."<tbody>\n";
|
2382 |
+
|
2383 |
foreach ($mesgs as $line) :
|
2384 |
$body .= "<tr>\n";
|
2385 |
foreach ($line as $col => $cell) :
|
2391 |
endforeach;
|
2392 |
$body .= "</tr>\n";
|
2393 |
endforeach;
|
2394 |
+
|
2395 |
$body .= "</tbody>\n</table>\n\n";
|
2396 |
endif;
|
2397 |
endforeach;
|
2398 |
+
|
2399 |
$body = apply_filters('feedwordpress_diagnostic_email_body', $body, $dlog);
|
2400 |
if (!is_null($body)) :
|
2401 |
$home = feedwordpress_display_url(get_bloginfo('url'));
|
2430 |
// e-mail address
|
2431 |
if (preg_match('/^mailto:(.*)$/', $ded, $ref)) :
|
2432 |
$recipients = array($ref[1]);
|
2433 |
+
|
2434 |
// userid
|
2435 |
elseif (preg_match('/^user:(.*)$/', $ded, $ref)) :
|
2436 |
$userdata = get_userdata((int) $ref[1]);
|
2437 |
$recipients = array($userdata->user_email);
|
2438 |
+
|
2439 |
// admins
|
2440 |
else :
|
2441 |
$recipients = FeedWordPressDiagnostic::admin_emails();
|
2458 |
endif;
|
2459 |
$head = apply_filters('feedwordpress_diagnostic_email_headers', $head);
|
2460 |
|
2461 |
+
foreach ($recipients as $email) :
|
2462 |
add_filter('wp_mail_content_type', array('FeedWordPress', 'allow_html_mail'));
|
2463 |
wp_mail($email, $subj, $body, $head);
|
2464 |
remove_filter('wp_mail_content_type', array('FeedWordPress', 'allow_html_mail'));
|
2465 |
endforeach;
|
2466 |
endif;
|
2467 |
+
|
2468 |
// Clear the logs
|
2469 |
$dlog['mesg']['persistent'] = array();
|
2470 |
$dlog['mesg']['occurrent'] = array();
|
2471 |
+
|
2472 |
// Set schedule for next update
|
2473 |
$dlog['schedule']['last'] = time();
|
2474 |
endif;
|
2478 |
'last' => time(),
|
2479 |
);
|
2480 |
endif;
|
2481 |
+
|
2482 |
update_option('feedwordpress_diagnostics_log', $dlog);
|
2483 |
} /* FeedWordPress::email_diagnostic_log () */
|
2484 |
+
|
2485 |
+
static function allow_html_mail () {
|
2486 |
return 'text/html';
|
2487 |
} /* FeedWordPress::allow_html_mail () */
|
2488 |
|
2489 |
+
static function admin_footer () {
|
2490 |
global $feedwordpress_admin_footer;
|
2491 |
foreach ($feedwordpress_admin_footer as $line) :
|
2492 |
echo '<div><pre>'.$line.'</pre></div>';
|
2493 |
endforeach;
|
2494 |
} /* FeedWordPress::admin_footer () */
|
2495 |
+
|
2496 |
+
static function log_prefix ($date = false) {
|
2497 |
$home = get_bloginfo('url');
|
2498 |
$prefix = '['.feedwordpress_display_url($home).'] [feedwordpress] ';
|
2499 |
if ($date) :
|
2501 |
endif;
|
2502 |
return $prefix;
|
2503 |
} /* FeedWordPress::log_prefix () */
|
2504 |
+
|
2505 |
+
static function menu_cap ($sub = false) {
|
2506 |
if ($sub) :
|
2507 |
$cap = apply_filters('feedwordpress_menu_settings_capacity', 'manage_options');
|
2508 |
else :
|
2510 |
endif;
|
2511 |
return $cap;
|
2512 |
} /* FeedWordPress::menu_cap () */
|
2513 |
+
|
2514 |
+
static function path ($filename = '') {
|
2515 |
global $fwp_path;
|
2516 |
+
|
2517 |
$path = $fwp_path;
|
2518 |
if (strlen($filename) > 0) :
|
2519 |
$path .= '/'.$filename;
|
2520 |
endif;
|
2521 |
return $path;
|
2522 |
+
} /* FeedWordPress::path () */
|
2523 |
+
|
2524 |
// These are superceded by MyPHP::param/post/get/request, but kept
|
2525 |
// here for backward compatibility.
|
2526 |
+
|
2527 |
+
static function param ($key, $type = 'REQUEST', $default = NULL) {
|
2528 |
return MyPHP::param($key, $default, $type);
|
2529 |
+
} /* FeedWordPress::param () */
|
2530 |
+
|
2531 |
+
static function post ($key, $default = NULL) {
|
2532 |
return MyPHP::post($key, $default);
|
2533 |
+
} /* FeedWordPress::post () */
|
2534 |
+
|
2535 |
+
} /* class FeedWordPress */
|
2536 |
|
2537 |
$feedwordpress_admin_footer = array();
|
2538 |
|
@@ -5,10 +5,6 @@ $fwp_credentials = NULL;
|
|
5 |
|
6 |
class FeedWordPress_File extends WP_SimplePie_File {
|
7 |
function FeedWordPress_File ($url, $timeout = 10, $redirects = 5, $headers = null, $useragent = null, $force_fsockopen = false) {
|
8 |
-
self::__construct($url, $timeout, $redirects, $headers, $useragent, $force_fsockopen);
|
9 |
-
}
|
10 |
-
|
11 |
-
function __construct ($url, $timeout = 10, $redirects = 5, $headers = null, $useragent = null, $force_fsockopen = false) {
|
12 |
global $feedwordpress;
|
13 |
global $wp_version;
|
14 |
|
@@ -16,7 +12,7 @@ class FeedWordPress_File extends WP_SimplePie_File {
|
|
16 |
if ($feedwordpress->subscribed($url)) :
|
17 |
$source = $feedwordpress->subscription($url);
|
18 |
endif;
|
19 |
-
|
20 |
$this->url = $url;
|
21 |
$this->timeout = $timeout;
|
22 |
$this->redirects = $redirects;
|
@@ -24,13 +20,13 @@ class FeedWordPress_File extends WP_SimplePie_File {
|
|
24 |
$this->useragent = $useragent;
|
25 |
|
26 |
$this->method = SIMPLEPIE_FILE_SOURCE_REMOTE;
|
27 |
-
|
28 |
global $wpdb;
|
29 |
global $fwp_credentials;
|
30 |
-
|
31 |
if ( preg_match('/^http(s)?:\/\//i', $url) ) :
|
32 |
$args = array( 'timeout' => $this->timeout, 'redirection' => $this->redirects);
|
33 |
-
|
34 |
if ( !empty($this->headers) )
|
35 |
$args['headers'] = $this->headers;
|
36 |
|
@@ -62,12 +58,12 @@ class FeedWordPress_File extends WP_SimplePie_File {
|
|
62 |
$args['authentication'] = $source->authentication_method();
|
63 |
$args['username'] = $source->username();
|
64 |
$args['password'] = $source->password();
|
65 |
-
|
66 |
endif;
|
67 |
|
68 |
-
FeedWordPress::diagnostic('updated_feeds:http', "HTTP [$url] ⇜ ".esc_html(
|
69 |
$res = wp_remote_request($url, $args);
|
70 |
-
FeedWordPress::diagnostic('updated_feeds:http', "HTTP [$url] ⇝ ".esc_html(
|
71 |
|
72 |
if ( is_wp_error($res) ) {
|
73 |
$this->error = 'WP HTTP Error: ' . $res->get_error_message();
|
@@ -77,13 +73,13 @@ class FeedWordPress_File extends WP_SimplePie_File {
|
|
77 |
$this->body = wp_remote_retrieve_body( $res );
|
78 |
$this->status_code = wp_remote_retrieve_response_code( $res );
|
79 |
}
|
80 |
-
|
81 |
if ($source InstanceOf SyndicatedLink) :
|
82 |
$source->update_setting('link/filesize', strlen($this->body));
|
83 |
$source->update_setting('link/http status', $this->status_code);
|
84 |
$source->save_settings(/*reload=*/ true);
|
85 |
endif;
|
86 |
-
|
87 |
// Do not allow schemes other than http(s)? for the time being.
|
88 |
// They are unlikely to be used; and unrestricted use of schemes
|
89 |
// allows for user to use an unrestricted file:/// scheme, which
|
5 |
|
6 |
class FeedWordPress_File extends WP_SimplePie_File {
|
7 |
function FeedWordPress_File ($url, $timeout = 10, $redirects = 5, $headers = null, $useragent = null, $force_fsockopen = false) {
|
|
|
|
|
|
|
|
|
8 |
global $feedwordpress;
|
9 |
global $wp_version;
|
10 |
|
12 |
if ($feedwordpress->subscribed($url)) :
|
13 |
$source = $feedwordpress->subscription($url);
|
14 |
endif;
|
15 |
+
|
16 |
$this->url = $url;
|
17 |
$this->timeout = $timeout;
|
18 |
$this->redirects = $redirects;
|
20 |
$this->useragent = $useragent;
|
21 |
|
22 |
$this->method = SIMPLEPIE_FILE_SOURCE_REMOTE;
|
23 |
+
|
24 |
global $wpdb;
|
25 |
global $fwp_credentials;
|
26 |
+
|
27 |
if ( preg_match('/^http(s)?:\/\//i', $url) ) :
|
28 |
$args = array( 'timeout' => $this->timeout, 'redirection' => $this->redirects);
|
29 |
+
|
30 |
if ( !empty($this->headers) )
|
31 |
$args['headers'] = $this->headers;
|
32 |
|
58 |
$args['authentication'] = $source->authentication_method();
|
59 |
$args['username'] = $source->username();
|
60 |
$args['password'] = $source->password();
|
61 |
+
|
62 |
endif;
|
63 |
|
64 |
+
FeedWordPress::diagnostic('updated_feeds:http', "HTTP [$url] ⇜ ".esc_html(MyPHP::val($args)));
|
65 |
$res = wp_remote_request($url, $args);
|
66 |
+
FeedWordPress::diagnostic('updated_feeds:http', "HTTP [$url] ⇝ ".esc_html(MyPHP::val($res)));
|
67 |
|
68 |
if ( is_wp_error($res) ) {
|
69 |
$this->error = 'WP HTTP Error: ' . $res->get_error_message();
|
73 |
$this->body = wp_remote_retrieve_body( $res );
|
74 |
$this->status_code = wp_remote_retrieve_response_code( $res );
|
75 |
}
|
76 |
+
|
77 |
if ($source InstanceOf SyndicatedLink) :
|
78 |
$source->update_setting('link/filesize', strlen($this->body));
|
79 |
$source->update_setting('link/http status', $this->status_code);
|
80 |
$source->save_settings(/*reload=*/ true);
|
81 |
endif;
|
82 |
+
|
83 |
// Do not allow schemes other than http(s)? for the time being.
|
84 |
// They are unlikely to be used; and unrestricted use of schemes
|
85 |
// allows for user to use an unrestricted file:/// scheme, which
|
@@ -1,6 +1,6 @@
|
|
1 |
-
<?php
|
2 |
class FeedWordPressHTML {
|
3 |
-
function attributeRegex ($tag, $attr) {
|
4 |
return ":(
|
5 |
(<($tag)\s+[^>]*)
|
6 |
($attr)=
|
@@ -16,7 +16,7 @@ class FeedWordPressHTML {
|
|
16 |
:ix";
|
17 |
} /* function FeedWordPressHTML::attributeRegex () */
|
18 |
|
19 |
-
function attributeMatch ($matches) {
|
20 |
for ($i = 0; $i <= 12; $i++) :
|
21 |
if (!isset($matches[$i])) :
|
22 |
$matches[$i] = '';
|
@@ -38,7 +38,7 @@ class FeedWordPressHTML {
|
|
38 |
);
|
39 |
} /* function FeedWordPressHTML::attributeMatch () */
|
40 |
|
41 |
-
function tagWithAttributeRegex ($tag, $attr, $value, $closing = true) {
|
42 |
return ":(
|
43 |
(<($tag)\s+[^>]*)
|
44 |
($attr)=
|
@@ -57,7 +57,7 @@ class FeedWordPressHTML {
|
|
57 |
:ix";
|
58 |
} /* FeedWordPressHTML::tagWithAttributeRegex () */
|
59 |
|
60 |
-
function tagWithAttributeMatch ($matches, $closing = true) {
|
61 |
for ($i = 0; $i <= 21; $i++) :
|
62 |
if (!isset($matches[$i])) :
|
63 |
$matches[$i] = '';
|
1 |
+
<?php
|
2 |
class FeedWordPressHTML {
|
3 |
+
static function attributeRegex ($tag, $attr) {
|
4 |
return ":(
|
5 |
(<($tag)\s+[^>]*)
|
6 |
($attr)=
|
16 |
:ix";
|
17 |
} /* function FeedWordPressHTML::attributeRegex () */
|
18 |
|
19 |
+
static function attributeMatch ($matches) {
|
20 |
for ($i = 0; $i <= 12; $i++) :
|
21 |
if (!isset($matches[$i])) :
|
22 |
$matches[$i] = '';
|
38 |
);
|
39 |
} /* function FeedWordPressHTML::attributeMatch () */
|
40 |
|
41 |
+
static function tagWithAttributeRegex ($tag, $attr, $value, $closing = true) {
|
42 |
return ":(
|
43 |
(<($tag)\s+[^>]*)
|
44 |
($attr)=
|
57 |
:ix";
|
58 |
} /* FeedWordPressHTML::tagWithAttributeRegex () */
|
59 |
|
60 |
+
static function tagWithAttributeMatch ($matches, $closing = true) {
|
61 |
for ($i = 0; $i <= 21; $i++) :
|
62 |
if (!isset($matches[$i])) :
|
63 |
$matches[$i] = '';
|
@@ -1,8 +1,9 @@
|
|
1 |
<?php
|
2 |
|
3 |
class FeedWordPressLocalPost {
|
4 |
-
|
5 |
-
|
|
|
6 |
public function __construct ($p = NULL) {
|
7 |
global $post;
|
8 |
|
@@ -92,7 +93,8 @@ class FeedWordPressLocalPost {
|
|
92 |
|
93 |
public function feed () {
|
94 |
global $feedwordpress;
|
95 |
-
|
|
|
96 |
}
|
97 |
|
98 |
public function feed_id () {
|
@@ -146,5 +148,41 @@ class FeedWordPressLocalPost {
|
|
146 |
|
147 |
} /* FeedWordPressLocalPost::is_exposed_to_formatting_filters () */
|
148 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
149 |
} /* class FeedWordPressLocalPost */
|
150 |
|
1 |
<?php
|
2 |
|
3 |
class FeedWordPressLocalPost {
|
4 |
+
public $post;
|
5 |
+
public $link;
|
6 |
+
|
7 |
public function __construct ($p = NULL) {
|
8 |
global $post;
|
9 |
|
93 |
|
94 |
public function feed () {
|
95 |
global $feedwordpress;
|
96 |
+
$this->link = $feedwordpress->subscription($this->feed_id());
|
97 |
+
return $this->link;
|
98 |
}
|
99 |
|
100 |
public function feed_id () {
|
148 |
|
149 |
} /* FeedWordPressLocalPost::is_exposed_to_formatting_filters () */
|
150 |
|
151 |
+
|
152 |
+
public function content () {
|
153 |
+
return apply_filters('the_content', $this->post->post_content, $this->post->ID);
|
154 |
+
}
|
155 |
+
|
156 |
+
public function title () {
|
157 |
+
return apply_filters('the_title', $this->post->post_title, $this->post->ID);
|
158 |
+
}
|
159 |
+
|
160 |
+
public function guid () {
|
161 |
+
return apply_filters('get_the_guid', $this->post->guid);
|
162 |
+
}
|
163 |
+
|
164 |
+
public function get_categories () {
|
165 |
+
$terms = wp_get_object_terms(
|
166 |
+
$this->post->ID,
|
167 |
+
get_taxonomies(array(
|
168 |
+
'public' => true,
|
169 |
+
), 'names'),
|
170 |
+
'all'
|
171 |
+
);
|
172 |
+
$rootUrl = get_bloginfo('url');
|
173 |
+
|
174 |
+
$cats = array();
|
175 |
+
foreach ($terms as $term) :
|
176 |
+
$taxUrl = MyPHP::url($rootUrl, array("taxonomy" => $term->taxonomy));
|
177 |
+
//array("taxonomy" => $term->taxonomy ));
|
178 |
+
$cats[] = new SimplePie_Category(
|
179 |
+
/*term=*/ $term->slug,
|
180 |
+
/*scheme=*/ $taxUrl,
|
181 |
+
/*label=*/ $term->name
|
182 |
+
);
|
183 |
+
endforeach;
|
184 |
+
return $cats;
|
185 |
+
}
|
186 |
+
|
187 |
} /* class FeedWordPressLocalPost */
|
188 |
|
@@ -24,11 +24,8 @@ class FeedWordPressRPC {
|
|
24 |
if (is_null($delta)):
|
25 |
return array('flerror' => true, 'message' => "Sorry. I don't syndicate <$args[1]>.");
|
26 |
else:
|
27 |
-
|
28 |
-
|
29 |
-
if (isset($delta['updated'])) { $mesg[] = ' '.$delta['updated'].' existing posts were updated'; }
|
30 |
-
|
31 |
-
return array('flerror' => false, 'message' => "Thanks for the ping.".implode(' and', $mesg));
|
32 |
endif;
|
33 |
}
|
34 |
|
24 |
if (is_null($delta)):
|
25 |
return array('flerror' => true, 'message' => "Sorry. I don't syndicate <$args[1]>.");
|
26 |
else:
|
27 |
+
$mesg = array();
|
28 |
+
return array('flerror' => false, 'message' => "Thanks for the ping.".fwp_update_set_results_message($delta));
|
|
|
|
|
|
|
29 |
endif;
|
30 |
}
|
31 |
|
@@ -649,17 +649,48 @@ class FeedWordPressSyndicationPage extends FeedWordPressAdminPage {
|
|
649 |
|
650 |
function bleg_box ($page, $box = NULL) {
|
651 |
?>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
652 |
<div class="donation-form">
|
653 |
-
<h4>
|
654 |
<form action="https://www.paypal.com/cgi-bin/webscr" accept-charset="UTF-8" method="post"><div>
|
655 |
<p><a href="http://feedwordpress.radgeek.com/">FeedWordPress</a> makes syndication
|
656 |
simple and empowers you to stream content from all over the web into your
|
657 |
-
WordPress hub.
|
658 |
<a href="http://feedwordpress.radgeek.com/donate/">a modest gift</a>
|
659 |
is the best way to support steady progress on development, enhancements,
|
660 |
support, and documentation.</p>
|
661 |
-
|
662 |
-
<
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
663 |
<input type="hidden" name="cmd" value="_xclick" />
|
664 |
<input type="hidden" name="item_name" value="FeedWordPress donation" />
|
665 |
<input type="hidden" name="no_shipping" value="1" />
|
@@ -667,9 +698,14 @@ support, and documentation.</p>
|
|
667 |
<input type="hidden" name="currency_code" value="USD" />
|
668 |
<input type="hidden" name="notify_url" value="http://feedwordpress.radgeek.com/ipn/donation" />
|
669 |
<input type="hidden" name="custom" value="1" />
|
670 |
-
<
|
671 |
-
</div>
|
672 |
-
|
|
|
|
|
|
|
|
|
|
|
673 |
|
674 |
<p>You can make a gift online (or
|
675 |
<a href="http://feedwordpress.radgeek.com/donation">set up an automatic
|
@@ -1023,10 +1059,7 @@ function fwp_dashboard_update_if_requested ($object) {
|
|
1023 |
echo "</ul>\n";
|
1024 |
|
1025 |
if (!is_null($tdelta)) :
|
1026 |
-
|
1027 |
-
if (isset($delta['new'])) : $mesg[] = ' '.$tdelta['new'].' new posts were syndicated'; endif;
|
1028 |
-
if (isset($delta['updated'])) : $mesg[] = ' '.$tdelta['updated'].' existing posts were updated'; endif;
|
1029 |
-
echo "<p>Update complete.".implode(' and', $mesg)."</p>";
|
1030 |
echo "\n"; flush();
|
1031 |
endif;
|
1032 |
echo "</div> <!-- class=\"updated\" -->\n";
|
649 |
|
650 |
function bleg_box ($page, $box = NULL) {
|
651 |
?>
|
652 |
+
<script type="text/javascript">
|
653 |
+
/* <![CDATA[ */
|
654 |
+
(function() {
|
655 |
+
var s = document.createElement('script'), t = document.getElementsByTagName('script')[0];
|
656 |
+
s.type = 'text/javascript';
|
657 |
+
s.async = true;
|
658 |
+
s.src = 'http://api.flattr.com/js/0.6/load.js?mode=auto';
|
659 |
+
t.parentNode.insertBefore(s, t);
|
660 |
+
})();
|
661 |
+
/* ]]> */</script>
|
662 |
+
|
663 |
<div class="donation-form">
|
664 |
+
<h4>Consider a Donation to FeedWordPress</h4>
|
665 |
<form action="https://www.paypal.com/cgi-bin/webscr" accept-charset="UTF-8" method="post"><div>
|
666 |
<p><a href="http://feedwordpress.radgeek.com/">FeedWordPress</a> makes syndication
|
667 |
simple and empowers you to stream content from all over the web into your
|
668 |
+
WordPress hub. If you’re finding FWP useful,
|
669 |
<a href="http://feedwordpress.radgeek.com/donate/">a modest gift</a>
|
670 |
is the best way to support steady progress on development, enhancements,
|
671 |
support, and documentation.</p>
|
672 |
+
|
673 |
+
<div class="donate" style="vertical-align: middle">
|
674 |
+
|
675 |
+
<div id="flattr-paypal">
|
676 |
+
|
677 |
+
<div style="display: inline-block; vertical-align: middle; ">
|
678 |
+
<a class="FlattrButton" style="display:none;" href="http://feedwordpress.radgeek.com/"></a>
|
679 |
+
<noscript>
|
680 |
+
<a href="http://flattr.com/thing/1380856/FeedWordPress" target="_blank"><img src="http://api.flattr.com/button/flattr-badge-large.png" alt="Flattr this" title="Flattr this" border="0" /></a>
|
681 |
+
</noscript>
|
682 |
+
<div>via Flattr</div>
|
683 |
+
|
684 |
+
</div> <!-- style="display: inline-block" -->
|
685 |
+
|
686 |
+
<div class="hovered-component" style="display: inline-block; vertical-align: bottom">
|
687 |
+
<a href="bitcoin:<?php print esc_attr(FEEDWORDPRESS_BLEG_BTC); ?>"><img src="<?php print esc_url(WP_PLUGIN_URL.'/'.FeedWordPress::path('btc-qr-64px.png')); ?>" alt="Donate" /></a>
|
688 |
+
<div><a href="bitcoin:<?php print esc_attr(FEEDWORDPRESS_BLEG_BTC); ?>">via bitcoin<span class="hover-on pop-over" style="background-color: #ddffdd; padding: 5px; color: black; border-radius: 5px;">bitcoin:<?php print esc_html(FEEDWORDPRESS_BLEG_BTC); ?></span></a></div>
|
689 |
+
</div>
|
690 |
+
|
691 |
+
<div style="display: inline-block; vertical-align: bottom">
|
692 |
+
<input type="image" name="submit" src="<?php print esc_url(WP_PLUGIN_URL.'/'.FeedWordPress::path('paypal-donation-64px.png')); ?>" alt="Donate through PayPal" />
|
693 |
+
<input type="hidden" name="business" value="distro.to.feedback@radgeek.com" />
|
694 |
<input type="hidden" name="cmd" value="_xclick" />
|
695 |
<input type="hidden" name="item_name" value="FeedWordPress donation" />
|
696 |
<input type="hidden" name="no_shipping" value="1" />
|
698 |
<input type="hidden" name="currency_code" value="USD" />
|
699 |
<input type="hidden" name="notify_url" value="http://feedwordpress.radgeek.com/ipn/donation" />
|
700 |
<input type="hidden" name="custom" value="1" />
|
701 |
+
<div>via PayPal</div>
|
702 |
+
</div> <!-- style="display: inline-block" -->
|
703 |
+
|
704 |
+
</div> <!-- id="flattr-paypal" -->
|
705 |
+
</div> <!-- class="donate" -->
|
706 |
+
|
707 |
+
</div> <!-- class="donation-form" -->
|
708 |
+
</form>
|
709 |
|
710 |
<p>You can make a gift online (or
|
711 |
<a href="http://feedwordpress.radgeek.com/donation">set up an automatic
|
1059 |
echo "</ul>\n";
|
1060 |
|
1061 |
if (!is_null($tdelta)) :
|
1062 |
+
echo "<p><strong>Update complete.</strong>".fwp_update_set_results_message($delta)."</p>";
|
|
|
|
|
|
|
1063 |
echo "\n"; flush();
|
1064 |
endif;
|
1065 |
echo "</div> <!-- class=\"updated\" -->\n";
|
@@ -9,19 +9,15 @@
|
|
9 |
|
10 |
class InspectPostMeta {
|
11 |
function InspectPostMeta ($in_hook = true) {
|
12 |
-
|
13 |
-
add_action('admin_menu', array($this, 'add_meta_box'));
|
14 |
-
else :
|
15 |
-
$this->add_meta_box();
|
16 |
-
endif;
|
17 |
}
|
18 |
|
19 |
-
function
|
20 |
add_meta_box(
|
21 |
/*id=*/ 'inspect_post_guid_box',
|
22 |
/*title=*/ 'Post GUID and Meta Data',
|
23 |
/*callback=*/ array($this, 'meta_box'),
|
24 |
-
/*page=*/
|
25 |
/*context=*/ 'normal',
|
26 |
/*priority=*/ 'default'
|
27 |
);
|
9 |
|
10 |
class InspectPostMeta {
|
11 |
function InspectPostMeta ($in_hook = true) {
|
12 |
+
add_action('add_meta_boxes', array($this, 'add_meta_boxes'), 10, 2);
|
|
|
|
|
|
|
|
|
13 |
}
|
14 |
|
15 |
+
function add_meta_boxes ($post_type, $post) {
|
16 |
add_meta_box(
|
17 |
/*id=*/ 'inspect_post_guid_box',
|
18 |
/*title=*/ 'Post GUID and Meta Data',
|
19 |
/*callback=*/ array($this, 'meta_box'),
|
20 |
+
/*page=*/ $post_type,
|
21 |
/*context=*/ 'normal',
|
22 |
/*priority=*/ 'default'
|
23 |
);
|
@@ -89,7 +89,7 @@ class MagpieFromSimplePie {
|
|
89 |
endif;
|
90 |
|
91 |
$this->normalize();
|
92 |
-
|
93 |
// In case anyone goes poking around our private members (uh...)
|
94 |
$this->feed_type = ($this->is_atom() ? 'Atom' : 'RSS');
|
95 |
$this->feed_version = $this->feed_version();
|
89 |
endif;
|
90 |
|
91 |
$this->normalize();
|
92 |
+
|
93 |
// In case anyone goes poking around our private members (uh...)
|
94 |
$this->feed_type = ($this->is_atom() ? 'Atom' : 'RSS');
|
95 |
$this->feed_version = $this->feed_version();
|
@@ -6,7 +6,7 @@ class MagpieMockLink extends SyndicatedLink {
|
|
6 |
|
7 |
function MagpieMockLink ($rss, $url) {
|
8 |
$this->link = $rss;
|
9 |
-
|
10 |
if (is_array($rss) and isset($rss['simplepie']) and isset($rss['magpie'])) :
|
11 |
$this->simplepie = $rss['simplepie'];
|
12 |
$this->magpie = $rss['magpie'];
|
@@ -18,7 +18,7 @@ class MagpieMockLink extends SyndicatedLink {
|
|
18 |
$this->id = -1;
|
19 |
$this->settings = array(
|
20 |
'unfamiliar category' => 'default',
|
21 |
-
|
22 |
);
|
23 |
} /* function MagpieMockLink::MagpieMockLink () */
|
24 |
|
@@ -30,14 +30,14 @@ class MagpieMockLink extends SyndicatedLink {
|
|
30 |
$this->link = $this->magpie;
|
31 |
} /* function MagpieMockLink::poll () */
|
32 |
|
33 |
-
function uri () {
|
34 |
return $this->url;
|
35 |
} /* function MagpieMockLink::uri() */
|
36 |
|
37 |
-
function homepage () {
|
38 |
return (!is_wp_error($this->simplepie) ? $this->simplepie->get_link() : null);
|
39 |
} /* function MagpieMockLink::homepage () */
|
40 |
-
|
41 |
function save_settings ($reload = false) {
|
42 |
// NOOP.
|
43 |
}
|
6 |
|
7 |
function MagpieMockLink ($rss, $url) {
|
8 |
$this->link = $rss;
|
9 |
+
|
10 |
if (is_array($rss) and isset($rss['simplepie']) and isset($rss['magpie'])) :
|
11 |
$this->simplepie = $rss['simplepie'];
|
12 |
$this->magpie = $rss['magpie'];
|
18 |
$this->id = -1;
|
19 |
$this->settings = array(
|
20 |
'unfamiliar category' => 'default',
|
21 |
+
|
22 |
);
|
23 |
} /* function MagpieMockLink::MagpieMockLink () */
|
24 |
|
30 |
$this->link = $this->magpie;
|
31 |
} /* function MagpieMockLink::poll () */
|
32 |
|
33 |
+
function uri ($params = array()) {
|
34 |
return $this->url;
|
35 |
} /* function MagpieMockLink::uri() */
|
36 |
|
37 |
+
function homepage ($fromFeed = true) {
|
38 |
return (!is_wp_error($this->simplepie) ? $this->simplepie->get_link() : null);
|
39 |
} /* function MagpieMockLink::homepage () */
|
40 |
+
|
41 |
function save_settings ($reload = false) {
|
42 |
// NOOP.
|
43 |
}
|
Binary file
|
@@ -14,15 +14,15 @@ class FeedWordPressPerformancePage extends FeedWordPressAdminPage {
|
|
14 |
function display () {
|
15 |
global $wpdb, $wp_db_version, $fwp_path;
|
16 |
global $fwp_post;
|
17 |
-
|
18 |
if (FeedWordPress::needs_upgrade()) :
|
19 |
fwp_upgrade_page();
|
20 |
return;
|
21 |
endif;
|
22 |
-
|
23 |
// If this is a POST, validate source and user credentials
|
24 |
FeedWordPressCompatibility::validate_http_request(/*action=*/ 'feedwordpress_performance', /*capability=*/ 'manage_options');
|
25 |
-
|
26 |
if (strtoupper($_SERVER['REQUEST_METHOD'])=='POST') :
|
27 |
$this->accept_POST($fwp_post);
|
28 |
do_action('feedwordpress_admin_page_performance_save', $fwp_post, $this);
|
@@ -41,7 +41,7 @@ class FeedWordPressPerformancePage extends FeedWordPressAdminPage {
|
|
41 |
$boxes_by_methods = array(
|
42 |
'performance_box' => __('Performance'),
|
43 |
);
|
44 |
-
|
45 |
foreach ($boxes_by_methods as $method => $title) :
|
46 |
add_meta_box(
|
47 |
/*id=*/ 'feedwordpress_'.$method,
|
@@ -79,19 +79,11 @@ class FeedWordPressPerformancePage extends FeedWordPressAdminPage {
|
|
79 |
$feeds = (($N == 1) ? __("feed") : __("feeds"));
|
80 |
$this->updated = sprintf(__("Cleared %d cached %s from WordPress database."), $N, $feeds);
|
81 |
endif;
|
82 |
-
|
83 |
-
if (isset($post['optimize_in'])) :
|
84 |
-
update_option('feedwordpress_optimize_in_clauses', true);
|
85 |
-
$this->updated = sprintf(__("Enabled optimizing inefficient IN clauses in SQL queries."));
|
86 |
-
elseif (isset($post['optimize_out'])) :
|
87 |
-
update_option('feedwordpress_optimize_in_clauses', false);
|
88 |
-
$this->updated = sprintf(__("Disabled optimizing inefficient IN clauses in SQL queries."));
|
89 |
-
endif;
|
90 |
} /* FeedWordPressPerformancePage::accept_POST () */
|
91 |
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
// Hey ho, let's go...
|
96 |
?>
|
97 |
<table class="editform" width="100%" cellspacing="2" cellpadding="5">
|
@@ -116,33 +108,6 @@ table. If you'd like to remove the index for any reason, you can do so here.</p>
|
|
116 |
|
117 |
<?php endif; ?>
|
118 |
|
119 |
-
<tr style="vertical-align: top">
|
120 |
-
<th width="33%" scope="row">Optimize IN clauses:</th>
|
121 |
-
<td width="67%"><?php if (!$optimize_in) : ?>
|
122 |
-
<input class="button" type="submit" name="optimize_in" value="Optimize inefficient IN clauses in SQL queries" />
|
123 |
-
|
124 |
-
<p><strong>Advanced setting.</strong> As of releases up to 3.3.2, WordPress
|
125 |
-
still generates many SQL queries with an extremely inefficient use of the IN
|
126 |
-
operator (for example, <code>SELECT user_id, meta_key, meta_value FROM
|
127 |
-
wp_usermeta WHERE user_id IN (1)</code>). When there is only one item in the
|
128 |
-
set, the IN operator is unnecessary; and inefficient, because it prevents SQL
|
129 |
-
from making use of indexes on the table being queried. Activating this setting
|
130 |
-
will cause these queries to get rewritten to use a simple equality operator when
|
131 |
-
there is only one item in the set (for example, the example query above would be
|
132 |
-
rewritten as <code>SELECT user_id, meta_key, meta_value FROM wp_usermeta WHERE
|
133 |
-
user_id = 1</code>).</p>
|
134 |
-
|
135 |
-
<p><strong>Note.</strong> This is an advanced setting, which affects WordPress's
|
136 |
-
database queries at a very low level. The change should be harmless, but
|
137 |
-
proceed with caution, and only if you are confident in your ability to restore
|
138 |
-
your WordPress installation from backups if something important should stop
|
139 |
-
working.</p>
|
140 |
-
|
141 |
-
<?php else : ?>
|
142 |
-
<input class="button" type="submit" name="optimize_out" value="Disable optimizing inefficient IN clauses" />
|
143 |
-
<p>You can use this setting to disable any attempts by FeedWordPress to optimize
|
144 |
-
or rewrite WordPress's SQL queries.</p>
|
145 |
-
<?php endif; ?></td>
|
146 |
</tr>
|
147 |
|
148 |
</td>
|
14 |
function display () {
|
15 |
global $wpdb, $wp_db_version, $fwp_path;
|
16 |
global $fwp_post;
|
17 |
+
|
18 |
if (FeedWordPress::needs_upgrade()) :
|
19 |
fwp_upgrade_page();
|
20 |
return;
|
21 |
endif;
|
22 |
+
|
23 |
// If this is a POST, validate source and user credentials
|
24 |
FeedWordPressCompatibility::validate_http_request(/*action=*/ 'feedwordpress_performance', /*capability=*/ 'manage_options');
|
25 |
+
|
26 |
if (strtoupper($_SERVER['REQUEST_METHOD'])=='POST') :
|
27 |
$this->accept_POST($fwp_post);
|
28 |
do_action('feedwordpress_admin_page_performance_save', $fwp_post, $this);
|
41 |
$boxes_by_methods = array(
|
42 |
'performance_box' => __('Performance'),
|
43 |
);
|
44 |
+
|
45 |
foreach ($boxes_by_methods as $method => $title) :
|
46 |
add_meta_box(
|
47 |
/*id=*/ 'feedwordpress_'.$method,
|
79 |
$feeds = (($N == 1) ? __("feed") : __("feeds"));
|
80 |
$this->updated = sprintf(__("Cleared %d cached %s from WordPress database."), $N, $feeds);
|
81 |
endif;
|
82 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
83 |
} /* FeedWordPressPerformancePage::accept_POST () */
|
84 |
|
85 |
+
static function performance_box ($page, $box = NULL) {
|
86 |
+
|
|
|
87 |
// Hey ho, let's go...
|
88 |
?>
|
89 |
<table class="editform" width="100%" cellspacing="2" cellpadding="5">
|
108 |
|
109 |
<?php endif; ?>
|
110 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
111 |
</tr>
|
112 |
|
113 |
</td>
|
@@ -3,8 +3,8 @@ Contributors: Charles Johnson
|
|
3 |
Donate link: http://feedwordpress.radgeek.com/
|
4 |
Tags: syndication, aggregation, feed, atom, rss
|
5 |
Requires at least: 3.0
|
6 |
-
Tested up to: 3.
|
7 |
-
Stable tag:
|
8 |
|
9 |
FeedWordPress syndicates content from feeds you choose into your WordPress weblog.
|
10 |
|
@@ -94,12 +94,46 @@ outs, see the documentation at the [FeedWordPress project homepage][].
|
|
94 |
|
95 |
== Changelog ==
|
96 |
|
97 |
-
=
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
98 |
|
|
|
|
|
99 |
* BUGFIX: PHP 5.4 compatibility -- includes some more extensive fixes to
|
100 |
compatibility issues with PHP 5.4's handling of global variables
|
101 |
|
102 |
-
*
|
|
|
|
|
|
|
|
|
|
|
103 |
properly included regardless of whether you are installing from github,
|
104 |
from SVN, or from the WordPress plugins page. If you've been getting
|
105 |
fatal errors about required modules not being found, this release should
|
3 |
Donate link: http://feedwordpress.radgeek.com/
|
4 |
Tags: syndication, aggregation, feed, atom, rss
|
5 |
Requires at least: 3.0
|
6 |
+
Tested up to: 3.9.1
|
7 |
+
Stable tag: 2014.0805
|
8 |
|
9 |
FeedWordPress syndicates content from feeds you choose into your WordPress weblog.
|
10 |
|
94 |
|
95 |
== Changelog ==
|
96 |
|
97 |
+
= 2014.0805 =
|
98 |
+
|
99 |
+
|
100 |
+
* FILTERS AND ADD-ONS: A number of new hooks for filters and add-ons to
|
101 |
+
further customize the behavior of FWP have been added.
|
102 |
+
|
103 |
+
* COMPATIBILITY/BUGFIX: Many users saw odd characters, especially "n,"
|
104 |
+
appearing in posts in versions of WordPress from 3.6 on, due to a change
|
105 |
+
in when the API expects HTML data for posts to be slashed and when it
|
106 |
+
does not. This has been fixed, so that the junk characters should no
|
107 |
+
longer appear, regardless of your version of WordPress.
|
108 |
+
|
109 |
+
* BUGFIX: A bug preventing FWP from saving categories assigned under
|
110 |
+
Syndication > Categories & Tags has been fixed.
|
111 |
+
|
112 |
+
* BUGFIX: Post-editing related metaboxes should now show up when you edit
|
113 |
+
items of any post type, including custom types, not only normal WordPress
|
114 |
+
posts.
|
115 |
+
|
116 |
+
* BUGFIX: A bug in the admin UI that caused the "Alternative Feeds" /
|
117 |
+
"Find Feeds" box to throw a permissions error has been fixed.
|
118 |
+
|
119 |
+
* BUGFIX: A bug preventing proper mapping of categories and other terms in
|
120 |
+
2013.0504 has been fixed.
|
121 |
+
|
122 |
+
* BUGFIX: A number of small fixes contributed through Github by Flynsarmy
|
123 |
+
should eliminate PHP warnings for many users on several methods that are
|
124 |
+
called as static methods within FeedWordPress.
|
125 |
|
126 |
+
= 2013.0504 =
|
127 |
+
|
128 |
* BUGFIX: PHP 5.4 compatibility -- includes some more extensive fixes to
|
129 |
compatibility issues with PHP 5.4's handling of global variables
|
130 |
|
131 |
+
* DIAGNOSTICS: New diagnostics settings added to help track behavior of
|
132 |
+
terms (categories, post tags, etc.) for syndicated posts.
|
133 |
+
|
134 |
+
= 2012.0504 =
|
135 |
+
|
136 |
+
* MODULE REORGANIZATION: Should ensure that all needed submodules will be
|
137 |
properly included regardless of whether you are installing from github,
|
138 |
from SVN, or from the WordPress plugins page. If you've been getting
|
139 |
fatal errors about required modules not being found, this release should
|
@@ -25,7 +25,7 @@
|
|
25 |
# backslashes (so, for example, a newline becomes "\n").
|
26 |
#
|
27 |
# The value of `cats` is used as a newline-separated list of
|
28 |
-
# default categories for any post coming from a particular feed.
|
29 |
# (In the example above, any posts from this feed will be placed
|
30 |
# in the "computers" and "web" categories--*in addition to* any
|
31 |
# categories that may already be applied to the posts.)
|
@@ -40,7 +40,7 @@ class SyndicatedLink {
|
|
40 |
var $id = null;
|
41 |
var $link = null;
|
42 |
var $settings = array ();
|
43 |
-
|
44 |
var $magpie = null;
|
45 |
|
46 |
function SyndicatedLink ($link) {
|
@@ -50,17 +50,17 @@ class SyndicatedLink {
|
|
50 |
$this->link = $link;
|
51 |
$this->id = $link->link_id;
|
52 |
else :
|
53 |
-
$this->id = $link;
|
54 |
$this->link = get_bookmark($link);
|
55 |
endif;
|
56 |
|
57 |
if (strlen($this->link->link_rss) > 0) :
|
58 |
$this->get_settings_from_notes();
|
59 |
endif;
|
60 |
-
|
61 |
add_filter('feedwordpress_update_complete', array($this, 'process_retirements'), 1000, 1);
|
62 |
} /* SyndicatedLink::SyndicatedLink () */
|
63 |
-
|
64 |
function found () {
|
65 |
return is_object($this->link) and !is_wp_error($this->link);
|
66 |
} /* SyndicatedLink::found () */
|
@@ -68,10 +68,10 @@ class SyndicatedLink {
|
|
68 |
function id () {
|
69 |
return (is_object($this->link) ? $this->link->link_id : NULL);
|
70 |
}
|
71 |
-
|
72 |
function stale () {
|
73 |
global $feedwordpress;
|
74 |
-
|
75 |
$stale = true;
|
76 |
if ($this->setting('update/hold')=='ping') :
|
77 |
$stale = false; // don't update on any timed updates; pings only
|
@@ -112,7 +112,7 @@ class SyndicatedLink {
|
|
112 |
if (!is_object($this->simplepie)) :
|
113 |
$this->fetch();
|
114 |
endif;
|
115 |
-
|
116 |
if (is_object($this->simplepie) and method_exists($this->simplepie, 'get_items')) :
|
117 |
$ret = apply_filters(
|
118 |
'syndicated_feed_items',
|
@@ -124,11 +124,11 @@ class SyndicatedLink {
|
|
124 |
endif;
|
125 |
return $ret;
|
126 |
}
|
127 |
-
|
128 |
function poll ($crash_ts = NULL) {
|
129 |
global $wpdb;
|
130 |
|
131 |
-
$url = $this->uri(array('add_params' => true));
|
132 |
FeedWordPress::diagnostic('updated_feeds', 'Polling feed ['.$url.']');
|
133 |
|
134 |
$this->fetch();
|
@@ -160,7 +160,7 @@ class SyndicatedLink {
|
|
160 |
if (!is_null($oldError)) :
|
161 |
// Copy over the in-error-since timestamp
|
162 |
$theError['since'] = $oldError['since'];
|
163 |
-
|
164 |
// If this is a repeat error, then we should
|
165 |
// take a step back before we try to fetch it
|
166 |
// again.
|
@@ -171,9 +171,9 @@ class SyndicatedLink {
|
|
171 |
$this->update_setting('update/ttl', $ttl, $this);
|
172 |
$this->update_setting('update/timed', 'automatically');
|
173 |
endif;
|
174 |
-
|
175 |
do_action('syndicated_feed_error', $theError, $oldError, $this);
|
176 |
-
|
177 |
$this->update_setting('update/error', serialize($theError));
|
178 |
$this->save_settings(/*reload=*/ true);
|
179 |
|
@@ -189,21 +189,21 @@ class SyndicatedLink {
|
|
189 |
if (!isset($channel['id'])) :
|
190 |
$channel['id'] = $this->link->link_rss;
|
191 |
endif;
|
192 |
-
|
193 |
$update = array();
|
194 |
if (!$this->hardcode('url') and isset($channel['link'])) :
|
195 |
-
$update[] = "link_url = '"
|
196 |
endif;
|
197 |
-
|
198 |
if (!$this->hardcode('name') and isset($channel['title'])) :
|
199 |
-
$update[] = "link_name = '"
|
200 |
endif;
|
201 |
-
|
202 |
if (!$this->hardcode('description')) :
|
203 |
if (isset($channel['tagline'])) :
|
204 |
-
$update[] = "link_description = '"
|
205 |
elseif (isset($channel['description'])) :
|
206 |
-
$update[] = "link_description = '"
|
207 |
endif;
|
208 |
endif;
|
209 |
|
@@ -211,7 +211,7 @@ class SyndicatedLink {
|
|
211 |
|
212 |
$this->update_setting('update/last', time());
|
213 |
list($ttl, $xml) = $this->ttl(/*return element=*/ true);
|
214 |
-
|
215 |
if (!is_null($ttl)) :
|
216 |
$this->update_setting('update/ttl', $ttl);
|
217 |
$this->update_setting('update/xml', $xml);
|
@@ -235,10 +235,10 @@ class SyndicatedLink {
|
|
235 |
|
236 |
$this->update_setting('update/unfinished', 'yes');
|
237 |
|
238 |
-
$update[] = "link_notes = '"
|
239 |
|
240 |
$update_set = implode(',', $update);
|
241 |
-
|
242 |
// Update the properties of the link from the feed information
|
243 |
$result = $wpdb->query("
|
244 |
UPDATE $wpdb->links
|
@@ -251,12 +251,12 @@ class SyndicatedLink {
|
|
251 |
$crashed = false;
|
252 |
|
253 |
$posts = $this->live_posts();
|
254 |
-
|
255 |
$this->magpie->originals = $posts;
|
256 |
|
257 |
// If this is a complete feed, rather than an incremental feed, we
|
258 |
// need to prepare to mark everything for presumptive retirement.
|
259 |
-
if ($this->
|
260 |
$q = new WP_Query(array(
|
261 |
'fields' => '_synfrom',
|
262 |
'post_status__not' => 'fwpretired',
|
@@ -268,7 +268,7 @@ class SyndicatedLink {
|
|
268 |
update_post_meta($p->ID, '_feedwordpress_retire_me_'.$this->id, '1');
|
269 |
endforeach;
|
270 |
endif;
|
271 |
-
|
272 |
if (is_array($posts)) :
|
273 |
foreach ($posts as $key => $item) :
|
274 |
$post = new SyndicatedPost($item, $this);
|
@@ -288,7 +288,7 @@ class SyndicatedLink {
|
|
288 |
unset($post);
|
289 |
endforeach;
|
290 |
endif;
|
291 |
-
|
292 |
if ('yes'==$this->setting('tombstones', 'tombstones', 'yes')) :
|
293 |
// Check for use of Atom tombstones. Spec:
|
294 |
// <http://tools.ietf.org/html/draft-snell-atompub-tombstones-18>
|
@@ -302,25 +302,25 @@ class SyndicatedLink {
|
|
302 |
$ref = $tombstone['attribs'][$ns]['ref'];
|
303 |
endif;
|
304 |
endforeach;
|
305 |
-
|
306 |
$q = new WP_Query(array(
|
307 |
'ignore_sticky_posts' => true,
|
308 |
'guid' => $ref,
|
309 |
'meta_key' => 'syndication_feed_id',
|
310 |
'meta_value' => $this->id, // Only allow a feed to tombstone its own entries.
|
311 |
));
|
312 |
-
|
313 |
foreach ($q->posts as $p) :
|
314 |
$old_status = $p->post_status;
|
315 |
FeedWordPress::diagnostic('syndicated_posts', 'Retiring existing post # '.$p->ID.' "'.$p->post_title.'" due to Atom tombstone element in feed.');
|
316 |
set_post_field('post_status', 'fwpretired', $p->ID);
|
317 |
wp_transition_post_status('fwpretired', $old_status, $p);
|
318 |
endforeach;
|
319 |
-
|
320 |
endforeach;
|
321 |
endif;
|
322 |
endif;
|
323 |
-
|
324 |
$suffix = ($crashed ? 'crashed' : 'completed');
|
325 |
do_action('update_syndicated_feed_items', $this->id, $this);
|
326 |
do_action("update_syndicated_feed_items_${suffix}", $this->id, $this);
|
@@ -333,28 +333,28 @@ class SyndicatedLink {
|
|
333 |
|
334 |
// Copy back any changes to feed settings made in the
|
335 |
// course of updating (e.g. new author rules)
|
336 |
-
$update_set = "link_notes = '"
|
337 |
-
|
338 |
// Update the properties of the link from the feed information
|
339 |
$result = $wpdb->query("
|
340 |
UPDATE $wpdb->links
|
341 |
SET $update_set
|
342 |
WHERE link_id='$this->id'
|
343 |
");
|
344 |
-
|
345 |
do_action("update_syndicated_feed_completed", $this->id, $this);
|
346 |
endif;
|
347 |
-
|
348 |
// All done; let's clean up.
|
349 |
$this->magpie = NULL;
|
350 |
-
|
351 |
// Avoid circular-reference memory leak in PHP < 5.3.
|
352 |
// Cf. <http://simplepie.org/wiki/faq/i_m_getting_memory_leaks>
|
353 |
if (method_exists($this->simplepie, '__destruct')) :
|
354 |
$this->simplepie->__destruct();
|
355 |
endif;
|
356 |
$this->simplepie = NULL;
|
357 |
-
|
358 |
return $new_count;
|
359 |
} /* SyndicatedLink::poll() */
|
360 |
|
@@ -377,9 +377,10 @@ class SyndicatedLink {
|
|
377 |
delete_post_meta($p->ID, '_feedwordpress_retire_me_'.$this->id);
|
378 |
endforeach;
|
379 |
endif;
|
|
|
380 |
return $delta;
|
381 |
}
|
382 |
-
|
383 |
/**
|
384 |
* Updates the URL for the feed syndicated by this link.
|
385 |
*
|
@@ -394,50 +395,50 @@ class SyndicatedLink {
|
|
394 |
$result = $wpdb->query("
|
395 |
UPDATE $wpdb->links
|
396 |
SET
|
397 |
-
link_rss = '"
|
398 |
-
WHERE link_id = '"
|
399 |
");
|
400 |
-
|
401 |
$ret = ($result ? true : false);
|
402 |
else :
|
403 |
$ret = false;
|
404 |
endif;
|
405 |
return $ret;
|
406 |
} /* SyndicatedLink::set_uri () */
|
407 |
-
|
408 |
function deactivate () {
|
409 |
global $wpdb;
|
410 |
-
|
411 |
$wpdb->query($wpdb->prepare("
|
412 |
UPDATE $wpdb->links SET link_visible = 'N' WHERE link_id = %d
|
413 |
", (int) $this->id));
|
414 |
} /* SyndicatedLink::deactivate () */
|
415 |
-
|
416 |
function delete () {
|
417 |
global $wpdb;
|
418 |
-
|
419 |
$wpdb->query($wpdb->prepare("
|
420 |
DELETE FROM $wpdb->postmeta WHERE meta_key='syndication_feed_id'
|
421 |
AND meta_value = '%s'
|
422 |
", $this->id));
|
423 |
-
|
424 |
$wpdb->query($wpdb->prepare("
|
425 |
DELETE FROM $wpdb->links WHERE link_id = %d
|
426 |
", (int) $this->id));
|
427 |
-
|
428 |
$this->id = NULL;
|
429 |
} /* SyndicatedLink::delete () */
|
430 |
-
|
431 |
function nuke () {
|
432 |
global $wpdb;
|
433 |
-
|
434 |
// Make a list of the items syndicated from this feed...
|
435 |
$post_ids = $wpdb->get_col($wpdb->prepare("
|
436 |
SELECT post_id FROM $wpdb->postmeta
|
437 |
WHERE meta_key = 'syndication_feed_id'
|
438 |
AND meta_value = '%s'
|
439 |
", $this->id));
|
440 |
-
|
441 |
// ... and kill them all
|
442 |
if (count($post_ids) > 0) :
|
443 |
foreach ($post_ids as $post_id) :
|
@@ -449,10 +450,10 @@ class SyndicatedLink {
|
|
449 |
);
|
450 |
endforeach;
|
451 |
endif;
|
452 |
-
|
453 |
$this->delete();
|
454 |
} /* SyndicatedLink::nuke () */
|
455 |
-
|
456 |
function map_name_to_new_user ($name, $newuser_name) {
|
457 |
global $wpdb;
|
458 |
|
@@ -477,7 +478,7 @@ class SyndicatedLink {
|
|
477 |
function imploded_settings () {
|
478 |
return array('cats', 'tags', 'match/cats', 'match/tags', 'match/filter');
|
479 |
}
|
480 |
-
|
481 |
function get_settings_from_notes () {
|
482 |
// Read off feed settings from link_notes
|
483 |
$notes = explode("\n", $this->link->link_notes);
|
@@ -497,7 +498,7 @@ class SyndicatedLink {
|
|
497 |
$this->settings['link/uri'] = $this->link->link_rss;
|
498 |
$this->settings['link/name'] = $this->link->link_name;
|
499 |
$this->settings['link/id'] = $this->link->link_id;
|
500 |
-
|
501 |
// `hardcode categories` and `unfamiliar categories` are
|
502 |
// deprecated in favor of `unfamiliar category`
|
503 |
if (
|
@@ -516,7 +517,7 @@ class SyndicatedLink {
|
|
516 |
// Set this up automagically for del.icio.us
|
517 |
$bits = parse_url($this->link->link_rss);
|
518 |
$tagspacers = array('del.icio.us', 'feeds.delicious.com');
|
519 |
-
if (!isset($this->settings['cat_split']) and in_array($bits['host'], $tagspacers)) :
|
520 |
$this->settings['cat_split'] = '\s'; // Whitespace separates multiple tags in del.icio.us RSS feeds
|
521 |
endif;
|
522 |
|
@@ -533,7 +534,7 @@ class SyndicatedLink {
|
|
533 |
if (isset($this->settings['terms'])) :
|
534 |
// Look for new format
|
535 |
$this->settings['terms'] = maybe_unserialize($this->settings['terms']);
|
536 |
-
|
537 |
if (!is_array($this->settings['terms'])) :
|
538 |
// Deal with old format instead. Ugh.
|
539 |
|
@@ -566,19 +567,19 @@ class SyndicatedLink {
|
|
566 |
$ma = array();
|
567 |
foreach ($author_rules as $rule) :
|
568 |
list($rule_type, $author_name, $author_action) = explode("\n", $rule);
|
569 |
-
|
570 |
// Normalize for case and whitespace
|
571 |
$rule_type = strtolower(trim($rule_type));
|
572 |
$author_name = strtolower(trim($author_name));
|
573 |
$author_action = strtolower(trim($author_action));
|
574 |
-
|
575 |
$ma[$rule_type][$author_name] = $author_action;
|
576 |
endforeach;
|
577 |
$this->settings['map authors'] = $ma;
|
578 |
endif;
|
579 |
|
580 |
} /* SyndicatedLink::get_settings_from_notes () */
|
581 |
-
|
582 |
function settings_to_notes () {
|
583 |
$to_notes = $this->settings;
|
584 |
|
@@ -601,12 +602,12 @@ class SyndicatedLink {
|
|
601 |
);
|
602 |
endif;
|
603 |
endforeach;
|
604 |
-
|
605 |
if (isset($to_notes['terms']) and is_array($to_notes['terms'])) :
|
606 |
// Serialize it.
|
607 |
$to_notes['terms'] = serialize($to_notes['terms']);
|
608 |
endif;
|
609 |
-
|
610 |
// Collapse the author mapping rule structure back into a flat string
|
611 |
if (isset($to_notes['map authors'])) :
|
612 |
$ma = array();
|
@@ -630,11 +631,11 @@ class SyndicatedLink {
|
|
630 |
|
631 |
// Save channel-level meta-data
|
632 |
foreach (array('link_name', 'link_description', 'link_url') as $what) :
|
633 |
-
$alter[] = "{$what} = '"
|
634 |
endforeach;
|
635 |
|
636 |
// Save settings to the notes field
|
637 |
-
$alter[] = "link_notes = '"
|
638 |
|
639 |
// Update the properties of the link from settings changes, etc.
|
640 |
$update_set = implode(", ", $alter);
|
@@ -644,7 +645,7 @@ class SyndicatedLink {
|
|
644 |
SET $update_set
|
645 |
WHERE link_id='$this->id'
|
646 |
");
|
647 |
-
|
648 |
if ($reload) :
|
649 |
// force reload of link information from DB
|
650 |
if (function_exists('clean_bookmark_cache')) :
|
@@ -667,7 +668,7 @@ class SyndicatedLink {
|
|
667 |
if (isset($this->settings[$name])) :
|
668 |
$ret = $this->settings[$name];
|
669 |
endif;
|
670 |
-
|
671 |
$no_value = (
|
672 |
is_null($ret)
|
673 |
or (is_string($ret) and strtolower($ret)==$default)
|
@@ -676,8 +677,13 @@ class SyndicatedLink {
|
|
676 |
if ($no_value and !is_null($fallback_global)) :
|
677 |
// Avoid duplication of this correction
|
678 |
$fallback_global = preg_replace('/^feedwordpress_/', '', $fallback_global);
|
679 |
-
|
680 |
-
|
|
|
|
|
|
|
|
|
|
|
681 |
endif;
|
682 |
|
683 |
$no_value = (
|
@@ -695,7 +701,7 @@ class SyndicatedLink {
|
|
695 |
$dd = $this->flatten_array($data, $prefix, $separator);
|
696 |
$this->settings = array_merge($this->settings, $dd);
|
697 |
} /* SyndicatedLink::merge_settings () */
|
698 |
-
|
699 |
function update_setting ($name, $value, $default = 'default') {
|
700 |
if (!is_null($value) and $value != $default) :
|
701 |
$this->settings[$name] = $value;
|
@@ -703,48 +709,55 @@ class SyndicatedLink {
|
|
703 |
unset($this->settings[$name]);
|
704 |
endif;
|
705 |
} /* SyndicatedLink::update_setting () */
|
706 |
-
|
707 |
-
function
|
708 |
return ('complete'==$this->setting('update_incremental', 'update_incremental', 'incremental'));
|
709 |
-
} /* SyndicatedLink::
|
710 |
-
|
711 |
function uri ($params = array()) {
|
712 |
$params = wp_parse_args($params, array(
|
713 |
'add_params' => false,
|
|
|
714 |
));
|
715 |
-
|
716 |
-
$
|
|
|
|
|
717 |
if (!is_null($uri) and strlen($uri) > 0 and $params['add_params']) :
|
718 |
$qp = maybe_unserialize($this->setting('query parameters', array()));
|
719 |
-
|
720 |
// For high-tech HTTP feed request kung fu
|
721 |
$qp = apply_filters('syndicated_feed_parameters', $qp, $uri, $this);
|
722 |
-
|
723 |
$q = array();
|
724 |
if (is_array($qp) and count($qp) > 0) :
|
725 |
foreach ($qp as $pair) :
|
726 |
$q[] = urlencode($pair[0]).'='.urlencode($pair[1]);
|
727 |
endforeach;
|
728 |
-
|
729 |
// Are we appending to a URI that already has params?
|
730 |
$sep = ((strpos($uri, "?")===false) ? '?' : '&');
|
731 |
-
|
732 |
// Tack it on
|
733 |
$uri .= $sep . implode("&", $q);
|
734 |
-
endif;
|
735 |
endif;
|
736 |
-
|
|
|
|
|
|
|
|
|
737 |
return $uri;
|
738 |
} /* SyndicatedLink::uri () */
|
739 |
|
740 |
function username () {
|
741 |
return $this->setting('http username', 'http_username', NULL);
|
742 |
} /* SyndicatedLink::username () */
|
743 |
-
|
744 |
function password () {
|
745 |
return $this->setting('http password', 'http_password', NULL);
|
746 |
} /* SyndicatedLink::password () */
|
747 |
-
|
748 |
function authentication_method () {
|
749 |
$auth = $this->setting('http auth method', NULL);
|
750 |
if (('-' == $auth) or (strlen($auth)==0)) :
|
@@ -753,7 +766,7 @@ class SyndicatedLink {
|
|
753 |
return $auth;
|
754 |
} /* SyndicatedLink::authentication_method () */
|
755 |
|
756 |
-
var $postmeta = array();
|
757 |
function postmeta ($params = array()) {
|
758 |
$params = wp_parse_args($params, /*defaults=*/ array(
|
759 |
"field" => NULL,
|
@@ -770,7 +783,7 @@ class SyndicatedLink {
|
|
770 |
if (!is_array($default_custom_settings)) :
|
771 |
$default_custom_settings = array();
|
772 |
endif;
|
773 |
-
|
774 |
// Next, get the settings for this particular feed.
|
775 |
$custom_settings = $this->setting('postmeta', NULL, NULL);
|
776 |
if ($custom_settings and !is_array($custom_settings)) :
|
@@ -779,10 +792,10 @@ class SyndicatedLink {
|
|
779 |
if (!is_array($custom_settings)) :
|
780 |
$custom_settings = array();
|
781 |
endif;
|
782 |
-
|
783 |
$this->postmeta[/*parsed=*/ false] = array_merge($default_custom_settings, $custom_settings);
|
784 |
$this->postmeta[/*parsed=*/ true] = array();
|
785 |
-
|
786 |
// Now, run through and parse them all.
|
787 |
foreach ($this->postmeta[/*parsed=*/ false] as $key => $meta) :
|
788 |
$meta = apply_filters("syndicated_link_post_meta_${key}_pre", $meta, $this);
|
@@ -797,12 +810,12 @@ class SyndicatedLink {
|
|
797 |
endif;
|
798 |
return $ret;
|
799 |
} /* SyndicatedLink::postmeta () */
|
800 |
-
|
801 |
function property_cascade ($fromFeed, $link_field, $setting, $method) {
|
802 |
$value = NULL;
|
803 |
if ($fromFeed) :
|
804 |
$value = $this->setting($setting, NULL, NULL, NULL);
|
805 |
-
|
806 |
$s = $this->simplepie;
|
807 |
$callable = (is_object($s) and method_exists($s, $method));
|
808 |
if (is_null($value) and $callable) :
|
@@ -813,7 +826,7 @@ class SyndicatedLink {
|
|
813 |
endif;
|
814 |
return $value;
|
815 |
} /* SyndicatedLink::property_cascade () */
|
816 |
-
|
817 |
function homepage ($fromFeed = true) {
|
818 |
return $this->property_cascade($fromFeed, 'link_url', 'feed/link', 'get_link');
|
819 |
} /* SyndicatedLink::homepage () */
|
@@ -824,17 +837,18 @@ class SyndicatedLink {
|
|
824 |
|
825 |
function guid () {
|
826 |
$ret = $this->setting('feed/id', NULL, $this->uri());
|
827 |
-
|
828 |
// If we can get it live from the feed, do so.
|
829 |
if (is_object($this->simplepie)) :
|
830 |
$search = array(
|
|
|
831 |
array(SIMPLEPIE_NAMESPACE_ATOM_10, 'id'),
|
832 |
array(SIMPLEPIE_NAMESPACE_ATOM_03, 'id'),
|
833 |
array(SIMPLEPIE_NAMESPACE_RSS_20, 'guid'),
|
834 |
array(SIMPLEPIE_NAMESPACE_DC_11, 'identifier'),
|
835 |
array(SIMPLEPIE_NAMESPACE_DC_10, 'identifier'),
|
836 |
);
|
837 |
-
|
838 |
foreach ($search as $pair) :
|
839 |
if ($id_tags = $this->simplepie->get_feed_tags($pair[0], $pair[1])) :
|
840 |
$ret = $id_tags[0]['data'];
|
@@ -848,6 +862,60 @@ class SyndicatedLink {
|
|
848 |
return $ret;
|
849 |
}
|
850 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
851 |
function ttl ($return_element = false) {
|
852 |
if (is_object($this->magpie)) :
|
853 |
$channel = $this->magpie->channel;
|
@@ -859,7 +927,7 @@ class SyndicatedLink {
|
|
859 |
// "ttl stands for time to live. It's a number of
|
860 |
// minutes that indicates how long a channel can be
|
861 |
// cached before refreshing from the source."
|
862 |
-
// <http://blogs.law.harvard.edu/tech/rss#ltttlgtSubelementOfLtchannelgt>
|
863 |
$xml = 'rss:ttl';
|
864 |
$ret = $channel['ttl'];
|
865 |
elseif (isset($channel['sy']['updatefrequency']) or isset($channel['sy']['updateperiod'])) :
|
@@ -878,8 +946,8 @@ class SyndicatedLink {
|
|
878 |
if (isset($channel['sy']['updateperiod'])) : $period = $channel['sy']['updateperiod'];
|
879 |
else : $period = 'daily';
|
880 |
endif;
|
881 |
-
|
882 |
-
// "sy:updateFrequency: Used to describe the frequency
|
883 |
// of updates in relation to the update period. A
|
884 |
// positive integer indicates how many times in that
|
885 |
// period the channel is updated. ... If omitted a value
|
@@ -887,17 +955,17 @@ class SyndicatedLink {
|
|
887 |
if (isset($channel['sy']['updatefrequency'])) : $freq = (int) $channel['sy']['updatefrequency'];
|
888 |
else : $freq = 1;
|
889 |
endif;
|
890 |
-
|
891 |
$xml = 'sy:updateFrequency';
|
892 |
$ret = (int) ($period_minutes[$period] / $freq);
|
893 |
else :
|
894 |
$xml = NULL;
|
895 |
$ret = NULL;
|
896 |
endif;
|
897 |
-
|
898 |
if ('yes'==$this->setting('update/minimum', 'update_minimum', 'no')) :
|
899 |
$min = (int) $this->setting('update/window', 'update_window', DEFAULT_UPDATE_PERIOD);
|
900 |
-
|
901 |
if ($min > $ret) :
|
902 |
$ret = NULL;
|
903 |
endif;
|
@@ -942,9 +1010,9 @@ class SyndicatedLink {
|
|
942 |
} /* SyndicatedLink::flatten_array () */
|
943 |
|
944 |
function hardcode ($what) {
|
945 |
-
|
946 |
$ret = $this->setting('hardcode '.$what, 'hardcode_'.$what, NULL);
|
947 |
-
|
948 |
if ('yes' == $ret) :
|
949 |
$ret = true;
|
950 |
else :
|
@@ -959,13 +1027,119 @@ class SyndicatedLink {
|
|
959 |
$g_set = ($fallback ? 'syndicated_' . $what . '_status' : NULL);
|
960 |
$ret = $this->setting($what.' status', $g_set, $default);
|
961 |
|
962 |
-
return
|
963 |
} /* SyndicatedLink:syndicated_status () */
|
964 |
-
|
965 |
function taxonomies () {
|
966 |
$post_type = $this->setting('syndicated post type', 'syndicated_post_type', 'post');
|
967 |
return get_object_taxonomies(array('object_type' => $post_type), 'names');
|
968 |
} /* SyndicatedLink::taxonomies () */
|
969 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
970 |
} // class SyndicatedLink
|
971 |
|
25 |
# backslashes (so, for example, a newline becomes "\n").
|
26 |
#
|
27 |
# The value of `cats` is used as a newline-separated list of
|
28 |
+
# default categories for any post coming from a particular feed.
|
29 |
# (In the example above, any posts from this feed will be placed
|
30 |
# in the "computers" and "web" categories--*in addition to* any
|
31 |
# categories that may already be applied to the posts.)
|
40 |
var $id = null;
|
41 |
var $link = null;
|
42 |
var $settings = array ();
|
43 |
+
public $simplepie = null;
|
44 |
var $magpie = null;
|
45 |
|
46 |
function SyndicatedLink ($link) {
|
50 |
$this->link = $link;
|
51 |
$this->id = $link->link_id;
|
52 |
else :
|
53 |
+
$this->id = $link;
|
54 |
$this->link = get_bookmark($link);
|
55 |
endif;
|
56 |
|
57 |
if (strlen($this->link->link_rss) > 0) :
|
58 |
$this->get_settings_from_notes();
|
59 |
endif;
|
60 |
+
|
61 |
add_filter('feedwordpress_update_complete', array($this, 'process_retirements'), 1000, 1);
|
62 |
} /* SyndicatedLink::SyndicatedLink () */
|
63 |
+
|
64 |
function found () {
|
65 |
return is_object($this->link) and !is_wp_error($this->link);
|
66 |
} /* SyndicatedLink::found () */
|
68 |
function id () {
|
69 |
return (is_object($this->link) ? $this->link->link_id : NULL);
|
70 |
}
|
71 |
+
|
72 |
function stale () {
|
73 |
global $feedwordpress;
|
74 |
+
|
75 |
$stale = true;
|
76 |
if ($this->setting('update/hold')=='ping') :
|
77 |
$stale = false; // don't update on any timed updates; pings only
|
112 |
if (!is_object($this->simplepie)) :
|
113 |
$this->fetch();
|
114 |
endif;
|
115 |
+
|
116 |
if (is_object($this->simplepie) and method_exists($this->simplepie, 'get_items')) :
|
117 |
$ret = apply_filters(
|
118 |
'syndicated_feed_items',
|
124 |
endif;
|
125 |
return $ret;
|
126 |
}
|
127 |
+
|
128 |
function poll ($crash_ts = NULL) {
|
129 |
global $wpdb;
|
130 |
|
131 |
+
$url = $this->uri(array('add_params' => true, 'fetch' => true));
|
132 |
FeedWordPress::diagnostic('updated_feeds', 'Polling feed ['.$url.']');
|
133 |
|
134 |
$this->fetch();
|
160 |
if (!is_null($oldError)) :
|
161 |
// Copy over the in-error-since timestamp
|
162 |
$theError['since'] = $oldError['since'];
|
163 |
+
|
164 |
// If this is a repeat error, then we should
|
165 |
// take a step back before we try to fetch it
|
166 |
// again.
|
171 |
$this->update_setting('update/ttl', $ttl, $this);
|
172 |
$this->update_setting('update/timed', 'automatically');
|
173 |
endif;
|
174 |
+
|
175 |
do_action('syndicated_feed_error', $theError, $oldError, $this);
|
176 |
+
|
177 |
$this->update_setting('update/error', serialize($theError));
|
178 |
$this->save_settings(/*reload=*/ true);
|
179 |
|
189 |
if (!isset($channel['id'])) :
|
190 |
$channel['id'] = $this->link->link_rss;
|
191 |
endif;
|
192 |
+
|
193 |
$update = array();
|
194 |
if (!$this->hardcode('url') and isset($channel['link'])) :
|
195 |
+
$update[] = "link_url = '".esc_sql($channel['link'])."'";
|
196 |
endif;
|
197 |
+
|
198 |
if (!$this->hardcode('name') and isset($channel['title'])) :
|
199 |
+
$update[] = "link_name = '".esc_sql($channel['title'])."'";
|
200 |
endif;
|
201 |
+
|
202 |
if (!$this->hardcode('description')) :
|
203 |
if (isset($channel['tagline'])) :
|
204 |
+
$update[] = "link_description = '".esc_sql($channel['tagline'])."'";
|
205 |
elseif (isset($channel['description'])) :
|
206 |
+
$update[] = "link_description = '".esc_sql($channel['description'])."'";
|
207 |
endif;
|
208 |
endif;
|
209 |
|
211 |
|
212 |
$this->update_setting('update/last', time());
|
213 |
list($ttl, $xml) = $this->ttl(/*return element=*/ true);
|
214 |
+
|
215 |
if (!is_null($ttl)) :
|
216 |
$this->update_setting('update/ttl', $ttl);
|
217 |
$this->update_setting('update/xml', $xml);
|
235 |
|
236 |
$this->update_setting('update/unfinished', 'yes');
|
237 |
|
238 |
+
$update[] = "link_notes = '".esc_sql($this->settings_to_notes())."'";
|
239 |
|
240 |
$update_set = implode(',', $update);
|
241 |
+
|
242 |
// Update the properties of the link from the feed information
|
243 |
$result = $wpdb->query("
|
244 |
UPDATE $wpdb->links
|
251 |
$crashed = false;
|
252 |
|
253 |
$posts = $this->live_posts();
|
254 |
+
|
255 |
$this->magpie->originals = $posts;
|
256 |
|
257 |
// If this is a complete feed, rather than an incremental feed, we
|
258 |
// need to prepare to mark everything for presumptive retirement.
|
259 |
+
if ($this->is_non_incremental()) :
|
260 |
$q = new WP_Query(array(
|
261 |
'fields' => '_synfrom',
|
262 |
'post_status__not' => 'fwpretired',
|
268 |
update_post_meta($p->ID, '_feedwordpress_retire_me_'.$this->id, '1');
|
269 |
endforeach;
|
270 |
endif;
|
271 |
+
|
272 |
if (is_array($posts)) :
|
273 |
foreach ($posts as $key => $item) :
|
274 |
$post = new SyndicatedPost($item, $this);
|
288 |
unset($post);
|
289 |
endforeach;
|
290 |
endif;
|
291 |
+
|
292 |
if ('yes'==$this->setting('tombstones', 'tombstones', 'yes')) :
|
293 |
// Check for use of Atom tombstones. Spec:
|
294 |
// <http://tools.ietf.org/html/draft-snell-atompub-tombstones-18>
|
302 |
$ref = $tombstone['attribs'][$ns]['ref'];
|
303 |
endif;
|
304 |
endforeach;
|
305 |
+
|
306 |
$q = new WP_Query(array(
|
307 |
'ignore_sticky_posts' => true,
|
308 |
'guid' => $ref,
|
309 |
'meta_key' => 'syndication_feed_id',
|
310 |
'meta_value' => $this->id, // Only allow a feed to tombstone its own entries.
|
311 |
));
|
312 |
+
|
313 |
foreach ($q->posts as $p) :
|
314 |
$old_status = $p->post_status;
|
315 |
FeedWordPress::diagnostic('syndicated_posts', 'Retiring existing post # '.$p->ID.' "'.$p->post_title.'" due to Atom tombstone element in feed.');
|
316 |
set_post_field('post_status', 'fwpretired', $p->ID);
|
317 |
wp_transition_post_status('fwpretired', $old_status, $p);
|
318 |
endforeach;
|
319 |
+
|
320 |
endforeach;
|
321 |
endif;
|
322 |
endif;
|
323 |
+
|
324 |
$suffix = ($crashed ? 'crashed' : 'completed');
|
325 |
do_action('update_syndicated_feed_items', $this->id, $this);
|
326 |
do_action("update_syndicated_feed_items_${suffix}", $this->id, $this);
|
333 |
|
334 |
// Copy back any changes to feed settings made in the
|
335 |
// course of updating (e.g. new author rules)
|
336 |
+
$update_set = "link_notes = '".esc_sql($this->settings_to_notes())."'";
|
337 |
+
|
338 |
// Update the properties of the link from the feed information
|
339 |
$result = $wpdb->query("
|
340 |
UPDATE $wpdb->links
|
341 |
SET $update_set
|
342 |
WHERE link_id='$this->id'
|
343 |
");
|
344 |
+
|
345 |
do_action("update_syndicated_feed_completed", $this->id, $this);
|
346 |
endif;
|
347 |
+
|
348 |
// All done; let's clean up.
|
349 |
$this->magpie = NULL;
|
350 |
+
|
351 |
// Avoid circular-reference memory leak in PHP < 5.3.
|
352 |
// Cf. <http://simplepie.org/wiki/faq/i_m_getting_memory_leaks>
|
353 |
if (method_exists($this->simplepie, '__destruct')) :
|
354 |
$this->simplepie->__destruct();
|
355 |
endif;
|
356 |
$this->simplepie = NULL;
|
357 |
+
|
358 |
return $new_count;
|
359 |
} /* SyndicatedLink::poll() */
|
360 |
|
377 |
delete_post_meta($p->ID, '_feedwordpress_retire_me_'.$this->id);
|
378 |
endforeach;
|
379 |
endif;
|
380 |
+
|
381 |
return $delta;
|
382 |
}
|
383 |
+
|
384 |
/**
|
385 |
* Updates the URL for the feed syndicated by this link.
|
386 |
*
|
395 |
$result = $wpdb->query("
|
396 |
UPDATE $wpdb->links
|
397 |
SET
|
398 |
+
link_rss = '".esc_sql($url)."'
|
399 |
+
WHERE link_id = '".esc_sql($this->id)."'
|
400 |
");
|
401 |
+
|
402 |
$ret = ($result ? true : false);
|
403 |
else :
|
404 |
$ret = false;
|
405 |
endif;
|
406 |
return $ret;
|
407 |
} /* SyndicatedLink::set_uri () */
|
408 |
+
|
409 |
function deactivate () {
|
410 |
global $wpdb;
|
411 |
+
|
412 |
$wpdb->query($wpdb->prepare("
|
413 |
UPDATE $wpdb->links SET link_visible = 'N' WHERE link_id = %d
|
414 |
", (int) $this->id));
|
415 |
} /* SyndicatedLink::deactivate () */
|
416 |
+
|
417 |
function delete () {
|
418 |
global $wpdb;
|
419 |
+
|
420 |
$wpdb->query($wpdb->prepare("
|
421 |
DELETE FROM $wpdb->postmeta WHERE meta_key='syndication_feed_id'
|
422 |
AND meta_value = '%s'
|
423 |
", $this->id));
|
424 |
+
|
425 |
$wpdb->query($wpdb->prepare("
|
426 |
DELETE FROM $wpdb->links WHERE link_id = %d
|
427 |
", (int) $this->id));
|
428 |
+
|
429 |
$this->id = NULL;
|
430 |
} /* SyndicatedLink::delete () */
|
431 |
+
|
432 |
function nuke () {
|
433 |
global $wpdb;
|
434 |
+
|
435 |
// Make a list of the items syndicated from this feed...
|
436 |
$post_ids = $wpdb->get_col($wpdb->prepare("
|
437 |
SELECT post_id FROM $wpdb->postmeta
|
438 |
WHERE meta_key = 'syndication_feed_id'
|
439 |
AND meta_value = '%s'
|
440 |
", $this->id));
|
441 |
+
|
442 |
// ... and kill them all
|
443 |
if (count($post_ids) > 0) :
|
444 |
foreach ($post_ids as $post_id) :
|
450 |
);
|
451 |
endforeach;
|
452 |
endif;
|
453 |
+
|
454 |
$this->delete();
|
455 |
} /* SyndicatedLink::nuke () */
|
456 |
+
|
457 |
function map_name_to_new_user ($name, $newuser_name) {
|
458 |
global $wpdb;
|
459 |
|
478 |
function imploded_settings () {
|
479 |
return array('cats', 'tags', 'match/cats', 'match/tags', 'match/filter');
|
480 |
}
|
481 |
+
|
482 |
function get_settings_from_notes () {
|
483 |
// Read off feed settings from link_notes
|
484 |
$notes = explode("\n", $this->link->link_notes);
|
498 |
$this->settings['link/uri'] = $this->link->link_rss;
|
499 |
$this->settings['link/name'] = $this->link->link_name;
|
500 |
$this->settings['link/id'] = $this->link->link_id;
|
501 |
+
|
502 |
// `hardcode categories` and `unfamiliar categories` are
|
503 |
// deprecated in favor of `unfamiliar category`
|
504 |
if (
|
517 |
// Set this up automagically for del.icio.us
|
518 |
$bits = parse_url($this->link->link_rss);
|
519 |
$tagspacers = array('del.icio.us', 'feeds.delicious.com');
|
520 |
+
if (!isset($this->settings['cat_split']) and in_array($bits['host'], $tagspacers)) :
|
521 |
$this->settings['cat_split'] = '\s'; // Whitespace separates multiple tags in del.icio.us RSS feeds
|
522 |
endif;
|
523 |
|
534 |
if (isset($this->settings['terms'])) :
|
535 |
// Look for new format
|
536 |
$this->settings['terms'] = maybe_unserialize($this->settings['terms']);
|
537 |
+
|
538 |
if (!is_array($this->settings['terms'])) :
|
539 |
// Deal with old format instead. Ugh.
|
540 |
|
567 |
$ma = array();
|
568 |
foreach ($author_rules as $rule) :
|
569 |
list($rule_type, $author_name, $author_action) = explode("\n", $rule);
|
570 |
+
|
571 |
// Normalize for case and whitespace
|
572 |
$rule_type = strtolower(trim($rule_type));
|
573 |
$author_name = strtolower(trim($author_name));
|
574 |
$author_action = strtolower(trim($author_action));
|
575 |
+
|
576 |
$ma[$rule_type][$author_name] = $author_action;
|
577 |
endforeach;
|
578 |
$this->settings['map authors'] = $ma;
|
579 |
endif;
|
580 |
|
581 |
} /* SyndicatedLink::get_settings_from_notes () */
|
582 |
+
|
583 |
function settings_to_notes () {
|
584 |
$to_notes = $this->settings;
|
585 |
|
602 |
);
|
603 |
endif;
|
604 |
endforeach;
|
605 |
+
|
606 |
if (isset($to_notes['terms']) and is_array($to_notes['terms'])) :
|
607 |
// Serialize it.
|
608 |
$to_notes['terms'] = serialize($to_notes['terms']);
|
609 |
endif;
|
610 |
+
|
611 |
// Collapse the author mapping rule structure back into a flat string
|
612 |
if (isset($to_notes['map authors'])) :
|
613 |
$ma = array();
|
631 |
|
632 |
// Save channel-level meta-data
|
633 |
foreach (array('link_name', 'link_description', 'link_url') as $what) :
|
634 |
+
$alter[] = "{$what} = '".esc_sql($this->link->{$what})."'";
|
635 |
endforeach;
|
636 |
|
637 |
// Save settings to the notes field
|
638 |
+
$alter[] = "link_notes = '".esc_sql($this->settings_to_notes())."'";
|
639 |
|
640 |
// Update the properties of the link from settings changes, etc.
|
641 |
$update_set = implode(", ", $alter);
|
645 |
SET $update_set
|
646 |
WHERE link_id='$this->id'
|
647 |
");
|
648 |
+
|
649 |
if ($reload) :
|
650 |
// force reload of link information from DB
|
651 |
if (function_exists('clean_bookmark_cache')) :
|
668 |
if (isset($this->settings[$name])) :
|
669 |
$ret = $this->settings[$name];
|
670 |
endif;
|
671 |
+
|
672 |
$no_value = (
|
673 |
is_null($ret)
|
674 |
or (is_string($ret) and strtolower($ret)==$default)
|
677 |
if ($no_value and !is_null($fallback_global)) :
|
678 |
// Avoid duplication of this correction
|
679 |
$fallback_global = preg_replace('/^feedwordpress_/', '', $fallback_global);
|
680 |
+
|
681 |
+
// Occasionally we'll get an array back. Convert it to a string
|
682 |
+
if ( is_array($fallback_global) && sizeof($fallback_global) )
|
683 |
+
$fallback_global = reset($fallback_global);
|
684 |
+
|
685 |
+
if ( !empty($fallback_global) )
|
686 |
+
$ret = get_option('feedwordpress_'.$fallback_global, /*default=*/ NULL);
|
687 |
endif;
|
688 |
|
689 |
$no_value = (
|
701 |
$dd = $this->flatten_array($data, $prefix, $separator);
|
702 |
$this->settings = array_merge($this->settings, $dd);
|
703 |
} /* SyndicatedLink::merge_settings () */
|
704 |
+
|
705 |
function update_setting ($name, $value, $default = 'default') {
|
706 |
if (!is_null($value) and $value != $default) :
|
707 |
$this->settings[$name] = $value;
|
709 |
unset($this->settings[$name]);
|
710 |
endif;
|
711 |
} /* SyndicatedLink::update_setting () */
|
712 |
+
|
713 |
+
function is_non_incremental () {
|
714 |
return ('complete'==$this->setting('update_incremental', 'update_incremental', 'incremental'));
|
715 |
+
} /* SyndicatedLink::is_non_incremental () */
|
716 |
+
|
717 |
function uri ($params = array()) {
|
718 |
$params = wp_parse_args($params, array(
|
719 |
'add_params' => false,
|
720 |
+
'fetch' => false,
|
721 |
));
|
722 |
+
|
723 |
+
$link_rss = (is_object($this->link) ? $this->link->link_rss : NULL);
|
724 |
+
|
725 |
+
$uri = $link_rss;
|
726 |
if (!is_null($uri) and strlen($uri) > 0 and $params['add_params']) :
|
727 |
$qp = maybe_unserialize($this->setting('query parameters', array()));
|
728 |
+
|
729 |
// For high-tech HTTP feed request kung fu
|
730 |
$qp = apply_filters('syndicated_feed_parameters', $qp, $uri, $this);
|
731 |
+
|
732 |
$q = array();
|
733 |
if (is_array($qp) and count($qp) > 0) :
|
734 |
foreach ($qp as $pair) :
|
735 |
$q[] = urlencode($pair[0]).'='.urlencode($pair[1]);
|
736 |
endforeach;
|
737 |
+
|
738 |
// Are we appending to a URI that already has params?
|
739 |
$sep = ((strpos($uri, "?")===false) ? '?' : '&');
|
740 |
+
|
741 |
// Tack it on
|
742 |
$uri .= $sep . implode("&", $q);
|
743 |
+
endif;
|
744 |
endif;
|
745 |
+
|
746 |
+
// Do we have any filters that apply here?
|
747 |
+
$uri = apply_filters('syndicated_link_uri', $uri, $link_rss, $qp, $params, $this);
|
748 |
+
|
749 |
+
// Return the filtered link URI.
|
750 |
return $uri;
|
751 |
} /* SyndicatedLink::uri () */
|
752 |
|
753 |
function username () {
|
754 |
return $this->setting('http username', 'http_username', NULL);
|
755 |
} /* SyndicatedLink::username () */
|
756 |
+
|
757 |
function password () {
|
758 |
return $this->setting('http password', 'http_password', NULL);
|
759 |
} /* SyndicatedLink::password () */
|
760 |
+
|
761 |
function authentication_method () {
|
762 |
$auth = $this->setting('http auth method', NULL);
|
763 |
if (('-' == $auth) or (strlen($auth)==0)) :
|
766 |
return $auth;
|
767 |
} /* SyndicatedLink::authentication_method () */
|
768 |
|
769 |
+
var $postmeta = array();
|
770 |
function postmeta ($params = array()) {
|
771 |
$params = wp_parse_args($params, /*defaults=*/ array(
|
772 |
"field" => NULL,
|
783 |
if (!is_array($default_custom_settings)) :
|
784 |
$default_custom_settings = array();
|
785 |
endif;
|
786 |
+
|
787 |
// Next, get the settings for this particular feed.
|
788 |
$custom_settings = $this->setting('postmeta', NULL, NULL);
|
789 |
if ($custom_settings and !is_array($custom_settings)) :
|
792 |
if (!is_array($custom_settings)) :
|
793 |
$custom_settings = array();
|
794 |
endif;
|
795 |
+
|
796 |
$this->postmeta[/*parsed=*/ false] = array_merge($default_custom_settings, $custom_settings);
|
797 |
$this->postmeta[/*parsed=*/ true] = array();
|
798 |
+
|
799 |
// Now, run through and parse them all.
|
800 |
foreach ($this->postmeta[/*parsed=*/ false] as $key => $meta) :
|
801 |
$meta = apply_filters("syndicated_link_post_meta_${key}_pre", $meta, $this);
|
810 |
endif;
|
811 |
return $ret;
|
812 |
} /* SyndicatedLink::postmeta () */
|
813 |
+
|
814 |
function property_cascade ($fromFeed, $link_field, $setting, $method) {
|
815 |
$value = NULL;
|
816 |
if ($fromFeed) :
|
817 |
$value = $this->setting($setting, NULL, NULL, NULL);
|
818 |
+
|
819 |
$s = $this->simplepie;
|
820 |
$callable = (is_object($s) and method_exists($s, $method));
|
821 |
if (is_null($value) and $callable) :
|
826 |
endif;
|
827 |
return $value;
|
828 |
} /* SyndicatedLink::property_cascade () */
|
829 |
+
|
830 |
function homepage ($fromFeed = true) {
|
831 |
return $this->property_cascade($fromFeed, 'link_url', 'feed/link', 'get_link');
|
832 |
} /* SyndicatedLink::homepage () */
|
837 |
|
838 |
function guid () {
|
839 |
$ret = $this->setting('feed/id', NULL, $this->uri());
|
840 |
+
|
841 |
// If we can get it live from the feed, do so.
|
842 |
if (is_object($this->simplepie)) :
|
843 |
$search = array(
|
844 |
+
array('', 'id'),
|
845 |
array(SIMPLEPIE_NAMESPACE_ATOM_10, 'id'),
|
846 |
array(SIMPLEPIE_NAMESPACE_ATOM_03, 'id'),
|
847 |
array(SIMPLEPIE_NAMESPACE_RSS_20, 'guid'),
|
848 |
array(SIMPLEPIE_NAMESPACE_DC_11, 'identifier'),
|
849 |
array(SIMPLEPIE_NAMESPACE_DC_10, 'identifier'),
|
850 |
);
|
851 |
+
|
852 |
foreach ($search as $pair) :
|
853 |
if ($id_tags = $this->simplepie->get_feed_tags($pair[0], $pair[1])) :
|
854 |
$ret = $id_tags[0]['data'];
|
862 |
return $ret;
|
863 |
}
|
864 |
|
865 |
+
function links ($params = array()) {
|
866 |
+
$params = wp_parse_args($params, array(
|
867 |
+
"rel" => NULL,
|
868 |
+
));
|
869 |
+
|
870 |
+
$fLinks = array();
|
871 |
+
$search = array(
|
872 |
+
array('', 'link'),
|
873 |
+
array(SIMPLEPIE_NAMESPACE_ATOM_10, 'link'),
|
874 |
+
array(SIMPLEPIE_NAMESPACE_ATOM_03, 'link'),
|
875 |
+
);
|
876 |
+
|
877 |
+
foreach ($search as $pair) :
|
878 |
+
if ($link_tags = $this->simplepie->get_feed_tags($pair[0], $pair[1])) :
|
879 |
+
$fLinks = array_merge($fLinks, $link_tags);
|
880 |
+
endif;
|
881 |
+
if ($link_tags = $this->simplepie->get_channel_tags($pair[0], $pair[1])) :
|
882 |
+
$fLinks = array_merge($fLinks, $link_tags);
|
883 |
+
endif;
|
884 |
+
endforeach;
|
885 |
+
|
886 |
+
$ret = array();
|
887 |
+
foreach ($fLinks as $link) :
|
888 |
+
$filter = false;
|
889 |
+
if (!is_null($params['rel'])) :
|
890 |
+
$filter = true;
|
891 |
+
|
892 |
+
if (isset($link['attribs'])) :
|
893 |
+
// Get a list of NSes from the search
|
894 |
+
foreach ($search as $pair) :
|
895 |
+
$ns = $pair[0];
|
896 |
+
|
897 |
+
if (isset($link['attribs'][$ns])
|
898 |
+
and isset($link['attribs'][$ns]['rel'])
|
899 |
+
) :
|
900 |
+
$rel = strtolower(trim($link['attribs'][$ns]['rel']));
|
901 |
+
$fRel = strtolower(trim($params['rel']));
|
902 |
+
|
903 |
+
if ($rel == $fRel) :
|
904 |
+
$filter = false;
|
905 |
+
endif;
|
906 |
+
endif;
|
907 |
+
endforeach;
|
908 |
+
endif;
|
909 |
+
endif;
|
910 |
+
|
911 |
+
if (!$filter) :
|
912 |
+
$ret[] = $link;
|
913 |
+
endif;
|
914 |
+
endforeach;
|
915 |
+
|
916 |
+
return $ret;
|
917 |
+
}
|
918 |
+
|
919 |
function ttl ($return_element = false) {
|
920 |
if (is_object($this->magpie)) :
|
921 |
$channel = $this->magpie->channel;
|
927 |
// "ttl stands for time to live. It's a number of
|
928 |
// minutes that indicates how long a channel can be
|
929 |
// cached before refreshing from the source."
|
930 |
+
// <http://blogs.law.harvard.edu/tech/rss#ltttlgtSubelementOfLtchannelgt>
|
931 |
$xml = 'rss:ttl';
|
932 |
$ret = $channel['ttl'];
|
933 |
elseif (isset($channel['sy']['updatefrequency']) or isset($channel['sy']['updateperiod'])) :
|
946 |
if (isset($channel['sy']['updateperiod'])) : $period = $channel['sy']['updateperiod'];
|
947 |
else : $period = 'daily';
|
948 |
endif;
|
949 |
+
|
950 |
+
// "sy:updateFrequency: Used to describe the frequency
|
951 |
// of updates in relation to the update period. A
|
952 |
// positive integer indicates how many times in that
|
953 |
// period the channel is updated. ... If omitted a value
|
955 |
if (isset($channel['sy']['updatefrequency'])) : $freq = (int) $channel['sy']['updatefrequency'];
|
956 |
else : $freq = 1;
|
957 |
endif;
|
958 |
+
|
959 |
$xml = 'sy:updateFrequency';
|
960 |
$ret = (int) ($period_minutes[$period] / $freq);
|
961 |
else :
|
962 |
$xml = NULL;
|
963 |
$ret = NULL;
|
964 |
endif;
|
965 |
+
|
966 |
if ('yes'==$this->setting('update/minimum', 'update_minimum', 'no')) :
|
967 |
$min = (int) $this->setting('update/window', 'update_window', DEFAULT_UPDATE_PERIOD);
|
968 |
+
|
969 |
if ($min > $ret) :
|
970 |
$ret = NULL;
|
971 |
endif;
|
1010 |
} /* SyndicatedLink::flatten_array () */
|
1011 |
|
1012 |
function hardcode ($what) {
|
1013 |
+
|
1014 |
$ret = $this->setting('hardcode '.$what, 'hardcode_'.$what, NULL);
|
1015 |
+
|
1016 |
if ('yes' == $ret) :
|
1017 |
$ret = true;
|
1018 |
else :
|
1027 |
$g_set = ($fallback ? 'syndicated_' . $what . '_status' : NULL);
|
1028 |
$ret = $this->setting($what.' status', $g_set, $default);
|
1029 |
|
1030 |
+
return esc_sql(trim(strtolower($ret)));
|
1031 |
} /* SyndicatedLink:syndicated_status () */
|
1032 |
+
|
1033 |
function taxonomies () {
|
1034 |
$post_type = $this->setting('syndicated post type', 'syndicated_post_type', 'post');
|
1035 |
return get_object_taxonomies(array('object_type' => $post_type), 'names');
|
1036 |
} /* SyndicatedLink::taxonomies () */
|
1037 |
+
|
1038 |
+
/**
|
1039 |
+
* category_ids: look up (and create) category ids from a list of
|
1040 |
+
* categories
|
1041 |
+
*
|
1042 |
+
* @param array $cats
|
1043 |
+
* @param string $unfamiliar_category
|
1044 |
+
* @param array|null $taxonomies
|
1045 |
+
* @return array
|
1046 |
+
*/
|
1047 |
+
function category_ids ($post, $cats, $unfamiliar_category = 'create', $taxonomies = NULL, $params = array()) {
|
1048 |
+
$singleton = (isset($params['singleton']) ? $params['singleton'] : true);
|
1049 |
+
$allowFilters = (isset($params['filters']) ? $params['filters'] : false);
|
1050 |
+
|
1051 |
+
$catTax = 'category';
|
1052 |
+
|
1053 |
+
if (is_null($taxonomies)) :
|
1054 |
+
$taxonomies = array('category');
|
1055 |
+
endif;
|
1056 |
+
|
1057 |
+
// We need to normalize whitespace because (1) trailing
|
1058 |
+
// whitespace can cause PHP and MySQL not to see eye to eye on
|
1059 |
+
// VARCHAR comparisons for some versions of MySQL (cf.
|
1060 |
+
// <http://dev.mysql.com/doc/mysql/en/char.html>), and (2)
|
1061 |
+
// because I doubt most people want to make a semantic
|
1062 |
+
// distinction between 'Computers' and 'Computers '
|
1063 |
+
$cats = array_map('trim', $cats);
|
1064 |
+
|
1065 |
+
$terms = array();
|
1066 |
+
foreach ($taxonomies as $tax) :
|
1067 |
+
$terms[$tax] = array();
|
1068 |
+
endforeach;
|
1069 |
+
|
1070 |
+
foreach ($cats as $cat_name) :
|
1071 |
+
if (strlen(trim($cat_name)) < 1) :
|
1072 |
+
continue;
|
1073 |
+
endif;
|
1074 |
+
|
1075 |
+
$oTerm = new SyndicatedPostTerm($cat_name, $taxonomies, $post);
|
1076 |
+
|
1077 |
+
if ($oTerm->is_familiar()) :
|
1078 |
+
|
1079 |
+
$tax = $oTerm->taxonomy();
|
1080 |
+
if (!isset($terms[$tax])) :
|
1081 |
+
$terms[$tax] = array();
|
1082 |
+
endif;
|
1083 |
+
$terms[$tax][] = $oTerm->id();
|
1084 |
+
|
1085 |
+
else :
|
1086 |
+
|
1087 |
+
if ('tag'==$unfamiliar_category) :
|
1088 |
+
$unfamiliar_category = 'create:post_tag';
|
1089 |
+
endif;
|
1090 |
+
|
1091 |
+
if (preg_match('/^create(:(.*))?$/i', $unfamiliar_category, $ref)) :
|
1092 |
+
$tax = $catTax; // Default
|
1093 |
+
|
1094 |
+
if (isset($ref[2])
|
1095 |
+
and strlen($ref[2]) > 2) :
|
1096 |
+
$tax = $ref[2];
|
1097 |
+
endif;
|
1098 |
+
|
1099 |
+
$inserted = $oTerm->insert($tax);
|
1100 |
+
if (!is_null($inserted)) :
|
1101 |
+
if (!isset($terms[$tax])) :
|
1102 |
+
$terms[$tax] = array();
|
1103 |
+
endif;
|
1104 |
+
$terms[$tax][] = $inserted;
|
1105 |
+
else :
|
1106 |
+
|
1107 |
+
endif; // !is_null($inserted)
|
1108 |
+
endif; // preg_match(...)
|
1109 |
+
|
1110 |
+
endif; /* ($oTerm->is_familiar()) */
|
1111 |
+
endforeach;
|
1112 |
+
|
1113 |
+
$filtersOn = $allowFilters;
|
1114 |
+
if ($allowFilters) :
|
1115 |
+
$filters = array_filter(
|
1116 |
+
$this->setting('match/filter', 'match_filter', array()),
|
1117 |
+
'remove_dummy_zero'
|
1118 |
+
);
|
1119 |
+
$filtersOn = ($filtersOn and is_array($filters) and (count($filters) > 0));
|
1120 |
+
endif;
|
1121 |
+
|
1122 |
+
// Check for filter conditions
|
1123 |
+
foreach ($terms as $tax => $term_ids) :
|
1124 |
+
if ($filtersOn
|
1125 |
+
and (count($term_ids)==0)
|
1126 |
+
and in_array($tax, $filters)) :
|
1127 |
+
$terms = NULL; // Drop the post
|
1128 |
+
break;
|
1129 |
+
else :
|
1130 |
+
$terms[$tax] = array_unique($term_ids);
|
1131 |
+
endif;
|
1132 |
+
endforeach;
|
1133 |
+
|
1134 |
+
if ($singleton and count($terms)==1) : // If we only searched one, just return the term IDs
|
1135 |
+
$terms = end($terms);
|
1136 |
+
endif;
|
1137 |
+
|
1138 |
+
FeedWordPress::diagnostic(
|
1139 |
+
'syndicated_posts:categories',
|
1140 |
+
'Category: MAPPED term names '.json_encode($cats).' to IDs: '.json_encode($terms)
|
1141 |
+
);
|
1142 |
+
return $terms;
|
1143 |
+
} /* SyndicatedLink::category_ids () */
|
1144 |
} // class SyndicatedLink
|
1145 |
|
@@ -1,5 +1,6 @@
|
|
1 |
<?php
|
2 |
require_once(dirname(__FILE__).'/feedtime.class.php');
|
|
|
3 |
|
4 |
/**
|
5 |
* class SyndicatedPost: FeedWordPress uses to manage the conversion of
|
@@ -10,7 +11,7 @@ require_once(dirname(__FILE__).'/feedtime.class.php');
|
|
10 |
* different feed formats, which may be useful to FeedWordPress users
|
11 |
* who make use of feed data in PHP add-ons and filters.
|
12 |
*
|
13 |
-
* @version
|
14 |
*/
|
15 |
class SyndicatedPost {
|
16 |
var $item = null; // MagpieRSS representation
|
@@ -19,7 +20,7 @@ class SyndicatedPost {
|
|
19 |
var $link = null;
|
20 |
var $feed = null;
|
21 |
var $feedmeta = null;
|
22 |
-
|
23 |
var $xmlns = array ();
|
24 |
|
25 |
var $post = array ();
|
@@ -27,7 +28,7 @@ class SyndicatedPost {
|
|
27 |
var $named = array ();
|
28 |
var $preset_terms = array ();
|
29 |
var $feed_terms = array ();
|
30 |
-
|
31 |
var $_freshness = null;
|
32 |
var $_wp_id = null;
|
33 |
var $_wp_post = null;
|
@@ -44,6 +45,9 @@ class SyndicatedPost {
|
|
44 |
function SyndicatedPost ($item, &$source) {
|
45 |
global $wpdb;
|
46 |
|
|
|
|
|
|
|
47 |
if (is_array($item)
|
48 |
and isset($item['simplepie'])
|
49 |
and isset($item['magpie'])) :
|
@@ -52,11 +56,11 @@ class SyndicatedPost {
|
|
52 |
$item = $item['magpie'];
|
53 |
elseif (is_a($item, 'SimplePie_Item')) :
|
54 |
$this->entry = $item;
|
55 |
-
|
56 |
// convert to Magpie for compat purposes
|
57 |
$mp = new MagpieFromSimplePie($source->simplepie, $this->entry);
|
58 |
$this->item = $mp->get_item();
|
59 |
-
|
60 |
// done with conversion object
|
61 |
$mp = NULL; unset($mp);
|
62 |
else :
|
@@ -76,9 +80,9 @@ class SyndicatedPost {
|
|
76 |
if (!isset($this->xmlns['reverse'][$ns])) :
|
77 |
$this->xmlns['reverse'][$ns] = array();
|
78 |
endif;
|
79 |
-
$this->xmlns['reverse'][$ns][] = $url;
|
80 |
endforeach;
|
81 |
-
|
82 |
// Fucking SimplePie.
|
83 |
$this->xmlns['reverse']['rss'][] = '';
|
84 |
|
@@ -100,7 +104,7 @@ class SyndicatedPost {
|
|
100 |
// Trigger global syndicated_item filter.
|
101 |
$changed = apply_filters('syndicated_item', $this->item, $this);
|
102 |
$this->item = $changed;
|
103 |
-
|
104 |
// Allow for feed-specific syndicated_item filters.
|
105 |
$changed = apply_filters(
|
106 |
"syndicated_item_".$source->uri(),
|
@@ -108,12 +112,12 @@ class SyndicatedPost {
|
|
108 |
$this
|
109 |
);
|
110 |
$this->item = $changed;
|
111 |
-
|
112 |
# Filters can halt further processing by returning NULL
|
113 |
if (is_null($this->item)) :
|
114 |
$this->post = NULL;
|
115 |
else :
|
116 |
-
# Note that nothing is run through
|
117 |
# That's deliberate. The escaping is done at the point
|
118 |
# of insertion, not here, to avoid double-escaping and
|
119 |
# to avoid screwing with syndicated_post filters
|
@@ -130,7 +134,7 @@ class SyndicatedPost {
|
|
130 |
// This just gives us an alphanumeric name for the author.
|
131 |
// We look up (or create) the numeric ID for the author
|
132 |
// in SyndicatedPost::add().
|
133 |
-
|
134 |
$this->post['post_content'] = apply_filters(
|
135 |
'syndicated_item_content',
|
136 |
$this->content(), $this
|
@@ -164,18 +168,18 @@ class SyndicatedPost {
|
|
164 |
// overwrite if necessary; thus preventing any munging.
|
165 |
$postMetaIn = $this->link->postmeta(array("parsed" => true));
|
166 |
$postMetaOut = array();
|
167 |
-
|
168 |
foreach ($postMetaIn as $key => $meta) :
|
169 |
$postMetaOut[$key] = $meta->do_substitutions($this);
|
170 |
endforeach;
|
171 |
-
|
172 |
foreach ($postMetaOut as $key => $values) :
|
173 |
$this->post['meta'][$key] = array();
|
174 |
foreach ($values as $value) :
|
175 |
$this->post['meta'][$key][] = apply_filters("syndicated_post_meta_{$key}", $value, $this);
|
176 |
endforeach;
|
177 |
endforeach;
|
178 |
-
|
179 |
// RSS 2.0 / Atom 1.0 enclosure support
|
180 |
$enclosures = $this->entry->get_enclosures();
|
181 |
if (is_array($enclosures)) : foreach ($enclosures as $enclosure) :
|
@@ -187,7 +191,7 @@ class SyndicatedPost {
|
|
187 |
|
188 |
// In case you want to point back to the blog this was
|
189 |
// syndicated from.
|
190 |
-
|
191 |
$sourcemeta['syndication_source'] = apply_filters(
|
192 |
'syndicated_item_source_title',
|
193 |
$this->link->name(),
|
@@ -203,7 +207,7 @@ class SyndicatedPost {
|
|
203 |
$this->link->guid(),
|
204 |
$this
|
205 |
);
|
206 |
-
|
207 |
// Make use of atom:source data, if present in an aggregated feed
|
208 |
$entry_source = $this->source();
|
209 |
if (!is_null($entry_source)) :
|
@@ -213,7 +217,7 @@ class SyndicatedPost {
|
|
213 |
elseif ($what=='feed') : $key = 'syndication_feed';
|
214 |
else : $key = "syndication_source_${what}";
|
215 |
endif;
|
216 |
-
|
217 |
$sourcemeta["${key}_original"] = apply_filters(
|
218 |
'syndicated_item_original_source_'.$what,
|
219 |
$value,
|
@@ -222,7 +226,7 @@ class SyndicatedPost {
|
|
222 |
endif;
|
223 |
endforeach;
|
224 |
endif;
|
225 |
-
|
226 |
foreach ($sourcemeta as $meta_key => $value) :
|
227 |
if (!is_null($value)) :
|
228 |
$this->post['meta'][$meta_key] = $value;
|
@@ -230,7 +234,7 @@ class SyndicatedPost {
|
|
230 |
endforeach;
|
231 |
|
232 |
// Store information on human-readable and machine-readable comment URIs
|
233 |
-
|
234 |
// Human-readable comment URI
|
235 |
$commentLink = apply_filters('syndicated_item_comments', $this->comment_link(), $this);
|
236 |
if (!is_null($commentLink)) : $this->post['meta']['rss:comments'] = $commentLink; endif;
|
@@ -273,14 +277,14 @@ class SyndicatedPost {
|
|
273 |
$cats = array_merge($cats, $fc);
|
274 |
endif;
|
275 |
$this->preset_terms['category'] = $cats;
|
276 |
-
|
277 |
// Now add categories from the post, if we have 'em
|
278 |
$cats = array();
|
279 |
$post_cats = $this->entry->get_categories();
|
280 |
if (is_array($post_cats)) : foreach ($post_cats as $cat) :
|
281 |
$cat_name = $cat->get_term();
|
282 |
if (!$cat_name) : $cat_name = $cat->get_label(); endif;
|
283 |
-
|
284 |
if ($this->link->setting('cat_split', NULL, NULL)) :
|
285 |
$pcre = "\007".$this->feedmeta['cat_split']."\007";
|
286 |
$cats = array_merge(
|
@@ -298,24 +302,24 @@ class SyndicatedPost {
|
|
298 |
endforeach; endif;
|
299 |
|
300 |
$this->feed_terms['category'] = apply_filters('syndicated_item_categories', $cats, $this);
|
301 |
-
|
302 |
// Tags: start with default tags, if any
|
303 |
$tags = array();
|
304 |
if ('no' != $this->link->setting('add/post_tag', NULL, 'yes')) :
|
305 |
$ft = get_option("feedwordpress_syndication_tags", NULL);
|
306 |
$tags = (is_null($ft) ? array() : explode(FEEDWORDPRESS_CAT_SEPARATOR, $ft));
|
307 |
endif;
|
308 |
-
|
309 |
$ft = $this->link->setting('tags', NULL, array());
|
310 |
if (is_array($ft)) :
|
311 |
$tags = array_merge($tags, $ft);
|
312 |
endif;
|
313 |
$this->preset_terms['post_tag'] = $tags;
|
314 |
-
|
315 |
// Scan post for /a[@rel='tag'] and use as tags if present
|
316 |
$tags = $this->inline_tags();
|
317 |
$this->feed_terms['post_tag'] = apply_filters('syndicated_item_tags', $tags, $this);
|
318 |
-
|
319 |
$taxonomies = $this->link->taxonomies();
|
320 |
$feedTerms = $this->link->setting('terms', NULL, array());
|
321 |
$globalTerms = get_option('feedwordpress_syndication_terms', array());
|
@@ -324,14 +328,14 @@ class SyndicatedPost {
|
|
324 |
foreach ($taxonomies as $tax) :
|
325 |
if (!isset($specials[$tax])) :
|
326 |
$terms = array();
|
327 |
-
|
328 |
// See if we should get the globals
|
329 |
if ('no' != $this->link->setting("add/$tax", NULL, 'yes')) :
|
330 |
if (isset($globalTerms[$tax])) :
|
331 |
$terms = $globalTerms[$tax];
|
332 |
endif;
|
333 |
endif;
|
334 |
-
|
335 |
// Now merge in the locals
|
336 |
if (isset($feedTerms[$tax])) :
|
337 |
$terms = array_merge($terms, $feedTerms[$tax]);
|
@@ -352,7 +356,7 @@ class SyndicatedPost {
|
|
352 |
|
353 |
function substitution_function ($name) {
|
354 |
$ret = NULL;
|
355 |
-
|
356 |
switch ($name) :
|
357 |
// Allowed PHP string functions
|
358 |
case 'trim':
|
@@ -366,7 +370,7 @@ class SyndicatedPost {
|
|
366 |
endswitch;
|
367 |
return $ret;
|
368 |
}
|
369 |
-
|
370 |
/**
|
371 |
* SyndicatedPost::query uses an XPath-like syntax to query arbitrary
|
372 |
* elements within the syndicated item.
|
@@ -383,9 +387,9 @@ class SyndicatedPost {
|
|
383 |
foreach ($match as $ref) :
|
384 |
$urlHash[md5($ref[1])] = $ref[1];
|
385 |
endforeach;
|
386 |
-
|
387 |
foreach ($urlHash as $hash => $url) :
|
388 |
-
$path = str_replace('{'.$url.'}', '{#'.$hash.'}', $path);
|
389 |
endforeach;
|
390 |
|
391 |
$path = explode('/', $path);
|
@@ -406,7 +410,7 @@ class SyndicatedPost {
|
|
406 |
while (strlen($node)==0 and !is_null($node)) :
|
407 |
$node = array_shift($path);
|
408 |
endwhile;
|
409 |
-
|
410 |
switch ($node) :
|
411 |
case 'feed' :
|
412 |
case 'channel' :
|
@@ -440,7 +444,7 @@ class SyndicatedPost {
|
|
440 |
$addenda = $elements[$element];
|
441 |
$contexts = $elements[$element];
|
442 |
endif;
|
443 |
-
|
444 |
foreach ($addenda as $index => $addendum) :
|
445 |
$context = $contexts[$index];
|
446 |
|
@@ -450,15 +454,15 @@ class SyndicatedPost {
|
|
450 |
endif;
|
451 |
endforeach;
|
452 |
endif;
|
453 |
-
endforeach;
|
454 |
endif;
|
455 |
endforeach;
|
456 |
-
|
457 |
$data = $matches;
|
458 |
endif;
|
459 |
$node = array_shift($path);
|
460 |
endwhile;
|
461 |
-
|
462 |
$matches = array();
|
463 |
foreach ($data as $datum) :
|
464 |
if (is_string($datum)) :
|
@@ -487,7 +491,7 @@ class SyndicatedPost {
|
|
487 |
'http://backend.userland.com/RSS2',
|
488 |
SIMPLEPIE_NAMESPACE_RSS_20,
|
489 |
);
|
490 |
-
|
491 |
$matches = array();
|
492 |
foreach ($rss as $ns) :
|
493 |
$data = $this->link->simplepie->get_feed_tags($ns, 'channel');
|
@@ -514,7 +518,7 @@ class SyndicatedPost {
|
|
514 |
else :
|
515 |
$defaultNS = SIMPLEPIE_NAMESPACE_RSS_20;
|
516 |
endif;
|
517 |
-
return $defaultNS;
|
518 |
} /* SyndicatedPost::xpath_default_namespace() */
|
519 |
|
520 |
function xpath_name_and_axis ($node) {
|
@@ -549,20 +553,20 @@ class SyndicatedPost {
|
|
549 |
$ns = array($ref[1]);
|
550 |
elseif (strpos($node, ':') !== FALSE) :
|
551 |
list($xmlns, $element) = explode(':', $node, 2);
|
552 |
-
|
553 |
if (isset($this->xmlns['reverse'][$xmlns])) :
|
554 |
$ns = $this->xmlns['reverse'][$xmlns];
|
555 |
else :
|
556 |
$ns = array($xmlns);
|
557 |
endif;
|
558 |
-
|
559 |
// Fucking SimplePie. For attributes in default xmlns.
|
560 |
$defaultNS = $this->xpath_default_namespace();
|
561 |
if (isset($this->xmlns['forward'][$defaultNS])
|
562 |
and ($xmlns==$this->xmlns['forward'][$defaultNS])) :
|
563 |
$ns[] = '';
|
564 |
endif;
|
565 |
-
|
566 |
if (isset($datum['xmlns'])) :
|
567 |
if (isset($datum['xmlns'][$xmlns])) :
|
568 |
$ns[] = $datum['xmlns'][$xmlns];
|
@@ -576,18 +580,60 @@ class SyndicatedPost {
|
|
576 |
return array_unique($ns);
|
577 |
} /* SyndicatedPost::xpath_possible_namespaces() */
|
578 |
|
579 |
-
function
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
580 |
$content = NULL;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
581 |
if (isset($this->item['atom_content'])) :
|
582 |
$content = $this->item['atom_content'];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
583 |
elseif (isset($this->item['xhtml']['body'])) :
|
584 |
$content = $this->item['xhtml']['body'];
|
585 |
elseif (isset($this->item['xhtml']['div'])) :
|
586 |
$content = $this->item['xhtml']['div'];
|
|
|
|
|
|
|
587 |
elseif (isset($this->item['content']['encoded']) and $this->item['content']['encoded']):
|
588 |
$content = $this->item['content']['encoded'];
|
589 |
-
|
590 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
591 |
endif;
|
592 |
return $content;
|
593 |
} /* SyndicatedPost::content() */
|
@@ -595,13 +641,13 @@ class SyndicatedPost {
|
|
595 |
function excerpt () {
|
596 |
# Identify and sanitize excerpt: atom:summary, or rss:description
|
597 |
$excerpt = $this->entry->get_description();
|
598 |
-
|
599 |
# Many RSS feeds use rss:description, inadvisably, to
|
600 |
# carry the entire post (typically with escaped HTML).
|
601 |
# If that's what happened, we don't want the full
|
602 |
# content for the excerpt.
|
603 |
$content = $this->content();
|
604 |
-
|
605 |
// Ignore whitespace, case, and tag cruft.
|
606 |
$theExcerpt = preg_replace('/\s+/', '', strtolower(strip_tags($excerpt)));
|
607 |
$theContent = preg_replace('/\s+/', '', strtolower(strip_tags($content)));
|
@@ -628,7 +674,7 @@ class SyndicatedPost {
|
|
628 |
function created ($params = array()) {
|
629 |
$unfiltered = false; $default = NULL;
|
630 |
extract($params);
|
631 |
-
|
632 |
$date = '';
|
633 |
if (isset($this->item['dc']['created'])) :
|
634 |
$date = $this->item['dc']['created'];
|
@@ -653,7 +699,7 @@ class SyndicatedPost {
|
|
653 |
else : // New style
|
654 |
extract($params);
|
655 |
endif;
|
656 |
-
|
657 |
$date = '';
|
658 |
$ts = null;
|
659 |
|
@@ -672,14 +718,14 @@ class SyndicatedPost {
|
|
672 |
elseif (isset($this->item['pubdate'])): // RSS 2.0
|
673 |
$date = $this->item['pubdate'];
|
674 |
endif;
|
675 |
-
|
676 |
if (strlen($date) > 0) :
|
677 |
$time = new FeedTime($date);
|
678 |
$ts = $time->timestamp();
|
679 |
elseif ($fallback) : // Fall back to <updated> / <modified> if present
|
680 |
$ts = $this->updated(/*fallback=*/ false, /*default=*/ $default);
|
681 |
endif;
|
682 |
-
|
683 |
# If everything failed, then default to the current time.
|
684 |
if (is_null($ts)) :
|
685 |
if (-1 == $default) :
|
@@ -688,7 +734,7 @@ class SyndicatedPost {
|
|
688 |
$ts = $default;
|
689 |
endif;
|
690 |
endif;
|
691 |
-
|
692 |
if (!$unfiltered) :
|
693 |
$ts = apply_filters('syndicated_item_published', $ts, $this);
|
694 |
endif;
|
@@ -718,14 +764,14 @@ class SyndicatedPost {
|
|
718 |
elseif (isset($this->item['updated'])): // Atom 1.0
|
719 |
$date = $this->item['updated'];
|
720 |
endif;
|
721 |
-
|
722 |
if (strlen($date) > 0) :
|
723 |
$time = new FeedTime($date);
|
724 |
$ts = $time->timestamp();
|
725 |
elseif ($fallback) : // Fall back to issued / dc:date
|
726 |
$ts = $this->published(/*fallback=*/ false, /*default=*/ $default);
|
727 |
endif;
|
728 |
-
|
729 |
# If everything failed, then default to the current time.
|
730 |
if (is_null($ts)) :
|
731 |
if (-1 == $default) :
|
@@ -766,19 +812,19 @@ class SyndicatedPost {
|
|
766 |
"content" => $this->content(),
|
767 |
"excerpt" => $this->excerpt(),
|
768 |
);
|
769 |
-
|
770 |
if ($hashed) :
|
771 |
$hash = md5(serialize($hash));
|
772 |
endif;
|
773 |
-
|
774 |
return $hash;
|
775 |
} /* SyndicatedPost::update_hash() */
|
776 |
|
777 |
-
|
778 |
return trailingslashit(get_bloginfo('url')).'?guid=';
|
779 |
}
|
780 |
-
|
781 |
-
|
782 |
$guid = trim($guid);
|
783 |
if (preg_match('/^[0-9a-z]{32}$/i', $guid)) : // MD5
|
784 |
$guid = SyndicatedPost::normalize_guid_prefix().strtolower($guid);
|
@@ -788,7 +834,7 @@ class SyndicatedPost {
|
|
788 |
$guid = trim($guid);
|
789 |
return $guid;
|
790 |
} /* SyndicatedPost::normalize_guid() */
|
791 |
-
|
792 |
function guid () {
|
793 |
$guid = null;
|
794 |
if (isset($this->item['id'])): // Atom 0.3 / 1.0
|
@@ -800,12 +846,12 @@ class SyndicatedPost {
|
|
800 |
elseif (isset($this->item['dc']['identifier'])) : // yeah, right
|
801 |
$guid = $this->item['dc']['identifier'];
|
802 |
endif;
|
803 |
-
|
804 |
// Un-set or too long to use as-is. Generate a tag: URI.
|
805 |
if (is_null($guid) or strlen($guid) > 250) :
|
806 |
// In case we need to check this again
|
807 |
$original_guid = $guid;
|
808 |
-
|
809 |
// The feed does not seem to have provided us with a
|
810 |
// usable unique identifier, so we'll have to cobble
|
811 |
// together a tag: URI that might work for us. The base
|
@@ -823,7 +869,7 @@ class SyndicatedPost {
|
|
823 |
// are hashed down into a nice, manageable tag: URI.
|
824 |
if (!is_null($original_guid)) :
|
825 |
$guid .= ',2010-12-03:id.'.md5($original_guid);
|
826 |
-
|
827 |
// If we have a date of creation, then we can use that
|
828 |
// to uniquely identify the item. (On the other hand, if
|
829 |
// the feed producer was consicentious enough to
|
@@ -831,7 +877,7 @@ class SyndicatedPost {
|
|
831 |
// conscientious enough to generate unique identifiers.)
|
832 |
elseif (!is_null($this->created())) :
|
833 |
$guid .= '://post.'.date('YmdHis', $this->created());
|
834 |
-
|
835 |
// Otherwise, use both the URI of the item, *and* the
|
836 |
// item's title. We have to use both because titles are
|
837 |
// often not unique, and sometimes links aren't unique
|
@@ -847,10 +893,10 @@ class SyndicatedPost {
|
|
847 |
endif;
|
848 |
return $guid;
|
849 |
} /* SyndicatedPost::guid() */
|
850 |
-
|
851 |
function author () {
|
852 |
$author = array ();
|
853 |
-
|
854 |
$aa = $this->entry->get_authors();
|
855 |
if (count($aa) > 0) :
|
856 |
$a = reset($aa);
|
@@ -881,7 +927,7 @@ class SyndicatedPost {
|
|
881 |
// e-mail address, but lots of people don't use
|
882 |
// it that way. So let's make of it what we can.
|
883 |
$author = parse_email_with_realname($this->item['author']);
|
884 |
-
|
885 |
if (!isset($author['name'])) :
|
886 |
if (isset($author['email'])) :
|
887 |
$author['name'] = $author['email'];
|
@@ -891,7 +937,7 @@ class SyndicatedPost {
|
|
891 |
endif;
|
892 |
endif;
|
893 |
endif;
|
894 |
-
|
895 |
if (!isset($author['name']) or is_null($author['name'])) :
|
896 |
// Nothing found. Try some crappy defaults.
|
897 |
if ($this->link->name()) :
|
@@ -901,14 +947,14 @@ class SyndicatedPost {
|
|
901 |
$author['name'] = $url['host'];
|
902 |
endif;
|
903 |
endif;
|
904 |
-
|
905 |
if (FEEDWORDPRESS_COMPATIBILITY) :
|
906 |
if (isset($this->item['author_email'])):
|
907 |
$author['email'] = $this->item['author_email'];
|
908 |
elseif (isset($this->feed->channel['author_email'])) :
|
909 |
$author['email'] = $this->feed->channel['author_email'];
|
910 |
endif;
|
911 |
-
|
912 |
if (isset($this->item['author_uri'])):
|
913 |
$author['uri'] = $this->item['author_uri'];
|
914 |
elseif (isset($this->item['author_url'])):
|
@@ -921,7 +967,7 @@ class SyndicatedPost {
|
|
921 |
$author['uri'] = $this->feed->channel['link'];
|
922 |
endif;
|
923 |
endif;
|
924 |
-
|
925 |
return $author;
|
926 |
} /* SyndicatedPost::author() */
|
927 |
|
@@ -945,7 +991,7 @@ class SyndicatedPost {
|
|
945 |
endif;
|
946 |
return $tags;
|
947 |
}
|
948 |
-
|
949 |
/**
|
950 |
* SyndicatedPost::isTaggedAs: Test whether a feed item is
|
951 |
* tagged / categorized with a given string. Case and leading and
|
@@ -953,7 +999,7 @@ class SyndicatedPost {
|
|
953 |
*
|
954 |
* @param string $tag Tag to check for
|
955 |
*
|
956 |
-
* @return bool Whether or not at least one of the categories / tags on
|
957 |
* $this->item is set to $tag (modulo case and leading and trailing
|
958 |
* whitespace)
|
959 |
*/
|
@@ -968,7 +1014,7 @@ class SyndicatedPost {
|
|
968 |
// on this item is stored under index "category#".
|
969 |
if (isset($this->item['category#'])) :
|
970 |
$numberOfCategories = (int) $this->item['category#'];
|
971 |
-
|
972 |
// We REALLY shouldn't have the old and busted MagpieRSS, but in
|
973 |
// case we do, it doesn't support multiple categories, but there
|
974 |
// might still be a single value under the "category" index.
|
@@ -1027,7 +1073,7 @@ class SyndicatedPost {
|
|
1027 |
endif;
|
1028 |
endfor;
|
1029 |
endif;
|
1030 |
-
return $enclosures;
|
1031 |
} /* SyndicatedPost::enclosures() */
|
1032 |
|
1033 |
function source ($what = NULL) {
|
@@ -1038,7 +1084,7 @@ class SyndicatedPost {
|
|
1038 |
$ret['title'] = $source->get_title();
|
1039 |
$ret['uri'] = $source->get_link();
|
1040 |
$ret['feed'] = $source->get_link(0, 'self');
|
1041 |
-
|
1042 |
if ($id_tags = $source->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'id')) :
|
1043 |
$ret['id'] = $id_tags[0]['data'];
|
1044 |
elseif ($id_tags = $source->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'id')) :
|
@@ -1051,16 +1097,16 @@ class SyndicatedPost {
|
|
1051 |
$ret['id'] = $id_tags[0]['data'];
|
1052 |
endif;
|
1053 |
endif;
|
1054 |
-
|
1055 |
if (!is_null($what) and is_scalar($what)) :
|
1056 |
$ret = $ret[$what];
|
1057 |
endif;
|
1058 |
return $ret;
|
1059 |
}
|
1060 |
-
|
1061 |
function comment_link () {
|
1062 |
$url = null;
|
1063 |
-
|
1064 |
// RSS 2.0 has a standard <comments> element:
|
1065 |
// "<comments> is an optional sub-element of <item>. If present,
|
1066 |
// it is the url of the comments page for the item."
|
@@ -1073,13 +1119,13 @@ class SyndicatedPost {
|
|
1073 |
// element with @rel="replies" and @type="text/html".
|
1074 |
// Unfortunately, SimplePie_Item::get_links() allows us to filter
|
1075 |
// by the value of @rel, but not by the value of @type. *sigh*
|
1076 |
-
|
1077 |
// Try Atom 1.0 first
|
1078 |
$linkElements = $this->entry->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link');
|
1079 |
-
|
1080 |
// Fall back and try Atom 0.3
|
1081 |
if (is_null($linkElements)) : $linkElements = $this->entry->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link'); endif;
|
1082 |
-
|
1083 |
// Now loop through the elements, screening by @rel and @type
|
1084 |
if (is_array($linkElements)) : foreach ($linkElements as $link) :
|
1085 |
$rel = (isset($link['attribs']['']['rel']) ? $link['attribs']['']['rel'] : 'alternate');
|
@@ -1170,9 +1216,9 @@ class SyndicatedPost {
|
|
1170 |
return $tag['prefix'] . $url . $tag['suffix'];
|
1171 |
} /* function SyndicatedPost::resolve_single_relative_uri() */
|
1172 |
|
1173 |
-
function resolve_relative_uris ($content, $obj) {
|
1174 |
$set = $obj->link->setting('resolve relative', 'resolve_relative', 'yes');
|
1175 |
-
if ($set and $set != 'no') :
|
1176 |
// Fallback: if we don't have anything better, use the
|
1177 |
// item link from the feed
|
1178 |
$obj->_base = $obj->permalink(); // Reset the base for resolving relative URIs
|
@@ -1194,7 +1240,7 @@ class SyndicatedPost {
|
|
1194 |
);
|
1195 |
endforeach;
|
1196 |
endif;
|
1197 |
-
|
1198 |
return $content;
|
1199 |
} /* function SyndicatedPost::resolve_relative_uris () */
|
1200 |
|
@@ -1209,7 +1255,7 @@ class SyndicatedPost {
|
|
1209 |
return $tag['before_attribute'].$tag['after_attribute'];
|
1210 |
}
|
1211 |
|
1212 |
-
function sanitize_content ($content, $obj) {
|
1213 |
# This kind of sucks. I intend to replace it with
|
1214 |
# lib_filter sometime soon.
|
1215 |
foreach ($obj->strip_attrs as $pair):
|
@@ -1246,50 +1292,69 @@ class SyndicatedPost {
|
|
1246 |
* still up-to-date.
|
1247 |
*
|
1248 |
* @return int A status code representing the freshness of the post
|
|
|
1249 |
* 0 = post already syndicated; no update needed
|
1250 |
* 1 = post already syndicated, but needs to be updated to latest
|
1251 |
* 2 = post has not yet been syndicated; needs to be created
|
1252 |
*/
|
1253 |
-
function freshness () {
|
1254 |
global $wpdb;
|
1255 |
|
1256 |
if ($this->filtered()) : // This should never happen.
|
1257 |
FeedWordPress::critical_bug('SyndicatedPost', $this, __LINE__, __FILE__);
|
1258 |
endif;
|
1259 |
-
|
1260 |
if (is_null($this->_freshness)) : // Not yet checked and cached.
|
1261 |
$guid = $this->post['guid'];
|
1262 |
-
$eguid =
|
1263 |
|
1264 |
$q = new WP_Query(array(
|
1265 |
'fields' => '_synfresh', // id, guid, post_modified_gmt
|
1266 |
'ignore_sticky_posts' => true,
|
1267 |
'guid' => $guid,
|
1268 |
));
|
1269 |
-
|
1270 |
$old_post = NULL;
|
1271 |
if ($q->have_posts()) :
|
1272 |
while ($q->have_posts()) : $q->the_post();
|
1273 |
$old_post = $q->post;
|
1274 |
endwhile;
|
1275 |
endif;
|
1276 |
-
|
1277 |
if (is_null($old_post)) : // No post with this guid
|
1278 |
FeedWordPress::diagnostic('feed_items:freshness', 'Item ['.$guid.'] "'.$this->entry->get_title().'" is a NEW POST.');
|
1279 |
$this->_wp_id = NULL;
|
1280 |
$this->_freshness = 2; // New content
|
1281 |
else :
|
1282 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1283 |
|
1284 |
-
$
|
|
|
1285 |
$updated_ts = $this->updated(/*fallback=*/ true, /*default=*/ NULL);
|
1286 |
|
1287 |
-
//
|
1288 |
-
|
1289 |
-
|
1290 |
-
|
1291 |
-
|
|
|
|
|
|
|
|
|
|
|
1292 |
|
|
|
|
|
1293 |
$updatedReason = NULL;
|
1294 |
if ($updated) :
|
1295 |
$updatedReason = preg_replace(
|
@@ -1300,6 +1365,9 @@ class SyndicatedPost {
|
|
1300 |
.date('Y-m-d H:i:s', $last_rev_ts)
|
1301 |
.')'
|
1302 |
);
|
|
|
|
|
|
|
1303 |
else :
|
1304 |
// Or the hash...
|
1305 |
$hash = $this->update_hash();
|
@@ -1309,24 +1377,31 @@ class SyndicatedPost {
|
|
1309 |
else :
|
1310 |
$updated = true; // Can't find syndication meta-data
|
1311 |
endif;
|
1312 |
-
|
1313 |
if ($updated and FeedWordPress::diagnostic_on('feed_items:freshness:reasons')) :
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1314 |
$updatedReason = ' has a not-yet-seen update hash: '
|
1315 |
-
.
|
1316 |
.' not in {'
|
1317 |
.implode(", ", array_map(array('FeedWordPress', 'val'), $seen))
|
1318 |
.'}. Basis: '
|
1319 |
-
.
|
1320 |
endif;
|
1321 |
endif;
|
1322 |
-
|
1323 |
$frozen = false;
|
1324 |
if ($updated) : // Ignore if the post is frozen
|
1325 |
$frozen = ('yes' == $this->link->setting('freeze updates', 'freeze_updates', NULL));
|
1326 |
if (!$frozen) :
|
1327 |
$frozen_values = get_post_custom_values('_syndication_freeze_updates', $old_post->ID);
|
1328 |
$frozen = (count($frozen_values) > 0 and 'yes' == $frozen_values[0]);
|
1329 |
-
|
1330 |
if ($frozen) :
|
1331 |
$updatedReason = ' IS BLOCKED FROM BEING UPDATED BY A UPDATE LOCK ON THIS POST, EVEN THOUGH IT '.$updatedReason;
|
1332 |
endif;
|
@@ -1334,7 +1409,7 @@ class SyndicatedPost {
|
|
1334 |
$updatedReason = ' IS BLOCKED FROM BEING UPDATED BY A FEEDWORDPRESS UPDATE LOCK, EVEN THOUGH IT '.$updatedReason;
|
1335 |
endif;
|
1336 |
endif;
|
1337 |
-
$
|
1338 |
|
1339 |
if ($updated) :
|
1340 |
FeedWordPress::diagnostic('feed_items:freshness', 'Item ['.$guid.'] "'.$this->entry->get_title().'" is an update of an existing post.');
|
@@ -1342,7 +1417,9 @@ class SyndicatedPost {
|
|
1342 |
$updatedReason = preg_replace('/\s+/', ' ', $updatedReason);
|
1343 |
FeedWordPress::diagnostic('feed_items:freshness:reasons', 'Item ['.$guid.'] "'.$this->entry->get_title().'" '.$updatedReason);
|
1344 |
endif;
|
1345 |
-
|
|
|
|
|
1346 |
$this->_wp_id = $old_post->ID;
|
1347 |
$this->_wp_post = $old_post;
|
1348 |
|
@@ -1359,9 +1436,88 @@ class SyndicatedPost {
|
|
1359 |
endif;
|
1360 |
endif;
|
1361 |
endif;
|
1362 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1363 |
}
|
1364 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1365 |
#################################################
|
1366 |
#### INTERNAL STORAGE AND MANAGEMENT METHODS ####
|
1367 |
#################################################
|
@@ -1370,7 +1526,7 @@ class SyndicatedPost {
|
|
1370 |
if ($this->filtered()) : // This should never happen.
|
1371 |
FeedWordPress::critical_bug('SyndicatedPost', $this, __LINE__, __FILE__);
|
1372 |
endif;
|
1373 |
-
|
1374 |
if (is_null($this->_wp_id) and is_null($this->_freshness)) :
|
1375 |
$fresh = $this->freshness(); // sets WP DB id in the process
|
1376 |
endif;
|
@@ -1383,9 +1539,9 @@ class SyndicatedPost {
|
|
1383 |
if ($this->filtered()) : // This should never happen.
|
1384 |
FeedWordPress::critical_bug('SyndicatedPost', $this, __LINE__, __FILE__);
|
1385 |
endif;
|
1386 |
-
|
1387 |
$freshness = $this->freshness();
|
1388 |
-
if ($
|
1389 |
# -- Look up, or create, numeric ID for author
|
1390 |
$this->post['post_author'] = $this->author_id (
|
1391 |
$this->link->setting('unfamiliar author', 'unfamiliar_author', 'create')
|
@@ -1396,8 +1552,10 @@ class SyndicatedPost {
|
|
1396 |
$this->post = NULL;
|
1397 |
endif;
|
1398 |
endif;
|
1399 |
-
|
1400 |
-
|
|
|
|
|
1401 |
$consider = array(
|
1402 |
'category' => array('abbr' => 'cats', 'domain' => array('category', 'post_tag')),
|
1403 |
'post_tag' => array('abbr' => 'tags', 'domain' => array('post_tag')),
|
@@ -1408,10 +1566,10 @@ class SyndicatedPost {
|
|
1408 |
if (!is_null($this->post)) : // Not filtered out yet
|
1409 |
# -- Look up, or create, numeric ID for categories
|
1410 |
$taxonomies = $this->link->setting("match/".$taxes['abbr'], 'match_'.$taxes['abbr'], $taxes['domain']);
|
1411 |
-
|
1412 |
// Eliminate dummy variables
|
1413 |
$taxonomies = array_filter($taxonomies, 'remove_dummy_zero');
|
1414 |
-
|
1415 |
$terms = $this->category_ids (
|
1416 |
$this->feed_terms[$what],
|
1417 |
$this->link->setting("unfamiliar {$what}", "unfamiliar_{$what}", 'create:'.$what),
|
@@ -1421,7 +1579,7 @@ class SyndicatedPost {
|
|
1421 |
'filters' => true,
|
1422 |
)
|
1423 |
);
|
1424 |
-
|
1425 |
if (is_null($terms) or is_null($termSet)) :
|
1426 |
// filtered out -- no matches
|
1427 |
else :
|
@@ -1457,7 +1615,7 @@ class SyndicatedPost {
|
|
1457 |
if (!isset($this->post['tax_input'][$tax])) :
|
1458 |
$this->post['tax_input'][$tax] = array();
|
1459 |
endif;
|
1460 |
-
|
1461 |
$this->post['tax_input'][$tax] = array_merge (
|
1462 |
$this->post['tax_input'][$tax],
|
1463 |
$this->category_ids (
|
@@ -1471,23 +1629,25 @@ class SyndicatedPost {
|
|
1471 |
endforeach;
|
1472 |
endif;
|
1473 |
endif;
|
1474 |
-
|
1475 |
-
|
|
|
|
|
1476 |
// Filter some individual fields
|
1477 |
-
|
1478 |
// If there already is a post slug (from syndication or by manual
|
1479 |
// editing) don't cause WP to overwrite it by sending in a NULL
|
1480 |
// post_name. Props Chris Fritz 2012-11-28.
|
1481 |
-
$post_name = (is_null($this->_wp_post) ? NULL : $this->_wp_post->post_name);
|
1482 |
|
1483 |
// Allow filters to set post slug. Props niska.
|
1484 |
$post_name = apply_filters('syndicated_post_slug', $post_name, $this);
|
1485 |
if (!empty($post_name)) :
|
1486 |
$this->post['post_name'] = $post_name;
|
1487 |
endif;
|
1488 |
-
|
1489 |
$this->post = apply_filters('syndicated_post', $this->post, $this);
|
1490 |
-
|
1491 |
// Allow for feed-specific syndicated_post filters.
|
1492 |
$this->post = apply_filters(
|
1493 |
"syndicated_post_".$this->link->uri(),
|
@@ -1495,7 +1655,7 @@ class SyndicatedPost {
|
|
1495 |
$this
|
1496 |
);
|
1497 |
endif;
|
1498 |
-
|
1499 |
// Hook in early to make sure these get inserted if at all possible
|
1500 |
add_action(
|
1501 |
/*hook=*/ 'transition_post_status',
|
@@ -1503,39 +1663,42 @@ class SyndicatedPost {
|
|
1503 |
/*priority=*/ -10000, /* very early */
|
1504 |
/*arguments=*/ 3
|
1505 |
);
|
1506 |
-
|
1507 |
-
$retval = array(1 => 'updated', 2 => 'new');
|
1508 |
|
1509 |
$ret = false;
|
1510 |
-
if (
|
1511 |
-
$diag =
|
1512 |
-
|
1513 |
-
|
1514 |
-
|
1515 |
-
FeedWordPress::diagnostic('syndicated_posts', $diag[$freshness]);
|
1516 |
-
|
1517 |
-
$this->insert_post(/*update=*/ ($freshness == 1));
|
1518 |
|
1519 |
-
$
|
1520 |
-
do_action($hook[$freshness], $this->wp_id(), $this);
|
1521 |
|
1522 |
-
$
|
|
|
|
|
|
|
|
|
|
|
1523 |
endif;
|
1524 |
|
1525 |
-
// If this is a legit, non-filtered post, tag it as found on the
|
1526 |
-
// regardless of fresh or stale status
|
1527 |
if (!$this->filtered()) :
|
1528 |
$key = '_feedwordpress_retire_me_' . $this->link->id;
|
1529 |
delete_post_meta($this->wp_id(), $key);
|
1530 |
-
|
1531 |
$status = get_post_field('post_status', $this->wp_id());
|
1532 |
-
if ('fwpretired'==$status and $this->link->
|
1533 |
-
FeedWordPress::diagnostic('syndicated_posts', "Un-retiring previously retired post # ".$this->wp_id()." due to re-appearance on non-incremental feed.");
|
1534 |
set_post_field('post_status', $this->post['post_status'], $this->wp_id());
|
1535 |
-
wp_transition_post_status($this->post['post_status'], $status, $
|
|
|
|
|
|
|
|
|
1536 |
endif;
|
1537 |
endif;
|
1538 |
-
|
1539 |
// Remove add_rss_meta hook
|
1540 |
remove_action(
|
1541 |
/*hook=*/ 'transition_post_status',
|
@@ -1546,17 +1709,18 @@ class SyndicatedPost {
|
|
1546 |
|
1547 |
return $ret;
|
1548 |
} /* function SyndicatedPost::store () */
|
1549 |
-
|
1550 |
-
function insert_post ($update = false) {
|
1551 |
global $wpdb;
|
1552 |
|
1553 |
$dbpost = $this->normalize_post(/*new=*/ true);
|
|
|
1554 |
if (!is_null($dbpost)) :
|
1555 |
$dbpost['post_pingback'] = false; // Tell WP 2.1 and 2.2 not to process for pingbacks
|
1556 |
-
|
1557 |
// This is a ridiculous fucking kludge necessitated by WordPress 2.6 munging authorship meta-data
|
1558 |
add_action('_wp_put_post_revision', array($this, 'fix_revision_meta'));
|
1559 |
-
|
1560 |
// Kludge to prevent kses filters from stripping the
|
1561 |
// content of posts when updating without a logged in
|
1562 |
// user who has `unfiltered_html` capability.
|
@@ -1568,17 +1732,17 @@ class SyndicatedPost {
|
|
1568 |
$removed[] = $munger;
|
1569 |
endif;
|
1570 |
endforeach;
|
1571 |
-
|
1572 |
if ($update and function_exists('get_post_field')) :
|
1573 |
// Don't munge status fields that the user may
|
1574 |
// have reset manually
|
1575 |
$doNotMunge = array('post_status', 'comment_status', 'ping_status');
|
1576 |
-
|
1577 |
foreach ($doNotMunge as $field) :
|
1578 |
$dbpost[$field] = get_post_field($field, $this->wp_id());
|
1579 |
endforeach;
|
1580 |
endif;
|
1581 |
-
|
1582 |
// WP3's wp_insert_post scans current_user_can() for the
|
1583 |
// tax_input, with no apparent way to override. Ugh.
|
1584 |
add_action(
|
@@ -1587,7 +1751,7 @@ class SyndicatedPost {
|
|
1587 |
/*priority=*/ -10001, /* very early */
|
1588 |
/*arguments=*/ 3
|
1589 |
);
|
1590 |
-
|
1591 |
// WP3 appears to override whatever you give it for
|
1592 |
// post_modified. Ugh.
|
1593 |
add_action(
|
@@ -1601,8 +1765,44 @@ class SyndicatedPost {
|
|
1601 |
$this->post['ID'] = $this->wp_id();
|
1602 |
$dbpost['ID'] = $this->post['ID'];
|
1603 |
endif;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1604 |
|
1605 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1606 |
|
1607 |
remove_action(
|
1608 |
/*hook=*/ 'transition_post_status',
|
@@ -1623,17 +1823,17 @@ class SyndicatedPost {
|
|
1623 |
foreach ($removed as $filter) :
|
1624 |
add_filter('content_save_pre', $filter);
|
1625 |
endforeach;
|
1626 |
-
|
1627 |
$this->validate_post_id($dbpost, $update, array(__CLASS__, __FUNCTION__));
|
1628 |
endif;
|
1629 |
} /* function SyndicatedPost::insert_post () */
|
1630 |
-
|
1631 |
function insert_new () {
|
1632 |
-
$this->insert_post(/*update=*/ false);
|
1633 |
} /* SyndicatedPost::insert_new() */
|
1634 |
|
1635 |
function update_existing () {
|
1636 |
-
$this->insert_post(/*update=*/ true);
|
1637 |
} /* SyndicatedPost::update_existing() */
|
1638 |
|
1639 |
/**
|
@@ -1660,7 +1860,7 @@ class SyndicatedPost {
|
|
1660 |
$feed_url = parse_url($this->post['meta']['syndication_feed']);
|
1661 |
$source_title = $feed_url['host'];
|
1662 |
endif;
|
1663 |
-
|
1664 |
$out['post_title'] = $source_title
|
1665 |
.' '.gmdate('Y-m-d H:i:s', $this->published() + $offset);
|
1666 |
// FIXME: Option for what to fill a blank title with...
|
@@ -1669,18 +1869,29 @@ class SyndicatedPost {
|
|
1669 |
// Normalize the guid if necessary.
|
1670 |
$out['guid'] = SyndicatedPost::normalize_guid($out['guid']);
|
1671 |
|
1672 |
-
// Why the fuck doesn't wp_insert_post already do this?
|
1673 |
-
foreach ($out as $key => $value) :
|
1674 |
-
if (is_string($value)) :
|
1675 |
-
$out[$key] = $wpdb->escape($value);
|
1676 |
-
else :
|
1677 |
-
$out[$key] = $value;
|
1678 |
-
endif;
|
1679 |
-
endforeach;
|
1680 |
-
|
1681 |
return $out;
|
1682 |
}
|
1683 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1684 |
/**
|
1685 |
* SyndicatedPost::validate_post_id()
|
1686 |
*
|
@@ -1702,8 +1913,9 @@ class SyndicatedPost {
|
|
1702 |
// notice if we are in debug mode.
|
1703 |
$mesg = "Failed to $verb item [$guid]. WordPress API returned no valid post ID.\n"
|
1704 |
."\t\tID = ".serialize($this->_wp_id)."\n"
|
1705 |
-
."\t\tURL = ".
|
1706 |
-
."\t\tFeed = ".
|
|
|
1707 |
FeedWordPress::diagnostic('updated_feeds:errors', "WordPress API error: $mesg");
|
1708 |
FeedWordPress::diagnostic('feed_items:rejected', $mesg);
|
1709 |
|
@@ -1711,9 +1923,9 @@ class SyndicatedPost {
|
|
1711 |
The WordPress API returned an invalid post ID
|
1712 |
when FeedWordPress tried to $verb item $guid
|
1713 |
[URL: $url]
|
1714 |
-
from the feed at $feed
|
1715 |
|
1716 |
-
$ns::_wp_id
|
1717 |
EOM;
|
1718 |
FeedWordPress::noncritical_bug(
|
1719 |
/*message=*/ $mesg,
|
@@ -1725,16 +1937,16 @@ EOM;
|
|
1725 |
);
|
1726 |
endif;
|
1727 |
} /* SyndicatedPost::validate_post_id() */
|
1728 |
-
|
1729 |
/**
|
1730 |
-
* SyndicatedPost::fix_revision_meta() -
|
1731 |
-
*
|
1732 |
-
* syndicated post.
|
1733 |
*
|
1734 |
-
* In their infinite wisdom, the WordPress coders have made it
|
1735 |
-
* impossible for a plugin that uses wp_insert_post() to set
|
1736 |
-
* meta-data (such as the author) when you store an old revision
|
1737 |
-
* updated post. Instead, it uses the WordPress defaults (=
|
1738 |
* active user ID if the process is running with a user logged in, or
|
1739 |
* = #0 if there is no user logged in). This results in bogus authorship
|
1740 |
* data for revisions that are syndicated from off the feed, unless we
|
@@ -1745,17 +1957,22 @@ EOM;
|
|
1745 |
*/
|
1746 |
function fix_revision_meta ($revision_id) {
|
1747 |
global $wpdb;
|
1748 |
-
|
1749 |
$post_author = (int) $this->post['post_author'];
|
1750 |
-
|
1751 |
$revision_id = (int) $revision_id;
|
1752 |
-
|
1753 |
-
|
1754 |
-
|
1755 |
-
|
1756 |
-
|
|
|
|
|
|
|
|
|
|
|
1757 |
} /* SyndicatedPost::fix_revision_meta () */
|
1758 |
-
|
1759 |
/**
|
1760 |
* SyndicatedPost::add_terms() -- if FeedWordPress is processing an
|
1761 |
* automatic update, that generally means that wp_insert_post() is being
|
@@ -1774,18 +1991,35 @@ EOM;
|
|
1774 |
* @param object $post The database record for the post just inserted.
|
1775 |
*/
|
1776 |
function add_terms ($new_status, $old_status, $post) {
|
|
|
1777 |
if ($new_status!='inherit') : // Bail if we are creating a revision.
|
1778 |
if ( is_array($this->post) and isset($this->post['tax_input']) and is_array($this->post['tax_input']) ) :
|
1779 |
foreach ($this->post['tax_input'] as $taxonomy => $terms) :
|
1780 |
if (is_array($terms)) :
|
1781 |
$terms = array_filter($terms); // strip out empties
|
1782 |
endif;
|
1783 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1784 |
endforeach;
|
1785 |
endif;
|
1786 |
endif;
|
|
|
1787 |
} /* SyndicatedPost::add_terms () */
|
1788 |
-
|
1789 |
/**
|
1790 |
* SyndicatedPost::fix_post_modified_ts() -- We would like to set
|
1791 |
* post_modified and post_modified_gmt to reflect the value of
|
@@ -1810,7 +2044,7 @@ EOM;
|
|
1810 |
), /*where=*/ array('ID' => $post->ID) );
|
1811 |
endif;
|
1812 |
} /* SyndicatedPost::fix_post_modified_ts () */
|
1813 |
-
|
1814 |
/**
|
1815 |
* SyndicatedPost::add_rss_meta: adds interesting meta-data to each entry
|
1816 |
* using the space for custom keys. The set of keys and values to add is
|
@@ -1833,7 +2067,7 @@ EOM;
|
|
1833 |
|
1834 |
if ( is_array($this->post) and isset($this->post['meta']) and is_array($this->post['meta']) ) :
|
1835 |
$postId = $post->ID;
|
1836 |
-
|
1837 |
// Aggregated posts should NOT send out pingbacks.
|
1838 |
// WordPress 2.1-2.2 claim you can tell them not to
|
1839 |
// using $post_pingback, but they don't listen, so we
|
@@ -1842,21 +2076,21 @@ EOM;
|
|
1842 |
DELETE FROM $wpdb->postmeta
|
1843 |
WHERE post_id='$postId' AND meta_key='_pingme'
|
1844 |
");
|
1845 |
-
|
1846 |
foreach ( $this->post['meta'] as $key => $values ) :
|
1847 |
-
$eKey =
|
1848 |
-
|
1849 |
// If this is an update, clear out the old
|
1850 |
// values to avoid duplication.
|
1851 |
$result = $wpdb->query("
|
1852 |
DELETE FROM $wpdb->postmeta
|
1853 |
WHERE post_id='$postId' AND meta_key='$eKey'
|
1854 |
");
|
1855 |
-
|
1856 |
// Allow for either a single value or an array
|
1857 |
if (!is_array($values)) $values = array($values);
|
1858 |
foreach ( $values as $value ) :
|
1859 |
-
FeedWordPress::diagnostic('syndicated_posts:meta_data', "Adding post meta-datum to post [$postId]: [$key] = ".
|
1860 |
add_post_meta($postId, $key, $value, /*unique=*/ false);
|
1861 |
endforeach;
|
1862 |
endforeach;
|
@@ -1881,7 +2115,7 @@ EOM;
|
|
1881 |
$source = $this->source();
|
1882 |
$forbidden = apply_filters('feedwordpress_forbidden_author_names',
|
1883 |
array('admin', 'administrator', 'www', 'root'));
|
1884 |
-
|
1885 |
// Prepare the list of candidates to try for author name: name from
|
1886 |
// feed, original source title (if any), immediate source title live
|
1887 |
// from feed, subscription title, prettied version of feed homepage URL,
|
@@ -1896,10 +2130,10 @@ EOM;
|
|
1896 |
if (strlen($this->link->homepage()) > 0) : $candidates[] = feedwordpress_display_url($this->link->homepage()); endif;
|
1897 |
$candidates[] = feedwordpress_display_url($this->link->uri());
|
1898 |
$candidates[] = 'unknown author';
|
1899 |
-
|
1900 |
// Pick the first one that works from the list, screening against empty
|
1901 |
// or forbidden names.
|
1902 |
-
|
1903 |
$author = NULL;
|
1904 |
while (is_null($author) and ($candidate = each($candidates))) :
|
1905 |
if (!is_null($candidate['value'])
|
@@ -1908,11 +2142,11 @@ EOM;
|
|
1908 |
$author = $candidate['value'];
|
1909 |
endif;
|
1910 |
endwhile;
|
1911 |
-
|
1912 |
$email = (isset($a['email']) ? $a['email'] : NULL);
|
1913 |
$authorUrl = (isset($a['uri']) ? $a['uri'] : NULL);
|
1914 |
|
1915 |
-
|
1916 |
$hostUrl = $this->link->homepage();
|
1917 |
if (is_null($hostUrl) or (strlen($hostUrl) < 0)) :
|
1918 |
$hostUrl = $this->link->uri();
|
@@ -1939,7 +2173,7 @@ EOM;
|
|
1939 |
// Uniqueness will be guaranteed below if necessary.
|
1940 |
|
1941 |
$url = parse_url($hostUrl);
|
1942 |
-
|
1943 |
$login = sanitize_user($url['host'], /*strict=*/ true);
|
1944 |
if (strlen($login) < 1) :
|
1945 |
// This isn't working. Frak it.
|
@@ -1952,11 +2186,11 @@ EOM;
|
|
1952 |
$nice_author = sanitize_title($author);
|
1953 |
$nice_author = apply_filters('pre_user_nicename', $nice_author);
|
1954 |
|
1955 |
-
$reg_author =
|
1956 |
-
$author =
|
1957 |
-
$email =
|
1958 |
-
$test_email =
|
1959 |
-
$authorUrl =
|
1960 |
|
1961 |
// Check for an existing author rule....
|
1962 |
if (isset($this->link->settings['map authors']['name']['*'])) :
|
@@ -1974,7 +2208,7 @@ EOM;
|
|
1974 |
// User name is filtered out
|
1975 |
elseif ('filter' == $author_rule) :
|
1976 |
$id = NULL;
|
1977 |
-
|
1978 |
else :
|
1979 |
// Check the database for an existing author record that might fit
|
1980 |
|
@@ -1987,7 +2221,7 @@ EOM;
|
|
1987 |
LENGTH(TRIM(LCASE(user_email))) > 0
|
1988 |
AND TRIM(LCASE(user_email)) = TRIM(LCASE('$test_email'))
|
1989 |
)");
|
1990 |
-
|
1991 |
// If that fails, look for aliases in the user meta data table
|
1992 |
if (is_null($id)) :
|
1993 |
$id = $wpdb->get_var(
|
@@ -2032,7 +2266,7 @@ EOM;
|
|
2032 |
if (isset($parts[1])) : $userdata['last_name'] = $parts[1]; endif;
|
2033 |
$userdata['display_name'] = $author;
|
2034 |
$userdata['role'] = 'contributor';
|
2035 |
-
|
2036 |
do { // Keep trying until you get it right. Or until PHP crashes, I guess.
|
2037 |
$id = wp_insert_user($userdata);
|
2038 |
if (is_wp_error($id)) :
|
@@ -2046,10 +2280,10 @@ EOM;
|
|
2046 |
case 'existing_user_email' :
|
2047 |
// No disassemble!
|
2048 |
$parts = explode('@', $userdata['user_email'], 2);
|
2049 |
-
|
2050 |
// Add a random disambiguator as a gmail-style username extension
|
2051 |
$parts[0] .= '+'.substr(md5(uniqid(microtime())), 0, 6);
|
2052 |
-
|
2053 |
// Reassemble
|
2054 |
$userdata['user_email'] = $parts[0].'@'.$parts[1];
|
2055 |
break;
|
@@ -2066,7 +2300,7 @@ EOM;
|
|
2066 |
|
2067 |
if ($id) :
|
2068 |
$this->link->settings['map authors']['name'][strtolower(trim($author))] = $id;
|
2069 |
-
|
2070 |
// Multisite: Check whether the author has been recorded
|
2071 |
// on *this* blog before. If not, put her down as a
|
2072 |
// Contributor for *this* blog.
|
@@ -2075,128 +2309,21 @@ EOM;
|
|
2075 |
$user->add_role('contributor');
|
2076 |
endif;
|
2077 |
endif;
|
2078 |
-
return $id;
|
2079 |
} /* function SyndicatedPost::author_id () */
|
2080 |
|
2081 |
/**
|
2082 |
-
* category_ids: look up (and create) category ids from a list of
|
|
|
2083 |
*
|
2084 |
* @param array $cats
|
2085 |
* @param string $unfamiliar_category
|
2086 |
* @param array|null $taxonomies
|
2087 |
* @return array
|
2088 |
-
*/
|
2089 |
function category_ids ($cats, $unfamiliar_category = 'create', $taxonomies = NULL, $params = array()) {
|
2090 |
-
$
|
2091 |
-
|
2092 |
-
|
2093 |
-
$catTax = 'category';
|
2094 |
-
|
2095 |
-
if (is_null($taxonomies)) :
|
2096 |
-
$taxonomies = array('category');
|
2097 |
-
endif;
|
2098 |
-
|
2099 |
-
// We need to normalize whitespace because (1) trailing
|
2100 |
-
// whitespace can cause PHP and MySQL not to see eye to eye on
|
2101 |
-
// VARCHAR comparisons for some versions of MySQL (cf.
|
2102 |
-
// <http://dev.mysql.com/doc/mysql/en/char.html>), and (2)
|
2103 |
-
// because I doubt most people want to make a semantic
|
2104 |
-
// distinction between 'Computers' and 'Computers '
|
2105 |
-
$cats = array_map('trim', $cats);
|
2106 |
-
|
2107 |
-
$terms = array();
|
2108 |
-
foreach ($taxonomies as $tax) :
|
2109 |
-
$terms[$tax] = array();
|
2110 |
-
endforeach;
|
2111 |
-
|
2112 |
-
foreach ($cats as $cat_name) :
|
2113 |
-
if (preg_match('/^{([^#}]*)#([0-9]+)}$/', $cat_name, $backref)) :
|
2114 |
-
$cat_id = (int) $backref[2];
|
2115 |
-
$tax = $backref[1];
|
2116 |
-
if (strlen($tax) < 1) :
|
2117 |
-
$tax = $catTax;
|
2118 |
-
endif;
|
2119 |
-
|
2120 |
-
$term = term_exists($cat_id, $tax);
|
2121 |
-
if (!is_wp_error($term) and !!$term) :
|
2122 |
-
if (!isset($terms[$tax])) :
|
2123 |
-
$terms[$tax] = array();
|
2124 |
-
endif;
|
2125 |
-
$terms[$tax][] = $cat_id;
|
2126 |
-
endif;
|
2127 |
-
elseif (strlen($cat_name) > 0) :
|
2128 |
-
$familiar = false;
|
2129 |
-
foreach ($taxonomies as $tax) :
|
2130 |
-
if ($tax!='category' or strtolower($cat_name)!='uncategorized') :
|
2131 |
-
$term = term_exists($cat_name, $tax);
|
2132 |
-
if (!is_wp_error($term) and !!$term) :
|
2133 |
-
$familiar = true;
|
2134 |
-
|
2135 |
-
if (is_array($term)) :
|
2136 |
-
$term_id = (int) $term['term_id'];
|
2137 |
-
else :
|
2138 |
-
$term_id = (int) $term;
|
2139 |
-
endif;
|
2140 |
-
|
2141 |
-
if (!isset($terms[$tax])) :
|
2142 |
-
$terms[$tax] = array();
|
2143 |
-
endif;
|
2144 |
-
$terms[$tax][] = $term_id;
|
2145 |
-
break; // We're done here.
|
2146 |
-
endif;
|
2147 |
-
endif;
|
2148 |
-
endforeach;
|
2149 |
-
|
2150 |
-
if (!$familiar) :
|
2151 |
-
if ('tag'==$unfamiliar_category) :
|
2152 |
-
$unfamiliar_category = 'create:post_tag';
|
2153 |
-
endif;
|
2154 |
-
|
2155 |
-
if (preg_match('/^create(:(.*))?$/i', $unfamiliar_category, $ref)) :
|
2156 |
-
$tax = $catTax; // Default
|
2157 |
-
if (isset($ref[2]) and strlen($ref[2]) > 2) :
|
2158 |
-
$tax = $ref[2];
|
2159 |
-
endif;
|
2160 |
-
$term = wp_insert_term($cat_name, $tax);
|
2161 |
-
if (is_wp_error($term)) :
|
2162 |
-
FeedWordPress::noncritical_bug('term insertion problem', array('cat_name' => $cat_name, 'term' => $term, 'this' => $this), __LINE__, __FILE__);
|
2163 |
-
else :
|
2164 |
-
if (!isset($terms[$tax])) :
|
2165 |
-
$terms[$tax] = array();
|
2166 |
-
endif;
|
2167 |
-
$terms[$tax][] = (int) $term['term_id'];
|
2168 |
-
endif;
|
2169 |
-
endif;
|
2170 |
-
endif;
|
2171 |
-
endif;
|
2172 |
-
endforeach;
|
2173 |
-
|
2174 |
-
$filtersOn = $allowFilters;
|
2175 |
-
if ($allowFilters) :
|
2176 |
-
$filters = array_filter(
|
2177 |
-
$this->link->setting('match/filter', 'match_filter', array()),
|
2178 |
-
'remove_dummy_zero'
|
2179 |
-
);
|
2180 |
-
$filtersOn = ($filtersOn and is_array($filters) and (count($filters) > 0));
|
2181 |
-
endif;
|
2182 |
-
|
2183 |
-
// Check for filter conditions
|
2184 |
-
foreach ($terms as $tax => $term_ids) :
|
2185 |
-
if ($filtersOn
|
2186 |
-
and (count($term_ids)==0)
|
2187 |
-
and in_array($tax, $filters)) :
|
2188 |
-
$terms = NULL; // Drop the post
|
2189 |
-
break;
|
2190 |
-
else :
|
2191 |
-
$terms[$tax] = array_unique($term_ids);
|
2192 |
-
endif;
|
2193 |
-
endforeach;
|
2194 |
-
|
2195 |
-
if ($singleton and count($terms)==1) : // If we only searched one, just return the term IDs
|
2196 |
-
$terms = end($terms);
|
2197 |
-
endif;
|
2198 |
-
return $terms;
|
2199 |
-
} // function SyndicatedPost::category_ids ()
|
2200 |
|
2201 |
} /* class SyndicatedPost */
|
2202 |
|
1 |
<?php
|
2 |
require_once(dirname(__FILE__).'/feedtime.class.php');
|
3 |
+
require_once(dirname(__FILE__).'/syndicatedpostterm.class.php');
|
4 |
|
5 |
/**
|
6 |
* class SyndicatedPost: FeedWordPress uses to manage the conversion of
|
11 |
* different feed formats, which may be useful to FeedWordPress users
|
12 |
* who make use of feed data in PHP add-ons and filters.
|
13 |
*
|
14 |
+
* @version 2013.0525
|
15 |
*/
|
16 |
class SyndicatedPost {
|
17 |
var $item = null; // MagpieRSS representation
|
20 |
var $link = null;
|
21 |
var $feed = null;
|
22 |
var $feedmeta = null;
|
23 |
+
|
24 |
var $xmlns = array ();
|
25 |
|
26 |
var $post = array ();
|
28 |
var $named = array ();
|
29 |
var $preset_terms = array ();
|
30 |
var $feed_terms = array ();
|
31 |
+
|
32 |
var $_freshness = null;
|
33 |
var $_wp_id = null;
|
34 |
var $_wp_post = null;
|
45 |
function SyndicatedPost ($item, &$source) {
|
46 |
global $wpdb;
|
47 |
|
48 |
+
if ( empty($item) && empty($source) )
|
49 |
+
return;
|
50 |
+
|
51 |
if (is_array($item)
|
52 |
and isset($item['simplepie'])
|
53 |
and isset($item['magpie'])) :
|
56 |
$item = $item['magpie'];
|
57 |
elseif (is_a($item, 'SimplePie_Item')) :
|
58 |
$this->entry = $item;
|
59 |
+
|
60 |
// convert to Magpie for compat purposes
|
61 |
$mp = new MagpieFromSimplePie($source->simplepie, $this->entry);
|
62 |
$this->item = $mp->get_item();
|
63 |
+
|
64 |
// done with conversion object
|
65 |
$mp = NULL; unset($mp);
|
66 |
else :
|
80 |
if (!isset($this->xmlns['reverse'][$ns])) :
|
81 |
$this->xmlns['reverse'][$ns] = array();
|
82 |
endif;
|
83 |
+
$this->xmlns['reverse'][$ns][] = $url;
|
84 |
endforeach;
|
85 |
+
|
86 |
// Fucking SimplePie.
|
87 |
$this->xmlns['reverse']['rss'][] = '';
|
88 |
|
104 |
// Trigger global syndicated_item filter.
|
105 |
$changed = apply_filters('syndicated_item', $this->item, $this);
|
106 |
$this->item = $changed;
|
107 |
+
|
108 |
// Allow for feed-specific syndicated_item filters.
|
109 |
$changed = apply_filters(
|
110 |
"syndicated_item_".$source->uri(),
|
112 |
$this
|
113 |
);
|
114 |
$this->item = $changed;
|
115 |
+
|
116 |
# Filters can halt further processing by returning NULL
|
117 |
if (is_null($this->item)) :
|
118 |
$this->post = NULL;
|
119 |
else :
|
120 |
+
# Note that nothing is run through esc_sql() here.
|
121 |
# That's deliberate. The escaping is done at the point
|
122 |
# of insertion, not here, to avoid double-escaping and
|
123 |
# to avoid screwing with syndicated_post filters
|
134 |
// This just gives us an alphanumeric name for the author.
|
135 |
// We look up (or create) the numeric ID for the author
|
136 |
// in SyndicatedPost::add().
|
137 |
+
|
138 |
$this->post['post_content'] = apply_filters(
|
139 |
'syndicated_item_content',
|
140 |
$this->content(), $this
|
168 |
// overwrite if necessary; thus preventing any munging.
|
169 |
$postMetaIn = $this->link->postmeta(array("parsed" => true));
|
170 |
$postMetaOut = array();
|
171 |
+
|
172 |
foreach ($postMetaIn as $key => $meta) :
|
173 |
$postMetaOut[$key] = $meta->do_substitutions($this);
|
174 |
endforeach;
|
175 |
+
|
176 |
foreach ($postMetaOut as $key => $values) :
|
177 |
$this->post['meta'][$key] = array();
|
178 |
foreach ($values as $value) :
|
179 |
$this->post['meta'][$key][] = apply_filters("syndicated_post_meta_{$key}", $value, $this);
|
180 |
endforeach;
|
181 |
endforeach;
|
182 |
+
|
183 |
// RSS 2.0 / Atom 1.0 enclosure support
|
184 |
$enclosures = $this->entry->get_enclosures();
|
185 |
if (is_array($enclosures)) : foreach ($enclosures as $enclosure) :
|
191 |
|
192 |
// In case you want to point back to the blog this was
|
193 |
// syndicated from.
|
194 |
+
|
195 |
$sourcemeta['syndication_source'] = apply_filters(
|
196 |
'syndicated_item_source_title',
|
197 |
$this->link->name(),
|
207 |
$this->link->guid(),
|
208 |
$this
|
209 |
);
|
210 |
+
|
211 |
// Make use of atom:source data, if present in an aggregated feed
|
212 |
$entry_source = $this->source();
|
213 |
if (!is_null($entry_source)) :
|
217 |
elseif ($what=='feed') : $key = 'syndication_feed';
|
218 |
else : $key = "syndication_source_${what}";
|
219 |
endif;
|
220 |
+
|
221 |
$sourcemeta["${key}_original"] = apply_filters(
|
222 |
'syndicated_item_original_source_'.$what,
|
223 |
$value,
|
226 |
endif;
|
227 |
endforeach;
|
228 |
endif;
|
229 |
+
|
230 |
foreach ($sourcemeta as $meta_key => $value) :
|
231 |
if (!is_null($value)) :
|
232 |
$this->post['meta'][$meta_key] = $value;
|
234 |
endforeach;
|
235 |
|
236 |
// Store information on human-readable and machine-readable comment URIs
|
237 |
+
|
238 |
// Human-readable comment URI
|
239 |
$commentLink = apply_filters('syndicated_item_comments', $this->comment_link(), $this);
|
240 |
if (!is_null($commentLink)) : $this->post['meta']['rss:comments'] = $commentLink; endif;
|
277 |
$cats = array_merge($cats, $fc);
|
278 |
endif;
|
279 |
$this->preset_terms['category'] = $cats;
|
280 |
+
|
281 |
// Now add categories from the post, if we have 'em
|
282 |
$cats = array();
|
283 |
$post_cats = $this->entry->get_categories();
|
284 |
if (is_array($post_cats)) : foreach ($post_cats as $cat) :
|
285 |
$cat_name = $cat->get_term();
|
286 |
if (!$cat_name) : $cat_name = $cat->get_label(); endif;
|
287 |
+
|
288 |
if ($this->link->setting('cat_split', NULL, NULL)) :
|
289 |
$pcre = "\007".$this->feedmeta['cat_split']."\007";
|
290 |
$cats = array_merge(
|
302 |
endforeach; endif;
|
303 |
|
304 |
$this->feed_terms['category'] = apply_filters('syndicated_item_categories', $cats, $this);
|
305 |
+
|
306 |
// Tags: start with default tags, if any
|
307 |
$tags = array();
|
308 |
if ('no' != $this->link->setting('add/post_tag', NULL, 'yes')) :
|
309 |
$ft = get_option("feedwordpress_syndication_tags", NULL);
|
310 |
$tags = (is_null($ft) ? array() : explode(FEEDWORDPRESS_CAT_SEPARATOR, $ft));
|
311 |
endif;
|
312 |
+
|
313 |
$ft = $this->link->setting('tags', NULL, array());
|
314 |
if (is_array($ft)) :
|
315 |
$tags = array_merge($tags, $ft);
|
316 |
endif;
|
317 |
$this->preset_terms['post_tag'] = $tags;
|
318 |
+
|
319 |
// Scan post for /a[@rel='tag'] and use as tags if present
|
320 |
$tags = $this->inline_tags();
|
321 |
$this->feed_terms['post_tag'] = apply_filters('syndicated_item_tags', $tags, $this);
|
322 |
+
|
323 |
$taxonomies = $this->link->taxonomies();
|
324 |
$feedTerms = $this->link->setting('terms', NULL, array());
|
325 |
$globalTerms = get_option('feedwordpress_syndication_terms', array());
|
328 |
foreach ($taxonomies as $tax) :
|
329 |
if (!isset($specials[$tax])) :
|
330 |
$terms = array();
|
331 |
+
|
332 |
// See if we should get the globals
|
333 |
if ('no' != $this->link->setting("add/$tax", NULL, 'yes')) :
|
334 |
if (isset($globalTerms[$tax])) :
|
335 |
$terms = $globalTerms[$tax];
|
336 |
endif;
|
337 |
endif;
|
338 |
+
|
339 |
// Now merge in the locals
|
340 |
if (isset($feedTerms[$tax])) :
|
341 |
$terms = array_merge($terms, $feedTerms[$tax]);
|
356 |
|
357 |
function substitution_function ($name) {
|
358 |
$ret = NULL;
|
359 |
+
|
360 |
switch ($name) :
|
361 |
// Allowed PHP string functions
|
362 |
case 'trim':
|
370 |
endswitch;
|
371 |
return $ret;
|
372 |
}
|
373 |
+
|
374 |
/**
|
375 |
* SyndicatedPost::query uses an XPath-like syntax to query arbitrary
|
376 |
* elements within the syndicated item.
|
387 |
foreach ($match as $ref) :
|
388 |
$urlHash[md5($ref[1])] = $ref[1];
|
389 |
endforeach;
|
390 |
+
|
391 |
foreach ($urlHash as $hash => $url) :
|
392 |
+
$path = str_replace('{'.$url.'}', '{#'.$hash.'}', $path);
|
393 |
endforeach;
|
394 |
|
395 |
$path = explode('/', $path);
|
410 |
while (strlen($node)==0 and !is_null($node)) :
|
411 |
$node = array_shift($path);
|
412 |
endwhile;
|
413 |
+
|
414 |
switch ($node) :
|
415 |
case 'feed' :
|
416 |
case 'channel' :
|
444 |
$addenda = $elements[$element];
|
445 |
$contexts = $elements[$element];
|
446 |
endif;
|
447 |
+
|
448 |
foreach ($addenda as $index => $addendum) :
|
449 |
$context = $contexts[$index];
|
450 |
|
454 |
endif;
|
455 |
endforeach;
|
456 |
endif;
|
457 |
+
endforeach;
|
458 |
endif;
|
459 |
endforeach;
|
460 |
+
|
461 |
$data = $matches;
|
462 |
endif;
|
463 |
$node = array_shift($path);
|
464 |
endwhile;
|
465 |
+
|
466 |
$matches = array();
|
467 |
foreach ($data as $datum) :
|
468 |
if (is_string($datum)) :
|
491 |
'http://backend.userland.com/RSS2',
|
492 |
SIMPLEPIE_NAMESPACE_RSS_20,
|
493 |
);
|
494 |
+
|
495 |
$matches = array();
|
496 |
foreach ($rss as $ns) :
|
497 |
$data = $this->link->simplepie->get_feed_tags($ns, 'channel');
|
518 |
else :
|
519 |
$defaultNS = SIMPLEPIE_NAMESPACE_RSS_20;
|
520 |
endif;
|
521 |
+
return $defaultNS;
|
522 |
} /* SyndicatedPost::xpath_default_namespace() */
|
523 |
|
524 |
function xpath_name_and_axis ($node) {
|
553 |
$ns = array($ref[1]);
|
554 |
elseif (strpos($node, ':') !== FALSE) :
|
555 |
list($xmlns, $element) = explode(':', $node, 2);
|
556 |
+
|
557 |
if (isset($this->xmlns['reverse'][$xmlns])) :
|
558 |
$ns = $this->xmlns['reverse'][$xmlns];
|
559 |
else :
|
560 |
$ns = array($xmlns);
|
561 |
endif;
|
562 |
+
|
563 |
// Fucking SimplePie. For attributes in default xmlns.
|
564 |
$defaultNS = $this->xpath_default_namespace();
|
565 |
if (isset($this->xmlns['forward'][$defaultNS])
|
566 |
and ($xmlns==$this->xmlns['forward'][$defaultNS])) :
|
567 |
$ns[] = '';
|
568 |
endif;
|
569 |
+
|
570 |
if (isset($datum['xmlns'])) :
|
571 |
if (isset($datum['xmlns'][$xmlns])) :
|
572 |
$ns[] = $datum['xmlns'][$xmlns];
|
580 |
return array_unique($ns);
|
581 |
} /* SyndicatedPost::xpath_possible_namespaces() */
|
582 |
|
583 |
+
function get_categories ($params = array()) {
|
584 |
+
return $this->entry->get_categories();
|
585 |
+
}
|
586 |
+
|
587 |
+
function title ($params = array()) {
|
588 |
+
return $this->entry->get_title();
|
589 |
+
} /* SyndicatedPost::title () */
|
590 |
+
|
591 |
+
function content ($params = array()) {
|
592 |
+
$params = wp_parse_args($params, array(
|
593 |
+
"full only" => false,
|
594 |
+
));
|
595 |
+
|
596 |
$content = NULL;
|
597 |
+
|
598 |
+
// FIXME: This is one of the main places in the code still using
|
599 |
+
// the outmoded SimplePie - to - Magpie construction. We could
|
600 |
+
// replace using SimplePie_Item::get_tags() here. (Or if really
|
601 |
+
// ambitious we could attempt to just use
|
602 |
+
// SimplePie_Item::get_content() with content-only set to TRUE
|
603 |
+
// and some sanitization in effect. -CJ 1jul14
|
604 |
+
|
605 |
+
// atom:content, standard method of providing full HTML content
|
606 |
+
// in Atom feeds.
|
607 |
if (isset($this->item['atom_content'])) :
|
608 |
$content = $this->item['atom_content'];
|
609 |
+
elseif (isset($this->item['atom']['atom_content'])) :
|
610 |
+
$content = $this->item['atom']['atom_content'];
|
611 |
+
|
612 |
+
// Some exotics: back in the day, before widespread convergence
|
613 |
+
// on content:encoding, some RSS feeds took advantage of XML
|
614 |
+
// namespaces to use an inline xhtml:body or xhtml:div element
|
615 |
+
// for full-content HTML. (E.g. Sam Ruby's feed, IIRC.)
|
616 |
elseif (isset($this->item['xhtml']['body'])) :
|
617 |
$content = $this->item['xhtml']['body'];
|
618 |
elseif (isset($this->item['xhtml']['div'])) :
|
619 |
$content = $this->item['xhtml']['div'];
|
620 |
+
|
621 |
+
// content:encoded, most common method of providing full HTML in
|
622 |
+
// RSS 2.0 feeds.
|
623 |
elseif (isset($this->item['content']['encoded']) and $this->item['content']['encoded']):
|
624 |
$content = $this->item['content']['encoded'];
|
625 |
+
|
626 |
+
// Fall back on elements that sometimes may contain full HTML
|
627 |
+
// but sometimes not.
|
628 |
+
elseif (!$params['full only']) :
|
629 |
+
|
630 |
+
// description element is sometimes used for full HTML
|
631 |
+
// sometimes for summary text in RSS. (By the letter of
|
632 |
+
// the standard, it should just be for summary text.)
|
633 |
+
if (isset($this->item['description'])) :
|
634 |
+
$content = $this->item['description'];
|
635 |
+
endif;
|
636 |
+
|
637 |
endif;
|
638 |
return $content;
|
639 |
} /* SyndicatedPost::content() */
|
641 |
function excerpt () {
|
642 |
# Identify and sanitize excerpt: atom:summary, or rss:description
|
643 |
$excerpt = $this->entry->get_description();
|
644 |
+
|
645 |
# Many RSS feeds use rss:description, inadvisably, to
|
646 |
# carry the entire post (typically with escaped HTML).
|
647 |
# If that's what happened, we don't want the full
|
648 |
# content for the excerpt.
|
649 |
$content = $this->content();
|
650 |
+
|
651 |
// Ignore whitespace, case, and tag cruft.
|
652 |
$theExcerpt = preg_replace('/\s+/', '', strtolower(strip_tags($excerpt)));
|
653 |
$theContent = preg_replace('/\s+/', '', strtolower(strip_tags($content)));
|
674 |
function created ($params = array()) {
|
675 |
$unfiltered = false; $default = NULL;
|
676 |
extract($params);
|
677 |
+
|
678 |
$date = '';
|
679 |
if (isset($this->item['dc']['created'])) :
|
680 |
$date = $this->item['dc']['created'];
|
699 |
else : // New style
|
700 |
extract($params);
|
701 |
endif;
|
702 |
+
|
703 |
$date = '';
|
704 |
$ts = null;
|
705 |
|
718 |
elseif (isset($this->item['pubdate'])): // RSS 2.0
|
719 |
$date = $this->item['pubdate'];
|
720 |
endif;
|
721 |
+
|
722 |
if (strlen($date) > 0) :
|
723 |
$time = new FeedTime($date);
|
724 |
$ts = $time->timestamp();
|
725 |
elseif ($fallback) : // Fall back to <updated> / <modified> if present
|
726 |
$ts = $this->updated(/*fallback=*/ false, /*default=*/ $default);
|
727 |
endif;
|
728 |
+
|
729 |
# If everything failed, then default to the current time.
|
730 |
if (is_null($ts)) :
|
731 |
if (-1 == $default) :
|
734 |
$ts = $default;
|
735 |
endif;
|
736 |
endif;
|
737 |
+
|
738 |
if (!$unfiltered) :
|
739 |
$ts = apply_filters('syndicated_item_published', $ts, $this);
|
740 |
endif;
|
764 |
elseif (isset($this->item['updated'])): // Atom 1.0
|
765 |
$date = $this->item['updated'];
|
766 |
endif;
|
767 |
+
|
768 |
if (strlen($date) > 0) :
|
769 |
$time = new FeedTime($date);
|
770 |
$ts = $time->timestamp();
|
771 |
elseif ($fallback) : // Fall back to issued / dc:date
|
772 |
$ts = $this->published(/*fallback=*/ false, /*default=*/ $default);
|
773 |
endif;
|
774 |
+
|
775 |
# If everything failed, then default to the current time.
|
776 |
if (is_null($ts)) :
|
777 |
if (-1 == $default) :
|
812 |
"content" => $this->content(),
|
813 |
"excerpt" => $this->excerpt(),
|
814 |
);
|
815 |
+
|
816 |
if ($hashed) :
|
817 |
$hash = md5(serialize($hash));
|
818 |
endif;
|
819 |
+
|
820 |
return $hash;
|
821 |
} /* SyndicatedPost::update_hash() */
|
822 |
|
823 |
+
static function normalize_guid_prefix () {
|
824 |
return trailingslashit(get_bloginfo('url')).'?guid=';
|
825 |
}
|
826 |
+
|
827 |
+
static function normalize_guid ($guid) {
|
828 |
$guid = trim($guid);
|
829 |
if (preg_match('/^[0-9a-z]{32}$/i', $guid)) : // MD5
|
830 |
$guid = SyndicatedPost::normalize_guid_prefix().strtolower($guid);
|
834 |
$guid = trim($guid);
|
835 |
return $guid;
|
836 |
} /* SyndicatedPost::normalize_guid() */
|
837 |
+
|
838 |
function guid () {
|
839 |
$guid = null;
|
840 |
if (isset($this->item['id'])): // Atom 0.3 / 1.0
|
846 |
elseif (isset($this->item['dc']['identifier'])) : // yeah, right
|
847 |
$guid = $this->item['dc']['identifier'];
|
848 |
endif;
|
849 |
+
|
850 |
// Un-set or too long to use as-is. Generate a tag: URI.
|
851 |
if (is_null($guid) or strlen($guid) > 250) :
|
852 |
// In case we need to check this again
|
853 |
$original_guid = $guid;
|
854 |
+
|
855 |
// The feed does not seem to have provided us with a
|
856 |
// usable unique identifier, so we'll have to cobble
|
857 |
// together a tag: URI that might work for us. The base
|
869 |
// are hashed down into a nice, manageable tag: URI.
|
870 |
if (!is_null($original_guid)) :
|
871 |
$guid .= ',2010-12-03:id.'.md5($original_guid);
|
872 |
+
|
873 |
// If we have a date of creation, then we can use that
|
874 |
// to uniquely identify the item. (On the other hand, if
|
875 |
// the feed producer was consicentious enough to
|
877 |
// conscientious enough to generate unique identifiers.)
|
878 |
elseif (!is_null($this->created())) :
|
879 |
$guid .= '://post.'.date('YmdHis', $this->created());
|
880 |
+
|
881 |
// Otherwise, use both the URI of the item, *and* the
|
882 |
// item's title. We have to use both because titles are
|
883 |
// often not unique, and sometimes links aren't unique
|
893 |
endif;
|
894 |
return $guid;
|
895 |
} /* SyndicatedPost::guid() */
|
896 |
+
|
897 |
function author () {
|
898 |
$author = array ();
|
899 |
+
|
900 |
$aa = $this->entry->get_authors();
|
901 |
if (count($aa) > 0) :
|
902 |
$a = reset($aa);
|
927 |
// e-mail address, but lots of people don't use
|
928 |
// it that way. So let's make of it what we can.
|
929 |
$author = parse_email_with_realname($this->item['author']);
|
930 |
+
|
931 |
if (!isset($author['name'])) :
|
932 |
if (isset($author['email'])) :
|
933 |
$author['name'] = $author['email'];
|
937 |
endif;
|
938 |
endif;
|
939 |
endif;
|
940 |
+
|
941 |
if (!isset($author['name']) or is_null($author['name'])) :
|
942 |
// Nothing found. Try some crappy defaults.
|
943 |
if ($this->link->name()) :
|
947 |
$author['name'] = $url['host'];
|
948 |
endif;
|
949 |
endif;
|
950 |
+
|
951 |
if (FEEDWORDPRESS_COMPATIBILITY) :
|
952 |
if (isset($this->item['author_email'])):
|
953 |
$author['email'] = $this->item['author_email'];
|
954 |
elseif (isset($this->feed->channel['author_email'])) :
|
955 |
$author['email'] = $this->feed->channel['author_email'];
|
956 |
endif;
|
957 |
+
|
958 |
if (isset($this->item['author_uri'])):
|
959 |
$author['uri'] = $this->item['author_uri'];
|
960 |
elseif (isset($this->item['author_url'])):
|
967 |
$author['uri'] = $this->feed->channel['link'];
|
968 |
endif;
|
969 |
endif;
|
970 |
+
|
971 |
return $author;
|
972 |
} /* SyndicatedPost::author() */
|
973 |
|
991 |
endif;
|
992 |
return $tags;
|
993 |
}
|
994 |
+
|
995 |
/**
|
996 |
* SyndicatedPost::isTaggedAs: Test whether a feed item is
|
997 |
* tagged / categorized with a given string. Case and leading and
|
999 |
*
|
1000 |
* @param string $tag Tag to check for
|
1001 |
*
|
1002 |
+
* @return bool Whether or not at least one of the categories / tags on
|
1003 |
* $this->item is set to $tag (modulo case and leading and trailing
|
1004 |
* whitespace)
|
1005 |
*/
|
1014 |
// on this item is stored under index "category#".
|
1015 |
if (isset($this->item['category#'])) :
|
1016 |
$numberOfCategories = (int) $this->item['category#'];
|
1017 |
+
|
1018 |
// We REALLY shouldn't have the old and busted MagpieRSS, but in
|
1019 |
// case we do, it doesn't support multiple categories, but there
|
1020 |
// might still be a single value under the "category" index.
|
1073 |
endif;
|
1074 |
endfor;
|
1075 |
endif;
|
1076 |
+
return $enclosures;
|
1077 |
} /* SyndicatedPost::enclosures() */
|
1078 |
|
1079 |
function source ($what = NULL) {
|
1084 |
$ret['title'] = $source->get_title();
|
1085 |
$ret['uri'] = $source->get_link();
|
1086 |
$ret['feed'] = $source->get_link(0, 'self');
|
1087 |
+
|
1088 |
if ($id_tags = $source->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'id')) :
|
1089 |
$ret['id'] = $id_tags[0]['data'];
|
1090 |
elseif ($id_tags = $source->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'id')) :
|
1097 |
$ret['id'] = $id_tags[0]['data'];
|
1098 |
endif;
|
1099 |
endif;
|
1100 |
+
|
1101 |
if (!is_null($what) and is_scalar($what)) :
|
1102 |
$ret = $ret[$what];
|
1103 |
endif;
|
1104 |
return $ret;
|
1105 |
}
|
1106 |
+
|
1107 |
function comment_link () {
|
1108 |
$url = null;
|
1109 |
+
|
1110 |
// RSS 2.0 has a standard <comments> element:
|
1111 |
// "<comments> is an optional sub-element of <item>. If present,
|
1112 |
// it is the url of the comments page for the item."
|
1119 |
// element with @rel="replies" and @type="text/html".
|
1120 |
// Unfortunately, SimplePie_Item::get_links() allows us to filter
|
1121 |
// by the value of @rel, but not by the value of @type. *sigh*
|
1122 |
+
|
1123 |
// Try Atom 1.0 first
|
1124 |
$linkElements = $this->entry->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link');
|
1125 |
+
|
1126 |
// Fall back and try Atom 0.3
|
1127 |
if (is_null($linkElements)) : $linkElements = $this->entry->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link'); endif;
|
1128 |
+
|
1129 |
// Now loop through the elements, screening by @rel and @type
|
1130 |
if (is_array($linkElements)) : foreach ($linkElements as $link) :
|
1131 |
$rel = (isset($link['attribs']['']['rel']) ? $link['attribs']['']['rel'] : 'alternate');
|
1216 |
return $tag['prefix'] . $url . $tag['suffix'];
|
1217 |
} /* function SyndicatedPost::resolve_single_relative_uri() */
|
1218 |
|
1219 |
+
static function resolve_relative_uris ($content, $obj) {
|
1220 |
$set = $obj->link->setting('resolve relative', 'resolve_relative', 'yes');
|
1221 |
+
if ($set and $set != 'no') :
|
1222 |
// Fallback: if we don't have anything better, use the
|
1223 |
// item link from the feed
|
1224 |
$obj->_base = $obj->permalink(); // Reset the base for resolving relative URIs
|
1240 |
);
|
1241 |
endforeach;
|
1242 |
endif;
|
1243 |
+
|
1244 |
return $content;
|
1245 |
} /* function SyndicatedPost::resolve_relative_uris () */
|
1246 |
|
1255 |
return $tag['before_attribute'].$tag['after_attribute'];
|
1256 |
}
|
1257 |
|
1258 |
+
static function sanitize_content ($content, $obj) {
|
1259 |
# This kind of sucks. I intend to replace it with
|
1260 |
# lib_filter sometime soon.
|
1261 |
foreach ($obj->strip_attrs as $pair):
|
1292 |
* still up-to-date.
|
1293 |
*
|
1294 |
* @return int A status code representing the freshness of the post
|
1295 |
+
* -1 = post already syndicated; has a revision that needs to be stored, but not updated to
|
1296 |
* 0 = post already syndicated; no update needed
|
1297 |
* 1 = post already syndicated, but needs to be updated to latest
|
1298 |
* 2 = post has not yet been syndicated; needs to be created
|
1299 |
*/
|
1300 |
+
function freshness ($format = 'number') {
|
1301 |
global $wpdb;
|
1302 |
|
1303 |
if ($this->filtered()) : // This should never happen.
|
1304 |
FeedWordPress::critical_bug('SyndicatedPost', $this, __LINE__, __FILE__);
|
1305 |
endif;
|
1306 |
+
|
1307 |
if (is_null($this->_freshness)) : // Not yet checked and cached.
|
1308 |
$guid = $this->post['guid'];
|
1309 |
+
$eguid = esc_sql($this->post['guid']);
|
1310 |
|
1311 |
$q = new WP_Query(array(
|
1312 |
'fields' => '_synfresh', // id, guid, post_modified_gmt
|
1313 |
'ignore_sticky_posts' => true,
|
1314 |
'guid' => $guid,
|
1315 |
));
|
1316 |
+
|
1317 |
$old_post = NULL;
|
1318 |
if ($q->have_posts()) :
|
1319 |
while ($q->have_posts()) : $q->the_post();
|
1320 |
$old_post = $q->post;
|
1321 |
endwhile;
|
1322 |
endif;
|
1323 |
+
|
1324 |
if (is_null($old_post)) : // No post with this guid
|
1325 |
FeedWordPress::diagnostic('feed_items:freshness', 'Item ['.$guid.'] "'.$this->entry->get_title().'" is a NEW POST.');
|
1326 |
$this->_wp_id = NULL;
|
1327 |
$this->_freshness = 2; // New content
|
1328 |
else :
|
1329 |
+
// Presume there is nothing new until we find
|
1330 |
+
// something new.
|
1331 |
+
$updated = false;
|
1332 |
+
$live = false;
|
1333 |
+
|
1334 |
+
// Pull the list of existing revisions to get
|
1335 |
+
// timestamps.
|
1336 |
+
$revisions = wp_get_post_revisions($old_post->ID);
|
1337 |
+
foreach ($revisions as $rev) :
|
1338 |
+
$revisions_ts[] = mysql2date('G', $rev->post_modified_gmt);
|
1339 |
+
endforeach;
|
1340 |
|
1341 |
+
$revisions_ts[] = mysql2date('G', $old_post->post_modified_gmt);
|
1342 |
+
$last_rev_ts = end($revisions_ts);
|
1343 |
$updated_ts = $this->updated(/*fallback=*/ true, /*default=*/ NULL);
|
1344 |
|
1345 |
+
// If we have an explicit updated timestamp,
|
1346 |
+
// check that against existing stamps.
|
1347 |
+
if (!is_null($updated_ts)) :
|
1348 |
+
$updated = !in_array($updated_ts, $revisions_ts);
|
1349 |
+
|
1350 |
+
// If this a newer revision, make it go
|
1351 |
+
// live. If an older one, just record
|
1352 |
+
// the contents.
|
1353 |
+
$live = ($updated and ($updated_ts > $last_rev_ts));
|
1354 |
+
endif;
|
1355 |
|
1356 |
+
// This is a revision we haven't seen before, judging by the date.
|
1357 |
+
|
1358 |
$updatedReason = NULL;
|
1359 |
if ($updated) :
|
1360 |
$updatedReason = preg_replace(
|
1365 |
.date('Y-m-d H:i:s', $last_rev_ts)
|
1366 |
.')'
|
1367 |
);
|
1368 |
+
|
1369 |
+
// The date does not indicate a new revision, so
|
1370 |
+
// let's check the hash.
|
1371 |
else :
|
1372 |
// Or the hash...
|
1373 |
$hash = $this->update_hash();
|
1377 |
else :
|
1378 |
$updated = true; // Can't find syndication meta-data
|
1379 |
endif;
|
1380 |
+
|
1381 |
if ($updated and FeedWordPress::diagnostic_on('feed_items:freshness:reasons')) :
|
1382 |
+
// In the absence of definitive
|
1383 |
+
// timestamp information, we
|
1384 |
+
// just have to assume that a
|
1385 |
+
// hash we haven't seen before
|
1386 |
+
// is a newer version.
|
1387 |
+
$live = true;
|
1388 |
+
|
1389 |
$updatedReason = ' has a not-yet-seen update hash: '
|
1390 |
+
.MyPHP::val($hash)
|
1391 |
.' not in {'
|
1392 |
.implode(", ", array_map(array('FeedWordPress', 'val'), $seen))
|
1393 |
.'}. Basis: '
|
1394 |
+
.MyPHP::val(array_keys($this->update_hash(false)));
|
1395 |
endif;
|
1396 |
endif;
|
1397 |
+
|
1398 |
$frozen = false;
|
1399 |
if ($updated) : // Ignore if the post is frozen
|
1400 |
$frozen = ('yes' == $this->link->setting('freeze updates', 'freeze_updates', NULL));
|
1401 |
if (!$frozen) :
|
1402 |
$frozen_values = get_post_custom_values('_syndication_freeze_updates', $old_post->ID);
|
1403 |
$frozen = (count($frozen_values) > 0 and 'yes' == $frozen_values[0]);
|
1404 |
+
|
1405 |
if ($frozen) :
|
1406 |
$updatedReason = ' IS BLOCKED FROM BEING UPDATED BY A UPDATE LOCK ON THIS POST, EVEN THOUGH IT '.$updatedReason;
|
1407 |
endif;
|
1409 |
$updatedReason = ' IS BLOCKED FROM BEING UPDATED BY A FEEDWORDPRESS UPDATE LOCK, EVEN THOUGH IT '.$updatedReason;
|
1410 |
endif;
|
1411 |
endif;
|
1412 |
+
$live = ($live and !$frozen);
|
1413 |
|
1414 |
if ($updated) :
|
1415 |
FeedWordPress::diagnostic('feed_items:freshness', 'Item ['.$guid.'] "'.$this->entry->get_title().'" is an update of an existing post.');
|
1417 |
$updatedReason = preg_replace('/\s+/', ' ', $updatedReason);
|
1418 |
FeedWordPress::diagnostic('feed_items:freshness:reasons', 'Item ['.$guid.'] "'.$this->entry->get_title().'" '.$updatedReason);
|
1419 |
endif;
|
1420 |
+
|
1421 |
+
$this->_freshness = apply_filters('syndicated_item_freshness', ($live ? 1 : -1), $updated, $frozen, $updated_ts, $last_rev_ts, $this);
|
1422 |
+
|
1423 |
$this->_wp_id = $old_post->ID;
|
1424 |
$this->_wp_post = $old_post;
|
1425 |
|
1436 |
endif;
|
1437 |
endif;
|
1438 |
endif;
|
1439 |
+
|
1440 |
+
switch ($format) :
|
1441 |
+
case 'status' :
|
1442 |
+
switch ($this->_freshness) :
|
1443 |
+
case -1:
|
1444 |
+
$ret = 'stored';
|
1445 |
+
break;
|
1446 |
+
case 0:
|
1447 |
+
$ret = NULL;
|
1448 |
+
break;
|
1449 |
+
case 1:
|
1450 |
+
$ret = 'updated';
|
1451 |
+
break;
|
1452 |
+
case 2:
|
1453 |
+
default:
|
1454 |
+
$ret = 'new';
|
1455 |
+
break;
|
1456 |
+
endswitch;
|
1457 |
+
break;
|
1458 |
+
case 'number' :
|
1459 |
+
default :
|
1460 |
+
$ret = $this->_freshness;
|
1461 |
+
endswitch;
|
1462 |
+
|
1463 |
+
|
1464 |
+
return $ret;
|
1465 |
+
} /* SyndicatedPost::freshness () */
|
1466 |
+
|
1467 |
+
function has_fresh_content () {
|
1468 |
+
return ( ! $this->filtered() and $this->freshness() != 0 );
|
1469 |
+
} /* SyndicatedPost::has_fresh_content () */
|
1470 |
+
|
1471 |
+
function this_revision_needs_original_post ($freshness = NULL) {
|
1472 |
+
if (is_null($freshness)) :
|
1473 |
+
$freshness = $this->freshness();
|
1474 |
+
endif;
|
1475 |
+
return ( $freshness >= 2 );
|
1476 |
}
|
1477 |
+
|
1478 |
+
function this_revision_is_current ($freshness = NULL) {
|
1479 |
+
if (is_null($freshness)) :
|
1480 |
+
$freshness = $this->freshness();
|
1481 |
+
endif;
|
1482 |
+
return ( $freshness >= 1 );
|
1483 |
+
} /* SyndicatedPost::this_revision_is_current () */
|
1484 |
+
|
1485 |
+
function fresh_content_is_update () {
|
1486 |
+
return ($this->freshness() < 2);
|
1487 |
+
} /* SyndicatedPost::fresh_content_is_update () */
|
1488 |
+
|
1489 |
+
function fresh_storage_diagnostic () {
|
1490 |
+
$ret = NULL;
|
1491 |
+
switch ($this->freshness()) :
|
1492 |
+
case -1 :
|
1493 |
+
$ret = 'Storing alternate revision of existing post # '.$this->wp_id().', "'.$this->post['post_title'].'"';
|
1494 |
+
break;
|
1495 |
+
case 1 :
|
1496 |
+
$ret = 'Updating existing post # '.$this->wp_id().', "'.$this->post['post_title'].'"';
|
1497 |
+
break;
|
1498 |
+
case 2 :
|
1499 |
+
default :
|
1500 |
+
$ret = 'Inserting new post "'.$this->post['post_title'].'"';
|
1501 |
+
break;
|
1502 |
+
endswitch;
|
1503 |
+
return $ret;
|
1504 |
+
} /* SyndicatedPost::fresh_storage_diagnostic() */
|
1505 |
+
|
1506 |
+
function fresh_storage_hook () {
|
1507 |
+
$ret = NULL;
|
1508 |
+
switch ($this->freshness()) :
|
1509 |
+
case -1 :
|
1510 |
+
case 1 :
|
1511 |
+
$ret = 'update_syndicated_item';
|
1512 |
+
break;
|
1513 |
+
case 2 :
|
1514 |
+
default :
|
1515 |
+
$ret = 'post_syndicated_item';
|
1516 |
+
break;
|
1517 |
+
endswitch;
|
1518 |
+
return $ret;
|
1519 |
+
} /* SyndicatedPost::fresh_storage_hook () */
|
1520 |
+
|
1521 |
#################################################
|
1522 |
#### INTERNAL STORAGE AND MANAGEMENT METHODS ####
|
1523 |
#################################################
|
1526 |
if ($this->filtered()) : // This should never happen.
|
1527 |
FeedWordPress::critical_bug('SyndicatedPost', $this, __LINE__, __FILE__);
|
1528 |
endif;
|
1529 |
+
|
1530 |
if (is_null($this->_wp_id) and is_null($this->_freshness)) :
|
1531 |
$fresh = $this->freshness(); // sets WP DB id in the process
|
1532 |
endif;
|
1539 |
if ($this->filtered()) : // This should never happen.
|
1540 |
FeedWordPress::critical_bug('SyndicatedPost', $this, __LINE__, __FILE__);
|
1541 |
endif;
|
1542 |
+
|
1543 |
$freshness = $this->freshness();
|
1544 |
+
if ($this->has_fresh_content()) :
|
1545 |
# -- Look up, or create, numeric ID for author
|
1546 |
$this->post['post_author'] = $this->author_id (
|
1547 |
$this->link->setting('unfamiliar author', 'unfamiliar_author', 'create')
|
1552 |
$this->post = NULL;
|
1553 |
endif;
|
1554 |
endif;
|
1555 |
+
|
1556 |
+
// We have to check again in case post has been filtered during
|
1557 |
+
// the author_id lookup
|
1558 |
+
if ($this->has_fresh_content()) :
|
1559 |
$consider = array(
|
1560 |
'category' => array('abbr' => 'cats', 'domain' => array('category', 'post_tag')),
|
1561 |
'post_tag' => array('abbr' => 'tags', 'domain' => array('post_tag')),
|
1566 |
if (!is_null($this->post)) : // Not filtered out yet
|
1567 |
# -- Look up, or create, numeric ID for categories
|
1568 |
$taxonomies = $this->link->setting("match/".$taxes['abbr'], 'match_'.$taxes['abbr'], $taxes['domain']);
|
1569 |
+
|
1570 |
// Eliminate dummy variables
|
1571 |
$taxonomies = array_filter($taxonomies, 'remove_dummy_zero');
|
1572 |
+
|
1573 |
$terms = $this->category_ids (
|
1574 |
$this->feed_terms[$what],
|
1575 |
$this->link->setting("unfamiliar {$what}", "unfamiliar_{$what}", 'create:'.$what),
|
1579 |
'filters' => true,
|
1580 |
)
|
1581 |
);
|
1582 |
+
|
1583 |
if (is_null($terms) or is_null($termSet)) :
|
1584 |
// filtered out -- no matches
|
1585 |
else :
|
1615 |
if (!isset($this->post['tax_input'][$tax])) :
|
1616 |
$this->post['tax_input'][$tax] = array();
|
1617 |
endif;
|
1618 |
+
|
1619 |
$this->post['tax_input'][$tax] = array_merge (
|
1620 |
$this->post['tax_input'][$tax],
|
1621 |
$this->category_ids (
|
1629 |
endforeach;
|
1630 |
endif;
|
1631 |
endif;
|
1632 |
+
|
1633 |
+
// We have to check again in case the post has been filtered
|
1634 |
+
// during the category/tags/taxonomy terms lookup
|
1635 |
+
if ($this->has_fresh_content()) :
|
1636 |
// Filter some individual fields
|
1637 |
+
|
1638 |
// If there already is a post slug (from syndication or by manual
|
1639 |
// editing) don't cause WP to overwrite it by sending in a NULL
|
1640 |
// post_name. Props Chris Fritz 2012-11-28.
|
1641 |
+
$post_name = (is_null($this->_wp_post) ? NULL : $this->_wp_post->post_name);
|
1642 |
|
1643 |
// Allow filters to set post slug. Props niska.
|
1644 |
$post_name = apply_filters('syndicated_post_slug', $post_name, $this);
|
1645 |
if (!empty($post_name)) :
|
1646 |
$this->post['post_name'] = $post_name;
|
1647 |
endif;
|
1648 |
+
|
1649 |
$this->post = apply_filters('syndicated_post', $this->post, $this);
|
1650 |
+
|
1651 |
// Allow for feed-specific syndicated_post filters.
|
1652 |
$this->post = apply_filters(
|
1653 |
"syndicated_post_".$this->link->uri(),
|
1655 |
$this
|
1656 |
);
|
1657 |
endif;
|
1658 |
+
|
1659 |
// Hook in early to make sure these get inserted if at all possible
|
1660 |
add_action(
|
1661 |
/*hook=*/ 'transition_post_status',
|
1663 |
/*priority=*/ -10000, /* very early */
|
1664 |
/*arguments=*/ 3
|
1665 |
);
|
|
|
|
|
1666 |
|
1667 |
$ret = false;
|
1668 |
+
if ($this->has_fresh_content()) :
|
1669 |
+
$diag = $this->fresh_storage_diagnostic();
|
1670 |
+
if (!is_null($diag)) :
|
1671 |
+
FeedWordPress::diagnostic('syndicated_posts', $diag);
|
1672 |
+
endif;
|
|
|
|
|
|
|
1673 |
|
1674 |
+
$this->insert_post(/*update=*/ $this->fresh_content_is_update(), $this->freshness());
|
|
|
1675 |
|
1676 |
+
$hook = $this->fresh_storage_hook();
|
1677 |
+
if (!is_null($hook)) :
|
1678 |
+
do_action($hook, $this->wp_id(), $this);
|
1679 |
+
endif;
|
1680 |
+
|
1681 |
+
$ret = $this->freshness('status');
|
1682 |
endif;
|
1683 |
|
1684 |
+
// If this is a legit, non-filtered post, tag it as found on the
|
1685 |
+
// feed regardless of fresh or stale status
|
1686 |
if (!$this->filtered()) :
|
1687 |
$key = '_feedwordpress_retire_me_' . $this->link->id;
|
1688 |
delete_post_meta($this->wp_id(), $key);
|
1689 |
+
|
1690 |
$status = get_post_field('post_status', $this->wp_id());
|
1691 |
+
if ('fwpretired'==$status and $this->link->is_non_incremental()) :
|
1692 |
+
FeedWordPress::diagnostic('syndicated_posts', "Un-retiring previously retired post # ".$this->wp_id()." due to re-appearance on non-incremental feed.");
|
1693 |
set_post_field('post_status', $this->post['post_status'], $this->wp_id());
|
1694 |
+
wp_transition_post_status($this->post['post_status'], $status, $this->post);
|
1695 |
+
elseif ('fwpzapped'==$status) :
|
1696 |
+
// Set this new revision up to be
|
1697 |
+
// blanked on the next update.
|
1698 |
+
add_post_meta($this->wp_id(), '_feedwordpress_zapped_blank_me', 2, /*single=*/ true);
|
1699 |
endif;
|
1700 |
endif;
|
1701 |
+
|
1702 |
// Remove add_rss_meta hook
|
1703 |
remove_action(
|
1704 |
/*hook=*/ 'transition_post_status',
|
1709 |
|
1710 |
return $ret;
|
1711 |
} /* function SyndicatedPost::store () */
|
1712 |
+
|
1713 |
+
function insert_post ($update = false, $freshness = 2) {
|
1714 |
global $wpdb;
|
1715 |
|
1716 |
$dbpost = $this->normalize_post(/*new=*/ true);
|
1717 |
+
|
1718 |
if (!is_null($dbpost)) :
|
1719 |
$dbpost['post_pingback'] = false; // Tell WP 2.1 and 2.2 not to process for pingbacks
|
1720 |
+
|
1721 |
// This is a ridiculous fucking kludge necessitated by WordPress 2.6 munging authorship meta-data
|
1722 |
add_action('_wp_put_post_revision', array($this, 'fix_revision_meta'));
|
1723 |
+
|
1724 |
// Kludge to prevent kses filters from stripping the
|
1725 |
// content of posts when updating without a logged in
|
1726 |
// user who has `unfiltered_html` capability.
|
1732 |
$removed[] = $munger;
|
1733 |
endif;
|
1734 |
endforeach;
|
1735 |
+
|
1736 |
if ($update and function_exists('get_post_field')) :
|
1737 |
// Don't munge status fields that the user may
|
1738 |
// have reset manually
|
1739 |
$doNotMunge = array('post_status', 'comment_status', 'ping_status');
|
1740 |
+
|
1741 |
foreach ($doNotMunge as $field) :
|
1742 |
$dbpost[$field] = get_post_field($field, $this->wp_id());
|
1743 |
endforeach;
|
1744 |
endif;
|
1745 |
+
|
1746 |
// WP3's wp_insert_post scans current_user_can() for the
|
1747 |
// tax_input, with no apparent way to override. Ugh.
|
1748 |
add_action(
|
1751 |
/*priority=*/ -10001, /* very early */
|
1752 |
/*arguments=*/ 3
|
1753 |
);
|
1754 |
+
|
1755 |
// WP3 appears to override whatever you give it for
|
1756 |
// post_modified. Ugh.
|
1757 |
add_action(
|
1765 |
$this->post['ID'] = $this->wp_id();
|
1766 |
$dbpost['ID'] = $this->post['ID'];
|
1767 |
endif;
|
1768 |
+
|
1769 |
+
// O.K., is this a new post? If so, we need to create
|
1770 |
+
// the basic post record before we do anything else.
|
1771 |
+
if ($this->this_revision_needs_original_post()) :
|
1772 |
+
// *sigh*, for handling inconsistent slash expectations < 3.6
|
1773 |
+
$sdbpost = $this->db_sanitize_post($dbpost);
|
1774 |
+
|
1775 |
+
// Go ahead and insert the first post record to
|
1776 |
+
// anchor the revision history.
|
1777 |
+
$this->_wp_id = wp_insert_post($sdbpost, /*return wp_error=*/ true);
|
1778 |
+
|
1779 |
+
$dbpost['ID'] = $this->_wp_id;
|
1780 |
+
endif;
|
1781 |
+
|
1782 |
+
// Now that we've made sure the original exists, insert
|
1783 |
+
// this version here as a revision.
|
1784 |
+
$revision_id = _wp_put_post_revision($dbpost, /*autosave=*/ false);
|
1785 |
+
|
1786 |
+
if (!$this->this_revision_needs_original_post()) :
|
1787 |
|
1788 |
+
if ($this->this_revision_is_current()) :
|
1789 |
+
|
1790 |
+
wp_restore_post_revision($revision_id);
|
1791 |
+
|
1792 |
+
else :
|
1793 |
+
|
1794 |
+
// If we do not activate this revision, then the
|
1795 |
+
// add_rss_meta will not be called, which is
|
1796 |
+
// more or less as it should be, but that means
|
1797 |
+
// we have to actively record this revision's
|
1798 |
+
// update hash from here.
|
1799 |
+
$postId = $this->post['ID'];
|
1800 |
+
$key = 'syndication_item_hash';
|
1801 |
+
$hash = $this->update_hash();
|
1802 |
+
FeedWordPress::diagnostic('syndicated_posts:meta_data', "Adding post meta-datum to post [$postId]: [$key] = ".FeedWordPress::val($hash, /*no newlines=*/ true));
|
1803 |
+
add_post_meta( $postId, $key, $hash, /*unique=*/ false );
|
1804 |
+
endif;
|
1805 |
+
endif;
|
1806 |
|
1807 |
remove_action(
|
1808 |
/*hook=*/ 'transition_post_status',
|
1823 |
foreach ($removed as $filter) :
|
1824 |
add_filter('content_save_pre', $filter);
|
1825 |
endforeach;
|
1826 |
+
|
1827 |
$this->validate_post_id($dbpost, $update, array(__CLASS__, __FUNCTION__));
|
1828 |
endif;
|
1829 |
} /* function SyndicatedPost::insert_post () */
|
1830 |
+
|
1831 |
function insert_new () {
|
1832 |
+
$this->insert_post(/*update=*/ false, 1);
|
1833 |
} /* SyndicatedPost::insert_new() */
|
1834 |
|
1835 |
function update_existing () {
|
1836 |
+
$this->insert_post(/*update=*/ true, 2);
|
1837 |
} /* SyndicatedPost::update_existing() */
|
1838 |
|
1839 |
/**
|
1860 |
$feed_url = parse_url($this->post['meta']['syndication_feed']);
|
1861 |
$source_title = $feed_url['host'];
|
1862 |
endif;
|
1863 |
+
|
1864 |
$out['post_title'] = $source_title
|
1865 |
.' '.gmdate('Y-m-d H:i:s', $this->published() + $offset);
|
1866 |
// FIXME: Option for what to fill a blank title with...
|
1869 |
// Normalize the guid if necessary.
|
1870 |
$out['guid'] = SyndicatedPost::normalize_guid($out['guid']);
|
1871 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1872 |
return $out;
|
1873 |
}
|
1874 |
|
1875 |
+
function db_sanitize_post ($out) {
|
1876 |
+
// < 3.6. Core API, including wp_insert_post(), will expect
|
1877 |
+
// properly slashed data. If wp_slash() exists, then this is
|
1878 |
+
// after the big change-over, and wp_insert_post() etc. will
|
1879 |
+
// expect *un*-slashed data.
|
1880 |
+
if (!function_exists('wp_slash')) :
|
1881 |
+
|
1882 |
+
foreach ($out as $key => $value) :
|
1883 |
+
if (is_string($value)) :
|
1884 |
+
$out[$key] = esc_sql($value);
|
1885 |
+
else :
|
1886 |
+
$out[$key] = $value;
|
1887 |
+
endif;
|
1888 |
+
endforeach;
|
1889 |
+
|
1890 |
+
endif;
|
1891 |
+
|
1892 |
+
return $out;
|
1893 |
+
}
|
1894 |
+
|
1895 |
/**
|
1896 |
* SyndicatedPost::validate_post_id()
|
1897 |
*
|
1913 |
// notice if we are in debug mode.
|
1914 |
$mesg = "Failed to $verb item [$guid]. WordPress API returned no valid post ID.\n"
|
1915 |
."\t\tID = ".serialize($this->_wp_id)."\n"
|
1916 |
+
."\t\tURL = ".MyPHP::val($url)
|
1917 |
+
."\t\tFeed = ".MyPHP::val($feed);
|
1918 |
+
|
1919 |
FeedWordPress::diagnostic('updated_feeds:errors', "WordPress API error: $mesg");
|
1920 |
FeedWordPress::diagnostic('feed_items:rejected', $mesg);
|
1921 |
|
1923 |
The WordPress API returned an invalid post ID
|
1924 |
when FeedWordPress tried to $verb item $guid
|
1925 |
[URL: $url]
|
1926 |
+
from the feed at $feed
|
1927 |
|
1928 |
+
$ns::_wp_id
|
1929 |
EOM;
|
1930 |
FeedWordPress::noncritical_bug(
|
1931 |
/*message=*/ $mesg,
|
1937 |
);
|
1938 |
endif;
|
1939 |
} /* SyndicatedPost::validate_post_id() */
|
1940 |
+
|
1941 |
/**
|
1942 |
+
* SyndicatedPost::fix_revision_meta() - Ensures that we get the meta
|
1943 |
+
* data (authorship, guid, etc.) that we want when storing revisions of
|
1944 |
+
* a syndicated post.
|
1945 |
*
|
1946 |
+
* In their infinite wisdom, the WordPress coders seem to have made it
|
1947 |
+
* completely impossible for a plugin that uses wp_insert_post() to set
|
1948 |
+
* certain meta-data (such as the author) when you store an old revision
|
1949 |
+
* of an updated post. Instead, it uses the WordPress defaults (= cur.
|
1950 |
* active user ID if the process is running with a user logged in, or
|
1951 |
* = #0 if there is no user logged in). This results in bogus authorship
|
1952 |
* data for revisions that are syndicated from off the feed, unless we
|
1957 |
*/
|
1958 |
function fix_revision_meta ($revision_id) {
|
1959 |
global $wpdb;
|
1960 |
+
|
1961 |
$post_author = (int) $this->post['post_author'];
|
1962 |
+
|
1963 |
$revision_id = (int) $revision_id;
|
1964 |
+
|
1965 |
+
// Let's fix the author.
|
1966 |
+
set_post_field('post_author', $this->post['post_author'], $revision_id);
|
1967 |
+
|
1968 |
+
// Let's fix the GUID to a dummy URL with the update hash.
|
1969 |
+
set_post_field('guid', 'http://feedwordpress.radgeek.com/?rev='.$this->update_hash(), $revision_id);
|
1970 |
+
|
1971 |
+
// Let's fire an event for add-ons and filters
|
1972 |
+
do_action('syndicated_post_fix_revision_meta', $revision_id, $this);
|
1973 |
+
|
1974 |
} /* SyndicatedPost::fix_revision_meta () */
|
1975 |
+
|
1976 |
/**
|
1977 |
* SyndicatedPost::add_terms() -- if FeedWordPress is processing an
|
1978 |
* automatic update, that generally means that wp_insert_post() is being
|
1991 |
* @param object $post The database record for the post just inserted.
|
1992 |
*/
|
1993 |
function add_terms ($new_status, $old_status, $post) {
|
1994 |
+
|
1995 |
if ($new_status!='inherit') : // Bail if we are creating a revision.
|
1996 |
if ( is_array($this->post) and isset($this->post['tax_input']) and is_array($this->post['tax_input']) ) :
|
1997 |
foreach ($this->post['tax_input'] as $taxonomy => $terms) :
|
1998 |
if (is_array($terms)) :
|
1999 |
$terms = array_filter($terms); // strip out empties
|
2000 |
endif;
|
2001 |
+
|
2002 |
+
$res = wp_set_post_terms(
|
2003 |
+
/*post_id=*/ $post->ID,
|
2004 |
+
/*terms=*/ $terms,
|
2005 |
+
/*taxonomy=*/ $taxonomy
|
2006 |
+
);
|
2007 |
+
|
2008 |
+
FeedWordPress::diagnostic(
|
2009 |
+
'syndicated_posts:categories',
|
2010 |
+
'Category: post('.json_encode($post->ID).') '.$taxonomy
|
2011 |
+
.' := '
|
2012 |
+
.json_encode($terms)
|
2013 |
+
.' / result: '
|
2014 |
+
.json_encode($res)
|
2015 |
+
);
|
2016 |
+
|
2017 |
endforeach;
|
2018 |
endif;
|
2019 |
endif;
|
2020 |
+
|
2021 |
} /* SyndicatedPost::add_terms () */
|
2022 |
+
|
2023 |
/**
|
2024 |
* SyndicatedPost::fix_post_modified_ts() -- We would like to set
|
2025 |
* post_modified and post_modified_gmt to reflect the value of
|
2044 |
), /*where=*/ array('ID' => $post->ID) );
|
2045 |
endif;
|
2046 |
} /* SyndicatedPost::fix_post_modified_ts () */
|
2047 |
+
|
2048 |
/**
|
2049 |
* SyndicatedPost::add_rss_meta: adds interesting meta-data to each entry
|
2050 |
* using the space for custom keys. The set of keys and values to add is
|
2067 |
|
2068 |
if ( is_array($this->post) and isset($this->post['meta']) and is_array($this->post['meta']) ) :
|
2069 |
$postId = $post->ID;
|
2070 |
+
|
2071 |
// Aggregated posts should NOT send out pingbacks.
|
2072 |
// WordPress 2.1-2.2 claim you can tell them not to
|
2073 |
// using $post_pingback, but they don't listen, so we
|
2076 |
DELETE FROM $wpdb->postmeta
|
2077 |
WHERE post_id='$postId' AND meta_key='_pingme'
|
2078 |
");
|
2079 |
+
|
2080 |
foreach ( $this->post['meta'] as $key => $values ) :
|
2081 |
+
$eKey = esc_sql($key);
|
2082 |
+
|
2083 |
// If this is an update, clear out the old
|
2084 |
// values to avoid duplication.
|
2085 |
$result = $wpdb->query("
|
2086 |
DELETE FROM $wpdb->postmeta
|
2087 |
WHERE post_id='$postId' AND meta_key='$eKey'
|
2088 |
");
|
2089 |
+
|
2090 |
// Allow for either a single value or an array
|
2091 |
if (!is_array($values)) $values = array($values);
|
2092 |
foreach ( $values as $value ) :
|
2093 |
+
FeedWordPress::diagnostic('syndicated_posts:meta_data', "Adding post meta-datum to post [$postId]: [$key] = ".MyPHP::val($value, /*no newlines=*/ true));
|
2094 |
add_post_meta($postId, $key, $value, /*unique=*/ false);
|
2095 |
endforeach;
|
2096 |
endforeach;
|
2115 |
$source = $this->source();
|
2116 |
$forbidden = apply_filters('feedwordpress_forbidden_author_names',
|
2117 |
array('admin', 'administrator', 'www', 'root'));
|
2118 |
+
|
2119 |
// Prepare the list of candidates to try for author name: name from
|
2120 |
// feed, original source title (if any), immediate source title live
|
2121 |
// from feed, subscription title, prettied version of feed homepage URL,
|
2130 |
if (strlen($this->link->homepage()) > 0) : $candidates[] = feedwordpress_display_url($this->link->homepage()); endif;
|
2131 |
$candidates[] = feedwordpress_display_url($this->link->uri());
|
2132 |
$candidates[] = 'unknown author';
|
2133 |
+
|
2134 |
// Pick the first one that works from the list, screening against empty
|
2135 |
// or forbidden names.
|
2136 |
+
|
2137 |
$author = NULL;
|
2138 |
while (is_null($author) and ($candidate = each($candidates))) :
|
2139 |
if (!is_null($candidate['value'])
|
2142 |
$author = $candidate['value'];
|
2143 |
endif;
|
2144 |
endwhile;
|
2145 |
+
|
2146 |
$email = (isset($a['email']) ? $a['email'] : NULL);
|
2147 |
$authorUrl = (isset($a['uri']) ? $a['uri'] : NULL);
|
2148 |
|
2149 |
+
|
2150 |
$hostUrl = $this->link->homepage();
|
2151 |
if (is_null($hostUrl) or (strlen($hostUrl) < 0)) :
|
2152 |
$hostUrl = $this->link->uri();
|
2173 |
// Uniqueness will be guaranteed below if necessary.
|
2174 |
|
2175 |
$url = parse_url($hostUrl);
|
2176 |
+
|
2177 |
$login = sanitize_user($url['host'], /*strict=*/ true);
|
2178 |
if (strlen($login) < 1) :
|
2179 |
// This isn't working. Frak it.
|
2186 |
$nice_author = sanitize_title($author);
|
2187 |
$nice_author = apply_filters('pre_user_nicename', $nice_author);
|
2188 |
|
2189 |
+
$reg_author = esc_sql(preg_quote($author));
|
2190 |
+
$author = esc_sql($author);
|
2191 |
+
$email = esc_sql($email);
|
2192 |
+
$test_email = esc_sql($test_email);
|
2193 |
+
$authorUrl = esc_sql($authorUrl);
|
2194 |
|
2195 |
// Check for an existing author rule....
|
2196 |
if (isset($this->link->settings['map authors']['name']['*'])) :
|
2208 |
// User name is filtered out
|
2209 |
elseif ('filter' == $author_rule) :
|
2210 |
$id = NULL;
|
2211 |
+
|
2212 |
else :
|
2213 |
// Check the database for an existing author record that might fit
|
2214 |
|
2221 |
LENGTH(TRIM(LCASE(user_email))) > 0
|
2222 |
AND TRIM(LCASE(user_email)) = TRIM(LCASE('$test_email'))
|
2223 |
)");
|
2224 |
+
|
2225 |
// If that fails, look for aliases in the user meta data table
|
2226 |
if (is_null($id)) :
|
2227 |
$id = $wpdb->get_var(
|
2266 |
if (isset($parts[1])) : $userdata['last_name'] = $parts[1]; endif;
|
2267 |
$userdata['display_name'] = $author;
|
2268 |
$userdata['role'] = 'contributor';
|
2269 |
+
|
2270 |
do { // Keep trying until you get it right. Or until PHP crashes, I guess.
|
2271 |
$id = wp_insert_user($userdata);
|
2272 |
if (is_wp_error($id)) :
|
2280 |
case 'existing_user_email' :
|
2281 |
// No disassemble!
|
2282 |
$parts = explode('@', $userdata['user_email'], 2);
|
2283 |
+
|
2284 |
// Add a random disambiguator as a gmail-style username extension
|
2285 |
$parts[0] .= '+'.substr(md5(uniqid(microtime())), 0, 6);
|
2286 |
+
|
2287 |
// Reassemble
|
2288 |
$userdata['user_email'] = $parts[0].'@'.$parts[1];
|
2289 |
break;
|
2300 |
|
2301 |
if ($id) :
|
2302 |
$this->link->settings['map authors']['name'][strtolower(trim($author))] = $id;
|
2303 |
+
|
2304 |
// Multisite: Check whether the author has been recorded
|
2305 |
// on *this* blog before. If not, put her down as a
|
2306 |
// Contributor for *this* blog.
|
2309 |
$user->add_role('contributor');
|
2310 |
endif;
|
2311 |
endif;
|
2312 |
+
return $id;
|
2313 |
} /* function SyndicatedPost::author_id () */
|
2314 |
|
2315 |
/**
|
2316 |
+
* category_ids: look up (and create) category ids from a list of
|
2317 |
+
* categories
|
2318 |
*
|
2319 |
* @param array $cats
|
2320 |
* @param string $unfamiliar_category
|
2321 |
* @param array|null $taxonomies
|
2322 |
* @return array
|
2323 |
+
*/
|
2324 |
function category_ids ($cats, $unfamiliar_category = 'create', $taxonomies = NULL, $params = array()) {
|
2325 |
+
return $this->link->category_ids($this, $cats, $unfamiliar_category, $taxonomies, $params);
|
2326 |
+
} /* SyndicatedPost::category_ids () */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2327 |
|
2328 |
} /* class SyndicatedPost */
|
2329 |
|
@@ -0,0 +1,215 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
class SyndicatedPostTerm {
|
3 |
+
private $term, $tax, $exists, $exists_in, $post;
|
4 |
+
|
5 |
+
public function __construct ($term, $taxonomies, $post) {
|
6 |
+
$catTax = 'category';
|
7 |
+
|
8 |
+
$this->post = $post;
|
9 |
+
|
10 |
+
// Default to these
|
11 |
+
$this->term = NULL;
|
12 |
+
$this->tax = NULL;
|
13 |
+
$this->exists = NULL;
|
14 |
+
$this->exists_in = NULL;
|
15 |
+
|
16 |
+
if (preg_match('/^{([^#}]*)#([0-9]+)}$/', $term, $backref)) :
|
17 |
+
$cat_id = (int) $backref[2];
|
18 |
+
$tax = $backref[1];
|
19 |
+
if (strlen($tax) < 1) :
|
20 |
+
$tax = $catTax;
|
21 |
+
endif;
|
22 |
+
|
23 |
+
$aTerm = get_term($cat_id, $tax);
|
24 |
+
if (!is_wp_error($aTerm) and !!$aTerm) :
|
25 |
+
$this->exists = (array) $aTerm;
|
26 |
+
$this->exists_in = $this->exists['taxonomy'];
|
27 |
+
|
28 |
+
$this->term = $this->exists['name'];
|
29 |
+
$this->tax = array($this->exists['taxonomy']);
|
30 |
+
endif;
|
31 |
+
|
32 |
+
else :
|
33 |
+
$this->term = $term;
|
34 |
+
$this->tax = $taxonomies;
|
35 |
+
|
36 |
+
// Leave exists/exists_in empty until we search()
|
37 |
+
|
38 |
+
endif;
|
39 |
+
|
40 |
+
if (is_null($this->tax)) :
|
41 |
+
$this->tax = array($catTax);
|
42 |
+
endif;
|
43 |
+
} /* SyndicatedPostTerm constructor */
|
44 |
+
|
45 |
+
public function is_familiar () {
|
46 |
+
$ex = $this->exists;
|
47 |
+
if (is_null($this->exists)) :
|
48 |
+
$ex = $this->search();
|
49 |
+
endif;
|
50 |
+
|
51 |
+
FeedWordPress::diagnostic(
|
52 |
+
'syndicated_posts:categories',
|
53 |
+
'Assigned category '.json_encode($this->term)
|
54 |
+
.' by feed; checking '.json_encode($this->tax)
|
55 |
+
. ' with result: '.json_encode($ex)
|
56 |
+
);
|
57 |
+
return (!is_wp_error($ex) and !!$ex);
|
58 |
+
} /* SyndicatedPostTerm::familiar () */
|
59 |
+
|
60 |
+
protected function search () {
|
61 |
+
|
62 |
+
// Either this is a numbered term code, which supplies the ID
|
63 |
+
// and the taxonomy explicitly (e.g.: {category#2}; in which
|
64 |
+
// case we have set $this->tax to a unit array containing only
|
65 |
+
// the correct taxonomy, or else we have a term name and an
|
66 |
+
// ordered array of taxonomies to search for that term name. In
|
67 |
+
// either case, loop through and check each pair of term
|
68 |
+
|
69 |
+
foreach ($this->tax as $tax) :
|
70 |
+
|
71 |
+
if (!$this->is_forbidden_in($tax)) :
|
72 |
+
|
73 |
+
$found = $this->fetch_record_in($tax);
|
74 |
+
if ($found) :
|
75 |
+
// When TRUE, the term has been found
|
76 |
+
// and is now stored in $this->exists
|
77 |
+
|
78 |
+
// Save the taxonomy we found this in.
|
79 |
+
$this->exists_in = $tax;
|
80 |
+
|
81 |
+
break;
|
82 |
+
endif;
|
83 |
+
|
84 |
+
endif;
|
85 |
+
|
86 |
+
endforeach;
|
87 |
+
|
88 |
+
FeedWordPress::diagnostic(
|
89 |
+
'syndicated_posts:categories:test',
|
90 |
+
'CHECKED familiarity of term '
|
91 |
+
.json_encode($this->term)
|
92 |
+
.' across '.json_encode($this->tax)
|
93 |
+
. ' with result: '.json_encode($record)
|
94 |
+
);
|
95 |
+
|
96 |
+
return $this->exists;
|
97 |
+
|
98 |
+
} /* SyndicatedPostTerm::search () */
|
99 |
+
|
100 |
+
protected function fetch_record_in ($tax) {
|
101 |
+
$record = term_exists($this->term, $tax);
|
102 |
+
|
103 |
+
FeedWordPress::diagnostic(
|
104 |
+
'syndicated_posts:categories:test',
|
105 |
+
'CHECK existence of '.$tax.': '
|
106 |
+
.json_encode($this->term)
|
107 |
+
.' with result: '.json_encode($record)
|
108 |
+
);
|
109 |
+
|
110 |
+
$found = (!is_wp_error($record) and !!$record);
|
111 |
+
|
112 |
+
if ($found) :
|
113 |
+
$this->exists = $record;
|
114 |
+
endif;
|
115 |
+
|
116 |
+
return $found;
|
117 |
+
} /* SyndicatedPostTerm::fetch_record_in() */
|
118 |
+
|
119 |
+
public function is_forbidden_in ($tax = NULL) {
|
120 |
+
$forbid = false; // Innocent until proven guilty.
|
121 |
+
|
122 |
+
$term = $this->term;
|
123 |
+
if (is_null($tax) and (count($this->tax) > 0)) :
|
124 |
+
$tax = $this->tax[0];
|
125 |
+
endif;
|
126 |
+
|
127 |
+
if ($tax=='category' and strtolower($term)=='uncategorized') :
|
128 |
+
$forbid = true;
|
129 |
+
endif;
|
130 |
+
|
131 |
+
// Run it through a filter.
|
132 |
+
return apply_filters('syndicated_post_forbidden_term', $forbid, $term, $tax, $this->post);
|
133 |
+
} /* SyndicatedPostTerm::is_forbidden_in () */
|
134 |
+
|
135 |
+
public function taxonomy () {
|
136 |
+
if (is_null($this->exists_in)) :
|
137 |
+
$this->search();
|
138 |
+
endif;
|
139 |
+
|
140 |
+
return $this->exists_in;
|
141 |
+
} /* SyndicatedPostTerm::taxonomy () */
|
142 |
+
|
143 |
+
public function id () {
|
144 |
+
$term_id = NULL;
|
145 |
+
|
146 |
+
if (is_null($this->exists)) :
|
147 |
+
$this->search();
|
148 |
+
endif;
|
149 |
+
|
150 |
+
$term = $this->exists;
|
151 |
+
if (is_array($term) or is_object($term)) :
|
152 |
+
|
153 |
+
// For hash tables of any sort, use the term_id member
|
154 |
+
$term = (array) $term;
|
155 |
+
$term_id = intval($term['term_id']);
|
156 |
+
|
157 |
+
elseif (is_numeric($term)) :
|
158 |
+
|
159 |
+
// For a straight numeric response, just return number
|
160 |
+
$term_id = intval($term);
|
161 |
+
|
162 |
+
endif;
|
163 |
+
|
164 |
+
return $term_id;
|
165 |
+
} /* SyndicatedPostTerm::id () */
|
166 |
+
|
167 |
+
public function insert ($tax = NULL) {
|
168 |
+
$ret = NULL;
|
169 |
+
|
170 |
+
if (is_null($tax)) :
|
171 |
+
if (count($this->tax) > 0) :
|
172 |
+
$tax = $this->tax[0];
|
173 |
+
endif;
|
174 |
+
endif;
|
175 |
+
|
176 |
+
if (!$this->is_forbidden_in($tax)) :
|
177 |
+
$aTerm = wp_insert_term($this->term, $tax);
|
178 |
+
if (is_wp_error($aTerm)) :
|
179 |
+
|
180 |
+
// If debug mode is ON, this will halt us here.
|
181 |
+
FeedWordPress::noncritical_bug(
|
182 |
+
'term insertion problem', array(
|
183 |
+
'term' => $this->term,
|
184 |
+
'result' => $aTerm,
|
185 |
+
'post' => $post,
|
186 |
+
'this' => $this
|
187 |
+
), __LINE__, __FILE__
|
188 |
+
);
|
189 |
+
|
190 |
+
// Otherwise, we'll continue & return NULL...
|
191 |
+
|
192 |
+
else :
|
193 |
+
$this->exists = $aTerm;
|
194 |
+
$this->exists_in = $tax;
|
195 |
+
|
196 |
+
$ret = $this->id();
|
197 |
+
endif;
|
198 |
+
|
199 |
+
FeedWordPress::diagnostic(
|
200 |
+
'syndicated_posts:categories',
|
201 |
+
'CREATED unfamiliar '.$tax.': '.json_encode($this->term).' with result: '.json_encode($aTerm)
|
202 |
+
);
|
203 |
+
else :
|
204 |
+
FeedWordPress::diagnostic(
|
205 |
+
'syndicated_posts:categories',
|
206 |
+
'Category: DID NOT CREATE unfamiliar '.$tax.': '.json_encode($this->term).':'
|
207 |
+
.' that '.$tax.' name is filtered out.'
|
208 |
+
);
|
209 |
+
endif;
|
210 |
+
|
211 |
+
return $ret;
|
212 |
+
} /* SyndicatedPostTerm::insert () */
|
213 |
+
|
214 |
+
} /* class SyndicatedPostTerm */
|
215 |
+
|
@@ -1,10 +1,8 @@
|
|
1 |
<?php
|
2 |
-
define('FEEDWORDPRESS_OPTIMIZE_IN_CLAUSES', get_option('feedwordpress_optimize_in_clauses', false));
|
3 |
|
4 |
class SyndicationDataQueries {
|
5 |
function SyndicationDataQueries () {
|
6 |
add_action('init', array($this, 'init'));
|
7 |
-
add_filter('query', array($this, 'optimize_in_clauses'));
|
8 |
add_action('parse_query', array($this, 'parse_query'), 10, 1);
|
9 |
add_filter('posts_search', array($this, 'posts_search'), 10, 2);
|
10 |
add_filter('posts_where', array($this, 'posts_where'), 10, 2);
|
@@ -17,44 +15,22 @@ class SyndicationDataQueries {
|
|
17 |
$wp->add_query_var('guid');
|
18 |
}
|
19 |
|
20 |
-
function optimize_in_clauses ($q) {
|
21 |
-
// This is kind of a dicey, low-level thing to do, and Christ,
|
22 |
-
// this is something WordPress should be doing on its own,
|
23 |
-
// so it's disabled by default. But you can enable it in
|
24 |
-
// Performance --> Optimize IN clauses
|
25 |
-
if (FEEDWORDPRESS_OPTIMIZE_IN_CLAUSES) :
|
26 |
-
if (preg_match_all('/ \s+ IN \s* \((\s*([0-9]+)\s*)\)/x', $q, $r, PREG_OFFSET_CAPTURE)) :
|
27 |
-
$from = 0; $nq = '';
|
28 |
-
foreach ($r[0] as $idx => $ref) :
|
29 |
-
$len = $ref[1] - $from;
|
30 |
-
$nq .= substr($q, $from, $len);
|
31 |
-
$nq .= ' = ' . $r[1][$idx][0];
|
32 |
-
$from = $ref[1] + strlen($ref[0]);
|
33 |
-
endforeach;
|
34 |
-
|
35 |
-
$q = $nq;
|
36 |
-
endif;
|
37 |
-
endif;
|
38 |
-
|
39 |
-
return $q;
|
40 |
-
}
|
41 |
-
|
42 |
function parse_query (&$q) {
|
43 |
if ($q->get('guid')) :
|
44 |
$q->is_single = false; // Causes nasty side-effects.
|
45 |
$q->is_singular = true; // Doesn't?
|
46 |
endif;
|
47 |
-
|
48 |
$ff = $q->get('fields');
|
49 |
if ($ff == '_synfresh' or $ff == '_synfrom') :
|
50 |
$q->query_vars['cache_results'] = false; // Not suitable.
|
51 |
endif;
|
52 |
} /* SyndicationDataQueries::parse_query () */
|
53 |
-
|
54 |
function pre_get_posts (&$q) {
|
55 |
-
//
|
56 |
}
|
57 |
-
|
58 |
function posts_request ($sql, &$query) {
|
59 |
if ($query->get('fields') == '_synfresh') :
|
60 |
FeedWordPress::diagnostic('feed_items:freshness:sql', "SQL: ".$sql);
|
@@ -67,7 +43,7 @@ class SyndicationDataQueries {
|
|
67 |
if ($guid = $query->get('guid')) :
|
68 |
if (strlen(trim($guid)) > 0) :
|
69 |
$seek = array($guid);
|
70 |
-
|
71 |
// MD5 hashes
|
72 |
if (preg_match('/^[0-9a-f]{32}$/i', $guid)) :
|
73 |
$seek[] = SyndicatedPost::normalize_guid_prefix().$guid;
|
@@ -79,43 +55,43 @@ class SyndicationDataQueries {
|
|
79 |
if ($guid != $nGuid) :
|
80 |
$seek[] = $nGuid;
|
81 |
endif;
|
82 |
-
|
83 |
// Escape to prevent frak-ups, injections, etc.
|
84 |
$seek = array_map('esc_sql', $seek);
|
85 |
-
|
86 |
// Assemble
|
87 |
$guidMatch = "(guid = '".implode("') OR (guid = '", $seek)."')";
|
88 |
$search .= " AND ($guidMatch)";
|
89 |
endif;
|
90 |
endif;
|
91 |
-
|
92 |
if ($query->get('fields')=='_synfresh') :
|
93 |
// Ugly hack to ensure we ONLY check by guid in syndicated freshness
|
94 |
// checks -- for reasons of both performance and correctness. Pitch:
|
95 |
$search .= " -- '";
|
96 |
elseif ($query->get('fields')=='_synfrom') :
|
97 |
-
$search .= " AND ({$wpdb->postmeta}.meta_key = '".$query->get('meta_key')."' AND {$wpdb->postmeta}.meta_value = '".$query->get('meta_value')."') -- '";
|
98 |
endif;
|
99 |
return $search;
|
100 |
} /* SyndicationDataQueries::posts_search () */
|
101 |
-
|
102 |
function posts_where ($where, &$q) {
|
103 |
global $wpdb;
|
104 |
-
|
105 |
// Ugly hack to ensure we ONLY check by guid in syndicated freshness
|
106 |
// checks -- for reasons of both performance and correctness. Catch:
|
107 |
if (strpos($where, " -- '") !== false) :
|
108 |
$bits = explode(" -- '", $where, 2);
|
109 |
$where = $bits[0];
|
110 |
endif;
|
111 |
-
|
112 |
if ($psn = $q->get('post_status__not')) :
|
113 |
-
$where .= " AND ({$wpdb->posts}.post_status <> '"
|
114 |
endif;
|
115 |
-
|
116 |
return $where;
|
117 |
} /* SyndicationDataQueries::post_where () */
|
118 |
-
|
119 |
function posts_fields ($fields, &$query) {
|
120 |
global $wpdb;
|
121 |
if ($f = $query->get('fields')) :
|
1 |
<?php
|
|
|
2 |
|
3 |
class SyndicationDataQueries {
|
4 |
function SyndicationDataQueries () {
|
5 |
add_action('init', array($this, 'init'));
|
|
|
6 |
add_action('parse_query', array($this, 'parse_query'), 10, 1);
|
7 |
add_filter('posts_search', array($this, 'posts_search'), 10, 2);
|
8 |
add_filter('posts_where', array($this, 'posts_where'), 10, 2);
|
15 |
$wp->add_query_var('guid');
|
16 |
}
|
17 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
18 |
function parse_query (&$q) {
|
19 |
if ($q->get('guid')) :
|
20 |
$q->is_single = false; // Causes nasty side-effects.
|
21 |
$q->is_singular = true; // Doesn't?
|
22 |
endif;
|
23 |
+
|
24 |
$ff = $q->get('fields');
|
25 |
if ($ff == '_synfresh' or $ff == '_synfrom') :
|
26 |
$q->query_vars['cache_results'] = false; // Not suitable.
|
27 |
endif;
|
28 |
} /* SyndicationDataQueries::parse_query () */
|
29 |
+
|
30 |
function pre_get_posts (&$q) {
|
31 |
+
//
|
32 |
}
|
33 |
+
|
34 |
function posts_request ($sql, &$query) {
|
35 |
if ($query->get('fields') == '_synfresh') :
|
36 |
FeedWordPress::diagnostic('feed_items:freshness:sql', "SQL: ".$sql);
|
43 |
if ($guid = $query->get('guid')) :
|
44 |
if (strlen(trim($guid)) > 0) :
|
45 |
$seek = array($guid);
|
46 |
+
|
47 |
// MD5 hashes
|
48 |
if (preg_match('/^[0-9a-f]{32}$/i', $guid)) :
|
49 |
$seek[] = SyndicatedPost::normalize_guid_prefix().$guid;
|
55 |
if ($guid != $nGuid) :
|
56 |
$seek[] = $nGuid;
|
57 |
endif;
|
58 |
+
|
59 |
// Escape to prevent frak-ups, injections, etc.
|
60 |
$seek = array_map('esc_sql', $seek);
|
61 |
+
|
62 |
// Assemble
|
63 |
$guidMatch = "(guid = '".implode("') OR (guid = '", $seek)."')";
|
64 |
$search .= " AND ($guidMatch)";
|
65 |
endif;
|
66 |
endif;
|
67 |
+
|
68 |
if ($query->get('fields')=='_synfresh') :
|
69 |
// Ugly hack to ensure we ONLY check by guid in syndicated freshness
|
70 |
// checks -- for reasons of both performance and correctness. Pitch:
|
71 |
$search .= " -- '";
|
72 |
elseif ($query->get('fields')=='_synfrom') :
|
73 |
+
$search .= " AND ({$wpdb->postmeta}.meta_key = '".$query->get('meta_key')."' AND {$wpdb->postmeta}.meta_value = '".$query->get('meta_value')."') -- '";
|
74 |
endif;
|
75 |
return $search;
|
76 |
} /* SyndicationDataQueries::posts_search () */
|
77 |
+
|
78 |
function posts_where ($where, &$q) {
|
79 |
global $wpdb;
|
80 |
+
|
81 |
// Ugly hack to ensure we ONLY check by guid in syndicated freshness
|
82 |
// checks -- for reasons of both performance and correctness. Catch:
|
83 |
if (strpos($where, " -- '") !== false) :
|
84 |
$bits = explode(" -- '", $where, 2);
|
85 |
$where = $bits[0];
|
86 |
endif;
|
87 |
+
|
88 |
if ($psn = $q->get('post_status__not')) :
|
89 |
+
$where .= " AND ({$wpdb->posts}.post_status <> '".esc_sql($psn)."')";
|
90 |
endif;
|
91 |
+
|
92 |
return $where;
|
93 |
} /* SyndicationDataQueries::post_where () */
|
94 |
+
|
95 |
function posts_fields ($fields, &$query) {
|
96 |
global $wpdb;
|
97 |
if ($f = $query->get('fields')) :
|