Version Description
-
WORDPRESS 3.5 COMPATIBILITY: This release has been tested for compatibility with new releases of WordPress, up to version 3.5, and any documented compatibility issues have been cleared -- in particular, if you were seeing error pages stating that you don't have permission to access the FeedWordPress Syndication page within the WordPress admin interface, then upgrading to this release should fix the problem.
As always, if you encounter any compatibility problems after upgrading your version of WordPress and your version of FeedWordPress to the most recent versions, please contact me with as detailed a description as possible of the issue you are encountering, the circumstances you're encountering it under, what you expect to see happening, and what is happening instead.
PHP 5.4 COMPATIBILITY: This release has been audited to fix potential problems with deprecation notices or fatal errors under recent versions of PHP. In particular, all uses of run-time pass-by-reference have been eliminated from the code; if you were seeing a fatal error reading "Call-time pass-by-reference has been removed ..." then upgrading to this release should fix the problem.
CUSTOMIZATION FRAMEWORK: A great deal of work has been done to make the underlying framework more flexible, so that PHP add-ons can be written to adapt FeedWordPress to handle custom XML vocabularies, expiration of posts under specified conditions, and other custom behavior.
BUGFIX: MANUALLY EDITED POST SLUGS NOT OVERWRITTEN. Thanks to a report by Chris Fritz, I've identified some code that causes post slugs for the posts generated by FWP to be rewritten with every update, even if the user has manually updated the slug from within the WordPress editing interface. This has been fixed: FWP will continue to generate new slugs for syndicated posts, but when syndicated posts are updated, they will retain the slug that they had at the time of the update; any manual changes to the post slug should be preserved.
USER-AGENT STRING: FeedWordPress now sends a distinctive User-Agent string identifying itself, and noting that it is a feed aggregator.
MISCELLANEOUS PERFORMANCE IMPROVEMENTS: A number of changes have been made to try to reduce the intensity and expense in terms of both database performance and web server memory consumption.
DIAGNOSTICS IMPROVEMENTS: A number of new and improved diagnostics have been added which should aid in understanding and troubleshooting issues that may arise.
Release Info
Developer | radgeek |
Plugin | FeedWordPress |
Version | 2012.1212 |
Comparing to | |
See all releases |
Code changes from version 2011.1019 to 2012.1212
- admin-ui.php +19 -4
- categories-page.php +4 -7
- compatability.php +1 -48
- diagnostics-page.php +109 -1
- feeds-page.php +74 -11
- feedtime.class.php +21 -4
- feedwordpie.class.php +73 -0
- feedwordpie_item.class.php +55 -0
- feedwordpress-content-type-sniffer.class.php +1 -1
- feedwordpress.php +170 -41
- feedwordpress_file.class.php +36 -14
- feedwordpress_parser.class.php +19 -2
- feedwordpresshtml.class.php +6 -5
- feedwordpresshttpauthenticator.class.php +69 -69
- feedwordpressparsedpostmeta.class.php +308 -0
- feedwordpressrpc.class.php +6 -6
- feedwordpresssyndicationpage.class.php +10 -9
- magpiefromsimplepie.class.php +12 -5
- performance-page.php +38 -0
- readme.txt +49 -2
- syndicatedlink.class.php +297 -175
- syndicatedpost.class.php +167 -100
- syndicationdataqueries.class.php +48 -10
@@ -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',
|
54 |
}
|
55 |
|
56 |
function update_feed () {
|
@@ -81,7 +81,7 @@ class FeedWordPressAdminPage {
|
|
81 |
}
|
82 |
|
83 |
function save_settings ($post) {
|
84 |
-
do_action($this->dispatch.'_save',
|
85 |
|
86 |
if ($this->for_feed_settings()) :
|
87 |
// Save settings
|
@@ -257,7 +257,7 @@ class FeedWordPressAdminPage {
|
|
257 |
"Feed" => array('page' => 'feeds-page.php', 'long' => 'Feeds & Updates'),
|
258 |
"Posts" => array('page' => 'posts-page.php', 'long' => 'Posts & Links'),
|
259 |
"Authors" => array('page' => 'authors-page.php', 'long' => 'Authors'),
|
260 |
-
'Categories' => array('page' => 'categories-page.php', 'long' => 'Categories'
|
261 |
);
|
262 |
|
263 |
$hrefPrefix = 'admin.php?';
|
@@ -444,7 +444,7 @@ class FeedWordPressAdminPage {
|
|
444 |
add_meta_box(
|
445 |
/*id=*/ $id,
|
446 |
/*title=*/ $title,
|
447 |
-
/*callback=*/ array(
|
448 |
/*page=*/ $this->meta_box_context(),
|
449 |
/*context=*/ $this->meta_box_context()
|
450 |
);
|
@@ -1118,8 +1118,17 @@ function fwp_syndication_manage_page_links_table_rows ($links, $page, $visible =
|
|
1118 |
endif;
|
1119 |
|
1120 |
// Prep: get last error timestamp, if any
|
|
|
1121 |
if (is_null($sLink->setting('update/error'))) :
|
1122 |
$errorsSince = '';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1123 |
else :
|
1124 |
$trClass[] = 'feed-error';
|
1125 |
|
@@ -1173,6 +1182,11 @@ function fwp_syndication_manage_page_links_table_rows ($links, $page, $visible =
|
|
1173 |
endif;
|
1174 |
$nextUpdate .= "</div></div>";
|
1175 |
|
|
|
|
|
|
|
|
|
|
|
1176 |
unset($sLink);
|
1177 |
|
1178 |
$alt_row = !$alt_row;
|
@@ -1221,6 +1235,7 @@ function fwp_syndication_manage_page_links_table_rows ($links, $page, $visible =
|
|
1221 |
<input type="submit" class="button" name="update_uri[<?php print esc_html($link->link_rss); ?>]" value="<?php _e('Update Now'); ?>" />
|
1222 |
</div>
|
1223 |
<?php print $lastUpdated; ?>
|
|
|
1224 |
<?php print $errorsSince; ?>
|
1225 |
<?php print $nextUpdate; ?>
|
1226 |
</td>
|
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 () {
|
81 |
}
|
82 |
|
83 |
function save_settings ($post) {
|
84 |
+
do_action($this->dispatch.'_save', $post, $this);
|
85 |
|
86 |
if ($this->for_feed_settings()) :
|
87 |
// Save settings
|
257 |
"Feed" => array('page' => 'feeds-page.php', 'long' => 'Feeds & Updates'),
|
258 |
"Posts" => array('page' => 'posts-page.php', 'long' => 'Posts & Links'),
|
259 |
"Authors" => array('page' => 'authors-page.php', 'long' => 'Authors'),
|
260 |
+
'Categories' => array('page' => 'categories-page.php', 'long' => 'Categories & Tags'),
|
261 |
);
|
262 |
|
263 |
$hrefPrefix = 'admin.php?';
|
444 |
add_meta_box(
|
445 |
/*id=*/ $id,
|
446 |
/*title=*/ $title,
|
447 |
+
/*callback=*/ array($this, $method),
|
448 |
/*page=*/ $this->meta_box_context(),
|
449 |
/*context=*/ $this->meta_box_context()
|
450 |
);
|
1118 |
endif;
|
1119 |
|
1120 |
// Prep: get last error timestamp, if any
|
1121 |
+
$fileSizeLines = array();
|
1122 |
if (is_null($sLink->setting('update/error'))) :
|
1123 |
$errorsSince = '';
|
1124 |
+
if (!is_null($sLink->setting('link/item count'))) :
|
1125 |
+
$N = $sLink->setting('link/item count');
|
1126 |
+
$fileSizeLines[] = sprintf((($N==1) ? __('%d item') : __('%d items')), $N);
|
1127 |
+
endif;
|
1128 |
+
|
1129 |
+
if (!is_null($sLink->setting('link/filesize'))) :
|
1130 |
+
$fileSizeLines[] = size_format($sLink->setting('link/filesize')). ' total';
|
1131 |
+
endif;
|
1132 |
else :
|
1133 |
$trClass[] = 'feed-error';
|
1134 |
|
1182 |
endif;
|
1183 |
$nextUpdate .= "</div></div>";
|
1184 |
|
1185 |
+
$fileSize = '';
|
1186 |
+
if (count($fileSizeLines) > 0) :
|
1187 |
+
$fileSize = '<div>'.implode(" / ", $fileSizeLines)."</div>";
|
1188 |
+
endif;
|
1189 |
+
|
1190 |
unset($sLink);
|
1191 |
|
1192 |
$alt_row = !$alt_row;
|
1235 |
<input type="submit" class="button" name="update_uri[<?php print esc_html($link->link_rss); ?>]" value="<?php _e('Update Now'); ?>" />
|
1236 |
</div>
|
1237 |
<?php print $lastUpdated; ?>
|
1238 |
+
<?php print $fileSize; ?>
|
1239 |
<?php print $errorsSince; ?>
|
1240 |
<?php print $nextUpdate; ?>
|
1241 |
</td>
|
@@ -10,9 +10,9 @@ class FeedWordPressCategoriesPage extends FeedWordPressAdminPage {
|
|
10 |
FeedWordPressAdminPage::FeedWordPressAdminPage('feedwordpresscategories', $link);
|
11 |
$this->dispatch = 'feedwordpress_admin_page_categories';
|
12 |
$this->pagenames = array(
|
13 |
-
'default' => 'Categories'
|
14 |
-
'settings-update' => 'Syndicated Categories'
|
15 |
-
'open-sheet' => 'Categories'
|
16 |
);
|
17 |
$this->filename = __FILE__;
|
18 |
}
|
@@ -599,12 +599,9 @@ blank.</p></td>
|
|
599 |
////////////////////////////////////////////////
|
600 |
|
601 |
$this->boxes_by_methods = array(
|
602 |
-
'feed_categories_box' => __('Feed Categories'
|
603 |
'categories_box' => array('title' => __('Categories'), 'id' => 'categorydiv'),
|
604 |
);
|
605 |
-
if (!FeedWordPressCompatibility::post_tags()) :
|
606 |
-
unset($this->boxes_by_methods['tags_box']);
|
607 |
-
endif;
|
608 |
|
609 |
parent::display();
|
610 |
}
|
10 |
FeedWordPressAdminPage::FeedWordPressAdminPage('feedwordpresscategories', $link);
|
11 |
$this->dispatch = 'feedwordpress_admin_page_categories';
|
12 |
$this->pagenames = array(
|
13 |
+
'default' => 'Categories & Tags',
|
14 |
+
'settings-update' => 'Syndicated Categories & Tags',
|
15 |
+
'open-sheet' => 'Categories & Tags',
|
16 |
);
|
17 |
$this->filename = __FILE__;
|
18 |
}
|
599 |
////////////////////////////////////////////////
|
600 |
|
601 |
$this->boxes_by_methods = array(
|
602 |
+
'feed_categories_box' => __('Feed Categories & Tags'),
|
603 |
'categories_box' => array('title' => __('Categories'), 'id' => 'categorydiv'),
|
604 |
);
|
|
|
|
|
|
|
605 |
|
606 |
parent::display();
|
607 |
}
|
@@ -69,10 +69,6 @@ class FeedWordPressCompatibility {
|
|
69 |
return $cat_id;
|
70 |
} /* FeedWordPressCompatibility::link_category_id () */
|
71 |
|
72 |
-
/*static*/ function post_tags () {
|
73 |
-
return FeedWordPressCompatibility::test_version(FWP_SCHEMA_23);
|
74 |
-
} /* FeedWordPressCompatibility::post_tags () */
|
75 |
-
|
76 |
/*static*/ function validate_http_request ($action = -1, $capability = null) {
|
77 |
// Only worry about this if we're using a method with significant side-effects
|
78 |
if (strtoupper($_SERVER['REQUEST_METHOD']) == 'POST') :
|
@@ -102,47 +98,11 @@ class FeedWordPressCompatibility {
|
|
102 |
/*static*/ function bottom_script_hook ($filename) {
|
103 |
global $fwp_path;
|
104 |
|
105 |
-
$hook = 'admin_footer';
|
106 |
-
if (FeedWordPressCompatibility::test_version(FWP_SCHEMA_28)) : // WordPress 2.8+
|
107 |
-
$hook = $hook . '-' . $fwp_path . '/' . basename($filename);
|
108 |
-
endif;
|
109 |
return $hook;
|
110 |
} /* FeedWordPressCompatibility::bottom_script_hook() */
|
111 |
} /* class FeedWordPressCompatibility */
|
112 |
|
113 |
-
define('FEEDWORDPRESS_AND_TAGS', (FeedWordPressCompatibility::post_tags() ? ' & Tags' : ''));
|
114 |
-
|
115 |
-
if (!function_exists('stripslashes_deep')) {
|
116 |
-
function stripslashes_deep($value) {
|
117 |
-
$value = is_array($value) ? array_map('stripslashes_deep', $value) : stripslashes($value);
|
118 |
-
return $value;
|
119 |
-
}
|
120 |
-
}
|
121 |
-
|
122 |
-
if (!function_exists('sanitize_user')) {
|
123 |
-
function sanitize_user ($text, $strict = false) {
|
124 |
-
return $text; // Don't munge it if it wasn't munged going in...
|
125 |
-
}
|
126 |
-
}
|
127 |
-
|
128 |
-
if (!function_exists('disabled')) {
|
129 |
-
/**
|
130 |
-
* Outputs the html disabled attribute.
|
131 |
-
*
|
132 |
-
* Compares the first two arguments and if identical marks as disabled
|
133 |
-
*
|
134 |
-
* @since 3.0.0
|
135 |
-
*
|
136 |
-
* @param mixed $disabled One of the values to compare
|
137 |
-
* @param mixed $current (true) The other value to compare if not just true
|
138 |
-
* @param bool $echo Whether to echo or just return the string
|
139 |
-
* @return string html attribute or empty string
|
140 |
-
*/
|
141 |
-
function disabled( $disabled, $current = true, $echo = true ) {
|
142 |
-
return __checked_selected_helper( $disabled, $current, $echo, 'disabled' );
|
143 |
-
}
|
144 |
-
} /* if */
|
145 |
-
|
146 |
// Compat
|
147 |
|
148 |
if (!function_exists('set_post_field')) {
|
@@ -175,13 +135,6 @@ if (!function_exists('set_post_field')) {
|
|
175 |
|
176 |
} /* if */
|
177 |
|
178 |
-
if (!function_exists('term_exists')) {
|
179 |
-
// Fucking WordPress 3.0 wordsmithing.
|
180 |
-
function term_exists ( $term, $taxonomy = '', $parent = 0 ) {
|
181 |
-
return is_term($term, $taxonomy, $parent);
|
182 |
-
}
|
183 |
-
} /* if */
|
184 |
-
|
185 |
require_once(dirname(__FILE__).'/feedwordpress-walker-category-checklist.class.php');
|
186 |
|
187 |
function fwp_category_checklist ($post_id = 0, $descendents_and_self = 0, $selected_cats = false, $params = array()) {
|
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') :
|
98 |
/*static*/ function bottom_script_hook ($filename) {
|
99 |
global $fwp_path;
|
100 |
|
101 |
+
$hook = 'admin_footer-'.$fwp_path.'/'.basename($filename);
|
|
|
|
|
|
|
102 |
return $hook;
|
103 |
} /* FeedWordPressCompatibility::bottom_script_hook() */
|
104 |
} /* class FeedWordPressCompatibility */
|
105 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
106 |
// Compat
|
107 |
|
108 |
if (!function_exists('set_post_field')) {
|
135 |
|
136 |
} /* if */
|
137 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
138 |
require_once(dirname(__FILE__).'/feedwordpress-walker-category-checklist.class.php');
|
139 |
|
140 |
function fwp_category_checklist ($post_id = 0, $descendents_and_self = 0, $selected_cats = false, $params = array()) {
|
@@ -7,6 +7,9 @@ class FeedWordPressDiagnosticsPage extends FeedWordPressAdminPage {
|
|
7 |
FeedWordPressAdminPage::FeedWordPressAdminPage('feedwordpressdiagnosticspage');
|
8 |
$this->dispatch = 'feedwordpress_diagnostics';
|
9 |
$this->filename = __FILE__;
|
|
|
|
|
|
|
10 |
}
|
11 |
|
12 |
function has_link () { return false; }
|
@@ -42,6 +45,7 @@ class FeedWordPressDiagnosticsPage extends FeedWordPressAdminPage {
|
|
42 |
'info_box' => __('Diagnostic Information'),
|
43 |
'diagnostics_box' => __('Display Diagnostics'),
|
44 |
'updates_box' => __('Updates'),
|
|
|
45 |
);
|
46 |
|
47 |
foreach ($boxes_by_methods as $method => $title) :
|
@@ -68,7 +72,8 @@ class FeedWordPressDiagnosticsPage extends FeedWordPressAdminPage {
|
|
68 |
|
69 |
function accept_POST ($post) {
|
70 |
if (isset($post['submit'])
|
71 |
-
or isset($post['save'])
|
|
|
72 |
update_option('feedwordpress_debug', $post['feedwordpress_debug']);
|
73 |
update_option('feedwordpress_secret_key', $post['feedwordpress_secret_key']);
|
74 |
|
@@ -102,6 +107,12 @@ class FeedWordPressDiagnosticsPage extends FeedWordPressAdminPage {
|
|
102 |
delete_option('feedwordpress_diagnostics_email_destination');
|
103 |
endif;
|
104 |
|
|
|
|
|
|
|
|
|
|
|
|
|
105 |
$this->updated = true; // Default update message
|
106 |
endif;
|
107 |
} /* FeedWordPressDiagnosticsPage::accept_POST () */
|
@@ -242,6 +253,7 @@ testing but absolutely inappropriate for a production server.</p>
|
|
242 |
'updated_feeds' => 'as each feed is checked for updates',
|
243 |
'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',
|
244 |
'updated_feeds:errors' => 'any time FeedWordPress encounters any errors while checking a feed for updates',
|
|
|
245 |
'syndicated_posts' => 'as each syndicated post is added to the database',
|
246 |
'feed_items' => 'as each syndicated item is considered on the feed',
|
247 |
'memory_usage' => 'indicating how much memory was used',
|
@@ -252,6 +264,7 @@ testing but absolutely inappropriate for a production server.</p>
|
|
252 |
'syndicated_posts:meta_data' => 'as syndication meta-data is added on the post',
|
253 |
),
|
254 |
'Advanced Diagnostics' => array(
|
|
|
255 |
'feed_items:freshness:sql' => 'when FeedWordPress issues the SQL query it uses to decide whether to treat items as new, updates, or duplicates',
|
256 |
'syndicated_posts:static_meta_data' => 'providing meta-data about syndicated posts in the Edit Posts interface',
|
257 |
),
|
@@ -289,6 +302,101 @@ testing but absolutely inappropriate for a production server.</p>
|
|
289 |
</table>
|
290 |
<?php
|
291 |
} /* FeedWordPressDiagnosticsPage::updates_box () */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
292 |
} /* class FeedWordPressDiagnosticsPage */
|
293 |
|
294 |
$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 |
}
|
14 |
|
15 |
function has_link () { return false; }
|
45 |
'info_box' => __('Diagnostic Information'),
|
46 |
'diagnostics_box' => __('Display Diagnostics'),
|
47 |
'updates_box' => __('Updates'),
|
48 |
+
'tests_box' => __('Diagnostic Tests'),
|
49 |
);
|
50 |
|
51 |
foreach ($boxes_by_methods as $method => $title) :
|
72 |
|
73 |
function accept_POST ($post) {
|
74 |
if (isset($post['submit'])
|
75 |
+
or isset($post['save'])
|
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 |
|
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 () */
|
253 |
'updated_feeds' => 'as each feed is checked for updates',
|
254 |
'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',
|
255 |
'updated_feeds:errors' => 'any time FeedWordPress encounters any errors while checking a feed for updates',
|
256 |
+
'updated_feeds:http' => "displaying the raw HTTP data passed to and from the feed being checked for updates",
|
257 |
'syndicated_posts' => 'as each syndicated post is added to the database',
|
258 |
'feed_items' => 'as each syndicated item is considered on the feed',
|
259 |
'memory_usage' => 'indicating how much memory was used',
|
264 |
'syndicated_posts:meta_data' => 'as syndication meta-data is added on the post',
|
265 |
),
|
266 |
'Advanced Diagnostics' => array(
|
267 |
+
'feed_items:freshness:reasons' => 'explaining the reason that a post was treated as an update to an existing post',
|
268 |
'feed_items:freshness:sql' => 'when FeedWordPress issues the SQL query it uses to decide whether to treat items as new, updates, or duplicates',
|
269 |
'syndicated_posts:static_meta_data' => 'providing meta-data about syndicated posts in the Edit Posts interface',
|
270 |
),
|
302 |
</table>
|
303 |
<?php
|
304 |
} /* FeedWordPressDiagnosticsPage::updates_box () */
|
305 |
+
|
306 |
+
function tests_box ($page, $box = NULL) {
|
307 |
+
?>
|
308 |
+
<script type="text/javascript">
|
309 |
+
function clone_http_test_args_keyvalue_prototype () {
|
310 |
+
var next = jQuery('#http-test-args').find('.http-test-args-keyvalue').length;
|
311 |
+
var newRow = jQuery('#http-test-args-keyvalue-prototype').clone().attr('id', 'http-test-args-keyvalue-' + next);
|
312 |
+
newRow.find('.http_test_args_key').attr('name', 'http_test_args_key['+next+']').val('');
|
313 |
+
newRow.find('.http_test_args_value').attr('name', 'http_test_args_value['+next+']').val('');
|
314 |
+
|
315 |
+
newRow.appendTo('#http-test-args');
|
316 |
+
return false;
|
317 |
+
}
|
318 |
+
</script>
|
319 |
+
|
320 |
+
<table class="edit-form">
|
321 |
+
<tr>
|
322 |
+
<th scope="row">HTTP:</th>
|
323 |
+
<td><div><input type="url" name="http_test_url" value="" placeholder="http://www.example.com/" size="127" style="width: 80%; max-width: 80.0em;" />
|
324 |
+
<input type="submit" name="feedwordpress_diagnostics_do[http_test]" value="Test »" /></div>
|
325 |
+
<div><select name="http_test_method" size="1">
|
326 |
+
<option value="wp_remote_request">wp_remote_request</option>
|
327 |
+
<option value="FeedWordPress_File">FeedWordPress_File</option>
|
328 |
+
</select></div>
|
329 |
+
<table>
|
330 |
+
<tr>
|
331 |
+
<td>
|
332 |
+
<div id="http-test-args">
|
333 |
+
<div id="http-test-args-keyvalue-prototype" class="http-test-args-keyvalue"><label>Args:
|
334 |
+
<input type="text" class='http_test_args_key' name="http_test_args_key[0]" value="" placeholder="key" /></label>
|
335 |
+
<label>= <input type="text" class='http_test_args_value' name="http_test_args_value[0]" value="" placeholder="value" /></label>
|
336 |
+
</div>
|
337 |
+
</div>
|
338 |
+
</td>
|
339 |
+
<td><a href="#http-test-args" onclick="return clone_http_test_args_keyvalue_prototype();">+ Add</a></td>
|
340 |
+
</tr>
|
341 |
+
</table>
|
342 |
+
|
343 |
+
<?php if (isset($page->test_html['http_test'])) : ?>
|
344 |
+
<div style="position: relative">
|
345 |
+
<div style="width: 100%; overflow: scroll; background-color: #eed">
|
346 |
+
<pre style="white-space: pre-wrap; white-space: -moz-pre-wrap; white-space: -o-pre-wrap;"><?php print $page->test_html['http_test']; ?></pre>
|
347 |
+
</div>
|
348 |
+
</div>
|
349 |
+
<?php endif; ?>
|
350 |
+
</td>
|
351 |
+
</tr>
|
352 |
+
</table>
|
353 |
+
|
354 |
+
<?php
|
355 |
+
} /* FeedWordPressDiagnosticsPage::tests_box () */
|
356 |
+
|
357 |
+
var $test_html;
|
358 |
+
function do_http_test ($post) {
|
359 |
+
if (isset($post['http_test_url']) and isset($post['http_test_method'])) :
|
360 |
+
$url = $post['http_test_url'];
|
361 |
+
|
362 |
+
$args = array();
|
363 |
+
if (isset($post['http_test_args_key'])) :
|
364 |
+
foreach ($post['http_test_args_key'] as $idx => $name) :
|
365 |
+
$name = trim($name);
|
366 |
+
if (strlen($name) > 0) :
|
367 |
+
$value = NULL;
|
368 |
+
if (isset($post['http_test_args_value'])
|
369 |
+
and isset($post['http_test_args_value'][$idx])) :
|
370 |
+
$value = $post['http_test_args_value'][$idx];
|
371 |
+
endif;
|
372 |
+
|
373 |
+
if (preg_match('/^javascript:(.*)$/i', $value, $refs)) :
|
374 |
+
if (function_exists('json_decode')) :
|
375 |
+
$json_value = json_decode($refs[1]);
|
376 |
+
if (!is_null($json_value)) :
|
377 |
+
$value = $json_value;
|
378 |
+
endif;
|
379 |
+
endif;
|
380 |
+
endif;
|
381 |
+
|
382 |
+
$args[$name] = $value;
|
383 |
+
endif;
|
384 |
+
endforeach;
|
385 |
+
endif;
|
386 |
+
|
387 |
+
switch ($post['http_test_method']) :
|
388 |
+
case 'wp_remote_request' :
|
389 |
+
$out = wp_remote_request($url, $args);
|
390 |
+
break;
|
391 |
+
case 'FeedWordPress_File' :
|
392 |
+
$out = new FeedWordPress_File($url);
|
393 |
+
break;
|
394 |
+
endswitch;
|
395 |
+
|
396 |
+
$this->test_html['http_test'] = esc_html(FeedWordPress::val($out));
|
397 |
+
endif;
|
398 |
+
} /* FeedWordPressDiagnosticsPage::do_http_test () */
|
399 |
+
|
400 |
} /* class FeedWordPressDiagnosticsPage */
|
401 |
|
402 |
$diagnosticsPage = new FeedWordPressDiagnosticsPage;
|
@@ -111,7 +111,7 @@ class FeedWordPressFeedsPage extends FeedWordPressAdminPage {
|
|
111 |
'global_feeds_box' => __('Update Scheduling'),
|
112 |
'updated_posts_box' => __('Updated Posts'),
|
113 |
'custom_settings_box' => __('Custom Feed Settings (for use in templates)'),
|
114 |
-
'
|
115 |
);
|
116 |
if ($this->for_default_settings()) :
|
117 |
unset($this->boxes_by_methods['custom_settings_box']);
|
@@ -265,13 +265,13 @@ class FeedWordPressFeedsPage extends FeedWordPressAdminPage {
|
|
265 |
|
266 |
$this->setting_radio_control(
|
267 |
'update/window', 'update_window',
|
268 |
-
array(
|
269 |
array(
|
270 |
'global-setting-default' => DEFAULT_UPDATE_PERIOD,
|
271 |
'default-input-name' => 'use_default_update_window',
|
272 |
'default-input-id' => 'use-default-update-window-yes',
|
273 |
'default-input-id-no' => 'use-default-update-window-no',
|
274 |
-
'labels' => array(
|
275 |
)
|
276 |
);
|
277 |
?></td>
|
@@ -363,22 +363,63 @@ class FeedWordPressFeedsPage extends FeedWordPressAdminPage {
|
|
363 |
print number_format(intval($setting)) . " " . (($setting==1) ? "second" : "seconds");
|
364 |
}
|
365 |
|
366 |
-
function
|
|
|
|
|
|
|
|
|
|
|
|
|
367 |
$this->setting_radio_control(
|
368 |
'fetch timeout', 'fetch_timeout',
|
369 |
-
array(
|
370 |
array(
|
371 |
'global-setting-default' => FEEDWORDPRESS_FETCH_TIMEOUT_DEFAULT,
|
372 |
'input-name' => 'fetch_timeout',
|
373 |
'default-input-name' => 'fetch_timeout_default',
|
374 |
-
'labels' => array(
|
375 |
)
|
376 |
);
|
377 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
378 |
|
379 |
function display_authentication_credentials_box ($params = array()) {
|
380 |
static $count = 0;
|
381 |
-
|
382 |
$params = wp_parse_args($params, array(
|
383 |
'username' => NULL,
|
384 |
'password' => NULL,
|
@@ -502,7 +543,7 @@ class FeedWordPressFeedsPage extends FeedWordPressAdminPage {
|
|
502 |
|
503 |
global $feedwordpress;
|
504 |
|
505 |
-
if (is_null($auth)) :
|
506 |
$auth = '-';
|
507 |
$hideAuth = true;
|
508 |
endif;
|
@@ -789,7 +830,21 @@ class FeedWordPressFeedsPage extends FeedWordPressAdminPage {
|
|
789 |
$feeds = array_values( // Renumber from 0..(N-1)
|
790 |
$feeds
|
791 |
);
|
792 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
793 |
if (count($feeds) > 0):
|
794 |
if ($feedSwitch) :
|
795 |
?>
|
@@ -815,7 +870,7 @@ class FeedWordPressFeedsPage extends FeedWordPressAdminPage {
|
|
815 |
foreach ($feeds as $key => $f):
|
816 |
$ofc = $fwp_credentials;
|
817 |
$fwp_credentials = $credentials; // Set
|
818 |
-
$pie = FeedWordPress::fetch($f);
|
819 |
$fwp_credentials = $ofc; // Re-Set
|
820 |
|
821 |
$rss = (is_wp_error($pie) ? $pie : new MagpieFromSimplePie($pie));
|
@@ -1161,6 +1216,14 @@ class FeedWordPressFeedsPage extends FeedWordPressAdminPage {
|
|
1161 |
endif;
|
1162 |
$this->update_setting('fetch timeout', $timeout);
|
1163 |
endif;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1164 |
|
1165 |
if (isset($post['update_minimum'])) :
|
1166 |
$this->update_setting('update/minimum', $post['update_minimum']);
|
111 |
'global_feeds_box' => __('Update Scheduling'),
|
112 |
'updated_posts_box' => __('Updated Posts'),
|
113 |
'custom_settings_box' => __('Custom Feed Settings (for use in templates)'),
|
114 |
+
'advanced_settings_box' => __('Advanced Settings'),
|
115 |
);
|
116 |
if ($this->for_default_settings()) :
|
117 |
unset($this->boxes_by_methods['custom_settings_box']);
|
265 |
|
266 |
$this->setting_radio_control(
|
267 |
'update/window', 'update_window',
|
268 |
+
array($this, 'update_window_edit_box'),
|
269 |
array(
|
270 |
'global-setting-default' => DEFAULT_UPDATE_PERIOD,
|
271 |
'default-input-name' => 'use_default_update_window',
|
272 |
'default-input-id' => 'use-default-update-window-yes',
|
273 |
'default-input-id-no' => 'use-default-update-window-no',
|
274 |
+
'labels' => array($this, 'update_window_currently'),
|
275 |
)
|
276 |
);
|
277 |
?></td>
|
363 |
print number_format(intval($setting)) . " " . (($setting==1) ? "second" : "seconds");
|
364 |
}
|
365 |
|
366 |
+
function advanced_settings_box ($page, $box = NULL) {
|
367 |
+
?>
|
368 |
+
<table class="edit-form">
|
369 |
+
<tr>
|
370 |
+
<th>Fetch Timeout:</th>
|
371 |
+
<td>
|
372 |
+
<?php
|
373 |
$this->setting_radio_control(
|
374 |
'fetch timeout', 'fetch_timeout',
|
375 |
+
array($this, 'fetch_timeout_setting'),
|
376 |
array(
|
377 |
'global-setting-default' => FEEDWORDPRESS_FETCH_TIMEOUT_DEFAULT,
|
378 |
'input-name' => 'fetch_timeout',
|
379 |
'default-input-name' => 'fetch_timeout_default',
|
380 |
+
'labels' => array($this, 'fetch_timeout_setting_value'),
|
381 |
)
|
382 |
);
|
383 |
+
?>
|
384 |
+
</td>
|
385 |
+
</tr>
|
386 |
+
<tr>
|
387 |
+
<th>Feed Update Type:</th>
|
388 |
+
<td><?php
|
389 |
+
$this->setting_radio_control('update_incremental', 'update_incremental',
|
390 |
+
/*options=*/ array(
|
391 |
+
'incremental' => '<strong>Incremental.</strong> When items no longer appear on the feed, keep them in the WordPress posts table.',
|
392 |
+
'complete' => '<strong>Complete.</strong> When items no longer appear on the feed, they are obsolete; retire them from the WordPress posts table.',
|
393 |
+
),
|
394 |
+
/*params=*/ array(
|
395 |
+
'setting-default' => NULL,
|
396 |
+
'global-setting-default' => 'incremental',
|
397 |
+
'default-input-value' => 'default',
|
398 |
+
)
|
399 |
+
); ?></td>
|
400 |
+
</tr>
|
401 |
+
<tr>
|
402 |
+
<th>Allow Feeds to Delete Posts:</th>
|
403 |
+
<td><?php
|
404 |
+
$this->setting_radio_control('tombstones', 'tombstones',
|
405 |
+
/*options=*/ array(
|
406 |
+
'yes' => 'Yes. If a feed indicates that one of its posts has been deleted, delete the local copy syndicated to this website.',
|
407 |
+
'no' => 'No. Even if a feed indicates that one of its posts has been deleted, retain the local copy on this website.',
|
408 |
+
),
|
409 |
+
/*params=*/ array(
|
410 |
+
'setting-default' => NULL,
|
411 |
+
'global-setting-default' => 'yes',
|
412 |
+
'default-input-value' => 'default',
|
413 |
+
)
|
414 |
+
); ?></td>
|
415 |
+
</tr>
|
416 |
+
</table>
|
417 |
+
<?php
|
418 |
+
} /* FeedWordPressFeedsPage::advanced_settings_box () */
|
419 |
|
420 |
function display_authentication_credentials_box ($params = array()) {
|
421 |
static $count = 0;
|
422 |
+
|
423 |
$params = wp_parse_args($params, array(
|
424 |
'username' => NULL,
|
425 |
'password' => NULL,
|
543 |
|
544 |
global $feedwordpress;
|
545 |
|
546 |
+
if (is_null($auth) or (strlen($auth)==0)) :
|
547 |
$auth = '-';
|
548 |
$hideAuth = true;
|
549 |
endif;
|
830 |
$feeds = array_values( // Renumber from 0..(N-1)
|
831 |
$feeds
|
832 |
);
|
833 |
+
|
834 |
+
// Allow for some simple FeedFinder results filtering
|
835 |
+
$feeds = apply_filters(
|
836 |
+
'feedwordpress_feedfinder_results',
|
837 |
+
$feeds,
|
838 |
+
array(
|
839 |
+
"url" => $lookup,
|
840 |
+
"auth" => $auth,
|
841 |
+
"username" => $username,
|
842 |
+
"password" => $password,
|
843 |
+
"finder" => $finder,
|
844 |
+
),
|
845 |
+
$this
|
846 |
+
);
|
847 |
+
|
848 |
if (count($feeds) > 0):
|
849 |
if ($feedSwitch) :
|
850 |
?>
|
870 |
foreach ($feeds as $key => $f):
|
871 |
$ofc = $fwp_credentials;
|
872 |
$fwp_credentials = $credentials; // Set
|
873 |
+
$pie = FeedWordPress::fetch($f, array("cache" => false));
|
874 |
$fwp_credentials = $ofc; // Re-Set
|
875 |
|
876 |
$rss = (is_wp_error($pie) ? $pie : new MagpieFromSimplePie($pie));
|
1216 |
endif;
|
1217 |
$this->update_setting('fetch timeout', $timeout);
|
1218 |
endif;
|
1219 |
+
|
1220 |
+
if (isset($post['update_incremental'])) :
|
1221 |
+
$this->update_setting('update_incremental', $post['update_incremental']);
|
1222 |
+
endif;
|
1223 |
+
|
1224 |
+
if (isset($post['tombstones'])) :
|
1225 |
+
$this->update_setting('tombstones', $post['tombstones']);
|
1226 |
+
endif;
|
1227 |
|
1228 |
if (isset($post['update_minimum'])) :
|
1229 |
$this->update_setting('update/minimum', $post['update_minimum']);
|
@@ -1,7 +1,24 @@
|
|
1 |
<?php
|
2 |
/**
|
3 |
* class FeedTime: handle common date-time formats used in feeds.
|
|
|
|
|
|
|
|
|
4 |
*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5 |
*/
|
6 |
class FeedTime {
|
7 |
var $rep;
|
@@ -21,10 +38,10 @@ class FeedTime {
|
|
21 |
$this->ts = $this->parse_w3cdtf();
|
22 |
|
23 |
if ($this->failed()) :
|
24 |
-
// In some versions of PHP, strtotime() does not
|
25 |
-
// the UT timezone.
|
26 |
-
// second of UTC, we'll just
|
27 |
-
// problems.
|
28 |
$time = preg_replace(
|
29 |
'/(\s)UT$/',
|
30 |
'$1UTC',
|
1 |
<?php
|
2 |
/**
|
3 |
* class FeedTime: handle common date-time formats used in feeds.
|
4 |
+
* We will try to be as tolerant as possible of different representations, since
|
5 |
+
* RSS Is A Fucking Mess, broken dates seem to be especially pervasive, etc.
|
6 |
+
* Supports anything that your version of PHP's strtotime() can handle; also has
|
7 |
+
* a built-in parser for W3C DTF, in case your PHP doesn't have that.
|
8 |
*
|
9 |
+
* Tries to parse a W3C DTF first; then falls back to strtotime(). If strtotime
|
10 |
+
* fails due to a mystery timezone, then we will try again on local time, with
|
11 |
+
* the timezone stripped out.
|
12 |
+
*
|
13 |
+
* To parse a string representation of a date-time from a feed, instantiate and
|
14 |
+
* then pull the timestamp:
|
15 |
+
*
|
16 |
+
* $time = new FeedTime($s);
|
17 |
+
* if (!$time->failed()) :
|
18 |
+
* $ts = $time->timestamp();
|
19 |
+
* else :
|
20 |
+
* // ...
|
21 |
+
* endif;
|
22 |
*/
|
23 |
class FeedTime {
|
24 |
var $rep;
|
38 |
$this->ts = $this->parse_w3cdtf();
|
39 |
|
40 |
if ($this->failed()) :
|
41 |
+
// In some versions of PHP, strtotime() does not
|
42 |
+
// support the UT timezone. But since UT is by
|
43 |
+
// definition within 1 second of UTC, we'll just
|
44 |
+
// convert it preemptively to avoid problems.
|
45 |
$time = preg_replace(
|
46 |
'/(\s)UT$/',
|
47 |
'$1UTC',
|
@@ -0,0 +1,73 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
define('FEEDWORDPIE_TYPE_CUSTOM_XML', ~SIMPLEPIE_TYPE_NONE & ~SIMPLEPIE_TYPE_ALL);
|
3 |
+
|
4 |
+
class FeedWordPie extends SimplePie {
|
5 |
+
var $subscription = NULL;
|
6 |
+
|
7 |
+
function set_feed_url ($url) {
|
8 |
+
global $fwp_oLinks;
|
9 |
+
if ($url InstanceOf SyndicatedLink) :
|
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();
|
17 |
+
|
18 |
+
// Pass it along down the line.
|
19 |
+
$url = $new_url;
|
20 |
+
|
21 |
+
else :
|
22 |
+
$this->subscription = NULL;
|
23 |
+
endif;
|
24 |
+
|
25 |
+
// OK, let's go.
|
26 |
+
return parent::set_feed_url($url);
|
27 |
+
} /* class SimplePie */
|
28 |
+
|
29 |
+
function get_type () {
|
30 |
+
// Allow filters to pre-empt a type determination from SimplePie
|
31 |
+
$ret = apply_filters(
|
32 |
+
'feedwordpie_get_type',
|
33 |
+
NULL,
|
34 |
+
$this
|
35 |
+
);
|
36 |
+
|
37 |
+
// If not preempted by a filter, fall back on SimplePie
|
38 |
+
if (is_null($ret)) :
|
39 |
+
$ret = parent::get_type();
|
40 |
+
endif;
|
41 |
+
|
42 |
+
return $ret;
|
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 |
+
parent::get_feed_tags($namespace, $tag),
|
50 |
+
$namespace,
|
51 |
+
$tag,
|
52 |
+
$this
|
53 |
+
);
|
54 |
+
}
|
55 |
+
|
56 |
+
function get_items ($start = 0, $end = 0) {
|
57 |
+
// Allow filters to set up for, or pre-empt, SimplePie handling
|
58 |
+
$ret = apply_filters(
|
59 |
+
'feedwordpie_get_items',
|
60 |
+
NULL,
|
61 |
+
$start,
|
62 |
+
$end,
|
63 |
+
$this
|
64 |
+
);
|
65 |
+
|
66 |
+
if (is_null($ret)) :
|
67 |
+
$ret = parent::get_items();
|
68 |
+
endif;
|
69 |
+
return $ret;
|
70 |
+
}
|
71 |
+
|
72 |
+
} /* class FeedWordPie */
|
73 |
+
|
@@ -0,0 +1,55 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
class FeedWordPie_Item extends SimplePie_Item {
|
3 |
+
|
4 |
+
function get_id ($hash = false) {
|
5 |
+
return apply_filters('feedwordpie_item_get_id', parent::get_id($hash), $hash, $this);
|
6 |
+
}
|
7 |
+
|
8 |
+
function get_title () {
|
9 |
+
return apply_filters('feedwordpie_item_get_title', parent::get_title(), $this);
|
10 |
+
}
|
11 |
+
|
12 |
+
function get_description ($description_only = false) {
|
13 |
+
return apply_filters('feedwordpie_item_get_description', parent::get_description($description_only), $description_only, $this);
|
14 |
+
}
|
15 |
+
|
16 |
+
function get_content ($content_only = false) {
|
17 |
+
return apply_filters('feedwordpie_item_get_content', parent::get_content($content_only), $content_only, $this);
|
18 |
+
}
|
19 |
+
|
20 |
+
function get_categories () {
|
21 |
+
return apply_filters('feedwordpie_item_get_categories', parent::get_categories(), $this);
|
22 |
+
}
|
23 |
+
|
24 |
+
function get_authors () {
|
25 |
+
return apply_filters('feedwordpie_item_get_authors', parent::get_authors(), $this);
|
26 |
+
}
|
27 |
+
function get_contributors () {
|
28 |
+
return apply_filters('feedwordpie_item_get_contributors', parent::get_contributors(), $this);
|
29 |
+
}
|
30 |
+
function get_copyright () {
|
31 |
+
return apply_filters('feedwordpie_item_get_copyright', parent::get_copyright(), $this);
|
32 |
+
}
|
33 |
+
function get_date ($date_format = 'j F Y, g:i a') {
|
34 |
+
return apply_filters('feedwordpie_item_get_date', parent::get_date($date_format), $date_format, $this);
|
35 |
+
}
|
36 |
+
function get_local_date ($date_format = '%c') {
|
37 |
+
return apply_filters('feedwordpie_item_get_local_date', parent::get_local_date($date_format), $date_format, $this);
|
38 |
+
}
|
39 |
+
function get_links ($rel = 'alternate') {
|
40 |
+
return apply_filters('feedwordpie_item_get_links', parent::get_links($rel), $rel, $this);
|
41 |
+
}
|
42 |
+
function get_enclosures () {
|
43 |
+
return apply_filters('feedwordpie_item_get_enclosures', parent::get_enclosures(), $this);
|
44 |
+
}
|
45 |
+
function get_latitude () {
|
46 |
+
return apply_filters('feedwordpie_item_get_lattitude', parent::get_lattitude(), $this);
|
47 |
+
}
|
48 |
+
function get_longitude () {
|
49 |
+
return apply_filters('feedwordpie_item_get_longitude', parent::get_longtidue(), $this);
|
50 |
+
}
|
51 |
+
function get_source () {
|
52 |
+
return apply_filters('feedwordpie_item_get_source', parent::get_source(), $this);
|
53 |
+
}
|
54 |
+
} /* class FeedWordPie_Item */
|
55 |
+
|
@@ -17,7 +17,7 @@ class FeedWordPress_Content_Type_Sniffer extends SimplePie_Content_Type_Sniffer
|
|
17 |
endif;
|
18 |
|
19 |
foreach ($this->file->headers['content-type'] as $type) :
|
20 |
-
$parts = array_map('trim',
|
21 |
if (isset($parts[1])) :
|
22 |
$type = $parts[0];
|
23 |
$charset = $parts[1];
|
17 |
endif;
|
18 |
|
19 |
foreach ($this->file->headers['content-type'] as $type) :
|
20 |
+
$parts = array_map('trim', explode(";", $type, 2));
|
21 |
if (isset($parts[1])) :
|
22 |
$type = $parts[0];
|
23 |
$charset = $parts[1];
|
@@ -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:
|
@@ -34,7 +34,7 @@ License: GPL
|
|
34 |
|
35 |
# -- Don't change these unless you know what you're doing...
|
36 |
|
37 |
-
define ('FEEDWORDPRESS_VERSION', '
|
38 |
define ('FEEDWORDPRESS_AUTHOR_CONTACT', 'http://radgeek.com/contact');
|
39 |
|
40 |
if (!defined('FEEDWORDPRESS_BLEG')) :
|
@@ -54,6 +54,8 @@ else :
|
|
54 |
endif;
|
55 |
endif;
|
56 |
define ('FEEDWORDPRESS_DEBUG', $feedwordpress_debug);
|
|
|
|
|
57 |
|
58 |
define ('FEEDWORDPRESS_CAT_SEPARATOR_PATTERN', '/[:\n]/');
|
59 |
define ('FEEDWORDPRESS_CAT_SEPARATOR', "\n");
|
@@ -119,6 +121,8 @@ require_once("${dir}/feedwordpresshtml.class.php");
|
|
119 |
require_once("${dir}/feedwordpress-content-type-sniffer.class.php");
|
120 |
require_once("${dir}/inspectpostmeta.class.php");
|
121 |
require_once("${dir}/syndicationdataqueries.class.php");
|
|
|
|
|
122 |
require_once("${dir}/feedwordpress_file.class.php");
|
123 |
require_once("${dir}/feedwordpress_parser.class.php");
|
124 |
require_once("${dir}/feedwordpressrpc.class.php");
|
@@ -183,6 +187,7 @@ if (!FeedWordPress::needs_upgrade()) : // only work if the conditions are safe!
|
|
183 |
remove_filter('pre_link_url', 'wp_filter_kses');
|
184 |
|
185 |
# Admin menu
|
|
|
186 |
add_action('admin_menu', 'fwp_add_pages');
|
187 |
add_action('admin_notices', 'fwp_check_debug');
|
188 |
|
@@ -214,12 +219,12 @@ if (!FeedWordPress::needs_upgrade()) : // only work if the conditions are safe!
|
|
214 |
# Cron-less auto-update. Hooray!
|
215 |
$autoUpdateHook = $feedwordpress->automatic_update_hook();
|
216 |
if (!is_null($autoUpdateHook)) :
|
217 |
-
add_action($autoUpdateHook, array(
|
218 |
endif;
|
219 |
|
220 |
-
add_action('init', array(
|
221 |
-
add_action('shutdown', array(
|
222 |
-
add_action('wp_dashboard_setup', array(
|
223 |
|
224 |
# Default sanitizers
|
225 |
add_filter('syndicated_item_content', array('SyndicatedPost', 'resolve_relative_uris'), 0, 2);
|
@@ -392,23 +397,12 @@ function get_syndication_feed_guid ($original = NULL, $id = NULL) {
|
|
392 |
function get_syndication_feed_id ($id = NULL) { list($u) = get_post_custom_values('syndication_feed_id', $id); return $u; }
|
393 |
function the_syndication_feed_id ($id = NULL) { echo get_syndication_feed_id($id); }
|
394 |
|
395 |
-
$feedwordpress_linkcache = array (); // only load links from database once
|
396 |
function get_syndication_feed_object ($id = NULL) {
|
397 |
-
global $
|
398 |
-
|
399 |
-
$link = NULL;
|
400 |
-
|
401 |
$feed_id = get_syndication_feed_id($id);
|
402 |
-
|
403 |
-
|
404 |
-
$link = $feedwordpress_linkcache[$feed_id];
|
405 |
-
else :
|
406 |
-
$link = new SyndicatedLink($feed_id);
|
407 |
-
$feedwordpress_linkcache[$feed_id] = $link;
|
408 |
-
endif;
|
409 |
-
endif;
|
410 |
-
return $link;
|
411 |
-
}
|
412 |
|
413 |
function get_feed_meta ($key, $id = NULL) {
|
414 |
$ret = NULL;
|
@@ -418,7 +412,7 @@ function get_feed_meta ($key, $id = NULL) {
|
|
418 |
$ret = $link->settings[$key];
|
419 |
endif;
|
420 |
return $ret;
|
421 |
-
} /* get_feed_meta() */
|
422 |
|
423 |
function get_syndication_permalink ($id = NULL) {
|
424 |
list($u) = get_post_custom_values('syndication_permalink', $id); return $u;
|
@@ -680,6 +674,12 @@ function fwp_add_pages () {
|
|
680 |
WP_PLUGIN_URL.'/'.FeedWordPress::path('feedwordpress-tiny.png')
|
681 |
);
|
682 |
|
|
|
|
|
|
|
|
|
|
|
|
|
683 |
do_action('feedwordpress_admin_menu_pre_feeds', $menu_cap, $settings_cap);
|
684 |
add_submenu_page(
|
685 |
$syndicationMenu, 'Syndicated Feeds & Updates', 'Feeds & Updates',
|
@@ -700,7 +700,7 @@ function fwp_add_pages () {
|
|
700 |
|
701 |
do_action('feedwordpress_admin_menu_pre_categories', $menu_cap, $settings_cap);
|
702 |
add_submenu_page(
|
703 |
-
$syndicationMenu, 'Categories'
|
704 |
$settings_cap, FeedWordPress::path('categories-page.php')
|
705 |
);
|
706 |
|
@@ -797,7 +797,13 @@ function fwp_publish_post_hook ($post_id) {
|
|
797 |
}
|
798 |
|
799 |
function feedwordpress_add_post_edit_controls () {
|
|
|
|
|
|
|
800 |
add_meta_box('feedwordpress-post-controls', __('Syndication'), 'feedwordpress_post_edit_controls', 'post', 'side', 'high');
|
|
|
|
|
|
|
801 |
if (FeedWordPress::diagnostic_on('syndicated_posts:static_meta_data')) :
|
802 |
$GLOBALS['inspectPostMeta'] = new InspectPostMeta;
|
803 |
endif;
|
@@ -897,19 +903,53 @@ class FeedWordPress {
|
|
897 |
);
|
898 |
|
899 |
var $feeds = NULL;
|
900 |
-
|
901 |
var $httpauth = NULL;
|
|
|
902 |
# function FeedWordPress (): Contructor; retrieve a list of feeds
|
903 |
function FeedWordPress () {
|
904 |
$this->feeds = array ();
|
|
|
905 |
$links = FeedWordPress::syndicated_links();
|
906 |
if ($links): foreach ($links as $link):
|
907 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
908 |
endforeach; endif;
|
909 |
-
|
910 |
$this->httpauth = new FeedWordPressHTTPAuthenticator;
|
911 |
} // FeedWordPress::FeedWordPress ()
|
912 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
913 |
# function update (): polls for updates on one or more Contributor feeds
|
914 |
#
|
915 |
# Arguments:
|
@@ -986,7 +1026,7 @@ class FeedWordPress {
|
|
986 |
endif;
|
987 |
|
988 |
// Randomize order for load balancing purposes
|
989 |
-
$feed_set = $this->feeds;
|
990 |
shuffle($feed_set);
|
991 |
|
992 |
$updateWindow = (int) get_option('feedwordpress_update_window', DEFAULT_UPDATE_PERIOD) * 60 /* sec/min */;
|
@@ -1001,10 +1041,13 @@ class FeedWordPress {
|
|
1001 |
), $uri);
|
1002 |
|
1003 |
$feed_set = apply_filters('feedwordpress_update_feeds', $feed_set, $uri);
|
1004 |
-
|
|
|
1005 |
// Loop through and check for new posts
|
1006 |
$delta = NULL; $remaining = $max_polls;
|
1007 |
-
foreach ($feed_set as $
|
|
|
|
|
1008 |
|
1009 |
// Has this process overstayed its welcome?
|
1010 |
if (
|
@@ -1157,6 +1200,15 @@ class FeedWordPress {
|
|
1157 |
return $ret;
|
1158 |
} // FeedWordPress::stale()
|
1159 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1160 |
function init () {
|
1161 |
global $fwp_path;
|
1162 |
|
@@ -1174,15 +1226,49 @@ class FeedWordPress {
|
|
1174 |
wp_enqueue_style('dashboard');
|
1175 |
wp_enqueue_style('feedwordpress-elements');
|
1176 |
|
1177 |
-
if (function_exists('wp_admin_css')) :
|
1178 |
wp_admin_css('css/dashboard');
|
1179 |
-
endif
|
1180 |
endif;
|
1181 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1182 |
$this->clear_cache_magic_url();
|
1183 |
$this->update_magic_url();
|
1184 |
} /* FeedWordPress::init() */
|
1185 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1186 |
function dashboard_setup () {
|
1187 |
$see_it = FeedWordPress::menu_cap();
|
1188 |
|
@@ -1202,12 +1288,12 @@ class FeedWordPress {
|
|
1202 |
add_meta_box(
|
1203 |
/*id=*/ $widget_id,
|
1204 |
/*title=*/ $widget_name,
|
1205 |
-
/*callback=*/ array(
|
1206 |
/*page=*/ 'dashboard',
|
1207 |
/*context=*/ $column,
|
1208 |
/*priority=*/ $priority
|
1209 |
);
|
1210 |
-
/*control_callback= array(
|
1211 |
|
1212 |
// This is kind of rude, I know, but the dashboard widget isn't
|
1213 |
// worth much if users don't know that it exists, and I don't
|
@@ -1244,6 +1330,20 @@ class FeedWordPress {
|
|
1244 |
$syndicationPage->dashboard_box($syndicationPage);
|
1245 |
} /* FeedWordPress::dashboard () */
|
1246 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1247 |
function update_magic_url () {
|
1248 |
global $wpdb;
|
1249 |
|
@@ -1604,11 +1704,11 @@ class FeedWordPress {
|
|
1604 |
endif;
|
1605 |
$timeout = intval($timeout);
|
1606 |
|
1607 |
-
$pie_class = apply_filters('feedwordpress_simplepie_class', '
|
1608 |
$cache_class = apply_filters('feedwordpress_cache_class', 'WP_Feed_Cache');
|
1609 |
$file_class = apply_filters('feedwordpress_file_class', 'FeedWordPress_File');
|
1610 |
$parser_class = apply_filters('feedwordpress_parser_class', 'FeedWordPress_Parser');
|
1611 |
-
|
1612 |
$sniffer_class = apply_filters('feedwordpress_sniffer_class', 'FeedWordPress_Content_Type_Sniffer');
|
1613 |
|
1614 |
$feed = new $pie_class;
|
@@ -1619,8 +1719,9 @@ class FeedWordPress {
|
|
1619 |
$feed->set_content_type_sniffer_class($sniffer_class);
|
1620 |
$feed->set_file_class($file_class);
|
1621 |
$feed->set_parser_class($parser_class);
|
|
|
1622 |
$feed->force_feed($force_feed);
|
1623 |
-
$feed->set_cache_duration(FeedWordPress::cache_duration());
|
1624 |
$feed->init();
|
1625 |
$feed->handle_content_type();
|
1626 |
|
@@ -1657,9 +1758,15 @@ class FeedWordPress {
|
|
1657 |
return ($magpies + $simplepies);
|
1658 |
} /* FeedWordPress::clear_cache () */
|
1659 |
|
1660 |
-
function cache_duration () {
|
|
|
|
|
|
|
|
|
1661 |
$duration = NULL;
|
1662 |
-
if (
|
|
|
|
|
1663 |
$duration = FEEDWORDPRESS_CACHE_AGE;
|
1664 |
endif;
|
1665 |
return $duration;
|
@@ -1760,6 +1867,7 @@ class FeedWordPress {
|
|
1760 |
error_log(FeedWordPress::log_prefix().' '.$out);
|
1761 |
break;
|
1762 |
case 'email' :
|
|
|
1763 |
if (is_null($persist)) :
|
1764 |
$sect = 'occurrent';
|
1765 |
$hook = (isset($dlog['mesg'][$sect]) ? count($dlog['mesg'][$sect]) : 0);
|
@@ -1801,7 +1909,11 @@ class FeedWordPress {
|
|
1801 |
return $ret;
|
1802 |
}
|
1803 |
|
1804 |
-
function email_diagnostic_log () {
|
|
|
|
|
|
|
|
|
1805 |
$dlog = get_option('feedwordpress_diagnostics_log', array());
|
1806 |
|
1807 |
if ($this->has_emailed_diagnostics($dlog)) :
|
@@ -1886,9 +1998,26 @@ EOMAIL;
|
|
1886 |
$recipients = FeedWordPressDiagnostic::admin_emails();
|
1887 |
endif;
|
1888 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1889 |
foreach ($recipients as $email) :
|
1890 |
add_filter('wp_mail_content_type', array('FeedWordPress', 'allow_html_mail'));
|
1891 |
-
wp_mail($email, $subj, $body);
|
1892 |
remove_filter('wp_mail_content_type', array('FeedWordPress', 'allow_html_mail'));
|
1893 |
endforeach;
|
1894 |
endif;
|
3 |
Plugin Name: FeedWordPress
|
4 |
Plugin URI: http://feedwordpress.radgeek.com/
|
5 |
Description: simple and flexible Atom/RSS syndication for WordPress
|
6 |
+
Version: 2012.1212
|
7 |
Author: Charles Johnson
|
8 |
Author URI: http://radgeek.com/
|
9 |
License: GPL
|
11 |
|
12 |
/**
|
13 |
* @package FeedWordPress
|
14 |
+
* @version 2012.1212
|
15 |
*/
|
16 |
|
17 |
# This uses code derived from:
|
34 |
|
35 |
# -- Don't change these unless you know what you're doing...
|
36 |
|
37 |
+
define ('FEEDWORDPRESS_VERSION', '2012.1212');
|
38 |
define ('FEEDWORDPRESS_AUTHOR_CONTACT', 'http://radgeek.com/contact');
|
39 |
|
40 |
if (!defined('FEEDWORDPRESS_BLEG')) :
|
54 |
endif;
|
55 |
endif;
|
56 |
define ('FEEDWORDPRESS_DEBUG', $feedwordpress_debug);
|
57 |
+
$feedwordpress_compatibility = true;
|
58 |
+
define ('FEEDWORDPRESS_COMPATIBILITY', $feedwordpress_compatibility);
|
59 |
|
60 |
define ('FEEDWORDPRESS_CAT_SEPARATOR_PATTERN', '/[:\n]/');
|
61 |
define ('FEEDWORDPRESS_CAT_SEPARATOR', "\n");
|
121 |
require_once("${dir}/feedwordpress-content-type-sniffer.class.php");
|
122 |
require_once("${dir}/inspectpostmeta.class.php");
|
123 |
require_once("${dir}/syndicationdataqueries.class.php");
|
124 |
+
require_once("${dir}/feedwordpie.class.php");
|
125 |
+
require_once("${dir}/feedwordpie_item.class.php");
|
126 |
require_once("${dir}/feedwordpress_file.class.php");
|
127 |
require_once("${dir}/feedwordpress_parser.class.php");
|
128 |
require_once("${dir}/feedwordpressrpc.class.php");
|
187 |
remove_filter('pre_link_url', 'wp_filter_kses');
|
188 |
|
189 |
# Admin menu
|
190 |
+
add_action('admin_init', array('feedwordpress', 'admin_init'));
|
191 |
add_action('admin_menu', 'fwp_add_pages');
|
192 |
add_action('admin_notices', 'fwp_check_debug');
|
193 |
|
219 |
# Cron-less auto-update. Hooray!
|
220 |
$autoUpdateHook = $feedwordpress->automatic_update_hook();
|
221 |
if (!is_null($autoUpdateHook)) :
|
222 |
+
add_action($autoUpdateHook, array($feedwordpress, 'auto_update'));
|
223 |
endif;
|
224 |
|
225 |
+
add_action('init', array($feedwordpress, 'init'));
|
226 |
+
add_action('shutdown', array($feedwordpress, 'email_diagnostic_log'));
|
227 |
+
add_action('wp_dashboard_setup', array($feedwordpress, 'dashboard_setup'));
|
228 |
|
229 |
# Default sanitizers
|
230 |
add_filter('syndicated_item_content', array('SyndicatedPost', 'resolve_relative_uris'), 0, 2);
|
397 |
function get_syndication_feed_id ($id = NULL) { list($u) = get_post_custom_values('syndication_feed_id', $id); return $u; }
|
398 |
function the_syndication_feed_id ($id = NULL) { echo get_syndication_feed_id($id); }
|
399 |
|
|
|
400 |
function get_syndication_feed_object ($id = NULL) {
|
401 |
+
global $feedwordpress;
|
402 |
+
|
|
|
|
|
403 |
$feed_id = get_syndication_feed_id($id);
|
404 |
+
return $feedwordpress->subscription($feed_id);
|
405 |
+
} /* function get_syndication_feed_object() */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
406 |
|
407 |
function get_feed_meta ($key, $id = NULL) {
|
408 |
$ret = NULL;
|
412 |
$ret = $link->settings[$key];
|
413 |
endif;
|
414 |
return $ret;
|
415 |
+
} /* function get_feed_meta() */
|
416 |
|
417 |
function get_syndication_permalink ($id = NULL) {
|
418 |
list($u) = get_post_custom_values('syndication_permalink', $id); return $u;
|
674 |
WP_PLUGIN_URL.'/'.FeedWordPress::path('feedwordpress-tiny.png')
|
675 |
);
|
676 |
|
677 |
+
do_action('feedwordpress_admin_menu_pre_feeds', $menu_cap, $settings_cap);
|
678 |
+
add_submenu_page(
|
679 |
+
$syndicationMenu, 'Syndicated Sites', 'Syndicated Sites',
|
680 |
+
$settings_cap, $syndicationMenu
|
681 |
+
);
|
682 |
+
|
683 |
do_action('feedwordpress_admin_menu_pre_feeds', $menu_cap, $settings_cap);
|
684 |
add_submenu_page(
|
685 |
$syndicationMenu, 'Syndicated Feeds & Updates', 'Feeds & Updates',
|
700 |
|
701 |
do_action('feedwordpress_admin_menu_pre_categories', $menu_cap, $settings_cap);
|
702 |
add_submenu_page(
|
703 |
+
$syndicationMenu, 'Categories & Tags', 'Categories & Tags',
|
704 |
$settings_cap, FeedWordPress::path('categories-page.php')
|
705 |
);
|
706 |
|
797 |
}
|
798 |
|
799 |
function feedwordpress_add_post_edit_controls () {
|
800 |
+
global $feedwordpress;
|
801 |
+
|
802 |
+
// Put in Manual Editing checkbox
|
803 |
add_meta_box('feedwordpress-post-controls', __('Syndication'), 'feedwordpress_post_edit_controls', 'post', 'side', 'high');
|
804 |
+
|
805 |
+
add_filter('user_can_richedit', array($feedwordpress, 'user_can_richedit'), 1000, 1);
|
806 |
+
|
807 |
if (FeedWordPress::diagnostic_on('syndicated_posts:static_meta_data')) :
|
808 |
$GLOBALS['inspectPostMeta'] = new InspectPostMeta;
|
809 |
endif;
|
903 |
);
|
904 |
|
905 |
var $feeds = NULL;
|
906 |
+
var $feedurls = NULL;
|
907 |
var $httpauth = NULL;
|
908 |
+
|
909 |
# function FeedWordPress (): Contructor; retrieve a list of feeds
|
910 |
function FeedWordPress () {
|
911 |
$this->feeds = array ();
|
912 |
+
$this->feedurls = array();
|
913 |
$links = FeedWordPress::syndicated_links();
|
914 |
if ($links): foreach ($links as $link):
|
915 |
+
$id = intval($link->link_id);
|
916 |
+
$url = $link->link_rss;
|
917 |
+
|
918 |
+
// Store for later reference.
|
919 |
+
$this->feeds[$id] = $id;
|
920 |
+
if (strlen($url) > 0) :
|
921 |
+
$this->feedurls[$url] = $id;
|
922 |
+
endif;
|
923 |
endforeach; endif;
|
924 |
+
|
925 |
$this->httpauth = new FeedWordPressHTTPAuthenticator;
|
926 |
} // FeedWordPress::FeedWordPress ()
|
927 |
|
928 |
+
function subscribed ($id) {
|
929 |
+
return (isset($this->feedurls[$id]) or isset($this->feeds[$id]));
|
930 |
+
} /* FeedWordPress::subscribed () */
|
931 |
+
|
932 |
+
function subscription ($which) {
|
933 |
+
$sub = NULL;
|
934 |
+
|
935 |
+
if (is_string($which) and isset($this->feedurls[$which])) :
|
936 |
+
$which = $this->feedurls[$which];
|
937 |
+
endif;
|
938 |
+
|
939 |
+
if (isset($this->feeds[$which])) :
|
940 |
+
$sub = $this->feeds[$which];
|
941 |
+
endif;
|
942 |
+
|
943 |
+
// Load 'er up if you haven't already.
|
944 |
+
if (!is_null($sub) and !($sub InstanceOf SyndicatedLink)) :
|
945 |
+
$link = new SyndicatedLink($sub);
|
946 |
+
$this->feeds[$which] = $link;
|
947 |
+
$sub = $link;
|
948 |
+
endif;
|
949 |
+
|
950 |
+
return $sub;
|
951 |
+
} /* FeedWordPress::subscriptions () */
|
952 |
+
|
953 |
# function update (): polls for updates on one or more Contributor feeds
|
954 |
#
|
955 |
# Arguments:
|
1026 |
endif;
|
1027 |
|
1028 |
// Randomize order for load balancing purposes
|
1029 |
+
$feed_set = array_keys($this->feeds);
|
1030 |
shuffle($feed_set);
|
1031 |
|
1032 |
$updateWindow = (int) get_option('feedwordpress_update_window', DEFAULT_UPDATE_PERIOD) * 60 /* sec/min */;
|
1041 |
), $uri);
|
1042 |
|
1043 |
$feed_set = apply_filters('feedwordpress_update_feeds', $feed_set, $uri);
|
1044 |
+
|
1045 |
+
|
1046 |
// Loop through and check for new posts
|
1047 |
$delta = NULL; $remaining = $max_polls;
|
1048 |
+
foreach ($feed_set as $feed_id) :
|
1049 |
+
|
1050 |
+
$feed = $this->subscription($feed_id);
|
1051 |
|
1052 |
// Has this process overstayed its welcome?
|
1053 |
if (
|
1200 |
return $ret;
|
1201 |
} // FeedWordPress::stale()
|
1202 |
|
1203 |
+
static function admin_init () {
|
1204 |
+
// WordPress 3.5+ compat: the WP devs are in the midst of removing Links from the WordPress core. Eventually we'll have to deal
|
1205 |
+
// with the possible disappearance of the wp_links table as a whole; but in the meantime, we just need to turn on the interface
|
1206 |
+
// element to avoid problems with user capabilities that presume the presence of the Links Manager in the admin UI.
|
1207 |
+
if (!intval(get_option('link_manager_enabled', false))) :
|
1208 |
+
update_option('link_manager_enabled', true);
|
1209 |
+
endif;
|
1210 |
+
} /* FeedWordPress::admin_init() */
|
1211 |
+
|
1212 |
function init () {
|
1213 |
global $fwp_path;
|
1214 |
|
1226 |
wp_enqueue_style('dashboard');
|
1227 |
wp_enqueue_style('feedwordpress-elements');
|
1228 |
|
1229 |
+
/*if (function_exists('wp_admin_css')) :
|
1230 |
wp_admin_css('css/dashboard');
|
1231 |
+
endif;*/
|
1232 |
endif;
|
1233 |
|
1234 |
+
// This is a special post status for hiding posts that have expired
|
1235 |
+
register_post_status('fwpretired', array(
|
1236 |
+
'label' => _x('Retired', 'post'),
|
1237 |
+
'label_count' => _n_noop('Retired <span class="count">(%s)</span>', 'Retired <span class="count">(%s)</span>'),
|
1238 |
+
'exclude_from_search' => true,
|
1239 |
+
'public' => false,
|
1240 |
+
'publicly_queryable' => false,
|
1241 |
+
'show_in_admin_all_list' => false,
|
1242 |
+
'show_in_admin_status_list' => true,
|
1243 |
+
));
|
1244 |
+
add_action(
|
1245 |
+
/*hook=*/ 'template_redirect',
|
1246 |
+
/*function=*/ array($this, 'redirect_retired'),
|
1247 |
+
/*priority=*/ -100
|
1248 |
+
);
|
1249 |
+
|
1250 |
$this->clear_cache_magic_url();
|
1251 |
$this->update_magic_url();
|
1252 |
} /* FeedWordPress::init() */
|
1253 |
|
1254 |
+
function redirect_retired () {
|
1255 |
+
global $wp_query;
|
1256 |
+
if (is_singular()) :
|
1257 |
+
if ('fwpretired'==$wp_query->post->post_status) :
|
1258 |
+
do_action('feedwordpress_redirect_retired', $wp_query->post);
|
1259 |
+
|
1260 |
+
if (!($template = get_404_template())) :
|
1261 |
+
$template = get_index_template();
|
1262 |
+
endif;
|
1263 |
+
if ($template = apply_filters('template_include', $template)) :
|
1264 |
+
header("HTTP/1.1 410 Gone");
|
1265 |
+
include($template);
|
1266 |
+
endif;
|
1267 |
+
exit;
|
1268 |
+
endif;
|
1269 |
+
endif;
|
1270 |
+
}
|
1271 |
+
|
1272 |
function dashboard_setup () {
|
1273 |
$see_it = FeedWordPress::menu_cap();
|
1274 |
|
1288 |
add_meta_box(
|
1289 |
/*id=*/ $widget_id,
|
1290 |
/*title=*/ $widget_name,
|
1291 |
+
/*callback=*/ array($this, 'dashboard'),
|
1292 |
/*page=*/ 'dashboard',
|
1293 |
/*context=*/ $column,
|
1294 |
/*priority=*/ $priority
|
1295 |
);
|
1296 |
+
/*control_callback= array($this, 'dashboard_control') */
|
1297 |
|
1298 |
// This is kind of rude, I know, but the dashboard widget isn't
|
1299 |
// worth much if users don't know that it exists, and I don't
|
1330 |
$syndicationPage->dashboard_box($syndicationPage);
|
1331 |
} /* FeedWordPress::dashboard () */
|
1332 |
|
1333 |
+
function user_can_richedit ($rich_edit) {
|
1334 |
+
|
1335 |
+
global $post;
|
1336 |
+
|
1337 |
+
if (is_syndicated($post->ID)) :
|
1338 |
+
// Disable visual editor and only allow operations
|
1339 |
+
// directly on HTML if post is syndicated.
|
1340 |
+
$rich_edit = false;
|
1341 |
+
endif;
|
1342 |
+
|
1343 |
+
return $rich_edit;
|
1344 |
+
|
1345 |
+
} /* FeedWordPress::user_can_richedit () */
|
1346 |
+
|
1347 |
function update_magic_url () {
|
1348 |
global $wpdb;
|
1349 |
|
1704 |
endif;
|
1705 |
$timeout = intval($timeout);
|
1706 |
|
1707 |
+
$pie_class = apply_filters('feedwordpress_simplepie_class', 'FeedWordPie');
|
1708 |
$cache_class = apply_filters('feedwordpress_cache_class', 'WP_Feed_Cache');
|
1709 |
$file_class = apply_filters('feedwordpress_file_class', 'FeedWordPress_File');
|
1710 |
$parser_class = apply_filters('feedwordpress_parser_class', 'FeedWordPress_Parser');
|
1711 |
+
$item_class = apply_filters('feedwordpress_item_class', 'FeedWordPie_Item');
|
1712 |
$sniffer_class = apply_filters('feedwordpress_sniffer_class', 'FeedWordPress_Content_Type_Sniffer');
|
1713 |
|
1714 |
$feed = new $pie_class;
|
1719 |
$feed->set_content_type_sniffer_class($sniffer_class);
|
1720 |
$feed->set_file_class($file_class);
|
1721 |
$feed->set_parser_class($parser_class);
|
1722 |
+
$feed->set_item_class($item_class);
|
1723 |
$feed->force_feed($force_feed);
|
1724 |
+
$feed->set_cache_duration(FeedWordPress::cache_duration($params));
|
1725 |
$feed->init();
|
1726 |
$feed->handle_content_type();
|
1727 |
|
1758 |
return ($magpies + $simplepies);
|
1759 |
} /* FeedWordPress::clear_cache () */
|
1760 |
|
1761 |
+
function cache_duration ($params = array()) {
|
1762 |
+
$params = wp_parse_args($params, array(
|
1763 |
+
"cache" => true,
|
1764 |
+
));
|
1765 |
+
|
1766 |
$duration = NULL;
|
1767 |
+
if (!$params['cache']) :
|
1768 |
+
$duration = 0;
|
1769 |
+
elseif (defined('FEEDWORDPRESS_CACHE_AGE')) :
|
1770 |
$duration = FEEDWORDPRESS_CACHE_AGE;
|
1771 |
endif;
|
1772 |
return $duration;
|
1867 |
error_log(FeedWordPress::log_prefix().' '.$out);
|
1868 |
break;
|
1869 |
case 'email' :
|
1870 |
+
|
1871 |
if (is_null($persist)) :
|
1872 |
$sect = 'occurrent';
|
1873 |
$hook = (isset($dlog['mesg'][$sect]) ? count($dlog['mesg'][$sect]) : 0);
|
1909 |
return $ret;
|
1910 |
}
|
1911 |
|
1912 |
+
function email_diagnostic_log ($params = array()) {
|
1913 |
+
$params = wp_parse_args($params, array(
|
1914 |
+
"force" => false,
|
1915 |
+
));
|
1916 |
+
|
1917 |
$dlog = get_option('feedwordpress_diagnostics_log', array());
|
1918 |
|
1919 |
if ($this->has_emailed_diagnostics($dlog)) :
|
1998 |
$recipients = FeedWordPressDiagnostic::admin_emails();
|
1999 |
endif;
|
2000 |
|
2001 |
+
$mesgId = 'feedwordpress+'.time().'@'.$home;
|
2002 |
+
$parentId = get_option('feedwordpress_diagnostics_email_root_message_id', NULL);
|
2003 |
+
|
2004 |
+
$head = array("Message-ID: <$mesgId>");
|
2005 |
+
if (!is_null($parentId)) :
|
2006 |
+
// We've already sent off a diagnostic message in the past. Let's do some
|
2007 |
+
// magic to help with threading, in the hopes that all diagnostic messages
|
2008 |
+
// get threaded together.
|
2009 |
+
$head[] = "References: <$parentId>";
|
2010 |
+
$head[] = "In-Reply-To: <$parentId>";
|
2011 |
+
$subj = "Re: ".$subj;
|
2012 |
+
else :
|
2013 |
+
// This is the first of its kind. Let's mark it as such.
|
2014 |
+
update_option('feedwordpress_diagnostics_email_root_message_id', $mesgId);
|
2015 |
+
endif;
|
2016 |
+
$head = apply_filters('feedwordpress_diagnostic_email_headers', $head);
|
2017 |
+
|
2018 |
foreach ($recipients as $email) :
|
2019 |
add_filter('wp_mail_content_type', array('FeedWordPress', 'allow_html_mail'));
|
2020 |
+
wp_mail($email, $subj, $body, $head);
|
2021 |
remove_filter('wp_mail_content_type', array('FeedWordPress', 'allow_html_mail'));
|
2022 |
endforeach;
|
2023 |
endif;
|
@@ -7,12 +7,20 @@ class FeedWordPress_File extends WP_SimplePie_File {
|
|
7 |
}
|
8 |
|
9 |
function __construct ($url, $timeout = 10, $redirects = 5, $headers = null, $useragent = null, $force_fsockopen = false) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
10 |
$this->url = $url;
|
11 |
$this->timeout = $timeout;
|
12 |
$this->redirects = $redirects;
|
13 |
$this->headers = $headers;
|
14 |
$this->useragent = $useragent;
|
15 |
-
|
16 |
$this->method = SIMPLEPIE_FILE_SOURCE_REMOTE;
|
17 |
|
18 |
global $wpdb;
|
@@ -24,8 +32,19 @@ class FeedWordPress_File extends WP_SimplePie_File {
|
|
24 |
if ( !empty($this->headers) )
|
25 |
$args['headers'] = $this->headers;
|
26 |
|
27 |
-
|
|
|
28 |
$args['user-agent'] = $this->useragent;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
29 |
|
30 |
// This is ugly as hell, but communicating up and down the chain
|
31 |
// in any other way is difficult.
|
@@ -36,21 +55,17 @@ class FeedWordPress_File extends WP_SimplePie_File {
|
|
36 |
$args['username'] = $fwp_credentials['username'];
|
37 |
$args['password'] = $fwp_credentials['password'];
|
38 |
|
39 |
-
|
40 |
-
|
41 |
-
$
|
42 |
-
|
43 |
-
);
|
44 |
-
if ($links) :
|
45 |
-
$source = new SyndicatedLink($links[0]);
|
46 |
-
$args['authentication'] = $source->authentication_method();
|
47 |
-
$args['username'] = $source->username();
|
48 |
-
$args['password'] = $source->password();
|
49 |
-
endif;
|
50 |
|
51 |
endif;
|
52 |
-
|
|
|
53 |
$res = wp_remote_request($url, $args);
|
|
|
54 |
|
55 |
if ( is_wp_error($res) ) {
|
56 |
$this->error = 'WP HTTP Error: ' . $res->get_error_message();
|
@@ -60,6 +75,13 @@ class FeedWordPress_File extends WP_SimplePie_File {
|
|
60 |
$this->body = wp_remote_retrieve_body( $res );
|
61 |
$this->status_code = wp_remote_retrieve_response_code( $res );
|
62 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
63 |
} else {
|
64 |
if ( ! $this->body = file_get_contents($url) ) {
|
65 |
$this->error = 'file_get_contents could not read the file';
|
7 |
}
|
8 |
|
9 |
function __construct ($url, $timeout = 10, $redirects = 5, $headers = null, $useragent = null, $force_fsockopen = false) {
|
10 |
+
global $feedwordpress;
|
11 |
+
global $wp_version;
|
12 |
+
|
13 |
+
$source = NULL;
|
14 |
+
if ($feedwordpress->subscribed($url)) :
|
15 |
+
$source = $feedwordpress->subscription($url);
|
16 |
+
endif;
|
17 |
+
|
18 |
$this->url = $url;
|
19 |
$this->timeout = $timeout;
|
20 |
$this->redirects = $redirects;
|
21 |
$this->headers = $headers;
|
22 |
$this->useragent = $useragent;
|
23 |
+
|
24 |
$this->method = SIMPLEPIE_FILE_SOURCE_REMOTE;
|
25 |
|
26 |
global $wpdb;
|
32 |
if ( !empty($this->headers) )
|
33 |
$args['headers'] = $this->headers;
|
34 |
|
35 |
+
// Use default FWP user agent unless custom has been specified
|
36 |
+
if ( SIMPLEPIE_USERAGENT != $this->useragent ) :
|
37 |
$args['user-agent'] = $this->useragent;
|
38 |
+
else :
|
39 |
+
$args['user-agent'] = apply_filters('feedwordpress_user_agent',
|
40 |
+
'FeedWordPress/'.FEEDWORDPRESS_VERSION
|
41 |
+
.' (aggregator:feedwordpress; WordPress/'.$wp_version
|
42 |
+
.' + '.SIMPLEPIE_NAME.'/'.SIMPLEPIE_VERSION
|
43 |
+
.'; Allow like Gecko; +http://feedwordpress.radgeek.com/) at '
|
44 |
+
. feedwordpress_display_url(get_bloginfo('url')),
|
45 |
+
$this
|
46 |
+
);
|
47 |
+
endif;
|
48 |
|
49 |
// This is ugly as hell, but communicating up and down the chain
|
50 |
// in any other way is difficult.
|
55 |
$args['username'] = $fwp_credentials['username'];
|
56 |
$args['password'] = $fwp_credentials['password'];
|
57 |
|
58 |
+
elseif ($source InstanceOf SyndicatedLink) :
|
59 |
+
|
60 |
+
$args['authentication'] = $source->authentication_method();
|
61 |
+
$args['username'] = $source->username();
|
62 |
+
$args['password'] = $source->password();
|
|
|
|
|
|
|
|
|
|
|
|
|
63 |
|
64 |
endif;
|
65 |
+
|
66 |
+
FeedWordPress::diagnostic('updated_feeds:http', "HTTP [$url] ⇜ ".esc_html(FeedWordPress::val($args)));
|
67 |
$res = wp_remote_request($url, $args);
|
68 |
+
FeedWordPress::diagnostic('updated_feeds:http', "HTTP [$url] ⇝ ".esc_html(FeedWordPress::val($res)));
|
69 |
|
70 |
if ( is_wp_error($res) ) {
|
71 |
$this->error = 'WP HTTP Error: ' . $res->get_error_message();
|
75 |
$this->body = wp_remote_retrieve_body( $res );
|
76 |
$this->status_code = wp_remote_retrieve_response_code( $res );
|
77 |
}
|
78 |
+
|
79 |
+
if ($source InstanceOf SyndicatedLink) :
|
80 |
+
$source->update_setting('link/filesize', strlen($this->body));
|
81 |
+
$source->update_setting('link/http status', $this->status_code);
|
82 |
+
$source->save_settings(/*reload=*/ true);
|
83 |
+
endif;
|
84 |
+
|
85 |
} else {
|
86 |
if ( ! $this->body = file_get_contents($url) ) {
|
87 |
$this->error = 'file_get_contents could not read the file';
|
@@ -1,6 +1,8 @@
|
|
1 |
<?php
|
2 |
class FeedWordPress_Parser extends SimplePie_Parser {
|
3 |
function parse (&$data, $encoding) {
|
|
|
|
|
4 |
// Use UTF-8 if we get passed US-ASCII, as every US-ASCII character is a UTF-8 character
|
5 |
if (strtoupper($encoding) === 'US-ASCII')
|
6 |
{
|
@@ -40,7 +42,7 @@ class FeedWordPress_Parser extends SimplePie_Parser {
|
|
40 |
|
41 |
if (substr($data, 0, 5) === '<?xml' && strspn(substr($data, 5, 1), "\x09\x0A\x0D\x20") && ($pos = strpos($data, '?>')) !== false)
|
42 |
{
|
43 |
-
$declaration
|
44 |
if ($declaration->parse())
|
45 |
{
|
46 |
$data = substr($data, $pos + 2);
|
@@ -78,8 +80,23 @@ class FeedWordPress_Parser extends SimplePie_Parser {
|
|
78 |
// Parse!
|
79 |
if (!xml_parse($xml, $data, true))
|
80 |
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
81 |
$this->error_code = xml_get_error_code($xml);
|
82 |
$this->error_string = xml_error_string($this->error_code);
|
|
|
83 |
$return = false;
|
84 |
}
|
85 |
|
@@ -93,7 +110,7 @@ class FeedWordPress_Parser extends SimplePie_Parser {
|
|
93 |
else
|
94 |
{
|
95 |
libxml_clear_errors();
|
96 |
-
$xml
|
97 |
$xml->xml($data);
|
98 |
while (@$xml->read())
|
99 |
{
|
1 |
<?php
|
2 |
class FeedWordPress_Parser extends SimplePie_Parser {
|
3 |
function parse (&$data, $encoding) {
|
4 |
+
$data = apply_filters('feedwordpress_parser_parse', $data, $encoding, $this);
|
5 |
+
|
6 |
// Use UTF-8 if we get passed US-ASCII, as every US-ASCII character is a UTF-8 character
|
7 |
if (strtoupper($encoding) === 'US-ASCII')
|
8 |
{
|
42 |
|
43 |
if (substr($data, 0, 5) === '<?xml' && strspn(substr($data, 5, 1), "\x09\x0A\x0D\x20") && ($pos = strpos($data, '?>')) !== false)
|
44 |
{
|
45 |
+
$declaration = new SimplePie_XML_Declaration_Parser(substr($data, 5, $pos - 5));
|
46 |
if ($declaration->parse())
|
47 |
{
|
48 |
$data = substr($data, $pos + 2);
|
80 |
// Parse!
|
81 |
if (!xml_parse($xml, $data, true))
|
82 |
{
|
83 |
+
if (class_exists('DOMDocument')) :
|
84 |
+
libxml_use_internal_errors(true);
|
85 |
+
$doc = new DOMDocument;
|
86 |
+
$doc->loadHTML('<html>'.$data.'</html>');
|
87 |
+
///*DBG*/ echo "<plaintext>";
|
88 |
+
///*DBG*/ $dd = $doc->getElementsByTagName('html');
|
89 |
+
///*DBG*/ for ($i = 0; $i < $dd->length; $i++) :
|
90 |
+
///*DBG*/ var_dump($dd->item($i)->nodeName);
|
91 |
+
///*DBG*/ endfor;
|
92 |
+
///*DBG*/ var_dump($doc);
|
93 |
+
libxml_use_internal_errors(false);
|
94 |
+
///*DBG*/ die;
|
95 |
+
endif;
|
96 |
+
|
97 |
$this->error_code = xml_get_error_code($xml);
|
98 |
$this->error_string = xml_error_string($this->error_code);
|
99 |
+
///*DBG*/ echo "WOOGA WOOGA"; var_dump($this->error_string); die;
|
100 |
$return = false;
|
101 |
}
|
102 |
|
110 |
else
|
111 |
{
|
112 |
libxml_clear_errors();
|
113 |
+
$xml = new XMLReader();
|
114 |
$xml->xml($data);
|
115 |
while (@$xml->read())
|
116 |
{
|
@@ -38,7 +38,7 @@ class FeedWordPressHTML {
|
|
38 |
);
|
39 |
} /* function FeedWordPressHTML::attributeMatch () */
|
40 |
|
41 |
-
function tagWithAttributeRegex ($tag, $attr, $value) {
|
42 |
return ":(
|
43 |
(<($tag)\s+[^>]*)
|
44 |
($attr)=
|
@@ -50,13 +50,14 @@ class FeedWordPressHTML {
|
|
50 |
|
|
51 |
\s*((?!/>)($value))
|
52 |
([^>]*>)
|
53 |
-
)
|
54 |
(((?!</($tag)>).)*)
|
55 |
(</($tag)>)
|
|
|
56 |
:ix";
|
57 |
} /* FeedWordPressHTML::tagWithAttributeRegex () */
|
58 |
|
59 |
-
function tagWithAttributeMatch ($matches) {
|
60 |
for ($i = 0; $i <= 21; $i++) :
|
61 |
if (!isset($matches[$i])) :
|
62 |
$matches[$i] = '';
|
@@ -77,8 +78,8 @@ class FeedWordPressHTML {
|
|
77 |
"before_attribute" => $matches[2],
|
78 |
"after_attribute" => $suffix,
|
79 |
"open_tag" => $matches[1].$matches[6].$value.$matches[6].$suffix,
|
80 |
-
"content" => $matches[17],
|
81 |
-
"close_tag" => $matches[20],
|
82 |
);
|
83 |
|
84 |
} /* FeedWordPressHTML::tagWithAttributeMatch () */
|
38 |
);
|
39 |
} /* function FeedWordPressHTML::attributeMatch () */
|
40 |
|
41 |
+
function tagWithAttributeRegex ($tag, $attr, $value, $closing = true) {
|
42 |
return ":(
|
43 |
(<($tag)\s+[^>]*)
|
44 |
($attr)=
|
50 |
|
|
51 |
\s*((?!/>)($value))
|
52 |
([^>]*>)
|
53 |
+
)".($closing ? "
|
54 |
(((?!</($tag)>).)*)
|
55 |
(</($tag)>)
|
56 |
+
" : "")."
|
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] = '';
|
78 |
"before_attribute" => $matches[2],
|
79 |
"after_attribute" => $suffix,
|
80 |
"open_tag" => $matches[1].$matches[6].$value.$matches[6].$suffix,
|
81 |
+
"content" => ($closing ? $matches[17] : NULL),
|
82 |
+
"close_tag" => ($closing ? $matches[20] : NULL),
|
83 |
);
|
84 |
|
85 |
} /* FeedWordPressHTML::tagWithAttributeMatch () */
|
@@ -2,18 +2,14 @@
|
|
2 |
class FeedWordPressHTTPAuthenticator {
|
3 |
var $args = array();
|
4 |
|
5 |
-
function FeedWordPressHTTPAuthenticator () {
|
6 |
-
self::__construct();
|
7 |
-
}
|
8 |
-
|
9 |
function __construct () {
|
10 |
-
add_filter('use_curl_transport', array(
|
11 |
foreach (array('fsockopen', 'fopen', 'streams', 'http_extension') as $transport) :
|
12 |
-
add_filter("use_{$transport}_transport", array(
|
13 |
endforeach;
|
14 |
|
15 |
-
add_filter('pre_http_request', array(
|
16 |
-
add_action('http_api_curl', array(
|
17 |
} /* FeedWordPressHTTPAuthenticator::__construct () */
|
18 |
|
19 |
function methods_available () {
|
@@ -45,70 +41,74 @@ class FeedWordPressHTTPAuthenticator {
|
|
45 |
));
|
46 |
|
47 |
// Ruh roh...
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
55 |
break;
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
// Wee ha!
|
66 |
-
$method = $this->args['authentication'];
|
67 |
-
$credentials = $this->args['username'];
|
68 |
-
if (!is_null($this->args['password'])) :
|
69 |
-
$credentials .= ':'.$args['password'];
|
70 |
-
endif;
|
71 |
-
|
72 |
-
// Remove these so we don't recurse all the way down
|
73 |
-
unset($this->args['authentication']);
|
74 |
-
unset($this->args['username']);
|
75 |
-
unset($this->args['password']);
|
76 |
-
|
77 |
-
$url = preg_replace('!(https?://)!', '$1'.$credentials.'@', $url);
|
78 |
-
|
79 |
-
// Subsidiary request
|
80 |
-
$pre = wp_remote_request($url, $this->args);
|
81 |
-
break;
|
82 |
-
endif;
|
83 |
-
case 'digest' :
|
84 |
-
if ($this->have_curl($args, $url)) :
|
85 |
-
// Don't need to do anything. http_api_curl hook takes care
|
86 |
-
// of it.
|
87 |
-
break;
|
88 |
-
endif;
|
89 |
-
default :
|
90 |
-
if (is_callable('WP_Http', '_get_first_available_transport')) :
|
91 |
-
$trans = WP_Http::_get_first_available_transport($args, $url);
|
92 |
-
if (!$trans) :
|
93 |
-
$trans = WP_Http::_get_first_available_transport(array(), $url);
|
94 |
-
endif;
|
95 |
-
elseif (is_callable('WP_Http', '_getTransport')) :
|
96 |
-
$transports = WP_Http::_getTransport($args);
|
97 |
-
$trans = get_class(reset($transports));
|
98 |
-
else :
|
99 |
-
$trans = 'HTTP';
|
100 |
endif;
|
101 |
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
112 |
return $pre;
|
113 |
} /* FeedWordPressHTTPAuthenticator::pre_http_request () */
|
114 |
|
2 |
class FeedWordPressHTTPAuthenticator {
|
3 |
var $args = array();
|
4 |
|
|
|
|
|
|
|
|
|
5 |
function __construct () {
|
6 |
+
add_filter('use_curl_transport', array($this, 'digest_do_it'), 2, 1000);
|
7 |
foreach (array('fsockopen', 'fopen', 'streams', 'http_extension') as $transport) :
|
8 |
+
add_filter("use_{$transport}_transport", array($this, 'digest_dont'), 2, 1000);
|
9 |
endforeach;
|
10 |
|
11 |
+
add_filter('pre_http_request', array($this, 'pre_http_request'), 10, 3);
|
12 |
+
add_action('http_api_curl', array($this, 'set_auth_options'), 1000, 1);
|
13 |
} /* FeedWordPressHTTPAuthenticator::__construct () */
|
14 |
|
15 |
function methods_available () {
|
41 |
));
|
42 |
|
43 |
// Ruh roh...
|
44 |
+
$auth = $this->args['authentication'];
|
45 |
+
if (is_null($auth) or (strlen($auth) == 0)) :
|
46 |
+
$this->args['authentication'] = '-';
|
47 |
+
endif;
|
48 |
+
|
49 |
+
switch ($this->args['authentication']) :
|
50 |
+
case '-' :
|
51 |
+
// No HTTP Auth method. Remove this stuff.
|
52 |
+
$this->args['authentication'] = NULL;
|
53 |
+
$this->args['username'] = NULL;
|
54 |
+
$this->args['password'] = NULL;
|
55 |
+
break;
|
56 |
+
case 'basic' :
|
57 |
+
if ($this->have_curl($args, $url)) :
|
58 |
+
// Don't need to do anything. http_api_curl hook takes care
|
59 |
+
// of it.
|
60 |
break;
|
61 |
+
elseif ($this->have_streams($args, $url)) :
|
62 |
+
// curl has a nice native way to jam in the username and
|
63 |
+
// passwd but streams and fsockopen do not. So we have to
|
64 |
+
// make a recursive call with the credentials in the URL.
|
65 |
+
// Wee ha!
|
66 |
+
$method = $this->args['authentication'];
|
67 |
+
$credentials = $this->args['username'];
|
68 |
+
if (!is_null($this->args['password'])) :
|
69 |
+
$credentials .= ':'.$args['password'];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
70 |
endif;
|
71 |
|
72 |
+
// Remove these so we don't recurse all the way down
|
73 |
+
unset($this->args['authentication']);
|
74 |
+
unset($this->args['username']);
|
75 |
+
unset($this->args['password']);
|
76 |
+
|
77 |
+
$url = preg_replace('!(https?://)!', '$1'.$credentials.'@', $url);
|
78 |
+
|
79 |
+
// Subsidiary request
|
80 |
+
$pre = wp_remote_request($url, $this->args);
|
81 |
+
break;
|
82 |
+
endif;
|
83 |
+
case 'digest' :
|
84 |
+
if ($this->have_curl($args, $url)) :
|
85 |
+
// Don't need to do anything. http_api_curl hook takes care
|
86 |
+
// of it.
|
87 |
+
break;
|
88 |
+
endif;
|
89 |
+
default :
|
90 |
+
if (is_callable('WP_Http', '_get_first_available_transport')) :
|
91 |
+
$trans = WP_Http::_get_first_available_transport($args, $url);
|
92 |
+
if (!$trans) :
|
93 |
+
$trans = WP_Http::_get_first_available_transport(array(), $url);
|
94 |
+
endif;
|
95 |
+
elseif (is_callable('WP_Http', '_getTransport')) :
|
96 |
+
$transports = WP_Http::_getTransport($args);
|
97 |
+
$trans = get_class(reset($transports));
|
98 |
+
else :
|
99 |
+
$trans = 'HTTP';
|
100 |
+
endif;
|
101 |
+
|
102 |
+
$pre = new WP_Error('http_request_failed',
|
103 |
+
sprintf(
|
104 |
+
__('%s cannot use %s authentication with the %s transport.'),
|
105 |
+
__CLASS__,
|
106 |
+
$args['authentication'],
|
107 |
+
$trans
|
108 |
+
)
|
109 |
+
);
|
110 |
+
endswitch;
|
111 |
+
|
112 |
return $pre;
|
113 |
} /* FeedWordPressHTTPAuthenticator::pre_http_request () */
|
114 |
|
@@ -0,0 +1,308 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
class FeedWordPressParsedPostMeta {
|
3 |
+
var $s, $ptr, $ptrEOS;
|
4 |
+
var $delims, $delimCount, $delimPtr;
|
5 |
+
var $paren;
|
6 |
+
|
7 |
+
var $parsed = NULL;
|
8 |
+
|
9 |
+
function __construct ($s) {
|
10 |
+
$this->s = $s;
|
11 |
+
$this->reset();
|
12 |
+
}
|
13 |
+
|
14 |
+
function reset () {
|
15 |
+
$this->parsed = NULL;
|
16 |
+
|
17 |
+
$this->ptr = 0;
|
18 |
+
$this->paren = 0;
|
19 |
+
$this->ptrEOS = strlen($this->s);
|
20 |
+
|
21 |
+
$this->delimCount['CDATA'] = preg_match_all('/\$/', $this->s, $this->delims['CDATA'], PREG_OFFSET_CAPTURE);
|
22 |
+
$this->delimPtr['CDATA'] = 0;
|
23 |
+
|
24 |
+
$this->delimCount['EXPR'] = preg_match_all('/[()\s]/', $this->s, $this->delims['EXPR'], PREG_OFFSET_CAPTURE);
|
25 |
+
$this->delimPtr['EXPR'] = 0;
|
26 |
+
}
|
27 |
+
|
28 |
+
function look () { return $this->s[$this->ptr]; }
|
29 |
+
function drop () { $this->anchor = $this->ptr; }
|
30 |
+
function take () { return substr($this->s, $this->anchor, ($this->ptr - $this->anchor)); }
|
31 |
+
function EOS () { return ($this->ptr >= $this->ptrEOS); }
|
32 |
+
|
33 |
+
function nextDelim ($which) {
|
34 |
+
$N = $this->delimCount[$which]; $ptr = $this->delimPtr[$which];
|
35 |
+
|
36 |
+
$next = -1;
|
37 |
+
while ( ($ptr < $N) and ($next < $this->ptr) ) :
|
38 |
+
$next = $this->delims[$which][0][$ptr][1];
|
39 |
+
$ptr++;
|
40 |
+
endwhile;
|
41 |
+
$this->delimPtr[$which] = $ptr;
|
42 |
+
|
43 |
+
if ($next < $this->ptr) :
|
44 |
+
$next = $this->ptrEOS;
|
45 |
+
endif;
|
46 |
+
return $next;
|
47 |
+
}
|
48 |
+
|
49 |
+
function substitute_terms ($post, $piece, $values = NULL) {
|
50 |
+
$terms = array();
|
51 |
+
if ('EXPR'==$piece[0]) :
|
52 |
+
// Parameter stored in $piece[1]
|
53 |
+
$param = $piece[1];
|
54 |
+
if (is_string($param)) :
|
55 |
+
if (!isset($values[$param])) :
|
56 |
+
$values[$param] = $post->query($param);
|
57 |
+
endif;
|
58 |
+
$term = $param;
|
59 |
+
$results = $values[$param];
|
60 |
+
else :
|
61 |
+
list($results, $term, $values) = $this->substitute_terms($post, $piece[1], $values);
|
62 |
+
endif;
|
63 |
+
|
64 |
+
// Filtering function, if any, stored in $piece[2]
|
65 |
+
if (isset($piece[2])) :
|
66 |
+
$filter = $post->substitution_function(trim(strtolower($piece[2])));
|
67 |
+
if (!is_null($filter)) :
|
68 |
+
foreach ($results as $key => $result) :
|
69 |
+
$results[$key] = $filter($result);
|
70 |
+
endforeach;
|
71 |
+
else :
|
72 |
+
$results = array(
|
73 |
+
"[[ERR: No such function (".$piece[2].")]]",
|
74 |
+
);
|
75 |
+
endif;
|
76 |
+
endif;
|
77 |
+
|
78 |
+
elseif ('CDATA'==$piece[0]) :
|
79 |
+
// Literal string stored in $piece[1]
|
80 |
+
$results = array($piece[1]);
|
81 |
+
$term = NULL;
|
82 |
+
endif;
|
83 |
+
return array($results, $term, $values);
|
84 |
+
}
|
85 |
+
|
86 |
+
function do_substitutions ($post, $in = NULL, $scratchpad = NULL) {
|
87 |
+
if (is_null($in)) :
|
88 |
+
$in = $this->get();
|
89 |
+
endif;
|
90 |
+
|
91 |
+
if (count($in) > 0) :
|
92 |
+
$out = array();
|
93 |
+
|
94 |
+
// Init. results set if not already initialized.
|
95 |
+
if (is_null($scratchpad)) :
|
96 |
+
$scratchpad = array(array('', array()));
|
97 |
+
endif;
|
98 |
+
|
99 |
+
// Grab the first
|
100 |
+
$piece = array_shift($in);
|
101 |
+
|
102 |
+
foreach ($scratchpad as $key => $scratch) :
|
103 |
+
$line = $scratch[0];
|
104 |
+
$element_values = $scratch[1];
|
105 |
+
|
106 |
+
switch ($piece[0]) :
|
107 |
+
case 'CDATA' :
|
108 |
+
$subs = array($piece[1]);
|
109 |
+
$term = NULL;
|
110 |
+
break;
|
111 |
+
case 'EXPR' :
|
112 |
+
list($subs, $term, $element_values) = $this->substitute_terms($post, $piece, $element_values);
|
113 |
+
break;
|
114 |
+
endswitch;
|
115 |
+
|
116 |
+
$constrained_values = $element_values;
|
117 |
+
foreach ($subs as $sub) :
|
118 |
+
|
119 |
+
if (isset($term)) :
|
120 |
+
$constrained_values[$term] = array($sub);
|
121 |
+
endif;
|
122 |
+
|
123 |
+
$out[] = array($line . $sub, $constrained_values);
|
124 |
+
endforeach;
|
125 |
+
|
126 |
+
endforeach;
|
127 |
+
|
128 |
+
if (count($in) > 0) :
|
129 |
+
$out = $this->do_substitutions($post, $in, $out);
|
130 |
+
endif;
|
131 |
+
else :
|
132 |
+
$out = NULL;
|
133 |
+
endif;
|
134 |
+
|
135 |
+
// Now that we are done, strip out the namespace elements.
|
136 |
+
if (is_array($out)) :
|
137 |
+
foreach ($out as $idx => $line) :
|
138 |
+
if (is_array($line)) :
|
139 |
+
$out[$idx] = $line[0];
|
140 |
+
endif;
|
141 |
+
endforeach;
|
142 |
+
endif;
|
143 |
+
|
144 |
+
return $out;
|
145 |
+
}
|
146 |
+
|
147 |
+
function get ($idx = NULL) {
|
148 |
+
$ret = $this->parse();
|
149 |
+
if ($idx) : $ret = $ret[$idx]; endif;
|
150 |
+
|
151 |
+
return $ret;
|
152 |
+
}
|
153 |
+
|
154 |
+
function parse () {
|
155 |
+
if (is_null($this->parsed)) :
|
156 |
+
$out = array();
|
157 |
+
|
158 |
+
$this->reset();
|
159 |
+
while (!$this->EOS()) :
|
160 |
+
switch ($this->look()) :
|
161 |
+
case '$' :
|
162 |
+
$this->ptr++;
|
163 |
+
$out[] = $this->EXPR();
|
164 |
+
break;
|
165 |
+
default :
|
166 |
+
$out[] = $this->CDATA();
|
167 |
+
endswitch;
|
168 |
+
endwhile;
|
169 |
+
|
170 |
+
$this->parsed = $out;
|
171 |
+
endif;
|
172 |
+
return $this->parsed;
|
173 |
+
}
|
174 |
+
|
175 |
+
function CDATA () {
|
176 |
+
$this->drop();
|
177 |
+
$this->ptr = $this->nextDelim('CDATA');
|
178 |
+
return array(__FUNCTION__, $this->take());
|
179 |
+
} /* FeedWordPressParsedPostMeta::CDATA() */
|
180 |
+
|
181 |
+
function EXPR () {
|
182 |
+
$ret = array(__FUNCTION__);
|
183 |
+
$paren0 = $this->paren;
|
184 |
+
$this->drop();
|
185 |
+
|
186 |
+
$ptr0 = $this->ptr;
|
187 |
+
|
188 |
+
$complete = false;
|
189 |
+
while (!$this->EOS() and !$complete) :
|
190 |
+
$tok = $this->look();
|
191 |
+
switch ($tok) :
|
192 |
+
case '(' :
|
193 |
+
|
194 |
+
$fun = $this->take();
|
195 |
+
|
196 |
+
// We're at the open paren; skip ahead past that.
|
197 |
+
$this->ptr++;
|
198 |
+
|
199 |
+
// And indent us one level in.
|
200 |
+
$this->paren++;
|
201 |
+
|
202 |
+
$delta = $this->EXPR();
|
203 |
+
if (isset($delta[2])) :
|
204 |
+
$ret[1] = $delta;
|
205 |
+
else :
|
206 |
+
$ret[1] = $delta[1];
|
207 |
+
endif;
|
208 |
+
|
209 |
+
if (strlen(trim($fun)) > 0) :
|
210 |
+
$ret[2] = trim($fun);
|
211 |
+
endif;
|
212 |
+
|
213 |
+
// We should be stopped on either a close paren or on EOS.
|
214 |
+
$this->ptr++;
|
215 |
+
|
216 |
+
// A top level expression terminates
|
217 |
+
// immediately with the closing of its
|
218 |
+
// parens. Lower-level expressions may
|
219 |
+
// have whitespace wrapper, etc.
|
220 |
+
$complete = ($this->paren <= 0);
|
221 |
+
|
222 |
+
$this->drop();
|
223 |
+
break;
|
224 |
+
|
225 |
+
case ')' :
|
226 |
+
|
227 |
+
if ($this->paren > 0) :
|
228 |
+
$this->paren--;
|
229 |
+
|
230 |
+
$complete = ($this->paren <= $paren0);
|
231 |
+
|
232 |
+
$fun = $this->take();
|
233 |
+
if (strlen(trim($fun)) > 0) :
|
234 |
+
$ret[1] = trim($fun);
|
235 |
+
endif;
|
236 |
+
|
237 |
+
$this->drop();
|
238 |
+
else :
|
239 |
+
$this->ptr++;
|
240 |
+
endif;
|
241 |
+
break;
|
242 |
+
|
243 |
+
case '$' :
|
244 |
+
if ($ptr0 == $this->ptr) :
|
245 |
+
// This is an escaped literal $
|
246 |
+
$this->ptr++;
|
247 |
+
$ret = array('CDATA', $tok);
|
248 |
+
$this->drop();
|
249 |
+
$complete = true;
|
250 |
+
break;
|
251 |
+
endif;
|
252 |
+
|
253 |
+
default :
|
254 |
+
if (ctype_space($tok) and ($this->paren <= 0)) :
|
255 |
+
// A loose $ should be treated as a literal $
|
256 |
+
if ($ptr0 == $this->ptr) :
|
257 |
+
$ret = array('CDATA', '$');
|
258 |
+
$this->drop();
|
259 |
+
endif;
|
260 |
+
$complete = true;
|
261 |
+
else :
|
262 |
+
$next = $this->nextDelim('EXPR');
|
263 |
+
|
264 |
+
// Skip ahead to the next potentially interesting character.
|
265 |
+
if (!is_null($next)) :
|
266 |
+
$this->ptr = $next;
|
267 |
+
else :
|
268 |
+
$this->ptr = $this->ptrEOS;
|
269 |
+
endif;
|
270 |
+
|
271 |
+
endif;
|
272 |
+
endswitch;
|
273 |
+
endwhile;
|
274 |
+
|
275 |
+
$var = '';
|
276 |
+
if ($this->anchor < $this->ptr) :
|
277 |
+
$var = trim($this->take());
|
278 |
+
endif;
|
279 |
+
if (strlen($var) > 0) :
|
280 |
+
$ret[1] = $var;
|
281 |
+
endif;
|
282 |
+
return $ret;
|
283 |
+
} /* FeedWordPressParsedPostMeta::EXPR () */
|
284 |
+
} /* class FeedWordPressParsedPostMeta */
|
285 |
+
|
286 |
+
if (basename($_SERVER['SCRIPT_FILENAME'])==basename(__FILE__)) :
|
287 |
+
$argv = $_SERVER['argv'];
|
288 |
+
array_shift($argv);
|
289 |
+
$N = reset($argv);
|
290 |
+
if (is_numeric($N)) :
|
291 |
+
array_shift($argv);
|
292 |
+
else :
|
293 |
+
$N = 1;
|
294 |
+
endif;
|
295 |
+
|
296 |
+
$t0 = microtime(/*float=*/ true);
|
297 |
+
for ($i = 0; $i < $N; $i++) :
|
298 |
+
$parse = new FeedWordPressParsedPostMeta(implode(" ", $argv));
|
299 |
+
$voo = ($parse->parse());
|
300 |
+
unset($parse);
|
301 |
+
endfor;
|
302 |
+
$t1 = microtime(/*float=*/ true);
|
303 |
+
|
304 |
+
echo "RESULT: "; var_dump($voo);
|
305 |
+
echo "ELAPSED TIME: "; print number_format(1000.0 * ($t1 - $t0)) . "ms\n";
|
306 |
+
echo "CONSUMED MEMORY: "; print number_format(memory_get_peak_usage() / 1024) . "KB\n";
|
307 |
+
endif;
|
308 |
+
|
@@ -5,15 +5,15 @@
|
|
5 |
|
6 |
class FeedWordPressRPC {
|
7 |
function FeedWordPressRPC () {
|
8 |
-
add_filter('xmlrpc_methods', array(
|
9 |
}
|
10 |
|
11 |
function xmlrpc_methods ($args = array()) {
|
12 |
-
$args['weblogUpdates.ping'] = array(
|
13 |
-
$args['feedwordpress.subscribe'] = array(
|
14 |
-
$args['feedwordpress.deactivate'] = array(
|
15 |
-
$args['feedwordpress.delete'] = array(
|
16 |
-
$args['feedwordpress.nuke'] = array(
|
17 |
return $args;
|
18 |
}
|
19 |
|
5 |
|
6 |
class FeedWordPressRPC {
|
7 |
function FeedWordPressRPC () {
|
8 |
+
add_filter('xmlrpc_methods', array($this, 'xmlrpc_methods'));
|
9 |
}
|
10 |
|
11 |
function xmlrpc_methods ($args = array()) {
|
12 |
+
$args['weblogUpdates.ping'] = array($this, 'ping');
|
13 |
+
$args['feedwordpress.subscribe'] = array($this, 'subscribe');
|
14 |
+
$args['feedwordpress.deactivate'] = array($this, 'deactivate');
|
15 |
+
$args['feedwordpress.delete'] = array($this, 'delete');
|
16 |
+
$args['feedwordpress.nuke'] = array($this, 'nuke');
|
17 |
return $args;
|
18 |
}
|
19 |
|
@@ -340,8 +340,6 @@ class FeedWordPressSyndicationPage extends FeedWordPressAdminPage {
|
|
340 |
return;
|
341 |
endif;
|
342 |
|
343 |
-
?>
|
344 |
-
<?php
|
345 |
$cont = true;
|
346 |
$dispatcher = array(
|
347 |
"feedfinder" => 'fwp_feedfinder_page',
|
@@ -352,8 +350,10 @@ class FeedWordPressSyndicationPage extends FeedWordPressAdminPage {
|
|
352 |
'Unsubscribe' => 'multidelete_page',
|
353 |
FWP_RESUB_CHECKED => 'multiundelete_page',
|
354 |
);
|
355 |
-
|
356 |
-
|
|
|
|
|
357 |
if (method_exists($this, $method)) :
|
358 |
$cont = $this->{$method}();
|
359 |
else :
|
@@ -384,7 +384,7 @@ class FeedWordPressSyndicationPage extends FeedWordPressAdminPage {
|
|
384 |
add_meta_box(
|
385 |
/*id=*/ 'feedwordpress_feeds_box',
|
386 |
/*title=*/ __('Syndicated sources'),
|
387 |
-
/*callback=*/ array(
|
388 |
/*page=*/ $this->meta_box_context(),
|
389 |
/*context =*/ $this->meta_box_context()
|
390 |
);
|
@@ -431,10 +431,11 @@ class FeedWordPressSyndicationPage extends FeedWordPressAdminPage {
|
|
431 |
|
432 |
// Hey ho, let's go...
|
433 |
?>
|
|
|
|
|
434 |
<p class="info" style="margin-bottom: 0px; border-bottom: 1px dotted black;">Managed by <a href="http://feedwordpress.radgeek.com/">FeedWordPress</a>
|
435 |
<?php print FEEDWORDPRESS_VERSION; ?>.</p>
|
436 |
<?php if (FEEDWORDPRESS_BLEG) : ?>
|
437 |
-
<div style="float: left; background: white; margin-top: 5px; margin-right: 5px;"><a href="<?php print $this->form_action(); ?>"><img src="<?php print esc_html(WP_PLUGIN_URL.'/'.$GLOBALS['fwp_path'].'/feedwordpress.png'); ?>" alt="" /></a></div>
|
438 |
<p class="info" style="margin-top: 0px; font-style: italic; font-size: 75%; color: #666;">If you find this tool useful for your daily work, you can
|
439 |
contribute to ongoing support and development with
|
440 |
<a href="http://feedwordpress.radgeek.com/donate/">a modest donation</a>.</p>
|
@@ -488,8 +489,8 @@ class FeedWordPressSyndicationPage extends FeedWordPressAdminPage {
|
|
488 |
value="Source URL" style="width: 55%;" /></label>
|
489 |
|
490 |
<?php FeedWordPressSettingsUI::magic_input_tip_js('add-uri'); ?>
|
491 |
-
|
492 |
-
<input style="vertical-align: middle;" type="image" src="<?php print WP_PLUGIN_URL.'/'.$fwp_path; ?>/plus.png" alt="<?php print FWP_SYNDICATE_NEW; ?>"
|
493 |
</form>
|
494 |
</div> <!-- id="add-single-uri" -->
|
495 |
|
@@ -1145,7 +1146,7 @@ updated to <<a href="<?php echo esc_html($fwp_post['feed']); ?>"><?php echo e
|
|
1145 |
|
1146 |
if (isset($existingLink)) :
|
1147 |
$auth = FeedWordPress::post('link_rss_auth_method');
|
1148 |
-
if (!is_null($auth) and $auth != '-') :
|
1149 |
$existingLink->update_setting('http auth method', $auth);
|
1150 |
$existingLink->update_setting('http username',
|
1151 |
FeedWordPress::post('link_rss_username')
|
340 |
return;
|
341 |
endif;
|
342 |
|
|
|
|
|
343 |
$cont = true;
|
344 |
$dispatcher = array(
|
345 |
"feedfinder" => 'fwp_feedfinder_page',
|
350 |
'Unsubscribe' => 'multidelete_page',
|
351 |
FWP_RESUB_CHECKED => 'multiundelete_page',
|
352 |
);
|
353 |
+
|
354 |
+
$act = FeedWordPress::param('action');
|
355 |
+
if (isset($dispatcher[$act])) :
|
356 |
+
$method = $dispatcher[$act];
|
357 |
if (method_exists($this, $method)) :
|
358 |
$cont = $this->{$method}();
|
359 |
else :
|
384 |
add_meta_box(
|
385 |
/*id=*/ 'feedwordpress_feeds_box',
|
386 |
/*title=*/ __('Syndicated sources'),
|
387 |
+
/*callback=*/ array($this, 'syndicated_sources_box'),
|
388 |
/*page=*/ $this->meta_box_context(),
|
389 |
/*context =*/ $this->meta_box_context()
|
390 |
);
|
431 |
|
432 |
// Hey ho, let's go...
|
433 |
?>
|
434 |
+
<div style="float: left; background: #F5F5F5; padding-top: 5px; padding-right: 5px;"><a href="<?php print $this->form_action(); ?>"><img src="<?php print esc_html(WP_PLUGIN_URL.'/'.$GLOBALS['fwp_path'].'/feedwordpress.png'); ?>" alt="" /></a></div>
|
435 |
+
|
436 |
<p class="info" style="margin-bottom: 0px; border-bottom: 1px dotted black;">Managed by <a href="http://feedwordpress.radgeek.com/">FeedWordPress</a>
|
437 |
<?php print FEEDWORDPRESS_VERSION; ?>.</p>
|
438 |
<?php if (FEEDWORDPRESS_BLEG) : ?>
|
|
|
439 |
<p class="info" style="margin-top: 0px; font-style: italic; font-size: 75%; color: #666;">If you find this tool useful for your daily work, you can
|
440 |
contribute to ongoing support and development with
|
441 |
<a href="http://feedwordpress.radgeek.com/donate/">a modest donation</a>.</p>
|
489 |
value="Source URL" style="width: 55%;" /></label>
|
490 |
|
491 |
<?php FeedWordPressSettingsUI::magic_input_tip_js('add-uri'); ?>
|
492 |
+
<input type="hidden" name="action" value="<?php print FWP_SYNDICATE_NEW; ?>" />
|
493 |
+
<input style="vertical-align: middle;" type="image" src="<?php print WP_PLUGIN_URL.'/'.$fwp_path; ?>/plus.png" alt="<?php print FWP_SYNDICATE_NEW; ?>" /></div>
|
494 |
</form>
|
495 |
</div> <!-- id="add-single-uri" -->
|
496 |
|
1146 |
|
1147 |
if (isset($existingLink)) :
|
1148 |
$auth = FeedWordPress::post('link_rss_auth_method');
|
1149 |
+
if (!is_null($auth) and (strlen($auth) > 0) and ($auth != '-')) :
|
1150 |
$existingLink->update_setting('http auth method', $auth);
|
1151 |
$existingLink->update_setting('http username',
|
1152 |
FeedWordPress::post('link_rss_username')
|
@@ -155,7 +155,8 @@ class MagpieFromSimplePie {
|
|
155 |
endforeach;
|
156 |
endforeach;
|
157 |
endforeach; endif;
|
158 |
-
|
|
|
159 |
} /* MagpieFromSimplePie::processFeedData() */
|
160 |
|
161 |
/**
|
@@ -183,7 +184,7 @@ class MagpieFromSimplePie {
|
|
183 |
+ $this->handleChildren($data, $path, 'processChannelData')
|
184 |
+ $ret;
|
185 |
|
186 |
-
return $ret;
|
187 |
} /* MagpieFromSimplePie::processChannelData() */
|
188 |
|
189 |
/**
|
@@ -213,7 +214,7 @@ class MagpieFromSimplePie {
|
|
213 |
+ $this->handleChildren($data, $path, 'processItemData')
|
214 |
+ $ret;
|
215 |
|
216 |
-
return $ret;
|
217 |
} /* MagpieFromSimplePie::processItemData() */
|
218 |
|
219 |
/**
|
@@ -250,7 +251,8 @@ class MagpieFromSimplePie {
|
|
250 |
endif;
|
251 |
endforeach;
|
252 |
endforeach; endif;
|
253 |
-
|
|
|
254 |
} /* MagpieFromSimplePie::handleAttributes() */
|
255 |
|
256 |
var $inImage = false;
|
@@ -346,7 +348,8 @@ class MagpieFromSimplePie {
|
|
346 |
endforeach; endforeach;
|
347 |
|
348 |
endforeach; endif;
|
349 |
-
|
|
|
350 |
} /* MagpieFromSimplePie::handleChildren() */
|
351 |
|
352 |
/**
|
@@ -386,6 +389,8 @@ class MagpieFromSimplePie {
|
|
386 |
* @uses FeedTime::timestamp
|
387 |
*/
|
388 |
function normalize () {
|
|
|
|
|
389 |
if (!is_null($this->channel)) :
|
390 |
// Normalize channel data
|
391 |
if ( $this->is_atom() ) :
|
@@ -497,6 +502,8 @@ class MagpieFromSimplePie {
|
|
497 |
$this->items[$i] = $item;
|
498 |
endfor;
|
499 |
endif;
|
|
|
|
|
500 |
} /* MagpieFromSimplePie::normalize() */
|
501 |
|
502 |
/**
|
155 |
endforeach;
|
156 |
endforeach;
|
157 |
endforeach; endif;
|
158 |
+
|
159 |
+
return apply_filters('feedwordpress_magpiefromsimplepie_processfeeddata', $ret, $data, $this);
|
160 |
} /* MagpieFromSimplePie::processFeedData() */
|
161 |
|
162 |
/**
|
184 |
+ $this->handleChildren($data, $path, 'processChannelData')
|
185 |
+ $ret;
|
186 |
|
187 |
+
return apply_filters('feedwordpress_magpiefromsimplepie_processchanneldata', $ret, $data, $path, $this);
|
188 |
} /* MagpieFromSimplePie::processChannelData() */
|
189 |
|
190 |
/**
|
214 |
+ $this->handleChildren($data, $path, 'processItemData')
|
215 |
+ $ret;
|
216 |
|
217 |
+
return apply_filters('feedwordpress_magpiefromsimplepie_processitemdata', $ret, $data, $path, $this);
|
218 |
} /* MagpieFromSimplePie::processItemData() */
|
219 |
|
220 |
/**
|
251 |
endif;
|
252 |
endforeach;
|
253 |
endforeach; endif;
|
254 |
+
|
255 |
+
return apply_filters('feedwordpress_magpiefromsimplepie_handleattributes', $ret, $data, $path, $this);
|
256 |
} /* MagpieFromSimplePie::handleAttributes() */
|
257 |
|
258 |
var $inImage = false;
|
348 |
endforeach; endforeach;
|
349 |
|
350 |
endforeach; endif;
|
351 |
+
|
352 |
+
return apply_filters('feedwordpress_magpiefromsimplepie_handlechildren', $ret, $data, $path, $method, $this);
|
353 |
} /* MagpieFromSimplePie::handleChildren() */
|
354 |
|
355 |
/**
|
389 |
* @uses FeedTime::timestamp
|
390 |
*/
|
391 |
function normalize () {
|
392 |
+
do_action('feedwordpress_magpiefromsimplepie_normalize_pre', $this);
|
393 |
+
|
394 |
if (!is_null($this->channel)) :
|
395 |
// Normalize channel data
|
396 |
if ( $this->is_atom() ) :
|
502 |
$this->items[$i] = $item;
|
503 |
endfor;
|
504 |
endif;
|
505 |
+
|
506 |
+
do_action('feedwordpress_magpiefromsimplepie_normalize_post', $this);
|
507 |
} /* MagpieFromSimplePie::normalize() */
|
508 |
|
509 |
/**
|
@@ -79,9 +79,19 @@ 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 |
} /* FeedWordPressPerformancePage::accept_POST () */
|
83 |
|
84 |
/*static*/ function performance_box ($page, $box = NULL) {
|
|
|
|
|
85 |
// Hey ho, let's go...
|
86 |
?>
|
87 |
<table class="editform" width="100%" cellspacing="2" cellpadding="5">
|
@@ -106,6 +116,34 @@ table. If you'd like to remove the index for any reason, you can do so here.</p>
|
|
106 |
|
107 |
<?php endif; ?>
|
108 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
109 |
|
110 |
</td>
|
111 |
</tr>
|
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 |
/*static*/ function performance_box ($page, $box = NULL) {
|
93 |
+
$optimize_in = get_option('feedwordpress_optimize_in_clauses', false);
|
94 |
+
|
95 |
// Hey ho, let's go...
|
96 |
?>
|
97 |
<table class="editform" width="100%" cellspacing="2" cellpadding="5">
|
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>
|
149 |
</tr>
|
@@ -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,6 +94,53 @@ outs, see the documentation at the [FeedWordPress project homepage][].
|
|
94 |
|
95 |
== Changelog ==
|
96 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
97 |
= 2011.1019 =
|
98 |
|
99 |
* BUGFIX: "THERE ARE NO HTTP TRANSPORTS AVAILABLE" ERROR FIXED: The initial
|
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.5
|
7 |
+
Stable tag: 2012.1212
|
8 |
|
9 |
FeedWordPress syndicates content from feeds you choose into your WordPress weblog.
|
10 |
|
94 |
|
95 |
== Changelog ==
|
96 |
|
97 |
+
= 2012.1212 =
|
98 |
+
|
99 |
+
* WORDPRESS 3.5 COMPATIBILITY: This release has been tested for compatibility
|
100 |
+
with new releases of WordPress, up to version 3.5, and any documented
|
101 |
+
compatibility issues have been cleared -- in particular, if you were seeing
|
102 |
+
error pages stating that you don't have permission to access the
|
103 |
+
FeedWordPress Syndication page within the WordPress admin interface, then
|
104 |
+
upgrading to this release should fix the problem.
|
105 |
+
|
106 |
+
As always, if you encounter any compatibility problems after upgrading your
|
107 |
+
version of WordPress and your version of FeedWordPress to the most recent
|
108 |
+
versions, please contact me with as detailed a description as possible of
|
109 |
+
the issue you are encountering, the circumstances you're encountering it
|
110 |
+
under, what you expect to see happening, and what is happening instead.
|
111 |
+
|
112 |
+
* PHP 5.4 COMPATIBILITY: This release has been audited to fix potential
|
113 |
+
problems with deprecation notices or fatal errors under recent versions
|
114 |
+
of PHP. In particular, all uses of run-time pass-by-reference have been
|
115 |
+
eliminated from the code; if you were seeing a fatal error reading
|
116 |
+
"Call-time pass-by-reference has been removed ..." then upgrading to
|
117 |
+
this release should fix the problem.
|
118 |
+
|
119 |
+
* CUSTOMIZATION FRAMEWORK: A great deal of work has been done to make the
|
120 |
+
underlying framework more flexible, so that PHP add-ons can be written
|
121 |
+
to adapt FeedWordPress to handle custom XML vocabularies, expiration of
|
122 |
+
posts under specified conditions, and other custom behavior.
|
123 |
+
|
124 |
+
* BUGFIX: MANUALLY EDITED POST SLUGS NOT OVERWRITTEN. Thanks to a report
|
125 |
+
by Chris Fritz, I've identified some code that causes post slugs for the
|
126 |
+
posts generated by FWP to be rewritten with every update, even if the
|
127 |
+
user has manually updated the slug from within the WordPress editing
|
128 |
+
interface. This has been fixed: FWP will continue to generate new slugs
|
129 |
+
for syndicated posts, but when syndicated posts are updated, they will
|
130 |
+
retain the slug that they had at the time of the update; any manual
|
131 |
+
changes to the post slug should be preserved.
|
132 |
+
|
133 |
+
* USER-AGENT STRING: FeedWordPress now sends a distinctive User-Agent
|
134 |
+
string identifying itself, and noting that it is a feed aggregator.
|
135 |
+
|
136 |
+
* MISCELLANEOUS PERFORMANCE IMPROVEMENTS: A number of changes have been
|
137 |
+
made to try to reduce the intensity and expense in terms of both
|
138 |
+
database performance and web server memory consumption.
|
139 |
+
|
140 |
+
* DIAGNOSTICS IMPROVEMENTS: A number of new and improved diagnostics have
|
141 |
+
been added which should aid in understanding and troubleshooting issues
|
142 |
+
that may arise.
|
143 |
+
|
144 |
= 2011.1019 =
|
145 |
|
146 |
* BUGFIX: "THERE ARE NO HTTP TRANSPORTS AVAILABLE" ERROR FIXED: The initial
|
@@ -34,6 +34,7 @@
|
|
34 |
# the function `get_feed_meta($key)` if this plugin is activated.
|
35 |
|
36 |
require_once(dirname(__FILE__).'/magpiefromsimplepie.class.php');
|
|
|
37 |
|
38 |
class SyndicatedLink {
|
39 |
var $id = null;
|
@@ -49,121 +50,25 @@ class SyndicatedLink {
|
|
49 |
$this->link = $link;
|
50 |
$this->id = $link->link_id;
|
51 |
else :
|
52 |
-
$this->id = $link;
|
53 |
-
|
54 |
-
$this->link = get_bookmark($link);
|
55 |
-
else :
|
56 |
-
$this->link = $wpdb->get_row("
|
57 |
-
SELECT * FROM $wpdb->links
|
58 |
-
WHERE (link_id = '".$wpdb->escape($link)."')"
|
59 |
-
);
|
60 |
-
endif;
|
61 |
endif;
|
62 |
|
63 |
if (strlen($this->link->link_rss) > 0) :
|
64 |
-
|
65 |
-
$notes = explode("\n", $this->link->link_notes);
|
66 |
-
foreach ($notes as $note):
|
67 |
-
$pair = explode(": ", $note, 2);
|
68 |
-
$key = (isset($pair[0]) ? $pair[0] : null);
|
69 |
-
$value = (isset($pair[1]) ? $pair[1] : null);
|
70 |
-
if (!is_null($key) and !is_null($value)) :
|
71 |
-
// Unescape and trim() off the whitespace.
|
72 |
-
// Thanks to Ray Lischner for pointing out the
|
73 |
-
// need to trim off whitespace.
|
74 |
-
$this->settings[$key] = stripcslashes (trim($value));
|
75 |
-
endif;
|
76 |
-
endforeach;
|
77 |
-
|
78 |
-
// "Magic" feed settings
|
79 |
-
$this->settings['link/uri'] = $this->link->link_rss;
|
80 |
-
$this->settings['link/name'] = $this->link->link_name;
|
81 |
-
$this->settings['link/id'] = $this->link->link_id;
|
82 |
-
|
83 |
-
// `hardcode categories` and `unfamiliar categories` are deprecated in favor of `unfamiliar category`
|
84 |
-
if (
|
85 |
-
isset($this->settings['unfamiliar categories'])
|
86 |
-
and !isset($this->settings['unfamiliar category'])
|
87 |
-
) :
|
88 |
-
$this->settings['unfamiliar category'] = $this->settings['unfamiliar categories'];
|
89 |
-
endif;
|
90 |
-
if (
|
91 |
-
FeedWordPress::affirmative($this->settings, 'hardcode categories')
|
92 |
-
and !isset($this->settings['unfamiliar category'])
|
93 |
-
) :
|
94 |
-
$this->settings['unfamiliar category'] = 'default';
|
95 |
-
endif;
|
96 |
-
|
97 |
-
// Set this up automagically for del.icio.us
|
98 |
-
$bits = parse_url($this->link->link_rss);
|
99 |
-
$tagspacers = array('del.icio.us', 'feeds.delicious.com');
|
100 |
-
if (!isset($this->settings['cat_split']) and in_array($bits['host'], $tagspacers)) :
|
101 |
-
$this->settings['cat_split'] = '\s'; // Whitespace separates multiple tags in del.icio.us RSS feeds
|
102 |
-
endif;
|
103 |
-
|
104 |
-
// Simple lists
|
105 |
-
foreach ($this->imploded_settings() as $what) :
|
106 |
-
if (isset($this->settings[$what])):
|
107 |
-
$this->settings[$what] = explode(
|
108 |
-
FEEDWORDPRESS_CAT_SEPARATOR,
|
109 |
-
$this->settings[$what]
|
110 |
-
);
|
111 |
-
endif;
|
112 |
-
endforeach;
|
113 |
-
|
114 |
-
if (isset($this->settings['terms'])) :
|
115 |
-
// Look for new format
|
116 |
-
$this->settings['terms'] = maybe_unserialize($this->settings['terms']);
|
117 |
-
|
118 |
-
if (!is_array($this->settings['terms'])) :
|
119 |
-
// Deal with old format instead. Ugh.
|
120 |
-
|
121 |
-
// Split on two *or more* consecutive breaks
|
122 |
-
// because in the old format, a taxonomy
|
123 |
-
// without any associated terms would
|
124 |
-
// produce tax_name#1\n\n\ntax_name#2\nterm,
|
125 |
-
// and the naive split on the first \n\n
|
126 |
-
// would screw up the tax_name#2 list.
|
127 |
-
//
|
128 |
-
// Props to David Morris for pointing this
|
129 |
-
// out.
|
130 |
-
|
131 |
-
$this->settings['terms'] = preg_split(
|
132 |
-
"/".FEEDWORDPRESS_CAT_SEPARATOR."{2,}/",
|
133 |
-
$this->settings['terms']
|
134 |
-
);
|
135 |
-
$terms = array();
|
136 |
-
foreach ($this->settings['terms'] as $line) :
|
137 |
-
$line = explode(FEEDWORDPRESS_CAT_SEPARATOR, $line);
|
138 |
-
$tax = array_shift($line);
|
139 |
-
$terms[$tax] = $line;
|
140 |
-
endforeach;
|
141 |
-
$this->settings['terms'] = $terms;
|
142 |
-
endif;
|
143 |
-
endif;
|
144 |
-
|
145 |
-
if (isset($this->settings['map authors'])) :
|
146 |
-
$author_rules = explode("\n\n", $this->settings['map authors']);
|
147 |
-
$ma = array();
|
148 |
-
foreach ($author_rules as $rule) :
|
149 |
-
list($rule_type, $author_name, $author_action) = explode("\n", $rule);
|
150 |
-
|
151 |
-
// Normalize for case and whitespace
|
152 |
-
$rule_type = strtolower(trim($rule_type));
|
153 |
-
$author_name = strtolower(trim($author_name));
|
154 |
-
$author_action = strtolower(trim($author_action));
|
155 |
-
|
156 |
-
$ma[$rule_type][$author_name] = $author_action;
|
157 |
-
endforeach;
|
158 |
-
$this->settings['map authors'] = $ma;
|
159 |
-
endif;
|
160 |
endif;
|
|
|
|
|
161 |
} /* SyndicatedLink::SyndicatedLink () */
|
162 |
|
163 |
function found () {
|
164 |
return is_object($this->link) and !is_wp_error($this->link);
|
165 |
} /* SyndicatedLink::found () */
|
166 |
|
|
|
|
|
|
|
|
|
167 |
function stale () {
|
168 |
global $feedwordpress;
|
169 |
|
@@ -197,10 +102,10 @@ class SyndicatedLink {
|
|
197 |
|
198 |
$this->simplepie = apply_filters(
|
199 |
'syndicated_feed',
|
200 |
-
FeedWordPress::fetch($
|
201 |
$this
|
202 |
);
|
203 |
-
|
204 |
// Filter compatibility mode
|
205 |
if (is_wp_error($this->simplepie)) :
|
206 |
$this->magpie = $this->simplepie;
|
@@ -210,10 +115,10 @@ class SyndicatedLink {
|
|
210 |
|
211 |
$new_count = NULL;
|
212 |
|
213 |
-
$resume =
|
214 |
if ($resume) :
|
215 |
// pick up where we left off
|
216 |
-
$processed = array_map('trim', explode("\n", $this->
|
217 |
else :
|
218 |
// begin at the beginning
|
219 |
$processed = array();
|
@@ -236,26 +141,25 @@ class SyndicatedLink {
|
|
236 |
// Copy over the in-error-since timestamp
|
237 |
$theError['since'] = $oldError['since'];
|
238 |
|
239 |
-
// If this is a repeat error, then we should
|
240 |
-
// a step back before we try to fetch it
|
241 |
-
|
242 |
-
$this->
|
243 |
-
$
|
244 |
-
$
|
245 |
-
|
246 |
-
$this->
|
|
|
247 |
endif;
|
248 |
|
249 |
do_action('syndicated_feed_error', $theError, $oldError, $this);
|
250 |
|
251 |
-
$this->
|
252 |
$this->save_settings(/*reload=*/ true);
|
253 |
|
254 |
elseif (is_object($this->simplepie)) :
|
255 |
// Success; clear out error setting, if any.
|
256 |
-
|
257 |
-
unset($this->settings['update/error']);
|
258 |
-
endif;
|
259 |
|
260 |
$new_count = array('new' => 0, 'updated' => 0);
|
261 |
|
@@ -282,30 +186,34 @@ class SyndicatedLink {
|
|
282 |
$update[] = "link_description = '".$wpdb->escape($channel['description'])."'";
|
283 |
endif;
|
284 |
endif;
|
285 |
-
|
286 |
-
$this->settings = array_merge($this->settings, $this->flatten_array($channel));
|
287 |
|
288 |
-
$this->
|
|
|
|
|
289 |
list($ttl, $xml) = $this->ttl(/*return element=*/ true);
|
290 |
|
291 |
if (!is_null($ttl)) :
|
292 |
-
$this->
|
293 |
-
$this->
|
294 |
-
$this->
|
295 |
else :
|
296 |
$ttl = $this->automatic_ttl();
|
297 |
-
$this->
|
298 |
-
$this->
|
299 |
-
$this->
|
300 |
endif;
|
301 |
-
$this->
|
302 |
-
$this->
|
|
|
|
|
|
|
|
|
303 |
|
304 |
if (!$this->setting('update/hold') != 'ping') :
|
305 |
-
$this->
|
306 |
endif;
|
307 |
|
308 |
-
$this->
|
309 |
|
310 |
$update[] = "link_notes = '".$wpdb->escape($this->settings_to_notes())."'";
|
311 |
|
@@ -325,11 +233,26 @@ class SyndicatedLink {
|
|
325 |
$posts = apply_filters(
|
326 |
'syndicated_feed_items',
|
327 |
$this->simplepie->get_items(),
|
328 |
-
|
329 |
);
|
330 |
|
331 |
$this->magpie->originals = $posts;
|
332 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
333 |
if (is_array($posts)) :
|
334 |
foreach ($posts as $key => $item) :
|
335 |
$post = new SyndicatedPost($item, $this);
|
@@ -349,18 +272,51 @@ class SyndicatedLink {
|
|
349 |
unset($post);
|
350 |
endforeach;
|
351 |
endif;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
352 |
$suffix = ($crashed ? 'crashed' : 'completed');
|
353 |
do_action('update_syndicated_feed_items', $this->id, $this);
|
354 |
do_action("update_syndicated_feed_items_${suffix}", $this->id, $this);
|
355 |
|
356 |
-
|
357 |
-
$to_notes = $this->settings;
|
358 |
-
|
359 |
-
$this->settings['update/processed'] = $processed;
|
360 |
if (!$crashed) :
|
361 |
-
$this->
|
362 |
endif;
|
|
|
363 |
|
|
|
|
|
364 |
$update_set = "link_notes = '".$wpdb->escape($this->settings_to_notes())."'";
|
365 |
|
366 |
// Update the properties of the link from the feed information
|
@@ -386,6 +342,28 @@ class SyndicatedLink {
|
|
386 |
return $new_count;
|
387 |
} /* SyndicatedLink::poll() */
|
388 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
389 |
/**
|
390 |
* Updates the URL for the feed syndicated by this link.
|
391 |
*
|
@@ -466,9 +444,11 @@ class SyndicatedLink {
|
|
466 |
$newuser_id = fwp_insert_new_user($newuser_name);
|
467 |
if (is_numeric($newuser_id)) :
|
468 |
if (is_null($name)) : // Unfamiliar author
|
469 |
-
$this->
|
470 |
else :
|
471 |
-
$this->
|
|
|
|
|
472 |
endif;
|
473 |
else :
|
474 |
// TODO: Add some error detection and reporting
|
@@ -481,6 +461,108 @@ class SyndicatedLink {
|
|
481 |
function imploded_settings () {
|
482 |
return array('cats', 'tags', 'match/cats', 'match/tags', 'match/filter');
|
483 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
484 |
function settings_to_notes () {
|
485 |
$to_notes = $this->settings;
|
486 |
|
@@ -593,6 +675,11 @@ class SyndicatedLink {
|
|
593 |
return $ret;
|
594 |
} /* SyndicatedLink::setting () */
|
595 |
|
|
|
|
|
|
|
|
|
|
|
596 |
function update_setting ($name, $value, $default = 'default') {
|
597 |
if (!is_null($value) and $value != $default) :
|
598 |
$this->settings[$name] = $value;
|
@@ -601,10 +688,14 @@ class SyndicatedLink {
|
|
601 |
endif;
|
602 |
} /* SyndicatedLink::update_setting () */
|
603 |
|
|
|
|
|
|
|
|
|
604 |
function uri ($params = array()) {
|
605 |
-
$params =
|
606 |
'add_params' => false,
|
607 |
-
)
|
608 |
|
609 |
$uri = (is_object($this->link) ? $this->link->link_rss : NULL);
|
610 |
if (!is_null($uri) and strlen($uri) > 0 and $params['add_params']) :
|
@@ -620,11 +711,11 @@ class SyndicatedLink {
|
|
620 |
endforeach;
|
621 |
|
622 |
// Are we appending to a URI that already has params?
|
623 |
-
$sep = ((strpos(
|
624 |
|
625 |
// Tack it on
|
626 |
$uri .= $sep . implode("&", $q);
|
627 |
-
endif;
|
628 |
endif;
|
629 |
|
630 |
return $uri;
|
@@ -645,15 +736,61 @@ class SyndicatedLink {
|
|
645 |
endif;
|
646 |
return $auth;
|
647 |
} /* SyndicatedLink::authentication_method () */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
648 |
|
649 |
-
function property_cascade ($fromFeed, $link_field, $setting, $
|
650 |
$value = NULL;
|
651 |
if ($fromFeed) :
|
652 |
-
|
653 |
-
|
654 |
-
|
655 |
-
and method_exists($
|
656 |
-
|
|
|
657 |
endif;
|
658 |
else :
|
659 |
$value = $this->link->{$link_field};
|
@@ -789,17 +926,13 @@ class SyndicatedLink {
|
|
789 |
} /* SyndicatedLink::flatten_array () */
|
790 |
|
791 |
function hardcode ($what) {
|
792 |
-
|
793 |
-
|
794 |
-
|
795 |
-
|
796 |
-
|
797 |
-
$ret = !FeedWordPress::negative($this->settings, "hardcode $what");
|
798 |
else :
|
799 |
-
|
800 |
-
// affirmative(): FALSE by default and TRUE if the
|
801 |
-
// setting is explicitly "yes"
|
802 |
-
$ret = FeedWordPress::affirmative($this->settings, "hardcode $what");
|
803 |
endif;
|
804 |
return $ret;
|
805 |
} /* SyndicatedLink::hardcode () */
|
@@ -807,19 +940,8 @@ class SyndicatedLink {
|
|
807 |
function syndicated_status ($what, $default, $fallback = true) {
|
808 |
global $wpdb;
|
809 |
|
810 |
-
|
811 |
-
|
812 |
-
$ret = $this->settings["$what status"];
|
813 |
-
|
814 |
-
// Or fall back to global default if we can
|
815 |
-
elseif ($fallback) :
|
816 |
-
$ret = FeedWordPress::syndicated_status($what, $default);
|
817 |
-
|
818 |
-
// Or use default value if we can't.
|
819 |
-
else :
|
820 |
-
$ret = $default;
|
821 |
-
|
822 |
-
endif;
|
823 |
|
824 |
return $wpdb->escape(trim(strtolower($ret)));
|
825 |
} /* SyndicatedLink:syndicated_status () */
|
34 |
# the function `get_feed_meta($key)` if this plugin is activated.
|
35 |
|
36 |
require_once(dirname(__FILE__).'/magpiefromsimplepie.class.php');
|
37 |
+
require_once(dirname(__FILE__).'/feedwordpressparsedpostmeta.class.php');
|
38 |
|
39 |
class SyndicatedLink {
|
40 |
var $id = null;
|
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 () */
|
67 |
|
68 |
+
function id () {
|
69 |
+
return (is_object($this->link) ? $this->link->link_id : NULL);
|
70 |
+
}
|
71 |
+
|
72 |
function stale () {
|
73 |
global $feedwordpress;
|
74 |
|
102 |
|
103 |
$this->simplepie = apply_filters(
|
104 |
'syndicated_feed',
|
105 |
+
FeedWordPress::fetch($this, array('timeout' => $timeout)),
|
106 |
$this
|
107 |
);
|
108 |
+
|
109 |
// Filter compatibility mode
|
110 |
if (is_wp_error($this->simplepie)) :
|
111 |
$this->magpie = $this->simplepie;
|
115 |
|
116 |
$new_count = NULL;
|
117 |
|
118 |
+
$resume = ('yes'==$this->setting('update/unfinished'));
|
119 |
if ($resume) :
|
120 |
// pick up where we left off
|
121 |
+
$processed = array_map('trim', explode("\n", $this->setting('update/processed')));
|
122 |
else :
|
123 |
// begin at the beginning
|
124 |
$processed = array();
|
141 |
// Copy over the in-error-since timestamp
|
142 |
$theError['since'] = $oldError['since'];
|
143 |
|
144 |
+
// If this is a repeat error, then we should
|
145 |
+
// take a step back before we try to fetch it
|
146 |
+
// again.
|
147 |
+
$this->update_setting('update/last', time(), NULL);
|
148 |
+
$ttl = $this->automatic_ttl();
|
149 |
+
$ttl = apply_filters('syndicated_feed_ttl', $ttl, $this);
|
150 |
+
$ttl = apply_filters('syndicated_feed_ttl_from_error', $ttl, $this);
|
151 |
+
$this->update_setting('update/ttl', $ttl, $this);
|
152 |
+
$this->update_setting('update/timed', 'automatically');
|
153 |
endif;
|
154 |
|
155 |
do_action('syndicated_feed_error', $theError, $oldError, $this);
|
156 |
|
157 |
+
$this->update_setting('update/error', serialize($theError));
|
158 |
$this->save_settings(/*reload=*/ true);
|
159 |
|
160 |
elseif (is_object($this->simplepie)) :
|
161 |
// Success; clear out error setting, if any.
|
162 |
+
$this->update_setting('update/error', NULL);
|
|
|
|
|
163 |
|
164 |
$new_count = array('new' => 0, 'updated' => 0);
|
165 |
|
186 |
$update[] = "link_description = '".$wpdb->escape($channel['description'])."'";
|
187 |
endif;
|
188 |
endif;
|
|
|
|
|
189 |
|
190 |
+
$this->merge_settings($channel, 'feed/');
|
191 |
+
|
192 |
+
$this->update_setting('update/last', time());
|
193 |
list($ttl, $xml) = $this->ttl(/*return element=*/ true);
|
194 |
|
195 |
if (!is_null($ttl)) :
|
196 |
+
$this->update_setting('update/ttl', $ttl);
|
197 |
+
$this->update_setting('update/xml', $xml);
|
198 |
+
$this->update_setting('update/timed', 'feed');
|
199 |
else :
|
200 |
$ttl = $this->automatic_ttl();
|
201 |
+
$this->update_setting('update/ttl', $ttl);
|
202 |
+
$this->update_setting('update/xml', NULL);
|
203 |
+
$this->update_setting('update/timed', 'automatically');
|
204 |
endif;
|
205 |
+
$this->update_setting('update/fudge', rand(0, ($ttl/3))*60);
|
206 |
+
$this->update_setting('update/ttl', apply_filters(
|
207 |
+
'syndicated_feed_ttl',
|
208 |
+
$this->setting('update/ttl'),
|
209 |
+
$this
|
210 |
+
));
|
211 |
|
212 |
if (!$this->setting('update/hold') != 'ping') :
|
213 |
+
$this->update_setting('update/hold', 'scheduled');
|
214 |
endif;
|
215 |
|
216 |
+
$this->update_setting('update/unfinished', 'yes');
|
217 |
|
218 |
$update[] = "link_notes = '".$wpdb->escape($this->settings_to_notes())."'";
|
219 |
|
233 |
$posts = apply_filters(
|
234 |
'syndicated_feed_items',
|
235 |
$this->simplepie->get_items(),
|
236 |
+
$this
|
237 |
);
|
238 |
|
239 |
$this->magpie->originals = $posts;
|
240 |
|
241 |
+
// If this is a complete feed, rather than an incremental feed, we
|
242 |
+
// need to prepare to mark everything for presumptive retirement.
|
243 |
+
if ($this->is_incremental()) :
|
244 |
+
$q = new WP_Query(array(
|
245 |
+
'fields' => '_synfrom',
|
246 |
+
'post_status__not' => 'fwpretired',
|
247 |
+
'ignore_sticky_posts' => true,
|
248 |
+
'meta_key' => 'syndication_feed_id',
|
249 |
+
'meta_value' => $this->id,
|
250 |
+
));
|
251 |
+
foreach ($q->posts as $p) :
|
252 |
+
update_post_meta($p->ID, '_feedwordpress_retire_me_'.$this->id, '1');
|
253 |
+
endforeach;
|
254 |
+
endif;
|
255 |
+
|
256 |
if (is_array($posts)) :
|
257 |
foreach ($posts as $key => $item) :
|
258 |
$post = new SyndicatedPost($item, $this);
|
272 |
unset($post);
|
273 |
endforeach;
|
274 |
endif;
|
275 |
+
|
276 |
+
if ('yes'==$this->setting('tombstones', 'tombstones', 'yes')) :
|
277 |
+
// Check for use of Atom tombstones. Spec:
|
278 |
+
// <http://tools.ietf.org/html/draft-snell-atompub-tombstones-18>
|
279 |
+
$tombstones = $this->simplepie->get_feed_tags('http://purl.org/atompub/tombstones/1.0', 'deleted-entry');
|
280 |
+
if (count($tombstones) > 0) :
|
281 |
+
foreach ($tombstones as $tombstone) :
|
282 |
+
$ref = NULL;
|
283 |
+
foreach (array('', 'http://purl.org/atompub/tombstones/1.0') as $ns) :
|
284 |
+
if (isset($tombstone['attribs'][$ns])
|
285 |
+
and isset($tombstone['attribs'][$ns]['ref'])) :
|
286 |
+
$ref = $tombstone['attribs'][$ns]['ref'];
|
287 |
+
endif;
|
288 |
+
endforeach;
|
289 |
+
|
290 |
+
$q = new WP_Query(array(
|
291 |
+
'ignore_sticky_posts' => true,
|
292 |
+
'guid' => $ref,
|
293 |
+
'meta_key' => 'syndication_feed_id',
|
294 |
+
'meta_value' => $this->id, // Only allow a feed to tombstone its own entries.
|
295 |
+
));
|
296 |
+
|
297 |
+
foreach ($q->posts as $p) :
|
298 |
+
$old_status = $p->post_status;
|
299 |
+
FeedWordPress::diagnostic('syndicated_posts', 'Retiring existing post # '.$p->ID.' "'.$p->post_title.'" due to Atom tombstone element in feed.');
|
300 |
+
set_post_field('post_status', 'fwpretired', $p->ID);
|
301 |
+
wp_transition_post_status('fwpretired', $old_status, $p);
|
302 |
+
endforeach;
|
303 |
+
|
304 |
+
endforeach;
|
305 |
+
endif;
|
306 |
+
endif;
|
307 |
+
|
308 |
$suffix = ($crashed ? 'crashed' : 'completed');
|
309 |
do_action('update_syndicated_feed_items', $this->id, $this);
|
310 |
do_action("update_syndicated_feed_items_${suffix}", $this->id, $this);
|
311 |
|
312 |
+
$this->update_setting('update/processed', $processed);
|
|
|
|
|
|
|
313 |
if (!$crashed) :
|
314 |
+
$this->update_setting('update/unfinished', 'no');
|
315 |
endif;
|
316 |
+
$this->update_setting('link/item count', count($posts));
|
317 |
|
318 |
+
// Copy back any changes to feed settings made in the
|
319 |
+
// course of updating (e.g. new author rules)
|
320 |
$update_set = "link_notes = '".$wpdb->escape($this->settings_to_notes())."'";
|
321 |
|
322 |
// Update the properties of the link from the feed information
|
342 |
return $new_count;
|
343 |
} /* SyndicatedLink::poll() */
|
344 |
|
345 |
+
function process_retirements ($delta) {
|
346 |
+
global $post;
|
347 |
+
|
348 |
+
$q = new WP_Query(array(
|
349 |
+
'fields' => '_synfrom',
|
350 |
+
'post_status__not' => 'fwpretired',
|
351 |
+
'ignore_sticky_posts' => true,
|
352 |
+
'meta_key' => '_feedwordpress_retire_me_'.$this->id,
|
353 |
+
'meta_value' => '1',
|
354 |
+
));
|
355 |
+
if ($q->have_posts()) :
|
356 |
+
foreach ($q->posts as $p) :
|
357 |
+
$old_status = $p->post_status;
|
358 |
+
FeedWordPress::diagnostic('syndicated_posts', 'Retiring existing post # '.$p->ID.' "'.$p->post_title.'" due to absence from a non-incremental feed.');
|
359 |
+
set_post_field('post_status', 'fwpretired', $p->ID);
|
360 |
+
wp_transition_post_status('fwpretired', $old_status, $p);
|
361 |
+
delete_post_meta($p->ID, '_feedwordpress_retire_me_'.$this->id);
|
362 |
+
endforeach;
|
363 |
+
endif;
|
364 |
+
return $delta;
|
365 |
+
}
|
366 |
+
|
367 |
/**
|
368 |
* Updates the URL for the feed syndicated by this link.
|
369 |
*
|
444 |
$newuser_id = fwp_insert_new_user($newuser_name);
|
445 |
if (is_numeric($newuser_id)) :
|
446 |
if (is_null($name)) : // Unfamiliar author
|
447 |
+
$this->update_setting('unfamiliar author', $newuser_id);
|
448 |
else :
|
449 |
+
$map = $this->setting('map authors');
|
450 |
+
$map['name'][$name] = $newuser_id;
|
451 |
+
$this->update_setting('map authors', $map);
|
452 |
endif;
|
453 |
else :
|
454 |
// TODO: Add some error detection and reporting
|
461 |
function imploded_settings () {
|
462 |
return array('cats', 'tags', 'match/cats', 'match/tags', 'match/filter');
|
463 |
}
|
464 |
+
|
465 |
+
function get_settings_from_notes () {
|
466 |
+
// Read off feed settings from link_notes
|
467 |
+
$notes = explode("\n", $this->link->link_notes);
|
468 |
+
foreach ($notes as $note):
|
469 |
+
$pair = explode(": ", $note, 2);
|
470 |
+
$key = (isset($pair[0]) ? $pair[0] : null);
|
471 |
+
$value = (isset($pair[1]) ? $pair[1] : null);
|
472 |
+
if (!is_null($key) and !is_null($value)) :
|
473 |
+
// Unescape and trim() off the whitespace.
|
474 |
+
// Thanks to Ray Lischner for pointing out the
|
475 |
+
// need to trim off whitespace.
|
476 |
+
$this->settings[$key] = stripcslashes (trim($value));
|
477 |
+
endif;
|
478 |
+
endforeach;
|
479 |
+
|
480 |
+
// "Magic" feed settings
|
481 |
+
$this->settings['link/uri'] = $this->link->link_rss;
|
482 |
+
$this->settings['link/name'] = $this->link->link_name;
|
483 |
+
$this->settings['link/id'] = $this->link->link_id;
|
484 |
+
|
485 |
+
// `hardcode categories` and `unfamiliar categories` are
|
486 |
+
// deprecated in favor of `unfamiliar category`
|
487 |
+
if (
|
488 |
+
isset($this->settings['unfamiliar categories'])
|
489 |
+
and !isset($this->settings['unfamiliar category'])
|
490 |
+
) :
|
491 |
+
$this->settings['unfamiliar category'] = $this->settings['unfamiliar categories'];
|
492 |
+
endif;
|
493 |
+
if (
|
494 |
+
FeedWordPress::affirmative($this->settings, 'hardcode categories')
|
495 |
+
and !isset($this->settings['unfamiliar category'])
|
496 |
+
) :
|
497 |
+
$this->settings['unfamiliar category'] = 'default';
|
498 |
+
endif;
|
499 |
+
|
500 |
+
// Set this up automagically for del.icio.us
|
501 |
+
$bits = parse_url($this->link->link_rss);
|
502 |
+
$tagspacers = array('del.icio.us', 'feeds.delicious.com');
|
503 |
+
if (!isset($this->settings['cat_split']) and in_array($bits['host'], $tagspacers)) :
|
504 |
+
$this->settings['cat_split'] = '\s'; // Whitespace separates multiple tags in del.icio.us RSS feeds
|
505 |
+
endif;
|
506 |
+
|
507 |
+
// Simple lists
|
508 |
+
foreach ($this->imploded_settings() as $what) :
|
509 |
+
if (isset($this->settings[$what])):
|
510 |
+
$this->settings[$what] = explode(
|
511 |
+
FEEDWORDPRESS_CAT_SEPARATOR,
|
512 |
+
$this->settings[$what]
|
513 |
+
);
|
514 |
+
endif;
|
515 |
+
endforeach;
|
516 |
+
|
517 |
+
if (isset($this->settings['terms'])) :
|
518 |
+
// Look for new format
|
519 |
+
$this->settings['terms'] = maybe_unserialize($this->settings['terms']);
|
520 |
+
|
521 |
+
if (!is_array($this->settings['terms'])) :
|
522 |
+
// Deal with old format instead. Ugh.
|
523 |
+
|
524 |
+
// Split on two *or more* consecutive breaks
|
525 |
+
// because in the old format, a taxonomy
|
526 |
+
// without any associated terms would
|
527 |
+
// produce tax_name#1\n\n\ntax_name#2\nterm,
|
528 |
+
// and the naive split on the first \n\n
|
529 |
+
// would screw up the tax_name#2 list.
|
530 |
+
//
|
531 |
+
// Props to David Morris for pointing this
|
532 |
+
// out.
|
533 |
+
|
534 |
+
$this->settings['terms'] = preg_split(
|
535 |
+
"/".FEEDWORDPRESS_CAT_SEPARATOR."{2,}/",
|
536 |
+
$this->settings['terms']
|
537 |
+
);
|
538 |
+
$terms = array();
|
539 |
+
foreach ($this->settings['terms'] as $line) :
|
540 |
+
$line = explode(FEEDWORDPRESS_CAT_SEPARATOR, $line);
|
541 |
+
$tax = array_shift($line);
|
542 |
+
$terms[$tax] = $line;
|
543 |
+
endforeach;
|
544 |
+
$this->settings['terms'] = $terms;
|
545 |
+
endif;
|
546 |
+
endif;
|
547 |
+
|
548 |
+
if (isset($this->settings['map authors'])) :
|
549 |
+
$author_rules = explode("\n\n", $this->settings['map authors']);
|
550 |
+
$ma = array();
|
551 |
+
foreach ($author_rules as $rule) :
|
552 |
+
list($rule_type, $author_name, $author_action) = explode("\n", $rule);
|
553 |
+
|
554 |
+
// Normalize for case and whitespace
|
555 |
+
$rule_type = strtolower(trim($rule_type));
|
556 |
+
$author_name = strtolower(trim($author_name));
|
557 |
+
$author_action = strtolower(trim($author_action));
|
558 |
+
|
559 |
+
$ma[$rule_type][$author_name] = $author_action;
|
560 |
+
endforeach;
|
561 |
+
$this->settings['map authors'] = $ma;
|
562 |
+
endif;
|
563 |
+
|
564 |
+
} /* SyndicatedLink::get_settings_from_notes () */
|
565 |
+
|
566 |
function settings_to_notes () {
|
567 |
$to_notes = $this->settings;
|
568 |
|
675 |
return $ret;
|
676 |
} /* SyndicatedLink::setting () */
|
677 |
|
678 |
+
function merge_settings ($data, $prefix, $separator = '/') {
|
679 |
+
$dd = $this->flatten_array($data, $prefix, $separator);
|
680 |
+
$this->settings = array_merge($this->settings, $dd);
|
681 |
+
} /* SyndicatedLink::merge_settings () */
|
682 |
+
|
683 |
function update_setting ($name, $value, $default = 'default') {
|
684 |
if (!is_null($value) and $value != $default) :
|
685 |
$this->settings[$name] = $value;
|
688 |
endif;
|
689 |
} /* SyndicatedLink::update_setting () */
|
690 |
|
691 |
+
function is_incremental () {
|
692 |
+
return ('complete'==$this->setting('update_incremental', 'update_incremental', 'incremental'));
|
693 |
+
} /* SyndicatedLink::is_incremental () */
|
694 |
+
|
695 |
function uri ($params = array()) {
|
696 |
+
$params = wp_parse_args($params, array(
|
697 |
'add_params' => false,
|
698 |
+
));
|
699 |
|
700 |
$uri = (is_object($this->link) ? $this->link->link_rss : NULL);
|
701 |
if (!is_null($uri) and strlen($uri) > 0 and $params['add_params']) :
|
711 |
endforeach;
|
712 |
|
713 |
// Are we appending to a URI that already has params?
|
714 |
+
$sep = ((strpos($uri, "?")===false) ? '?' : '&');
|
715 |
|
716 |
// Tack it on
|
717 |
$uri .= $sep . implode("&", $q);
|
718 |
+
endif;
|
719 |
endif;
|
720 |
|
721 |
return $uri;
|
736 |
endif;
|
737 |
return $auth;
|
738 |
} /* SyndicatedLink::authentication_method () */
|
739 |
+
|
740 |
+
var $postmeta = array();
|
741 |
+
function postmeta ($params = array()) {
|
742 |
+
$params = wp_parse_args($params, /*defaults=*/ array(
|
743 |
+
"field" => NULL,
|
744 |
+
"parsed" => false,
|
745 |
+
"force" => false,
|
746 |
+
));
|
747 |
+
|
748 |
+
if ($params['force'] or !isset($this->postmeta[/*parsed = */ false])) :
|
749 |
+
// First, get the global settings.
|
750 |
+
$default_custom_settings = get_option('feedwordpress_custom_settings');
|
751 |
+
if ($default_custom_settings and !is_array($default_custom_settings)) :
|
752 |
+
$default_custom_settings = unserialize($default_custom_settings);
|
753 |
+
endif;
|
754 |
+
if (!is_array($default_custom_settings)) :
|
755 |
+
$default_custom_settings = array();
|
756 |
+
endif;
|
757 |
+
|
758 |
+
// Next, get the settings for this particular feed.
|
759 |
+
$custom_settings = $this->setting('postmeta', NULL, NULL);
|
760 |
+
if ($custom_settings and !is_array($custom_settings)) :
|
761 |
+
$custom_settings = unserialize($custom_settings);
|
762 |
+
endif;
|
763 |
+
if (!is_array($custom_settings)) :
|
764 |
+
$custom_settings = array();
|
765 |
+
endif;
|
766 |
+
|
767 |
+
$this->postmeta[/*parsed=*/ false] = array_merge($default_custom_settings, $custom_settings);
|
768 |
+
$this->postmeta[/*parsed=*/ true] = array();
|
769 |
+
|
770 |
+
// Now, run through and parse them all.
|
771 |
+
foreach ($this->postmeta[/*parsed=*/ false] as $key => $meta) :
|
772 |
+
$meta = apply_filters("syndicated_link_post_meta_${key}_pre", $meta, $this);
|
773 |
+
$this->postmeta[/*parsed=*/ false][$key] = $meta;
|
774 |
+
$this->postmeta[/*parsed=*/ true][$key] = new FeedWordPressParsedPostMeta($meta);
|
775 |
+
endforeach;
|
776 |
+
endif;
|
777 |
+
|
778 |
+
$ret = $this->postmeta[!!$params['parsed']];
|
779 |
+
if (is_string($params['field'])) :
|
780 |
+
$ret = $ret[$params['field']];
|
781 |
+
endif;
|
782 |
+
return $ret;
|
783 |
+
} /* SyndicatedLink::postmeta () */
|
784 |
|
785 |
+
function property_cascade ($fromFeed, $link_field, $setting, $method) {
|
786 |
$value = NULL;
|
787 |
if ($fromFeed) :
|
788 |
+
$value = $this->setting($setting, NULL, NULL, NULL);
|
789 |
+
|
790 |
+
$s = $this->simplepie;
|
791 |
+
$callable = (is_object($s) and method_exists($s, $method));
|
792 |
+
if (is_null($value) and $callable) :
|
793 |
+
$fallback = $s->{$method}();
|
794 |
endif;
|
795 |
else :
|
796 |
$value = $this->link->{$link_field};
|
926 |
} /* SyndicatedLink::flatten_array () */
|
927 |
|
928 |
function hardcode ($what) {
|
929 |
+
|
930 |
+
$ret = $this->setting('hardcode '.$what, 'hardcode_'.$what, NULL);
|
931 |
+
|
932 |
+
if ('yes' == $ret) :
|
933 |
+
$ret = true;
|
|
|
934 |
else :
|
935 |
+
$ret = false;
|
|
|
|
|
|
|
936 |
endif;
|
937 |
return $ret;
|
938 |
} /* SyndicatedLink::hardcode () */
|
940 |
function syndicated_status ($what, $default, $fallback = true) {
|
941 |
global $wpdb;
|
942 |
|
943 |
+
$g_set = ($fallback ? 'syndicated_' . $what . '_status' : NULL);
|
944 |
+
$ret = $this->setting($what.' status', $g_set, $default);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
945 |
|
946 |
return $wpdb->escape(trim(strtolower($ret)));
|
947 |
} /* SyndicatedLink:syndicated_status () */
|
@@ -30,6 +30,7 @@ class SyndicatedPost {
|
|
30 |
|
31 |
var $_freshness = null;
|
32 |
var $_wp_id = null;
|
|
|
33 |
|
34 |
/**
|
35 |
* SyndicatedPost constructor: Given a feed item and the source from
|
@@ -158,48 +159,16 @@ class SyndicatedPost {
|
|
158 |
// Unique ID (hopefully a unique tag: URI); failing that, the permalink
|
159 |
$this->post['guid'] = apply_filters('syndicated_item_guid', $this->guid(), $this);
|
160 |
|
161 |
-
// User-supplied custom settings to apply to each post.
|
162 |
-
|
163 |
-
if
|
164 |
-
|
165 |
-
endif;
|
166 |
-
if (!is_array($default_custom_settings)) :
|
167 |
-
$default_custom_settings = array();
|
168 |
-
endif;
|
169 |
-
|
170 |
-
$custom_settings = (isset($this->link->settings['postmeta']) ? $this->link->settings['postmeta'] : null);
|
171 |
-
if ($custom_settings and !is_array($custom_settings)) :
|
172 |
-
$custom_settings = unserialize($custom_settings);
|
173 |
-
endif;
|
174 |
-
if (!is_array($custom_settings)) :
|
175 |
-
$custom_settings = array();
|
176 |
-
endif;
|
177 |
-
|
178 |
-
$postMetaIn = array_merge($default_custom_settings, $custom_settings);
|
179 |
$postMetaOut = array();
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
foreach ($postMetaIn as $key => $values) :
|
184 |
-
if (is_string($values)) : $values = array($values); endif;
|
185 |
-
|
186 |
-
$postMetaOut[$key] = array();
|
187 |
-
foreach ($values as $value) :
|
188 |
-
if (preg_match('/\$\( ([^)]+) \)/x', $value, $ref)) :
|
189 |
-
$elements = $this->query($ref[1]);
|
190 |
-
foreach ($elements as $element) :
|
191 |
-
$postMetaOut[$key][] = str_replace(
|
192 |
-
$ref[0],
|
193 |
-
$element,
|
194 |
-
$value
|
195 |
-
);
|
196 |
-
endforeach;
|
197 |
-
else :
|
198 |
-
$postMetaOut[$key][] = $value;
|
199 |
-
endif;
|
200 |
-
endforeach;
|
201 |
endforeach;
|
202 |
-
|
203 |
foreach ($postMetaOut as $key => $values) :
|
204 |
$this->post['meta'][$key] = array();
|
205 |
foreach ($values as $value) :
|
@@ -380,6 +349,23 @@ class SyndicatedPost {
|
|
380 |
#####################################
|
381 |
#### EXTRACT DATA FROM FEED ITEM ####
|
382 |
#####################################
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
383 |
|
384 |
/**
|
385 |
* SyndicatedPost::query uses an XPath-like syntax to query arbitrary
|
@@ -772,8 +758,20 @@ class SyndicatedPost {
|
|
772 |
return $this->_hashes[$id];
|
773 |
}
|
774 |
|
775 |
-
function update_hash () {
|
776 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
777 |
} /* SyndicatedPost::update_hash() */
|
778 |
|
779 |
/*static*/ function normalize_guid_prefix () {
|
@@ -853,56 +851,77 @@ class SyndicatedPost {
|
|
853 |
function author () {
|
854 |
$author = array ();
|
855 |
|
856 |
-
|
857 |
-
|
858 |
-
|
859 |
-
|
860 |
-
|
861 |
-
|
862 |
-
|
863 |
-
|
864 |
-
|
865 |
-
|
866 |
-
|
867 |
-
|
868 |
-
|
869 |
-
|
870 |
-
|
871 |
-
|
872 |
-
|
873 |
-
|
874 |
-
|
875 |
-
|
876 |
-
|
877 |
-
|
878 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
879 |
endif;
|
880 |
endif;
|
881 |
-
elseif ($this->link->name()) :
|
882 |
-
$author['name'] = $this->link->name();
|
883 |
-
else :
|
884 |
-
$url = parse_url($this->link->uri());
|
885 |
-
$author['name'] = $url['host'];
|
886 |
endif;
|
887 |
|
888 |
-
if (isset($
|
889 |
-
|
890 |
-
|
891 |
-
|
|
|
|
|
|
|
|
|
892 |
endif;
|
893 |
|
894 |
-
if (
|
895 |
-
|
896 |
-
|
897 |
-
|
898 |
-
|
899 |
-
|
900 |
-
|
901 |
-
|
902 |
-
|
903 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
904 |
endif;
|
905 |
-
|
906 |
return $author;
|
907 |
} /* SyndicatedPost::author() */
|
908 |
|
@@ -1170,7 +1189,7 @@ class SyndicatedPost {
|
|
1170 |
$pattern = FeedWordPressHTML::attributeRegex($tag, $attr);
|
1171 |
$content = preg_replace_callback (
|
1172 |
$pattern,
|
1173 |
-
array(
|
1174 |
$content
|
1175 |
);
|
1176 |
endforeach;
|
@@ -1199,7 +1218,7 @@ class SyndicatedPost {
|
|
1199 |
|
1200 |
$content = preg_replace_callback (
|
1201 |
$pattern,
|
1202 |
-
array(
|
1203 |
$content
|
1204 |
);
|
1205 |
endforeach;
|
@@ -1270,9 +1289,18 @@ class SyndicatedPost {
|
|
1270 |
!is_null($updated_ts)
|
1271 |
and ($updated_ts > $last_rev_ts)
|
1272 |
);
|
1273 |
-
|
1274 |
-
|
1275 |
-
if (
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1276 |
// Or the hash...
|
1277 |
$hash = $this->update_hash();
|
1278 |
$seen = $this->stored_hashes($old_post->ID);
|
@@ -1281,6 +1309,15 @@ class SyndicatedPost {
|
|
1281 |
else :
|
1282 |
$updated = true; // Can't find syndication meta-data
|
1283 |
endif;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1284 |
endif;
|
1285 |
|
1286 |
$frozen = false;
|
@@ -1289,15 +1326,26 @@ class SyndicatedPost {
|
|
1289 |
if (!$frozen) :
|
1290 |
$frozen_values = get_post_custom_values('_syndication_freeze_updates', $old_post->ID);
|
1291 |
$frozen = (count($frozen_values) > 0 and 'yes' == $frozen_values[0]);
|
|
|
|
|
|
|
|
|
|
|
|
|
1292 |
endif;
|
1293 |
endif;
|
1294 |
$updated = ($updated and !$frozen);
|
1295 |
|
1296 |
if ($updated) :
|
1297 |
FeedWordPress::diagnostic('feed_items:freshness', 'Item ['.$guid.'] "'.$this->entry->get_title().'" is an update of an existing post.');
|
|
|
|
|
|
|
|
|
1298 |
$this->_freshness = 1; // Updated content
|
1299 |
$this->_wp_id = $old_post->ID;
|
1300 |
-
|
|
|
1301 |
// We want this to keep a running list of all the
|
1302 |
// processed update hashes.
|
1303 |
$this->post['meta']['syndication_item_hash'] = array_merge(
|
@@ -1427,8 +1475,13 @@ class SyndicatedPost {
|
|
1427 |
if (!$this->filtered() and $freshness > 0) :
|
1428 |
// Filter some individual fields
|
1429 |
|
|
|
|
|
|
|
|
|
|
|
1430 |
// Allow filters to set post slug. Props niska.
|
1431 |
-
$post_name = apply_filters('syndicated_post_slug',
|
1432 |
if (!empty($post_name)) :
|
1433 |
$this->post['post_name'] = $post_name;
|
1434 |
endif;
|
@@ -1446,7 +1499,7 @@ class SyndicatedPost {
|
|
1446 |
// Hook in early to make sure these get inserted if at all possible
|
1447 |
add_action(
|
1448 |
/*hook=*/ 'transition_post_status',
|
1449 |
-
/*callback=*/ array(
|
1450 |
/*priority=*/ -10000, /* very early */
|
1451 |
/*arguments=*/ 3
|
1452 |
);
|
@@ -1469,10 +1522,24 @@ class SyndicatedPost {
|
|
1469 |
$ret = $retval[$freshness];
|
1470 |
endif;
|
1471 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1472 |
// Remove add_rss_meta hook
|
1473 |
remove_action(
|
1474 |
/*hook=*/ 'transition_post_status',
|
1475 |
-
/*callback=*/ array(
|
1476 |
/*priority=*/ -10000, /* very early */
|
1477 |
/*arguments=*/ 3
|
1478 |
);
|
@@ -1509,14 +1576,14 @@ class SyndicatedPost {
|
|
1509 |
|
1510 |
foreach ($doNotMunge as $field) :
|
1511 |
$dbpost[$field] = get_post_field($field, $this->wp_id());
|
1512 |
-
endforeach;
|
1513 |
endif;
|
1514 |
|
1515 |
// WP3's wp_insert_post scans current_user_can() for the
|
1516 |
// tax_input, with no apparent way to override. Ugh.
|
1517 |
add_action(
|
1518 |
/*hook=*/ 'transition_post_status',
|
1519 |
-
/*callback=*/ array(
|
1520 |
/*priority=*/ -10001, /* very early */
|
1521 |
/*arguments=*/ 3
|
1522 |
);
|
@@ -1525,7 +1592,7 @@ class SyndicatedPost {
|
|
1525 |
// post_modified. Ugh.
|
1526 |
add_action(
|
1527 |
/*hook=*/ 'transition_post_status',
|
1528 |
-
/*callback=*/ array(
|
1529 |
/*priority=*/ -10000, /* very early */
|
1530 |
/*arguments=*/ 3
|
1531 |
);
|
@@ -1539,14 +1606,14 @@ class SyndicatedPost {
|
|
1539 |
|
1540 |
remove_action(
|
1541 |
/*hook=*/ 'transition_post_status',
|
1542 |
-
/*callback=*/ array(
|
1543 |
/*priority=*/ -10001, /* very early */
|
1544 |
/*arguments=*/ 3
|
1545 |
);
|
1546 |
|
1547 |
remove_action(
|
1548 |
/*hook=*/ 'transition_post_status',
|
1549 |
-
/*callback=*/ array(
|
1550 |
/*priority=*/ -10000, /* very early */
|
1551 |
/*arguments=*/ 3
|
1552 |
);
|
@@ -1554,7 +1621,7 @@ class SyndicatedPost {
|
|
1554 |
// Turn off ridiculous fucking kludges #1 and #2
|
1555 |
remove_action('_wp_put_post_revision', array($this, 'fix_revision_meta'));
|
1556 |
foreach ($removed as $filter) :
|
1557 |
-
add_filter('content_save_pre', $
|
1558 |
endforeach;
|
1559 |
|
1560 |
$this->validate_post_id($dbpost, $update, array(__CLASS__, __FUNCTION__));
|
30 |
|
31 |
var $_freshness = null;
|
32 |
var $_wp_id = null;
|
33 |
+
var $_wp_post = null;
|
34 |
|
35 |
/**
|
36 |
* SyndicatedPost constructor: Given a feed item and the source from
|
159 |
// Unique ID (hopefully a unique tag: URI); failing that, the permalink
|
160 |
$this->post['guid'] = apply_filters('syndicated_item_guid', $this->guid(), $this);
|
161 |
|
162 |
+
// User-supplied custom settings to apply to each post.
|
163 |
+
// Do first so that FWP-generated custom settings will
|
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) :
|
349 |
#####################################
|
350 |
#### EXTRACT DATA FROM FEED ITEM ####
|
351 |
#####################################
|
352 |
+
|
353 |
+
function substitution_function ($name) {
|
354 |
+
$ret = NULL;
|
355 |
+
|
356 |
+
switch ($name) :
|
357 |
+
// Allowed PHP string functions
|
358 |
+
case 'trim':
|
359 |
+
case 'ltrim':
|
360 |
+
case 'rtrim':
|
361 |
+
case 'strtoupper':
|
362 |
+
case 'strtolower':
|
363 |
+
case 'urlencode':
|
364 |
+
case 'urldecode':
|
365 |
+
$ret = $name;
|
366 |
+
endswitch;
|
367 |
+
return $ret;
|
368 |
+
}
|
369 |
|
370 |
/**
|
371 |
* SyndicatedPost::query uses an XPath-like syntax to query arbitrary
|
758 |
return $this->_hashes[$id];
|
759 |
}
|
760 |
|
761 |
+
function update_hash ($hashed = true) {
|
762 |
+
// Basis for tracking possible changes to item.
|
763 |
+
$hash = array(
|
764 |
+
"title" => $this->entry->get_title(),
|
765 |
+
"link" => $this->permalink(),
|
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 |
/*static*/ function normalize_guid_prefix () {
|
851 |
function author () {
|
852 |
$author = array ();
|
853 |
|
854 |
+
$aa = $this->entry->get_authors();
|
855 |
+
if (count($aa) > 0) :
|
856 |
+
$a = reset($aa);
|
857 |
+
|
858 |
+
$author = array(
|
859 |
+
'name' => $a->get_name(),
|
860 |
+
'email' => $a->get_email(),
|
861 |
+
'uri' => $a->get_link(),
|
862 |
+
);
|
863 |
+
endif;
|
864 |
+
|
865 |
+
if (FEEDWORDPRESS_COMPATIBILITY) :
|
866 |
+
// Search through the MagpieRSS elements: Atom, Dublin Core, RSS
|
867 |
+
if (isset($this->item['author_name'])):
|
868 |
+
$author['name'] = $this->item['author_name'];
|
869 |
+
elseif (isset($this->item['dc']['creator'])):
|
870 |
+
$author['name'] = $this->item['dc']['creator'];
|
871 |
+
elseif (isset($this->item['dc']['contributor'])):
|
872 |
+
$author['name'] = $this->item['dc']['contributor'];
|
873 |
+
elseif (isset($this->feed->channel['dc']['creator'])) :
|
874 |
+
$author['name'] = $this->feed->channel['dc']['creator'];
|
875 |
+
elseif (isset($this->feed->channel['dc']['contributor'])) :
|
876 |
+
$author['name'] = $this->feed->channel['dc']['contributor'];
|
877 |
+
elseif (isset($this->feed->channel['author_name'])) :
|
878 |
+
$author['name'] = $this->feed->channel['author_name'];
|
879 |
+
elseif ($this->feed->is_rss() and isset($this->item['author'])) :
|
880 |
+
// The author element in RSS is allegedly an
|
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'];
|
888 |
+
else :
|
889 |
+
$author['name'] = $this->feed->channel['title'];
|
890 |
+
endif;
|
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()) :
|
898 |
+
$author['name'] = $this->link->name();
|
899 |
+
else :
|
900 |
+
$url = parse_url($this->link->uri());
|
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'])):
|
915 |
+
$author['uri'] = $this->item['author_url'];
|
916 |
+
elseif (isset($this->feed->channel['author_uri'])) :
|
917 |
+
$author['uri'] = $this->item['author_uri'];
|
918 |
+
elseif (isset($this->feed->channel['author_url'])) :
|
919 |
+
$author['uri'] = $this->item['author_url'];
|
920 |
+
elseif (isset($this->feed->channel['link'])) :
|
921 |
+
$author['uri'] = $this->feed->channel['link'];
|
922 |
+
endif;
|
923 |
endif;
|
924 |
+
|
925 |
return $author;
|
926 |
} /* SyndicatedPost::author() */
|
927 |
|
1189 |
$pattern = FeedWordPressHTML::attributeRegex($tag, $attr);
|
1190 |
$content = preg_replace_callback (
|
1191 |
$pattern,
|
1192 |
+
array($obj, 'resolve_single_relative_uri'),
|
1193 |
$content
|
1194 |
);
|
1195 |
endforeach;
|
1218 |
|
1219 |
$content = preg_replace_callback (
|
1220 |
$pattern,
|
1221 |
+
array($obj, 'strip_attribute_from_tag'),
|
1222 |
$content
|
1223 |
);
|
1224 |
endforeach;
|
1289 |
!is_null($updated_ts)
|
1290 |
and ($updated_ts > $last_rev_ts)
|
1291 |
);
|
1292 |
+
|
1293 |
+
$updatedReason = NULL;
|
1294 |
+
if ($updated) :
|
1295 |
+
$updatedReason = preg_replace(
|
1296 |
+
"/\s+/", " ",
|
1297 |
+
'has been marked with a new timestamp ('
|
1298 |
+
.date('Y-m-d H:i:s', $updated_ts)
|
1299 |
+
." > "
|
1300 |
+
.date('Y-m-d H:i:s', $last_rev_ts)
|
1301 |
+
.')'
|
1302 |
+
);
|
1303 |
+
else :
|
1304 |
// Or the hash...
|
1305 |
$hash = $this->update_hash();
|
1306 |
$seen = $this->stored_hashes($old_post->ID);
|
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 |
+
.FeedWordPress::val($hash)
|
1316 |
+
.' not in {'
|
1317 |
+
.implode(", ", array_map(array('FeedWordPress', 'val'), $seen))
|
1318 |
+
.'}. Basis: '
|
1319 |
+
.FeedWordPress::val(array_keys($this->update_hash(false)));
|
1320 |
+
endif;
|
1321 |
endif;
|
1322 |
|
1323 |
$frozen = false;
|
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;
|
1333 |
+
else :
|
1334 |
+
$updatedReason = ' IS BLOCKED FROM BEING UPDATED BY A FEEDWORDPRESS UPDATE LOCK, EVEN THOUGH IT '.$updatedReason;
|
1335 |
endif;
|
1336 |
endif;
|
1337 |
$updated = ($updated and !$frozen);
|
1338 |
|
1339 |
if ($updated) :
|
1340 |
FeedWordPress::diagnostic('feed_items:freshness', 'Item ['.$guid.'] "'.$this->entry->get_title().'" is an update of an existing post.');
|
1341 |
+
if (!is_null($updatedReason)) :
|
1342 |
+
$updatedReason = preg_replace('/\s+/', ' ', $updatedReason);
|
1343 |
+
FeedWordPress::diagnostic('feed_items:freshness:reasons', 'Item ['.$guid.'] "'.$this->entry->get_title().'" '.$updatedReason);
|
1344 |
+
endif;
|
1345 |
$this->_freshness = 1; // Updated content
|
1346 |
$this->_wp_id = $old_post->ID;
|
1347 |
+
$this->_wp_post = $old_post;
|
1348 |
+
|
1349 |
// We want this to keep a running list of all the
|
1350 |
// processed update hashes.
|
1351 |
$this->post['meta']['syndication_item_hash'] = array_merge(
|
1475 |
if (!$this->filtered() and $freshness > 0) :
|
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;
|
1499 |
// Hook in early to make sure these get inserted if at all possible
|
1500 |
add_action(
|
1501 |
/*hook=*/ 'transition_post_status',
|
1502 |
+
/*callback=*/ array($this, 'add_rss_meta'),
|
1503 |
/*priority=*/ -10000, /* very early */
|
1504 |
/*arguments=*/ 3
|
1505 |
);
|
1522 |
$ret = $retval[$freshness];
|
1523 |
endif;
|
1524 |
|
1525 |
+
// If this is a legit, non-filtered post, tag it as found on the feed
|
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->is_incremental()) :
|
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, $old_status, $this->post);
|
1536 |
+
endif;
|
1537 |
+
endif;
|
1538 |
+
|
1539 |
// Remove add_rss_meta hook
|
1540 |
remove_action(
|
1541 |
/*hook=*/ 'transition_post_status',
|
1542 |
+
/*callback=*/ array($this, 'add_rss_meta'),
|
1543 |
/*priority=*/ -10000, /* very early */
|
1544 |
/*arguments=*/ 3
|
1545 |
);
|
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(
|
1585 |
/*hook=*/ 'transition_post_status',
|
1586 |
+
/*callback=*/ array($this, 'add_terms'),
|
1587 |
/*priority=*/ -10001, /* very early */
|
1588 |
/*arguments=*/ 3
|
1589 |
);
|
1592 |
// post_modified. Ugh.
|
1593 |
add_action(
|
1594 |
/*hook=*/ 'transition_post_status',
|
1595 |
+
/*callback=*/ array($this, 'fix_post_modified_ts'),
|
1596 |
/*priority=*/ -10000, /* very early */
|
1597 |
/*arguments=*/ 3
|
1598 |
);
|
1606 |
|
1607 |
remove_action(
|
1608 |
/*hook=*/ 'transition_post_status',
|
1609 |
+
/*callback=*/ array($this, 'add_terms'),
|
1610 |
/*priority=*/ -10001, /* very early */
|
1611 |
/*arguments=*/ 3
|
1612 |
);
|
1613 |
|
1614 |
remove_action(
|
1615 |
/*hook=*/ 'transition_post_status',
|
1616 |
+
/*callback=*/ array($this, 'fix_post_modified_ts'),
|
1617 |
/*priority=*/ -10000, /* very early */
|
1618 |
/*arguments=*/ 3
|
1619 |
);
|
1621 |
// Turn off ridiculous fucking kludges #1 and #2
|
1622 |
remove_action('_wp_put_post_revision', array($this, 'fix_revision_meta'));
|
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__));
|
@@ -1,12 +1,15 @@
|
|
1 |
<?php
|
|
|
|
|
2 |
class SyndicationDataQueries {
|
3 |
function SyndicationDataQueries () {
|
4 |
-
add_action('init', array(
|
5 |
-
|
6 |
-
|
7 |
-
add_filter('
|
8 |
-
add_filter('
|
9 |
-
add_filter('
|
|
|
10 |
}
|
11 |
|
12 |
function init () {
|
@@ -14,13 +17,36 @@ class SyndicationDataQueries {
|
|
14 |
$wp->add_query_var('guid');
|
15 |
}
|
16 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
17 |
function parse_query (&$q) {
|
18 |
if ($q->get('guid')) :
|
19 |
-
$q->is_single = false;
|
20 |
$q->is_singular = true; // Doesn't?
|
21 |
endif;
|
22 |
|
23 |
-
|
|
|
24 |
$q->query_vars['cache_results'] = false; // Not suitable.
|
25 |
endif;
|
26 |
} /* SyndicationDataQueries::parse_query () */
|
@@ -35,7 +61,7 @@ class SyndicationDataQueries {
|
|
35 |
endif;
|
36 |
return $sql;
|
37 |
}
|
38 |
-
|
39 |
function posts_search ($search, &$query) {
|
40 |
global $wpdb;
|
41 |
if ($guid = $query->get('guid')) :
|
@@ -67,17 +93,26 @@ class SyndicationDataQueries {
|
|
67 |
// Ugly hack to ensure we ONLY check by guid in syndicated freshness
|
68 |
// checks -- for reasons of both performance and correctness. Pitch:
|
69 |
$search .= " -- '";
|
|
|
|
|
70 |
endif;
|
71 |
return $search;
|
72 |
} /* SyndicationDataQueries::posts_search () */
|
73 |
|
74 |
function posts_where ($where, &$q) {
|
|
|
|
|
75 |
// Ugly hack to ensure we ONLY check by guid in syndicated freshness
|
76 |
// checks -- for reasons of both performance and correctness. Catch:
|
77 |
if (strpos($where, " -- '") !== false) :
|
78 |
$bits = explode(" -- '", $where, 2);
|
79 |
$where = $bits[0];
|
80 |
endif;
|
|
|
|
|
|
|
|
|
|
|
81 |
return $where;
|
82 |
} /* SyndicationDataQueries::post_where () */
|
83 |
|
@@ -86,7 +121,10 @@ class SyndicationDataQueries {
|
|
86 |
if ($f = $query->get('fields')) :
|
87 |
switch ($f) :
|
88 |
case '_synfresh' :
|
89 |
-
$fields = "{$wpdb->posts}.ID, {$wpdb->posts}.guid, {$wpdb->posts}.post_modified_gmt";
|
|
|
|
|
|
|
90 |
break;
|
91 |
default :
|
92 |
// Do nothing.
|
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);
|
11 |
+
add_filter('posts_fields', array($this, 'posts_fields'), 10, 2);
|
12 |
+
add_filter('posts_request', array($this, 'posts_request'), 10, 2);
|
13 |
}
|
14 |
|
15 |
function init () {
|
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 () */
|
61 |
endif;
|
62 |
return $sql;
|
63 |
}
|
64 |
+
|
65 |
function posts_search ($search, &$query) {
|
66 |
global $wpdb;
|
67 |
if ($guid = $query->get('guid')) :
|
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 wp_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 <> '".$wpdb->escape($psn)."')";
|
114 |
+
endif;
|
115 |
+
|
116 |
return $where;
|
117 |
} /* SyndicationDataQueries::post_where () */
|
118 |
|
121 |
if ($f = $query->get('fields')) :
|
122 |
switch ($f) :
|
123 |
case '_synfresh' :
|
124 |
+
$fields = "{$wpdb->posts}.ID, {$wpdb->posts}.guid, {$wpdb->posts}.post_modified_gmt, {$wpdb->posts}.post_name";
|
125 |
+
break;
|
126 |
+
case '_synfrom' :
|
127 |
+
$fields = "{$wpdb->posts}.ID, {$wpdb->posts}.guid, {$wpdb->posts}.post_title, {$wpdb->postmeta}.meta_value";
|
128 |
break;
|
129 |
default :
|
130 |
// Do nothing.
|