Version Description
Download this release
Release Info
Developer | radgeek |
Plugin | FeedWordPress |
Version | 0.99 |
Comparing to | |
See all releases |
Code changes from version 0.981 to 0.99
- ChangeLog.text +116 -1
- OPTIONAL/wp-includes/rss.php +822 -451
- README.text +134 -140
- wp-content/plugins/{feedwordpress.php → feedwordpress/feedwordpress.php} +1656 -1501
- wp-content/plugins/feedwordpress/syndication-options.php +252 -0
- wp-content/update-feeds.php +0 -205
ChangeLog.text
CHANGED
@@ -1,9 +1,124 @@
|
|
1 |
FeedWordPress Change Log
|
2 |
========================
|
3 |
|
4 |
-
Changes from 0.
|
5 |
--------------------------
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
6 |
|
|
|
|
|
7 |
Version 0.981 is a narrowly targeted bugfix and compatibility release, whose
|
8 |
main purpose is to resolve a major outstanding problem: the incompatibility
|
9 |
between version 0.98 of WordPress and the recently released WordPress 2.1.
|
1 |
FeedWordPress Change Log
|
2 |
========================
|
3 |
|
4 |
+
Changes from 0.981 to 0.99
|
5 |
--------------------------
|
6 |
+
Version 0.99 adds several significant new features, fixes some bugs, and
|
7 |
+
provides compatability with WordPress 2.2.x and 2.3.x.
|
8 |
+
|
9 |
+
* WORDPRESS 2.2 AND 2.3 COMPATIBILITY: FeedWordPress should now be
|
10 |
+
compatible with WordPress version 2.2 and the upcoming WordPress
|
11 |
+
version 2.3. In particular, it has been tested extensively against
|
12 |
+
WordPress 2.2.3 and WordPress 2.3 Release Candidate 1.
|
13 |
+
|
14 |
+
* AUTOMATIC UPDATES WITHOUT CRON: FeedWordPress now allows you to
|
15 |
+
automatically schedule checks for new posts without using external task
|
16 |
+
scheduling tools such as cron. In order to enable automatic updates, go
|
17 |
+
to **Syndication --> Options** and set "Check for new posts" to
|
18 |
+
"automatically." For details, see "Automatic Feed Updates" in
|
19 |
+
README.text.
|
20 |
+
|
21 |
+
An important side-effect of the changes to the update system is that if
|
22 |
+
you were previously using the cron job and the `update-feeds.php` script
|
23 |
+
to schedule updates, you need to change your cron set-up. The old
|
24 |
+
`update-feeds.php` script no longer exists. Instead, if you wish to use
|
25 |
+
a cron job to guarantee updates on a particular schedule, you should
|
26 |
+
have the cron job fetch the front page of your blog (for example, by
|
27 |
+
using `curl http://www.zyx.com/blog/ > /dev/null`) instead of activating
|
28 |
+
the `update-feeds.php` script. If automatic updates have been enabled,
|
29 |
+
fetching the front page will automatically trigger the update process.
|
30 |
+
|
31 |
+
* INTERFACE REORGANIZATION: All FeedWordPress functions are now located
|
32 |
+
under a top-level "Syndication" menu in the WordPress Dashboard. To
|
33 |
+
manage the list of syndicated sites, manually check for new posts on
|
34 |
+
one or more feeds, or syndicate a new site, you should use the main page
|
35 |
+
under **Syndication**. To change global settings for FeedWordPress,
|
36 |
+
you should use **Syndication --> Options**.
|
37 |
+
|
38 |
+
* FILE STRUCTURE REORGANIZATION: Due to a combination of changing styles
|
39 |
+
for FeedWordPress plugins and lingering bugs in the FeedWordPress admin
|
40 |
+
menu code, the code for FeedWordPress is now contained in two different
|
41 |
+
PHP files, which should be installed together in a subdirectory of your
|
42 |
+
plugins directory named `feedwordpress`. (See README.text for
|
43 |
+
installation and upgrade instructions relating to the change.)
|
44 |
+
|
45 |
+
* MULTIPLE CATEGORIES SETTING: Some feeds use non-standard methods to
|
46 |
+
indicate multiple categories within a single category element. (The most
|
47 |
+
popular site to do this is del.icio.us, which separates tags with a
|
48 |
+
space.) FeedWordPress now allows you to set an optional setting, for any
|
49 |
+
feed which does this, indicating the character or characters used to
|
50 |
+
divide multiple categories, using a Perl-compatible regular expression.
|
51 |
+
(In the case of del.icio.us feeds, FeedWordPress will automatically use
|
52 |
+
\s for the pattern without your having to do any further configuration.)
|
53 |
+
To turn this setting on, simply use the "Edit" link for the feed that
|
54 |
+
you want to turn it on for.
|
55 |
+
|
56 |
+
* REGULAR EXPRESSION BUG FIXED: Eliminated a minor bug in the regular
|
57 |
+
expressions for e-mail addresses (used in parsing RSS `author`
|
58 |
+
elements), which could produce unsightly error messages for some users
|
59 |
+
parsing RSS 2.0 feeds.
|
60 |
+
|
61 |
+
* DATE / UPDATE BUG FIXED: A bug in date handling was eliminated that may
|
62 |
+
have caused problems if any of (1) WordPress, or (2) PHP, or (3) your
|
63 |
+
web server, or (4) your MySQL server, has been set to use a different
|
64 |
+
time zone from the one that any of the others is set to use. If
|
65 |
+
FeedWordPress has not been properly updating updated posts, or has been
|
66 |
+
updating posts when there shouldn't be any changes for the update, this
|
67 |
+
release may solve that problem.
|
68 |
+
|
69 |
+
* GOOGLE READER BUGS FIXED: A couple of bugs that made it difficult for
|
70 |
+
FeedWordPress to interact with Google Reader public feeds have been
|
71 |
+
fixed. Firstly, if you encountered an error message reading "There was a
|
72 |
+
problem adding the newsfeed. [SQL: ]" when you tried to add the feed,
|
73 |
+
the cause of this error has been fixed. Secondly, if you succeeded in
|
74 |
+
getting FeedWordPress to check a Google Reader feed, only to find that
|
75 |
+
the title of posts had junk squashed on to the end of them, that bug
|
76 |
+
has been fixed too. To fix this bug, you must install the newest version
|
77 |
+
of the optional MagpieRSS upgrade.
|
78 |
+
|
79 |
+
* FILTER PARAMETERS: Due to an old, old bug in WordPress 1.5.0 (which was
|
80 |
+
what was available back when I first wrote the filter interface),
|
81 |
+
FeedWordPress has traditionally only passed one parameter to
|
82 |
+
syndicated_item and syndicated_post filters functions -- an array
|
83 |
+
containing either the Magpie representation of a syndicated item from
|
84 |
+
the feed, or the database representation of a post about to be inserted
|
85 |
+
into the WordPress database. If you needed information about the feed
|
86 |
+
that the item came from, this was accessible only through a pair of
|
87 |
+
global variables, $fwp_channel and $fwp_feedmeta.
|
88 |
+
|
89 |
+
Since it's been a pretty long time since WordPress 1.5.0 was in
|
90 |
+
widespread usage, I have gone ahead and added an optional second
|
91 |
+
parameter to the invocation of the syndicated_item and syndicated_post
|
92 |
+
filters. If you have written a filter for FeedWordPress that uses either
|
93 |
+
of these hooks, you can now register that filter to accept 2 parameters.
|
94 |
+
If you do so, the second parameter will be a SyndicatedPost object,
|
95 |
+
which, among other things, allows you to access information about the
|
96 |
+
feed from which an item is syndicated using the $post->feed and the
|
97 |
+
$post->feedmeta elements (where $post is the name of the second
|
98 |
+
parameter).
|
99 |
+
|
100 |
+
NOTE THAT THE OLD GLOBAL VARIABLES ARE STILL AVAILABLE, for the time
|
101 |
+
being at least, so existing filters will not break with the upgrade.
|
102 |
+
They should be considered deprecated, however, and may be eliminated in
|
103 |
+
the future.
|
104 |
+
|
105 |
+
* FILTER CHANGE / BUGFIX: the array that is passed as the first argument
|
106 |
+
syndicated_post filters no longer is no longer backslash-escaped for
|
107 |
+
MySQL when filters are called. This was originally a bug, or an
|
108 |
+
oversight; the contents of the array should only be escaped for the
|
109 |
+
database *after* they have gone through all filters. IF YOU HAVE WRITTEN
|
110 |
+
ANY syndicated_post FILTERS THAT PRESUME THE OLD BEHAVIOR OF PASSING IN
|
111 |
+
STRINGS THAT ARE ALREADY BACKSLASH-ESCAPED, UPDATE YOUR FILTERS
|
112 |
+
ACCORDINGLY.
|
113 |
+
|
114 |
+
* OTHER MINOR BUGFIXES AND INTERNAL CHANGES: The internal architecture of
|
115 |
+
FeedWordPress has been significantly changed to make the code more
|
116 |
+
modular and clean; hopefully this should help reduce the number of
|
117 |
+
compatibility updates that are needed, and make them easier and quicker
|
118 |
+
when they are needed.
|
119 |
|
120 |
+
Changes from 0.98 to 0.981
|
121 |
+
--------------------------
|
122 |
Version 0.981 is a narrowly targeted bugfix and compatibility release, whose
|
123 |
main purpose is to resolve a major outstanding problem: the incompatibility
|
124 |
between version 0.98 of WordPress and the recently released WordPress 2.1.
|
OPTIONAL/wp-includes/rss.php
CHANGED
@@ -4,7 +4,7 @@
|
|
4 |
* Author: Kellan Elliot-McCrea <kellan@protest.net>
|
5 |
* WordPress development team <http://www.wordpress.org/>
|
6 |
* Charles Johnson <technophilia@radgeek.com>
|
7 |
-
* Version: 0.
|
8 |
* License: GPL
|
9 |
*
|
10 |
* Provenance:
|
@@ -99,7 +99,7 @@ $wp_encoding = get_settings('blog_charset');
|
|
99 |
define('MAGPIE_OUTPUT_ENCODING', ($wp_encoding?$wp_encoding:'ISO-8859-1'));
|
100 |
|
101 |
################################################################################
|
102 |
-
## rss_parse.inc: from MagpieRSS 0.
|
103 |
################################################################################
|
104 |
|
105 |
/**
|
@@ -126,27 +126,92 @@ class MagpieRSS {
|
|
126 |
var $WARNING = "";
|
127 |
|
128 |
// define some constants
|
129 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
130 |
var $_ATOM_CONTENT_CONSTRUCTS = array(
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
var $_XHTML_CONTENT_CONSTRUCTS = array('body', 'div');
|
136 |
var $_KNOWN_ENCODINGS = array('UTF-8', 'US-ASCII', 'ISO-8859-1');
|
137 |
|
138 |
// parser variables, useless if you're not a parser, treat as private
|
139 |
-
var $stack
|
|
|
140 |
var $inchannel = false;
|
141 |
var $initem = false;
|
142 |
-
|
143 |
var $incontent = array(); // non-empty if in namespaced XML content field
|
144 |
-
var $
|
|
|
145 |
|
146 |
var $intextinput = false;
|
147 |
var $inimage = false;
|
|
|
148 |
var $current_namespace = false;
|
149 |
-
|
|
|
150 |
/**
|
151 |
* Set up XML parser, parse source, and return populated RSS object..
|
152 |
*
|
@@ -176,7 +241,7 @@ class MagpieRSS {
|
|
176 |
*
|
177 |
*/
|
178 |
function MagpieRSS ($source, $output_encoding='ISO-8859-1',
|
179 |
-
$input_encoding=null, $detect_encoding=true)
|
180 |
{
|
181 |
# if PHP xml isn't compiled in, die
|
182 |
#
|
@@ -207,7 +272,9 @@ class MagpieRSS {
|
|
207 |
'feed_start_element', 'feed_end_element' );
|
208 |
|
209 |
xml_set_character_data_handler( $this->parser, 'feed_cdata' );
|
210 |
-
|
|
|
|
|
211 |
$status = xml_parse( $this->parser, $source );
|
212 |
|
213 |
if (! $status ) {
|
@@ -227,67 +294,114 @@ class MagpieRSS {
|
|
227 |
$this->normalize();
|
228 |
}
|
229 |
|
230 |
-
function feed_start_element($p, $element, &$
|
231 |
-
$el =
|
232 |
-
|
233 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
234 |
// check for a namespace, and split if found
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
239 |
}
|
240 |
-
|
241 |
-
|
|
|
|
|
242 |
}
|
243 |
}
|
244 |
|
|
|
|
|
245 |
# if feed type isn't set, then this is first element of feed
|
246 |
# identify feed from root element
|
247 |
#
|
248 |
if (!isset($this->feed_type) ) {
|
249 |
if ( $el == 'rdf' ) {
|
250 |
$this->feed_type = RSS;
|
|
|
251 |
$this->feed_version = '1.0';
|
252 |
}
|
253 |
elseif ( $el == 'rss' ) {
|
254 |
$this->feed_type = RSS;
|
|
|
255 |
$this->feed_version = $attrs['version'];
|
256 |
}
|
257 |
elseif ( $el == 'feed' ) {
|
258 |
$this->feed_type = ATOM;
|
259 |
-
|
|
|
|
|
260 |
$this->feed_version = '1.0';
|
261 |
-
|
262 |
-
|
263 |
-
|
264 |
-
|
265 |
$this->inchannel = true;
|
266 |
}
|
267 |
return;
|
268 |
}
|
269 |
-
|
270 |
// if we're inside a namespaced content construct, treat tags as text
|
271 |
if ( !empty($this->incontent) )
|
272 |
{
|
273 |
-
|
274 |
-
|
275 |
-
|
276 |
-
|
277 |
-
|
278 |
-
|
279 |
-
|
280 |
-
|
281 |
-
|
282 |
-
|
283 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
284 |
}
|
285 |
-
|
286 |
-
|
287 |
-
{
|
288 |
$this->inchannel = true;
|
289 |
}
|
290 |
-
|
291 |
elseif ($el == 'item' or $el == 'entry' )
|
292 |
{
|
293 |
$this->initem = true;
|
@@ -316,328 +430,378 @@ class MagpieRSS {
|
|
316 |
|
317 |
// set stack[0] to current element
|
318 |
else {
|
319 |
-
|
320 |
-
|
321 |
-
|
322 |
-
|
323 |
-
|
324 |
-
|
325 |
-
|
326 |
-
|
327 |
-
|
328 |
-
|
329 |
-
|
330 |
-
|
331 |
-
|
332 |
-
|
333 |
-
|
334 |
-
|
335 |
-
|
336 |
-
|
337 |
-
|
338 |
-
// assume that everything accepts namespaced XML
|
339 |
-
// (that will pass through some non-validating feeds;
|
340 |
-
// but so what? this isn't a validating parser)
|
341 |
-
$this->incontent = array();
|
342 |
-
array_push($this->incontent, $el); // start a stack
|
343 |
-
|
344 |
-
if (
|
345 |
-
isset($attrs['type'])
|
346 |
-
and trim(strtolower($attrs['type']))=='xhtml'
|
347 |
-
) {
|
348 |
-
$this->exclude_top = true;
|
349 |
-
} else {
|
350 |
-
$this->exclude_top = false;
|
351 |
-
}
|
352 |
-
}
|
353 |
-
# Handle inline XHTML body elements --CWJ
|
354 |
-
elseif (
|
355 |
-
($this->current_namespace=='xhtml' or (isset($attrs['xmlns']) and $attrs['xmlns'] == 'http://www.w3.org/1999/xhtml'))
|
356 |
-
and in_array($el, $this->_XHTML_CONTENT_CONSTRUCTS) )
|
357 |
-
{
|
358 |
-
$this->current_namespace = 'xhtml';
|
359 |
-
$this->incontent = array();
|
360 |
-
array_push($this->incontent, $el); // start a stack
|
361 |
-
$this->exclude_top = false;
|
362 |
-
}
|
363 |
|
364 |
-
|
365 |
-
|
366 |
-
|
367 |
-
|
368 |
-
|
369 |
|
370 |
-
|
371 |
-
array_shift($this->stack);
|
372 |
-
array_unshift($this->stack, $el.'#'.($n+1));
|
373 |
-
$elpath = join('_', array_reverse($this->stack));
|
374 |
-
}
|
375 |
|
376 |
-
|
377 |
-
|
378 |
-
|
379 |
-
|
380 |
-
|
381 |
-
|
382 |
-
|
383 |
-
|
384 |
-
|
385 |
-
|
386 |
-
|
387 |
-
|
388 |
-
|
389 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
390 |
}
|
391 |
}
|
392 |
-
|
393 |
|
394 |
-
|
395 |
function feed_cdata ($p, $text) {
|
396 |
-
|
397 |
if ($this->incontent) {
|
398 |
-
|
399 |
-
|
400 |
-
else {
|
401 |
-
$current_el = join('_', array_reverse($this->stack));
|
402 |
$this->append($current_el, $text);
|
403 |
}
|
404 |
}
|
405 |
|
406 |
function feed_end_element ($p, $el) {
|
407 |
-
|
408 |
-
|
409 |
-
|
410 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
411 |
|
412 |
-
|
413 |
-
|
414 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
415 |
|
416 |
-
|
417 |
-
|
418 |
-
|
|
|
419 |
}
|
420 |
|
421 |
-
|
422 |
-
|
423 |
-
|
424 |
-
|
425 |
-
|
426 |
-
|
427 |
-
|
428 |
-
|
|
|
|
|
|
|
|
|
429 |
}
|
430 |
-
} else { // shift the opening of the content construct off the normal stack
|
431 |
-
array_shift( $this->stack );
|
432 |
-
}
|
433 |
-
}
|
434 |
-
elseif ( $el == 'item' or $el == 'entry' )
|
435 |
-
{
|
436 |
-
$this->items[] = $this->current_item;
|
437 |
-
$this->current_item = array();
|
438 |
-
$this->initem = false;
|
439 |
|
440 |
-
|
441 |
-
|
442 |
-
|
443 |
-
|
444 |
-
|
445 |
-
|
446 |
-
|
447 |
-
|
448 |
-
|
449 |
-
|
450 |
-
|
451 |
-
|
452 |
-
|
453 |
-
|
454 |
-
|
455 |
-
|
456 |
-
|
457 |
-
|
458 |
-
|
459 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
460 |
}
|
461 |
-
|
462 |
-
|
463 |
function concat (&$str1, $str2="") {
|
464 |
if (!isset($str1) ) {
|
465 |
$str1="";
|
466 |
}
|
467 |
$str1 .= $str2;
|
468 |
}
|
469 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
470 |
function append_content($text) {
|
471 |
-
|
472 |
-
|
473 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
474 |
} else {
|
475 |
-
|
476 |
}
|
477 |
-
|
478 |
-
|
479 |
if ($this->current_namespace) {
|
480 |
-
|
481 |
} else {
|
482 |
-
|
483 |
}
|
484 |
-
|
485 |
}
|
486 |
|
487 |
// smart append - field and namespace aware
|
488 |
function append($el, $text) {
|
489 |
-
|
490 |
-
return;
|
491 |
-
}
|
492 |
-
if ( $this->current_namespace )
|
493 |
-
{
|
494 |
-
if ( $this->initem ) {
|
495 |
-
$this->concat(
|
496 |
-
$this->current_item[ $this->current_namespace ][ $el ], $text);
|
497 |
-
}
|
498 |
-
elseif ($this->inchannel) {
|
499 |
-
$this->concat(
|
500 |
-
$this->channel[ $this->current_namespace][ $el ], $text );
|
501 |
-
}
|
502 |
-
elseif ($this->intextinput) {
|
503 |
-
$this->concat(
|
504 |
-
$this->textinput[ $this->current_namespace][ $el ], $text );
|
505 |
-
}
|
506 |
-
elseif ($this->inimage) {
|
507 |
-
$this->concat(
|
508 |
-
$this->image[ $this->current_namespace ][ $el ], $text );
|
509 |
-
}
|
510 |
-
}
|
511 |
-
else {
|
512 |
-
if ( $this->initem ) {
|
513 |
-
$this->concat(
|
514 |
-
$this->current_item[ $el ], $text);
|
515 |
-
}
|
516 |
-
elseif ($this->intextinput) {
|
517 |
-
$this->concat(
|
518 |
-
$this->textinput[ $el ], $text );
|
519 |
-
}
|
520 |
-
elseif ($this->inimage) {
|
521 |
-
$this->concat(
|
522 |
-
$this->image[ $el ], $text );
|
523 |
-
}
|
524 |
-
elseif ($this->inchannel) {
|
525 |
-
$this->concat(
|
526 |
-
$this->channel[ $el ], $text );
|
527 |
-
}
|
528 |
-
|
529 |
-
}
|
530 |
}
|
531 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
532 |
// smart count - field and namespace aware
|
533 |
function element_count ($el, $set = NULL) {
|
534 |
-
|
535 |
-
|
536 |
-
|
537 |
-
|
538 |
-
|
539 |
-
if ( $this->initem ) {
|
540 |
-
if (!is_null($set)) { $this->current_item[ $this->current_namespace ][ $el.'#' ] = $set; }
|
541 |
-
$ret = (isset($this->current_item[ $this->current_namespace ][ $el.'#' ]) ?
|
542 |
-
$this->current_item[ $this->current_namespace ][ $el.'#' ] : 0);
|
543 |
-
}
|
544 |
-
elseif ($this->inchannel) {
|
545 |
-
if (!is_null($set)) { $this->channel[ $this->current_namespace ][ $el.'#' ] = $set; }
|
546 |
-
$ret = (isset($this->channel[ $this->current_namespace][ $el.'#' ]) ?
|
547 |
-
$this->channel[ $this->current_namespace][ $el.'#' ] : 0);
|
548 |
-
}
|
549 |
-
}
|
550 |
-
else {
|
551 |
-
if ( $this->initem ) {
|
552 |
-
if (!is_null($set)) { $this->current_item[ $el.'#' ] = $set; }
|
553 |
-
$ret = (isset($this->current_item[ $el.'#' ]) ?
|
554 |
-
$this->current_item[ $el.'#' ] : 0);
|
555 |
-
}
|
556 |
-
elseif ($this->inchannel) {
|
557 |
-
if (!is_null($set)) {$this->channel[ $el.'#' ] = $set; }
|
558 |
-
$ret = (isset($this->channel[ $el.'#' ]) ?
|
559 |
-
$this->channel[ $el.'#' ] : 0);
|
560 |
-
}
|
561 |
-
}
|
562 |
-
return $ret;
|
563 |
}
|
564 |
|
565 |
function normalize_enclosure (&$source, $from, &$dest, $to, $i) {
|
566 |
-
|
567 |
-
|
568 |
-
|
569 |
-
|
570 |
-
|
571 |
-
|
572 |
-
|
573 |
-
|
574 |
-
|
575 |
-
|
576 |
-
|
577 |
-
|
578 |
-
|
579 |
-
|
580 |
-
|
581 |
-
|
582 |
-
|
583 |
}
|
584 |
|
585 |
function normalize_atom_person (&$source, $person, &$dest, $to, $i) {
|
586 |
-
|
587 |
-
|
588 |
|
589 |
-
|
590 |
-
|
591 |
-
|
592 |
|
593 |
-
|
594 |
-
|
595 |
-
|
596 |
|
597 |
-
|
598 |
-
|
599 |
-
|
600 |
-
|
601 |
-
|
602 |
-
|
603 |
-
|
604 |
-
|
605 |
-
|
606 |
-
|
607 |
-
|
608 |
-
|
609 |
-
|
610 |
}
|
611 |
|
612 |
// Normalize Atom 1.0 and RSS 2.0 categories to Dublin Core...
|
613 |
function normalize_category (&$source, $from, &$dest, $to, $i) {
|
614 |
-
|
615 |
-
|
616 |
-
|
617 |
-
// first normalize category elements: Atom 1.0 <=> RSS 2.0
|
618 |
-
if ( isset($source["{$cat_id}@term"]) ) { // category identifier
|
619 |
-
$source[$cat_id] = $source["{$cat_id}@term"];
|
620 |
-
} elseif ( $this->feed_type == RSS ) {
|
621 |
-
$source["{$cat_id}@term"] = $source[$cat_id];
|
622 |
-
}
|
623 |
-
|
624 |
-
if ( isset($source["{$cat_id}@scheme"]) ) { // URI to taxonomy
|
625 |
-
$source["{$cat_id}@domain"] = $source["{$cat_id}@scheme"];
|
626 |
-
} elseif ( isset($source["{$cat_id}@domain"]) ) {
|
627 |
-
$source["{$cat_id}@scheme"] = $source["{$cat_id}@domain"];
|
628 |
-
}
|
629 |
|
630 |
-
|
631 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
632 |
}
|
633 |
|
634 |
// ... or vice versa
|
635 |
function normalize_dc_subject (&$source, $from, &$dest, $to, $i) {
|
636 |
-
|
637 |
-
|
638 |
|
639 |
-
|
640 |
-
|
641 |
}
|
642 |
|
643 |
// simplify the logic for normalize(). Makes sure that count of elements and
|
@@ -645,120 +809,124 @@ class MagpieRSS {
|
|
645 |
// with things like attributes or change formats or the like, pass it a
|
646 |
// callback to handle each element.
|
647 |
function normalize_element (&$source, $from, &$dest, $to, $via = NULL) {
|
648 |
-
|
649 |
-
|
650 |
-
|
651 |
-
|
652 |
-
|
653 |
-
|
654 |
|
655 |
-
|
656 |
-
|
657 |
-
|
658 |
-
|
659 |
-
|
660 |
-
|
661 |
-
|
662 |
-
|
663 |
-
|
664 |
-
|
665 |
-
|
666 |
}
|
667 |
|
668 |
function normalize () {
|
669 |
// if atom populate rss fields and normalize 0.3 and 1.0 feeds
|
670 |
if ( $this->is_atom() ) {
|
671 |
-
|
672 |
-
|
673 |
-
|
674 |
-
|
675 |
-
|
676 |
-
|
677 |
-
|
678 |
-
|
679 |
-
|
680 |
-
|
681 |
-
|
682 |
-
|
683 |
-
|
684 |
-
// Atom elements to RSS elements
|
685 |
-
$this->normalize_element($this->channel, 'subtitle', $this->channel, 'description');
|
686 |
-
|
687 |
-
if ( isset($this->channel['logo']) ) {
|
688 |
-
$this->normalize_element($this->channel, 'logo', $this->image, 'url');
|
689 |
-
$this->normalize_element($this->channel, 'link', $this->image, 'link');
|
690 |
-
$this->normalize_element($this->channel, 'title', $this->image, 'title');
|
691 |
-
}
|
692 |
-
|
693 |
-
for ( $i = 0; $i < count($this->items); $i++) {
|
694 |
-
$item = $this->items[$i];
|
695 |
|
696 |
-
|
697 |
-
|
698 |
-
|
699 |
-
|
700 |
-
|
701 |
-
|
702 |
-
|
703 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
704 |
|
705 |
-
|
706 |
-
|
707 |
-
|
708 |
-
|
709 |
-
|
710 |
-
|
711 |
-
|
712 |
-
|
713 |
-
|
714 |
-
|
715 |
-
|
716 |
-
|
717 |
-
|
718 |
-
|
719 |
-
|
720 |
-
|
|
|
|
|
721 |
|
722 |
-
|
723 |
-
|
724 |
-
|
725 |
-
|
726 |
-
|
727 |
-
|
728 |
-
|
729 |
-
|
730 |
-
|
731 |
-
|
732 |
-
}
|
733 |
}
|
|
|
734 |
}
|
|
|
|
|
735 |
|
736 |
-
|
737 |
-
|
738 |
-
|
739 |
-
|
740 |
-
|
741 |
-
|
742 |
|
743 |
-
|
744 |
-
|
745 |
-
|
746 |
-
|
747 |
-
|
748 |
-
|
749 |
-
|
750 |
|
751 |
-
|
752 |
-
|
753 |
-
|
754 |
-
|
755 |
-
|
756 |
-
|
757 |
-
|
758 |
-
|
759 |
|
760 |
-
|
761 |
-
|
762 |
}
|
763 |
elseif ( $this->is_rss() ) {
|
764 |
// RSS elements to Atom elements
|
@@ -766,38 +934,37 @@ class MagpieRSS {
|
|
766 |
$this->normalize_element($this->channel, 'description', $this->channel, 'subtitle'); // Atom 1.0 (yay wordsmithing!)
|
767 |
$this->normalize_element($this->image, 'url', $this->channel, 'logo');
|
768 |
|
769 |
-
|
770 |
-
|
771 |
-
|
772 |
-
|
773 |
-
|
774 |
-
|
775 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
776 |
|
777 |
-
|
778 |
-
|
779 |
-
|
780 |
-
|
781 |
-
|
782 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
783 |
}
|
784 |
-
|
785 |
-
// Normalized item timestamp
|
786 |
-
if ( $this->is_rss() == '1.0' and isset($item['dc']['date']) ) {
|
787 |
-
$epoch = @parse_w3cdtf($item['dc']['date']);
|
788 |
-
if ($epoch and $epoch > 0) {
|
789 |
-
$item['date_timestamp'] = $epoch;
|
790 |
-
}
|
791 |
-
}
|
792 |
-
elseif ( isset($item['pubdate']) ) {
|
793 |
-
$epoch = @strtotime($item['pubdate']);
|
794 |
-
if ($epoch > 0) {
|
795 |
-
$item['date_timestamp'] = $epoch;
|
796 |
-
}
|
797 |
-
}
|
798 |
-
|
799 |
-
$this->items[$i] = $item;
|
800 |
-
}
|
801 |
}
|
802 |
}
|
803 |
|
@@ -835,7 +1002,7 @@ class MagpieRSS {
|
|
835 |
$this->encoding = $out_enc;
|
836 |
xml_parser_set_option($parser, XML_OPTION_TARGET_ENCODING, $out_enc);
|
837 |
}
|
838 |
-
|
839 |
return array($parser, $source);
|
840 |
}
|
841 |
|
@@ -955,30 +1122,52 @@ class MagpieRSS {
|
|
955 |
// magic ID function for multiple elemenets.
|
956 |
// can be called as static MagpieRSS::element_id()
|
957 |
function element_id ($el, $counter) {
|
958 |
-
|
959 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
960 |
} // end class RSS
|
961 |
|
962 |
-
function map_attrs($k, $v) {
|
963 |
-
return "$k=\"$v\"";
|
964 |
-
}
|
965 |
|
966 |
// patch to support medieval versions of PHP4.1.x,
|
967 |
// courtesy, Ryan Currie, ryan@digibliss.com
|
968 |
|
969 |
if (!function_exists('array_change_key_case')) {
|
970 |
-
|
971 |
-
|
972 |
|
973 |
|
974 |
-
|
975 |
if ($case==CASE_LOWER) $cmd='strtolower';
|
976 |
elseif ($case==CASE_UPPER) $cmd='strtoupper';
|
977 |
foreach($array as $key=>$value) {
|
978 |
$output[$cmd($key)]=$value;
|
979 |
}
|
980 |
return $output;
|
981 |
-
|
982 |
|
983 |
}
|
984 |
|
@@ -1012,7 +1201,7 @@ require_once( dirname(__FILE__) . '/class-snoopy.php');
|
|
1012 |
version will be return, if it exists (and if MAGPIE_CACHE_FRESH_ONLY is off)
|
1013 |
\*=======================================================================*/
|
1014 |
|
1015 |
-
define('MAGPIE_VERSION', '0.
|
1016 |
|
1017 |
$MAGPIE_ERROR = "";
|
1018 |
|
@@ -1030,7 +1219,7 @@ function fetch_rss ($url) {
|
|
1030 |
// fetch file, and parse it
|
1031 |
$resp = _fetch_remote_file( $url );
|
1032 |
if ( is_success( $resp->status ) ) {
|
1033 |
-
return _response_to_rss( $resp );
|
1034 |
}
|
1035 |
else {
|
1036 |
error("Failed to fetch $url and cache is off");
|
@@ -1103,7 +1292,7 @@ function fetch_rss ($url) {
|
|
1103 |
return $rss;
|
1104 |
}
|
1105 |
elseif ( is_success( $resp->status ) ) {
|
1106 |
-
$rss = _response_to_rss( $resp );
|
1107 |
if ( $rss ) {
|
1108 |
if (MAGPIE_DEBUG > 1) {
|
1109 |
debug("Fetch successful");
|
@@ -1216,12 +1405,13 @@ function _fetch_remote_file ($url, $headers = "" ) {
|
|
1216 |
Input: an HTTP response object (see Snoopy)
|
1217 |
Output: parsed RSS object (see rss_parse)
|
1218 |
\*=======================================================================*/
|
1219 |
-
function _response_to_rss ($resp) {
|
1220 |
-
$rss = new MagpieRSS( $resp->results, MAGPIE_OUTPUT_ENCODING, MAGPIE_INPUT_ENCODING, MAGPIE_DETECT_ENCODING );
|
1221 |
|
1222 |
// if RSS parsed successfully
|
1223 |
if ( $rss and !$rss->ERROR) {
|
1224 |
-
|
|
|
1225 |
// find Etag, and Last-Modified
|
1226 |
foreach($resp->headers as $h) {
|
1227 |
// 2003-03-02 - Nicola Asuni (www.tecnick.com) - fixed bug "Undefined offset: 1"
|
@@ -1233,6 +1423,8 @@ function _response_to_rss ($resp) {
|
|
1233 |
$val = "";
|
1234 |
}
|
1235 |
|
|
|
|
|
1236 |
if ( $field == 'ETag' ) {
|
1237 |
$rss->etag = $val;
|
1238 |
}
|
@@ -1591,6 +1783,185 @@ function parse_w3cdtf ( $date_str ) {
|
|
1591 |
}
|
1592 |
}
|
1593 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1594 |
################################################################################
|
1595 |
## WordPress: wp_rss(), get_rss() ##############################################
|
1596 |
################################################################################
|
4 |
* Author: Kellan Elliot-McCrea <kellan@protest.net>
|
5 |
* WordPress development team <http://www.wordpress.org/>
|
6 |
* Charles Johnson <technophilia@radgeek.com>
|
7 |
+
* Version: 0.85wp (2007.09.24)
|
8 |
* License: GPL
|
9 |
*
|
10 |
* Provenance:
|
99 |
define('MAGPIE_OUTPUT_ENCODING', ($wp_encoding?$wp_encoding:'ISO-8859-1'));
|
100 |
|
101 |
################################################################################
|
102 |
+
## rss_parse.inc: from MagpieRSS 0.85 ##########################################
|
103 |
################################################################################
|
104 |
|
105 |
/**
|
126 |
var $WARNING = "";
|
127 |
|
128 |
// define some constants
|
129 |
+
var $_XMLNS_FAMILIAR = array (
|
130 |
+
'http://www.w3.org/2005/Atom' => 'atom' /* 1.0 */,
|
131 |
+
'http://purl.org/atom/ns#' => 'atom' /* pre-1.0 */,
|
132 |
+
'http://purl.org/rss/1.0/' => 'rss' /* 1.0 */,
|
133 |
+
'http://backend.userland.com/RSS2' => 'rss' /* 2.0 */,
|
134 |
+
'http://www.w3.org/1999/02/22-rdf-syntax-ns#' => 'rdf',
|
135 |
+
'http://www.w3.org/1999/xhtml' => 'xhtml',
|
136 |
+
'http://purl.org/dc/elements/1.1/' => 'dc',
|
137 |
+
'http://purl.org/dc/terms/' => 'dcterms',
|
138 |
+
'http://purl.org/rss/1.0/modules/content/' => 'content',
|
139 |
+
'http://purl.org/rss/1.0/modules/syndication/' => 'sy',
|
140 |
+
'http://purl.org/rss/1.0/modules/taxonomy/' => 'taxo',
|
141 |
+
'http://purl.org/rss/1.0/modules/dc/' => 'dc',
|
142 |
+
'http://wellformedweb.org/CommentAPI/' => 'wfw',
|
143 |
+
'http://webns.net/mvcb/' => 'admin',
|
144 |
+
'http://purl.org/rss/1.0/modules/annotate/' => 'annotate',
|
145 |
+
'http://xmlns.com/foaf/0.1/' => 'foaf',
|
146 |
+
'http://madskills.com/public/xml/rss/module/trackback/' => 'trackback',
|
147 |
+
'http://web.resource.org/cc/' => 'cc'
|
148 |
+
);
|
149 |
+
|
150 |
+
var $_XMLBASE_RESOLVE = array (
|
151 |
+
// Atom 0.3 and 1.0 xml:base support
|
152 |
+
'atom' => array (
|
153 |
+
'link' => array ('href' => true),
|
154 |
+
'content' => array ('src' => true, '*xml' => true, '*html' => true),
|
155 |
+
'summary' => array ('*xml' => true, '*html' => true),
|
156 |
+
'title' => array ('*xml' => true, '*html' => true),
|
157 |
+
'rights' => array ('*xml' => true, '*html' => true),
|
158 |
+
'subtitle' => array ('*xml' => true, '*html' => true),
|
159 |
+
'info' => array('*xml' => true, '*html' => true),
|
160 |
+
'tagline' => array('*xml' => true, '*html' => true),
|
161 |
+
'copyright' => array ('*xml' => true, '*html' => true),
|
162 |
+
'generator' => array ('uri' => true, 'url' => true),
|
163 |
+
'uri' => array ('*content' => true),
|
164 |
+
'url' => array ('*content' => true),
|
165 |
+
'icon' => array ('*content' => true),
|
166 |
+
'logo' => array ('*content' => true),
|
167 |
+
),
|
168 |
+
|
169 |
+
// for inline namespaced XHTML
|
170 |
+
'xhtml' => array (
|
171 |
+
'a' => array ('href' => true),
|
172 |
+
'applet' => array('codebase' => true),
|
173 |
+
'area' => array('href' => true),
|
174 |
+
'blockquote' => array('cite' => true),
|
175 |
+
'body' => array('background' => true),
|
176 |
+
'del' => array('cite' => true),
|
177 |
+
'form' => array('action' => true),
|
178 |
+
'frame' => array('longdesc' => true, 'src' => true),
|
179 |
+
'iframe' => array('longdesc' => true, 'iframe' => true, 'src' => true),
|
180 |
+
'head' => array('profile' => true),
|
181 |
+
'img' => array('longdesc' => true, 'src' => true, 'usemap' => true),
|
182 |
+
'input' => array('src' => true, 'usemap' => true),
|
183 |
+
'ins' => array('cite' => true),
|
184 |
+
'link' => array('href' => true),
|
185 |
+
'object' => array('classid' => true, 'codebase' => true, 'data' => true, 'usemap' => true),
|
186 |
+
'q' => array('cite' => true),
|
187 |
+
'script' => array('src' => true),
|
188 |
+
),
|
189 |
+
);
|
190 |
+
|
191 |
var $_ATOM_CONTENT_CONSTRUCTS = array(
|
192 |
+
'content', 'summary', 'title', /* common */
|
193 |
+
'info', 'tagline', 'copyright', /* Atom 0.3 */
|
194 |
+
'rights', 'subtitle', /* Atom 1.0 */
|
195 |
+
);
|
196 |
var $_XHTML_CONTENT_CONSTRUCTS = array('body', 'div');
|
197 |
var $_KNOWN_ENCODINGS = array('UTF-8', 'US-ASCII', 'ISO-8859-1');
|
198 |
|
199 |
// parser variables, useless if you're not a parser, treat as private
|
200 |
+
var $stack = array('element' => array (), 'xmlns' => array (), 'xml:base' => array ()); // stack of XML data
|
201 |
+
|
202 |
var $inchannel = false;
|
203 |
var $initem = false;
|
204 |
+
|
205 |
var $incontent = array(); // non-empty if in namespaced XML content field
|
206 |
+
var $xml_escape = false; // true when accepting namespaced XML
|
207 |
+
var $exclude_top = false; // true when Atom 1.0 type="xhtml"
|
208 |
|
209 |
var $intextinput = false;
|
210 |
var $inimage = false;
|
211 |
+
var $root_namespaces = array();
|
212 |
var $current_namespace = false;
|
213 |
+
var $working_namespace_table = array();
|
214 |
+
|
215 |
/**
|
216 |
* Set up XML parser, parse source, and return populated RSS object..
|
217 |
*
|
241 |
*
|
242 |
*/
|
243 |
function MagpieRSS ($source, $output_encoding='ISO-8859-1',
|
244 |
+
$input_encoding=null, $detect_encoding=true, $base_uri=null)
|
245 |
{
|
246 |
# if PHP xml isn't compiled in, die
|
247 |
#
|
272 |
'feed_start_element', 'feed_end_element' );
|
273 |
|
274 |
xml_set_character_data_handler( $this->parser, 'feed_cdata' );
|
275 |
+
|
276 |
+
$this->stack['xml:base'] = array($base_uri);
|
277 |
+
|
278 |
$status = xml_parse( $this->parser, $source );
|
279 |
|
280 |
if (! $status ) {
|
294 |
$this->normalize();
|
295 |
}
|
296 |
|
297 |
+
function feed_start_element($p, $element, &$attributes) {
|
298 |
+
$el = strtolower($element);
|
299 |
+
|
300 |
+
$namespaces = end($this->stack['xmlns']);
|
301 |
+
$baseuri = end($this->stack['xml:base']);
|
302 |
+
|
303 |
+
if (isset($attributes['xml:base'])) {
|
304 |
+
$baseuri = Relative_URI::resolve($attributes['xml:base'], $baseuri);
|
305 |
+
}
|
306 |
+
array_push($this->stack['xml:base'], $baseuri);
|
307 |
+
|
308 |
+
// scan for xml namespace declarations. ugly ugly ugly.
|
309 |
+
// theoretically we could use xml_set_start_namespace_decl_handler and
|
310 |
+
// xml_set_end_namespace_decl_handler to handle this more elegantly, but
|
311 |
+
// support for these is buggy
|
312 |
+
foreach ($attributes as $attr => $value) {
|
313 |
+
if ( preg_match('/^xmlns(\:([A-Z_a-z].*))?$/', $attr, $match) ) {
|
314 |
+
$ns = (isset($match[2]) ? $match[2] : '');
|
315 |
+
$namespaces[$ns] = $value;
|
316 |
+
}
|
317 |
+
}
|
318 |
+
|
319 |
+
array_push($this->stack['xmlns'], $namespaces);
|
320 |
+
|
321 |
// check for a namespace, and split if found
|
322 |
+
// Don't munge content tags
|
323 |
+
$ns = $this->namespace($element);
|
324 |
+
if ( empty($this->incontent) ) {
|
325 |
+
$el = strtolower($ns['element']);
|
326 |
+
$this->current_namespace = $ns['effective'];
|
327 |
+
}
|
328 |
+
|
329 |
+
$nsc = $ns['canonical']; $nse = $ns['element'];
|
330 |
+
if ( isset($this->_XMLBASE_RESOLVE[$nsc][$nse]) ) {
|
331 |
+
if (isset($this->_XMLBASE_RESOLVE[$nsc][$nse]['*xml'])) {
|
332 |
+
$attributes['xml:base'] = $baseuri;
|
333 |
}
|
334 |
+
foreach ($attributes as $key => $value) {
|
335 |
+
if (isset($this->_XMLBASE_RESOLVE[$nsc][$nse][strtolower($key)])) {
|
336 |
+
$attributes[$key] = Relative_URI::resolve($attributes[$key], $baseuri);
|
337 |
+
}
|
338 |
}
|
339 |
}
|
340 |
|
341 |
+
$attrs = array_change_key_case($attributes, CASE_LOWER);
|
342 |
+
|
343 |
# if feed type isn't set, then this is first element of feed
|
344 |
# identify feed from root element
|
345 |
#
|
346 |
if (!isset($this->feed_type) ) {
|
347 |
if ( $el == 'rdf' ) {
|
348 |
$this->feed_type = RSS;
|
349 |
+
$this->root_namespaces = array('rss', 'rdf');
|
350 |
$this->feed_version = '1.0';
|
351 |
}
|
352 |
elseif ( $el == 'rss' ) {
|
353 |
$this->feed_type = RSS;
|
354 |
+
$this->root_namespaces = array('rss');
|
355 |
$this->feed_version = $attrs['version'];
|
356 |
}
|
357 |
elseif ( $el == 'feed' ) {
|
358 |
$this->feed_type = ATOM;
|
359 |
+
$this->root_namespaces = array('atom');
|
360 |
+
if ($ns['uri'] == 'http://www.w3.org/2005/Atom') { // Atom 1.0
|
361 |
+
$this->root_namespaces = array('atom');
|
362 |
$this->feed_version = '1.0';
|
363 |
+
}
|
364 |
+
else { // Atom 0.3, probably.
|
365 |
+
$this->feed_version = $attrs['version'];
|
366 |
+
}
|
367 |
$this->inchannel = true;
|
368 |
}
|
369 |
return;
|
370 |
}
|
371 |
+
|
372 |
// if we're inside a namespaced content construct, treat tags as text
|
373 |
if ( !empty($this->incontent) )
|
374 |
{
|
375 |
+
if ((count($this->incontent) > 1) or !$this->exclude_top) {
|
376 |
+
if ($ns['effective']=='xhtml') {
|
377 |
+
$tag = $ns['element'];
|
378 |
+
}
|
379 |
+
else {
|
380 |
+
$tag = $element;
|
381 |
+
$xmlns = 'xmlns';
|
382 |
+
if (strlen($ns['prefix'])>0) {
|
383 |
+
$xmlns = $xmlns . ':' . $ns['prefix'];
|
384 |
+
}
|
385 |
+
$attributes[$xmlns] = $ns['uri']; // make sure it's visible
|
386 |
+
}
|
387 |
+
|
388 |
+
// if tags are inlined, then flatten
|
389 |
+
$attrs_str = join(' ',
|
390 |
+
array_map(array($this, 'map_attrs'),
|
391 |
+
array_keys($attributes),
|
392 |
+
array_values($attributes) )
|
393 |
+
);
|
394 |
+
|
395 |
+
if (strlen($attrs_str) > 0) { $attrs_str = ' '.$attrs_str; }
|
396 |
+
$this->append_content( "<{$tag}{$attrs_str}>" );
|
397 |
+
}
|
398 |
+
array_push($this->incontent, $ns); // stack for parsing content XML
|
399 |
}
|
400 |
+
|
401 |
+
elseif ( $el == 'channel' ) {
|
|
|
402 |
$this->inchannel = true;
|
403 |
}
|
404 |
+
|
405 |
elseif ($el == 'item' or $el == 'entry' )
|
406 |
{
|
407 |
$this->initem = true;
|
430 |
|
431 |
// set stack[0] to current element
|
432 |
else {
|
433 |
+
// Atom support many links per containing element.
|
434 |
+
// Magpie treats link elements of type rel='alternate'
|
435 |
+
// as being equivalent to RSS's simple link element.
|
436 |
+
|
437 |
+
$atom_link = false;
|
438 |
+
if ($this->feed_type == ATOM and $el == 'link') {
|
439 |
+
$atom_link = true;
|
440 |
+
if (isset($attrs['rel']) and $attrs['rel'] != 'alternate') {
|
441 |
+
$el = $el . "_" . $attrs['rel']; // pseudo-element names for Atom link elements
|
442 |
+
}
|
443 |
+
}
|
444 |
+
# handle atom content constructs
|
445 |
+
elseif ( $this->feed_type == ATOM and in_array($el, $this->_ATOM_CONTENT_CONSTRUCTS) )
|
446 |
+
{
|
447 |
+
// avoid clashing w/ RSS mod_content
|
448 |
+
if ($el == 'content' ) {
|
449 |
+
$el = 'atom_content';
|
450 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
451 |
|
452 |
+
// assume that everything accepts namespaced XML
|
453 |
+
// (that will pass through some non-validating feeds;
|
454 |
+
// but so what? this isn't a validating parser)
|
455 |
+
$this->incontent = array();
|
456 |
+
array_push($this->incontent, $ns); // start a stack
|
457 |
|
458 |
+
$this->xml_escape = $this->accepts_namespaced_xml($attrs);
|
|
|
|
|
|
|
|
|
459 |
|
460 |
+
if ( isset($attrs['type']) and trim(strtolower($attrs['type']))=='xhtml') {
|
461 |
+
$this->exclude_top = true;
|
462 |
+
} else {
|
463 |
+
$this->exclude_top = false;
|
464 |
+
}
|
465 |
+
}
|
466 |
+
# Handle inline XHTML body elements --CWJ
|
467 |
+
elseif ($ns['effective']=='xhtml' and in_array($el, $this->_XHTML_CONTENT_CONSTRUCTS)) {
|
468 |
+
$this->current_namespace = 'xhtml';
|
469 |
+
$this->incontent = array();
|
470 |
+
array_push($this->incontent, $ns); // start a stack
|
471 |
+
|
472 |
+
$this->xml_escape = true;
|
473 |
+
$this->exclude_top = false;
|
474 |
+
}
|
475 |
+
|
476 |
+
array_unshift($this->stack['element'], $el);
|
477 |
+
$elpath = join('_', array_reverse($this->stack['element']));
|
478 |
+
|
479 |
+
$n = $this->element_count($elpath);
|
480 |
+
$this->element_count($elpath, $n+1);
|
481 |
+
|
482 |
+
if ($n > 0) {
|
483 |
+
array_shift($this->stack['element']);
|
484 |
+
array_unshift($this->stack['element'], $el.'#'.($n+1));
|
485 |
+
$elpath = join('_', array_reverse($this->stack['element']));
|
486 |
+
}
|
487 |
+
|
488 |
+
// this makes the baby Jesus cry, but we can't do it in normalize()
|
489 |
+
// because we've made the element name for Atom links unpredictable
|
490 |
+
// by tacking on the relation to the end. -CWJ
|
491 |
+
if ($atom_link and isset($attrs['href'])) {
|
492 |
+
$this->append($elpath, $attrs['href']);
|
493 |
+
}
|
494 |
+
|
495 |
+
// add attributes
|
496 |
+
if (count($attrs) > 0) {
|
497 |
+
$this->append($elpath.'@', join(',', array_keys($attrs)));
|
498 |
+
foreach ($attrs as $attr => $value) {
|
499 |
+
$this->append($elpath.'@'.$attr, $value);
|
500 |
+
}
|
501 |
+
}
|
502 |
}
|
503 |
}
|
|
|
504 |
|
|
|
505 |
function feed_cdata ($p, $text) {
|
|
|
506 |
if ($this->incontent) {
|
507 |
+
if ($this->xml_escape) { $text = htmlspecialchars($text, ENT_COMPAT, $this->encoding); }
|
508 |
+
$this->append_content( $text );
|
509 |
+
} else {
|
510 |
+
$current_el = join('_', array_reverse($this->stack['element']));
|
511 |
$this->append($current_el, $text);
|
512 |
}
|
513 |
}
|
514 |
|
515 |
function feed_end_element ($p, $el) {
|
516 |
+
$closer = $this->namespace($el);
|
517 |
+
|
518 |
+
if ( $this->incontent ) {
|
519 |
+
$opener = array_pop($this->incontent);
|
520 |
+
|
521 |
+
// balance tags properly
|
522 |
+
// note: i don't think this is actually neccessary
|
523 |
+
if ($opener != $closer) {
|
524 |
+
array_push($this->incontent, $opener);
|
525 |
+
$this->append_content("<$el />");
|
526 |
+
} elseif ($this->incontent) { // are we in the content construct still?
|
527 |
+
if ((count($this->incontent) > 1) or !$this->exclude_top) {
|
528 |
+
if ($closer['effective']=='xhtml') {
|
529 |
+
$tag = $closer['element'];
|
530 |
+
}
|
531 |
+
else {
|
532 |
+
$tag = $el;
|
533 |
+
}
|
534 |
+
$this->append_content("</$tag>");
|
535 |
+
}
|
536 |
+
} else { // if we're done with the content construct, shift the opening of the content construct off the normal stack
|
537 |
+
array_shift( $this->stack['element'] );
|
538 |
+
}
|
539 |
+
}
|
540 |
+
elseif ($closer['effective'] == '') {
|
541 |
+
$el = strtolower($closer['element']);
|
542 |
+
if ( $el == 'item' or $el == 'entry' ) {
|
543 |
+
$this->items[] = $this->current_item;
|
544 |
+
$this->current_item = array();
|
545 |
+
$this->initem = false;
|
546 |
+
$this->current_category = 0;
|
547 |
+
}
|
548 |
+
elseif ($this->feed_type == RSS and $el == 'textinput' ) {
|
549 |
+
$this->intextinput = false;
|
550 |
+
}
|
551 |
+
elseif ($this->feed_type == RSS and $el == 'image' ) {
|
552 |
+
$this->inimage = false;
|
553 |
+
}
|
554 |
+
elseif ($el == 'channel' or $el == 'feed' ) {
|
555 |
+
$this->inchannel = false;
|
556 |
+
} else {
|
557 |
+
$nsc = $closer['canonical']; $nse = $closer['element'];
|
558 |
+
if (isset($this->_XMLBASE_RESOLVE[$nsc][$nse]['*content'])) {
|
559 |
+
// Resolve relative URI in content of tag
|
560 |
+
$this->dereference_current_element();
|
561 |
+
}
|
562 |
+
array_shift( $this->stack['element'] );
|
563 |
+
}
|
564 |
+
} else {
|
565 |
+
$nsc = $closer['canonical']; $nse = strtolower($closer['element']);
|
566 |
+
if (isset($this->_XMLBASE_RESOLVE[$nsc][$nse]['*content'])) {
|
567 |
+
// Resolve relative URI in content of tag
|
568 |
+
$this->dereference_current_element();
|
569 |
+
}
|
570 |
+
array_shift( $this->stack['element'] );
|
571 |
+
}
|
572 |
+
|
573 |
+
if ( !$this->incontent ) { // Don't munge the namespace after finishing with elements in namespaced content constructs -CWJ
|
574 |
+
$this->current_namespace = false;
|
575 |
+
}
|
576 |
+
array_pop($this->stack['xmlns']);
|
577 |
+
array_pop($this->stack['xml:base']);
|
578 |
+
}
|
579 |
+
|
580 |
+
// Namespace handling functions
|
581 |
+
function namespace ($element) {
|
582 |
+
$namespaces = end($this->stack['xmlns']);
|
583 |
+
$ns = '';
|
584 |
+
if ( strpos( $element, ':' ) ) {
|
585 |
+
list($ns, $element) = split( ':', $element, 2);
|
586 |
+
}
|
587 |
+
|
588 |
+
$uri = (isset($namespaces[$ns]) ? $namespaces[$ns] : null);
|
589 |
|
590 |
+
if (!is_null($uri)) {
|
591 |
+
$canonical = (
|
592 |
+
isset($this->_XMLNS_FAMILIAR[$uri])
|
593 |
+
? $this->_XMLNS_FAMILIAR[$uri]
|
594 |
+
: $uri
|
595 |
+
);
|
596 |
+
} else {
|
597 |
+
$canonical = $ns;
|
598 |
+
}
|
599 |
|
600 |
+
if (in_array($canonical, $this->root_namespaces)) {
|
601 |
+
$effective = '';
|
602 |
+
} else {
|
603 |
+
$effective = $canonical;
|
604 |
}
|
605 |
|
606 |
+
return array('effective' => $effective, 'canonical' => $canonical, 'prefix' => $ns, 'uri' => $uri, 'element' => $element);
|
607 |
+
}
|
608 |
+
|
609 |
+
// Utility functions for accessing data structure
|
610 |
+
|
611 |
+
// for smart, namespace-aware methods...
|
612 |
+
function magpie_data ($el, $method, $text = NULL) {
|
613 |
+
$ret = NULL;
|
614 |
+
if ($el) {
|
615 |
+
if (is_array($method)) {
|
616 |
+
$el = $this->{$method['key']}($el);
|
617 |
+
$method = $method['value'];
|
618 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
619 |
|
620 |
+
if ( $this->current_namespace ) {
|
621 |
+
if ( $this->initem ) {
|
622 |
+
$ret = $this->{$method} (
|
623 |
+
$this->current_item[ $this->current_namespace ][ $el ],
|
624 |
+
$text
|
625 |
+
);
|
626 |
+
}
|
627 |
+
elseif ($this->inchannel) {
|
628 |
+
$ret = $this->{$method} (
|
629 |
+
$this->channel[ $this->current_namespace][ $el ],
|
630 |
+
$text
|
631 |
+
);
|
632 |
+
}
|
633 |
+
elseif ($this->intextinput) {
|
634 |
+
$ret = $this->{$method} (
|
635 |
+
$this->textinput[ $this->current_namespace][ $el ],
|
636 |
+
$text
|
637 |
+
);
|
638 |
+
}
|
639 |
+
elseif ($this->inimage) {
|
640 |
+
$ret = $this->{$method} (
|
641 |
+
$this->image[ $this->current_namespace ][ $el ], $text );
|
642 |
+
}
|
643 |
+
}
|
644 |
+
else {
|
645 |
+
if ( $this->initem ) {
|
646 |
+
$ret = $this->{$method} (
|
647 |
+
$this->current_item[ $el ], $text);
|
648 |
+
}
|
649 |
+
elseif ($this->intextinput) {
|
650 |
+
$ret = $this->{$method} (
|
651 |
+
$this->textinput[ $el ], $text );
|
652 |
+
}
|
653 |
+
elseif ($this->inimage) {
|
654 |
+
$ret = $this->{$method} (
|
655 |
+
$this->image[ $el ], $text );
|
656 |
+
}
|
657 |
+
elseif ($this->inchannel) {
|
658 |
+
$ret = $this->{$method} (
|
659 |
+
$this->channel[ $el ], $text );
|
660 |
+
}
|
661 |
+
}
|
662 |
+
}
|
663 |
+
return $ret;
|
664 |
}
|
665 |
+
|
|
|
666 |
function concat (&$str1, $str2="") {
|
667 |
if (!isset($str1) ) {
|
668 |
$str1="";
|
669 |
}
|
670 |
$str1 .= $str2;
|
671 |
}
|
672 |
+
|
673 |
+
function retrieve_value (&$el, $text /*ignore*/) {
|
674 |
+
return $el;
|
675 |
+
}
|
676 |
+
function replace_value (&$el, $text) {
|
677 |
+
$el = $text;
|
678 |
+
}
|
679 |
+
function counter_key ($el) {
|
680 |
+
return $el.'#';
|
681 |
+
}
|
682 |
+
|
683 |
+
|
684 |
function append_content($text) {
|
685 |
+
$construct = reset($this->incontent);
|
686 |
+
$ns = $construct['effective'];
|
687 |
+
|
688 |
+
// Keeping data about parent elements is necessary to
|
689 |
+
// properly handle atom:source and its children elements
|
690 |
+
$tag = join('_', array_reverse($this->stack['element']));
|
691 |
+
|
692 |
+
if ( $this->initem ) {
|
693 |
+
if ($ns) {
|
694 |
+
$this->concat( $this->current_item[$ns][$tag], $text );
|
695 |
} else {
|
696 |
+
$this->concat( $this->current_item[$tag], $text );
|
697 |
}
|
698 |
+
}
|
699 |
+
elseif ( $this->inchannel ) {
|
700 |
if ($this->current_namespace) {
|
701 |
+
$this->concat( $this->channel[$ns][$tag], $text );
|
702 |
} else {
|
703 |
+
$this->concat( $this->channel[$tag], $text );
|
704 |
}
|
705 |
+
}
|
706 |
}
|
707 |
|
708 |
// smart append - field and namespace aware
|
709 |
function append($el, $text) {
|
710 |
+
$this->magpie_data($el, 'concat', $text);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
711 |
}
|
712 |
|
713 |
+
function dereference_current_element () {
|
714 |
+
$el = join('_', array_reverse($this->stack['element']));
|
715 |
+
$base = end($this->stack['xml:base']);
|
716 |
+
$uri = $this->magpie_data($el, 'retrieve_value');
|
717 |
+
$this->magpie_data($el, 'replace_value', Relative_URI::resolve($uri, $base));
|
718 |
+
}
|
719 |
+
|
720 |
// smart count - field and namespace aware
|
721 |
function element_count ($el, $set = NULL) {
|
722 |
+
if (!is_null($set)) {
|
723 |
+
$ret = $this->magpie_data($el, array('key' => 'counter_key', 'value' => 'replace_value'), $set);
|
724 |
+
}
|
725 |
+
$ret = $this->magpie_data($el, array('key' => 'counter_key', 'value' => 'retrieve_value'));
|
726 |
+
return ($ret ? $ret : 0);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
727 |
}
|
728 |
|
729 |
function normalize_enclosure (&$source, $from, &$dest, $to, $i) {
|
730 |
+
$id_from = $this->element_id($from, $i);
|
731 |
+
$id_to = $this->element_id($to, $i);
|
732 |
+
if (isset($source["{$id_from}@"])) {
|
733 |
+
foreach (explode(',', $source["{$id_from}@"]) as $attr) {
|
734 |
+
if ($from=='link_enclosure' and $attr=='href') { // from Atom
|
735 |
+
$dest["{$id_to}@url"] = $source["{$id_from}@{$attr}"];
|
736 |
+
$dest["{$id_to}"] = $source["{$id_from}@{$attr}"];
|
737 |
+
}
|
738 |
+
elseif ($from=='enclosure' and $attr=='url') { // from RSS
|
739 |
+
$dest["{$id_to}@href"] = $source["{$id_from}@{$attr}"];
|
740 |
+
$dest["{$id_to}"] = $source["{$id_from}@{$attr}"];
|
741 |
+
}
|
742 |
+
else {
|
743 |
+
$dest["{$id_to}@{$attr}"] = $source["{$id_from}@{$attr}"];
|
744 |
+
}
|
745 |
+
}
|
746 |
+
}
|
747 |
}
|
748 |
|
749 |
function normalize_atom_person (&$source, $person, &$dest, $to, $i) {
|
750 |
+
$id = $this->element_id($person, $i);
|
751 |
+
$id_to = $this->element_id($to, $i);
|
752 |
|
753 |
+
// Atom 0.3 <=> Atom 1.0
|
754 |
+
if ($this->feed_version >= 1.0) { $used = 'uri'; $norm = 'url'; }
|
755 |
+
else { $used = 'url'; $norm = 'uri'; }
|
756 |
|
757 |
+
if (isset($source["{$id}_{$used}"])) {
|
758 |
+
$dest["{$id_to}_{$norm}"] = $source["{$id}_{$used}"];
|
759 |
+
}
|
760 |
|
761 |
+
// Atom to RSS 2.0 and Dublin Core
|
762 |
+
// RSS 2.0 person strings should be valid e-mail addresses if possible.
|
763 |
+
if (isset($source["{$id}_email"])) {
|
764 |
+
$rss_author = $source["{$id}_email"];
|
765 |
+
}
|
766 |
+
if (isset($source["{$id}_name"])) {
|
767 |
+
$rss_author = $source["{$id}_name"]
|
768 |
+
. (isset($rss_author) ? " <$rss_author>" : '');
|
769 |
+
}
|
770 |
+
if (isset($rss_author)) {
|
771 |
+
$source[$id] = $rss_author; // goes to top-level author or contributor
|
772 |
+
$dest[$id_to] = $rss_author; // goes to dc:creator or dc:contributor
|
773 |
+
}
|
774 |
}
|
775 |
|
776 |
// Normalize Atom 1.0 and RSS 2.0 categories to Dublin Core...
|
777 |
function normalize_category (&$source, $from, &$dest, $to, $i) {
|
778 |
+
$cat_id = $this->element_id($from, $i);
|
779 |
+
$dc_id = $this->element_id($to, $i);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
780 |
|
781 |
+
// first normalize category elements: Atom 1.0 <=> RSS 2.0
|
782 |
+
if ( isset($source["{$cat_id}@term"]) ) { // category identifier
|
783 |
+
$source[$cat_id] = $source["{$cat_id}@term"];
|
784 |
+
} elseif ( $this->feed_type == RSS ) {
|
785 |
+
$source["{$cat_id}@term"] = $source[$cat_id];
|
786 |
+
}
|
787 |
+
|
788 |
+
if ( isset($source["{$cat_id}@scheme"]) ) { // URI to taxonomy
|
789 |
+
$source["{$cat_id}@domain"] = $source["{$cat_id}@scheme"];
|
790 |
+
} elseif ( isset($source["{$cat_id}@domain"]) ) {
|
791 |
+
$source["{$cat_id}@scheme"] = $source["{$cat_id}@domain"];
|
792 |
+
}
|
793 |
+
|
794 |
+
// Now put the identifier into dc:subject
|
795 |
+
$dest[$dc_id] = $source[$cat_id];
|
796 |
}
|
797 |
|
798 |
// ... or vice versa
|
799 |
function normalize_dc_subject (&$source, $from, &$dest, $to, $i) {
|
800 |
+
$dc_id = $this->element_id($from, $i);
|
801 |
+
$cat_id = $this->element_id($to, $i);
|
802 |
|
803 |
+
$dest[$cat_id] = $source[$dc_id]; // RSS 2.0
|
804 |
+
$dest["{$cat_id}@term"] = $source[$dc_id]; // Atom 1.0
|
805 |
}
|
806 |
|
807 |
// simplify the logic for normalize(). Makes sure that count of elements and
|
809 |
// with things like attributes or change formats or the like, pass it a
|
810 |
// callback to handle each element.
|
811 |
function normalize_element (&$source, $from, &$dest, $to, $via = NULL) {
|
812 |
+
if (isset($source[$from]) or isset($source["{$from}#"])) {
|
813 |
+
if (isset($source["{$from}#"])) {
|
814 |
+
$n = $source["{$from}#"];
|
815 |
+
$dest["{$to}#"] = $source["{$from}#"];
|
816 |
+
}
|
817 |
+
else { $n = 1; }
|
818 |
|
819 |
+
for ($i = 1; $i <= $n; $i++) {
|
820 |
+
if (isset($via)) { // custom callback for ninja attacks
|
821 |
+
$this->{$via}($source, $from, $dest, $to, $i);
|
822 |
+
}
|
823 |
+
else { // just make it the same
|
824 |
+
$from_id = $this->element_id($from, $i);
|
825 |
+
$to_id = $this->element_id($to, $i);
|
826 |
+
$dest[$to_id] = $source[$from_id];
|
827 |
+
}
|
828 |
+
}
|
829 |
+
}
|
830 |
}
|
831 |
|
832 |
function normalize () {
|
833 |
// if atom populate rss fields and normalize 0.3 and 1.0 feeds
|
834 |
if ( $this->is_atom() ) {
|
835 |
+
// Atom 1.0 elements <=> Atom 0.3 elements (Thanks, o brilliant wordsmiths of the Atom 1.0 standard!)
|
836 |
+
if ($this->feed_version < 1.0) {
|
837 |
+
$this->normalize_element($this->channel, 'tagline', $this->channel, 'subtitle');
|
838 |
+
$this->normalize_element($this->channel, 'copyright', $this->channel, 'rights');
|
839 |
+
$this->normalize_element($this->channel, 'modified', $this->channel, 'updated');
|
840 |
+
} else {
|
841 |
+
$this->normalize_element($this->channel, 'subtitle', $this->channel, 'tagline');
|
842 |
+
$this->normalize_element($this->channel, 'rights', $this->channel, 'copyright');
|
843 |
+
$this->normalize_element($this->channel, 'updated', $this->channel, 'modified');
|
844 |
+
}
|
845 |
+
$this->normalize_element($this->channel, 'author', $this->channel['dc'], 'creator', 'normalize_atom_person');
|
846 |
+
$this->normalize_element($this->channel, 'contributor', $this->channel['dc'], 'contributor', 'normalize_atom_person');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
847 |
|
848 |
+
// Atom elements to RSS elements
|
849 |
+
$this->normalize_element($this->channel, 'subtitle', $this->channel, 'description');
|
850 |
+
|
851 |
+
if ( isset($this->channel['logo']) ) {
|
852 |
+
$this->normalize_element($this->channel, 'logo', $this->image, 'url');
|
853 |
+
$this->normalize_element($this->channel, 'link', $this->image, 'link');
|
854 |
+
$this->normalize_element($this->channel, 'title', $this->image, 'title');
|
855 |
+
}
|
856 |
+
|
857 |
+
for ( $i = 0; $i < count($this->items); $i++) {
|
858 |
+
$item = $this->items[$i];
|
859 |
+
|
860 |
+
// Atom 1.0 elements <=> Atom 0.3 elements
|
861 |
+
if ($this->feed_version < 1.0) {
|
862 |
+
$this->normalize_element($item, 'modified', $item, 'updated');
|
863 |
+
$this->normalize_element($item, 'issued', $item, 'published');
|
864 |
+
} else {
|
865 |
+
$this->normalize_element($item, 'updated', $item, 'modified');
|
866 |
+
$this->normalize_element($item, 'published', $item, 'issued');
|
867 |
+
}
|
868 |
|
869 |
+
// "If an atom:entry element does not contain
|
870 |
+
// atom:author elements, then the atom:author elements
|
871 |
+
// of the contained atom:source element are considered
|
872 |
+
// to apply. In an Atom Feed Document, the atom:author
|
873 |
+
// elements of the containing atom:feed element are
|
874 |
+
// considered to apply to the entry if there are no
|
875 |
+
// atom:author elements in the locations described
|
876 |
+
// above." <http://atompub.org/2005/08/17/draft-ietf-atompub-format-11.html#rfc.section.4.2.1>
|
877 |
+
if (!isset($item["author#"])) {
|
878 |
+
if (isset($item["source_author#"])) { // from aggregation source
|
879 |
+
$source = $item;
|
880 |
+
$author = "source_author";
|
881 |
+
} elseif (isset($this->channel["author#"])) { // from containing feed
|
882 |
+
$source = $this->channel;
|
883 |
+
$author = "author";
|
884 |
+
} else {
|
885 |
+
$author = null;
|
886 |
+
}
|
887 |
|
888 |
+
if (!is_null($author)) {
|
889 |
+
$item["author#"] = $source["{$author}#"];
|
890 |
+
for ($au = 1; $au <= $item["author#"]; $au++) {
|
891 |
+
$id_to = $this->element_id('author', $au);
|
892 |
+
$id_from = $this->element_id($author, $au);
|
893 |
+
|
894 |
+
$item[$id_to] = $source[$id_from];
|
895 |
+
foreach (array('name', 'email', 'uri', 'url') as $what) {
|
896 |
+
if (isset($source["{$id_from}_{$what}"])) {
|
897 |
+
$item["{$id_to}_{$what}"] = $source["{$id_from}_{$what}"];
|
|
|
898 |
}
|
899 |
+
}
|
900 |
}
|
901 |
+
}
|
902 |
+
}
|
903 |
|
904 |
+
// Atom elements to RSS elements
|
905 |
+
$this->normalize_element($item, 'author', $item['dc'], 'creator', 'normalize_atom_person');
|
906 |
+
$this->normalize_element($item, 'contributor', $item['dc'], 'contributor', 'normalize_atom_person');
|
907 |
+
$this->normalize_element($item, 'summary', $item, 'description');
|
908 |
+
$this->normalize_element($item, 'atom_content', $item['content'], 'encoded');
|
909 |
+
$this->normalize_element($item, 'link_enclosure', $item, 'enclosure', 'normalize_enclosure');
|
910 |
|
911 |
+
// Categories
|
912 |
+
if ( isset($item['category#']) ) { // Atom 1.0 categories to dc:subject and RSS 2.0 categories
|
913 |
+
$this->normalize_element($item, 'category', $item['dc'], 'subject', 'normalize_category');
|
914 |
+
}
|
915 |
+
elseif ( isset($item['dc']['subject#']) ) { // dc:subject to Atom 1.0 and RSS 2.0 categories
|
916 |
+
$this->normalize_element($item['dc'], 'subject', $item, 'category', 'normalize_dc_subject');
|
917 |
+
}
|
918 |
|
919 |
+
// Normalized item timestamp
|
920 |
+
$atom_date = (isset($item['published']) ) ? $item['published'] : $item['updated'];
|
921 |
+
if ( $atom_date ) {
|
922 |
+
$epoch = @parse_w3cdtf($atom_date);
|
923 |
+
if ($epoch and $epoch > 0) {
|
924 |
+
$item['date_timestamp'] = $epoch;
|
925 |
+
}
|
926 |
+
}
|
927 |
|
928 |
+
$this->items[$i] = $item;
|
929 |
+
}
|
930 |
}
|
931 |
elseif ( $this->is_rss() ) {
|
932 |
// RSS elements to Atom elements
|
934 |
$this->normalize_element($this->channel, 'description', $this->channel, 'subtitle'); // Atom 1.0 (yay wordsmithing!)
|
935 |
$this->normalize_element($this->image, 'url', $this->channel, 'logo');
|
936 |
|
937 |
+
for ( $i = 0; $i < count($this->items); $i++) {
|
938 |
+
$item = $this->items[$i];
|
939 |
+
|
940 |
+
// RSS elements to Atom elements
|
941 |
+
$this->normalize_element($item, 'description', $item, 'summary');
|
942 |
+
$this->normalize_element($item, 'enclosure', $item, 'link_enclosure', 'normalize_enclosure');
|
943 |
+
|
944 |
+
// Categories
|
945 |
+
if ( isset($item['category#']) ) { // RSS 2.0 categories to dc:subject and Atom 1.0 categories
|
946 |
+
$this->normalize_element($item, 'category', $item['dc'], 'subject', 'normalize_category');
|
947 |
+
}
|
948 |
+
elseif ( isset($item['dc']['subject#']) ) { // dc:subject to Atom 1.0 and RSS 2.0 categories
|
949 |
+
$this->normalize_element($item['dc'], 'subject', $item, 'category', 'normalize_dc_subject');
|
950 |
+
}
|
951 |
|
952 |
+
// Normalized item timestamp
|
953 |
+
if ( $this->is_rss() == '1.0' and isset($item['dc']['date']) ) {
|
954 |
+
$epoch = @parse_w3cdtf($item['dc']['date']);
|
955 |
+
if ($epoch and $epoch > 0) {
|
956 |
+
$item['date_timestamp'] = $epoch;
|
957 |
+
}
|
958 |
+
}
|
959 |
+
elseif ( isset($item['pubdate']) ) {
|
960 |
+
$epoch = @strtotime($item['pubdate']);
|
961 |
+
if ($epoch > 0) {
|
962 |
+
$item['date_timestamp'] = $epoch;
|
963 |
+
}
|
964 |
+
}
|
965 |
+
|
966 |
+
$this->items[$i] = $item;
|
967 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
968 |
}
|
969 |
}
|
970 |
|
1002 |
$this->encoding = $out_enc;
|
1003 |
xml_parser_set_option($parser, XML_OPTION_TARGET_ENCODING, $out_enc);
|
1004 |
}
|
1005 |
+
xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, false);
|
1006 |
return array($parser, $source);
|
1007 |
}
|
1008 |
|
1122 |
// magic ID function for multiple elemenets.
|
1123 |
// can be called as static MagpieRSS::element_id()
|
1124 |
function element_id ($el, $counter) {
|
1125 |
+
return $el . (($counter > 1) ? '#'.$counter : '');
|
1126 |
}
|
1127 |
+
|
1128 |
+
function map_attrs($k, $v) {
|
1129 |
+
return $k.'="'.htmlspecialchars($v, ENT_COMPAT, $this->encoding).'"';
|
1130 |
+
}
|
1131 |
+
|
1132 |
+
function accepts_namespaced_xml ($attrs) {
|
1133 |
+
$mode = (isset($attrs['mode']) ? trim(strtolower($attrs['mode'])) : 'xml');
|
1134 |
+
$type = (isset($attrs['type']) ? trim(strtolower($attrs['type'])) : null);
|
1135 |
+
if ($this->feed_type == ATOM and $this->feed_version < 1.0) {
|
1136 |
+
if ($mode=='xml' and preg_match(':[/+](html|xml)$:i', $type)) {
|
1137 |
+
$ret = true;
|
1138 |
+
} else {
|
1139 |
+
$ret = false;
|
1140 |
+
}
|
1141 |
+
} elseif ($this->feed_type == ATOM and $this->feed_version >= 1.0) {
|
1142 |
+
if ($type=='xhtml' or preg_match(':[/+]xml$:i', $type)) {
|
1143 |
+
$ret = true;
|
1144 |
+
} else {
|
1145 |
+
$ret = false;
|
1146 |
+
}
|
1147 |
+
} else {
|
1148 |
+
$ret = false; // Don't munge unless you're sure
|
1149 |
+
}
|
1150 |
+
return $ret;
|
1151 |
+
}
|
1152 |
} // end class RSS
|
1153 |
|
|
|
|
|
|
|
1154 |
|
1155 |
// patch to support medieval versions of PHP4.1.x,
|
1156 |
// courtesy, Ryan Currie, ryan@digibliss.com
|
1157 |
|
1158 |
if (!function_exists('array_change_key_case')) {
|
1159 |
+
define("CASE_UPPER",1);
|
1160 |
+
define("CASE_LOWER",0);
|
1161 |
|
1162 |
|
1163 |
+
function array_change_key_case($array,$case=CASE_LOWER) {
|
1164 |
if ($case==CASE_LOWER) $cmd='strtolower';
|
1165 |
elseif ($case==CASE_UPPER) $cmd='strtoupper';
|
1166 |
foreach($array as $key=>$value) {
|
1167 |
$output[$cmd($key)]=$value;
|
1168 |
}
|
1169 |
return $output;
|
1170 |
+
}
|
1171 |
|
1172 |
}
|
1173 |
|
1201 |
version will be return, if it exists (and if MAGPIE_CACHE_FRESH_ONLY is off)
|
1202 |
\*=======================================================================*/
|
1203 |
|
1204 |
+
define('MAGPIE_VERSION', '0.85');
|
1205 |
|
1206 |
$MAGPIE_ERROR = "";
|
1207 |
|
1219 |
// fetch file, and parse it
|
1220 |
$resp = _fetch_remote_file( $url );
|
1221 |
if ( is_success( $resp->status ) ) {
|
1222 |
+
return _response_to_rss( $resp, $url );
|
1223 |
}
|
1224 |
else {
|
1225 |
error("Failed to fetch $url and cache is off");
|
1292 |
return $rss;
|
1293 |
}
|
1294 |
elseif ( is_success( $resp->status ) ) {
|
1295 |
+
$rss = _response_to_rss( $resp, $url );
|
1296 |
if ( $rss ) {
|
1297 |
if (MAGPIE_DEBUG > 1) {
|
1298 |
debug("Fetch successful");
|
1405 |
Input: an HTTP response object (see Snoopy)
|
1406 |
Output: parsed RSS object (see rss_parse)
|
1407 |
\*=======================================================================*/
|
1408 |
+
function _response_to_rss ($resp, $url = null) {
|
1409 |
+
$rss = new MagpieRSS( $resp->results, MAGPIE_OUTPUT_ENCODING, MAGPIE_INPUT_ENCODING, MAGPIE_DETECT_ENCODING, $url );
|
1410 |
|
1411 |
// if RSS parsed successfully
|
1412 |
if ( $rss and !$rss->ERROR) {
|
1413 |
+
$rss->http_status = $resp->status;
|
1414 |
+
|
1415 |
// find Etag, and Last-Modified
|
1416 |
foreach($resp->headers as $h) {
|
1417 |
// 2003-03-02 - Nicola Asuni (www.tecnick.com) - fixed bug "Undefined offset: 1"
|
1423 |
$val = "";
|
1424 |
}
|
1425 |
|
1426 |
+
$rss->header[$field] = $val;
|
1427 |
+
|
1428 |
if ( $field == 'ETag' ) {
|
1429 |
$rss->etag = $val;
|
1430 |
}
|
1783 |
}
|
1784 |
}
|
1785 |
|
1786 |
+
# Relative URI static class: PHP class for resolving relative URLs
|
1787 |
+
#
|
1788 |
+
# This class is derived (under the terms of the GPL) from URL Class 0.3 by
|
1789 |
+
# Keyvan Minoukadeh <keyvan@k1m.com>, which is great but more than we need
|
1790 |
+
# for MagpieRSS's purposes. The class has been stripped down to a single
|
1791 |
+
# public method: Relative_URI::resolve($url, $base), which resolves the URI in
|
1792 |
+
# $url relative to the URI in $base
|
1793 |
+
#
|
1794 |
+
# FeedWordPress also uses this class. So if we have it loaded in, don't load it
|
1795 |
+
# again.
|
1796 |
+
#
|
1797 |
+
# -- Charles Johnson <technophilia@radgeek.com>
|
1798 |
+
if (!class_exists('Relative_URI')) {
|
1799 |
+
class Relative_URI
|
1800 |
+
{
|
1801 |
+
// Resolve relative URI in $url against the base URI in $base. If $base
|
1802 |
+
// is not supplied, then we use the REQUEST_URI of this script.
|
1803 |
+
//
|
1804 |
+
// I'm hoping this method reflects RFC 2396 Section 5.2
|
1805 |
+
function resolve ($url, $base = NULL)
|
1806 |
+
{
|
1807 |
+
if (is_null($base)):
|
1808 |
+
$base = 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
|
1809 |
+
endif;
|
1810 |
+
|
1811 |
+
$base = Relative_URI::_encode(trim($base));
|
1812 |
+
$uri_parts = Relative_URI::_parse_url($base);
|
1813 |
+
|
1814 |
+
$url = Relative_URI::_encode(trim($url));
|
1815 |
+
$parts = Relative_URI::_parse_url($url);
|
1816 |
+
|
1817 |
+
$uri_parts['fragment'] = (isset($parts['fragment']) ? $parts['fragment'] : null);
|
1818 |
+
$uri_parts['query'] = (isset($parts['query']) ? $parts['query'] : null);
|
1819 |
+
|
1820 |
+
// if path is empty, and scheme, host, and query are undefined,
|
1821 |
+
// the URL is referring the base URL
|
1822 |
+
|
1823 |
+
if (($parts['path'] == '') && !isset($parts['scheme']) && !isset($parts['host']) && !isset($parts['query'])) {
|
1824 |
+
// If the URI is empty or only a fragment, return the base URI
|
1825 |
+
return $base . (isset($parts['fragment']) ? '#'.$parts['fragment'] : '');
|
1826 |
+
} elseif (isset($parts['scheme'])) {
|
1827 |
+
// If the scheme is set, then the URI is absolute.
|
1828 |
+
return $url;
|
1829 |
+
} elseif (isset($parts['host'])) {
|
1830 |
+
$uri_parts['host'] = $parts['host'];
|
1831 |
+
$uri_parts['path'] = $parts['path'];
|
1832 |
+
} else {
|
1833 |
+
// We have a relative path but not a host.
|
1834 |
+
|
1835 |
+
// start ugly fix:
|
1836 |
+
// prepend slash to path if base host is set, base path is not set, and url path is not absolute
|
1837 |
+
if ($uri_parts['host'] && ($uri_parts['path'] == '')
|
1838 |
+
&& (strlen($parts['path']) > 0)
|
1839 |
+
&& (substr($parts['path'], 0, 1) != '/')) {
|
1840 |
+
$parts['path'] = '/'.$parts['path'];
|
1841 |
+
} // end ugly fix
|
1842 |
+
|
1843 |
+
if (substr($parts['path'], 0, 1) == '/') {
|
1844 |
+
$uri_parts['path'] = $parts['path'];
|
1845 |
+
} else {
|
1846 |
+
// copy base path excluding any characters after the last (right-most) slash character
|
1847 |
+
$buffer = substr($uri_parts['path'], 0, (int)strrpos($uri_parts['path'], '/')+1);
|
1848 |
+
// append relative path
|
1849 |
+
$buffer .= $parts['path'];
|
1850 |
+
// remove "./" where "." is a complete path segment.
|
1851 |
+
$buffer = str_replace('/./', '/', $buffer);
|
1852 |
+
if (substr($buffer, 0, 2) == './') {
|
1853 |
+
$buffer = substr($buffer, 2);
|
1854 |
+
}
|
1855 |
+
// if buffer ends with "." as a complete path segment, remove it
|
1856 |
+
if (substr($buffer, -2) == '/.') {
|
1857 |
+
$buffer = substr($buffer, 0, -1);
|
1858 |
+
}
|
1859 |
+
// remove "<segment>/../" where <segment> is a complete path segment not equal to ".."
|
1860 |
+
$search_finished = false;
|
1861 |
+
$segment = explode('/', $buffer);
|
1862 |
+
while (!$search_finished) {
|
1863 |
+
for ($x=0; $x+1 < count($segment);) {
|
1864 |
+
if (($segment[$x] != '') && ($segment[$x] != '..') && ($segment[$x+1] == '..')) {
|
1865 |
+
if ($x+2 == count($segment)) $segment[] = '';
|
1866 |
+
unset($segment[$x], $segment[$x+1]);
|
1867 |
+
$segment = array_values($segment);
|
1868 |
+
continue 2;
|
1869 |
+
} else {
|
1870 |
+
$x++;
|
1871 |
+
}
|
1872 |
+
}
|
1873 |
+
$search_finished = true;
|
1874 |
+
}
|
1875 |
+
$buffer = (count($segment) == 1) ? '/' : implode('/', $segment);
|
1876 |
+
$uri_parts['path'] = $buffer;
|
1877 |
+
|
1878 |
+
}
|
1879 |
+
}
|
1880 |
+
|
1881 |
+
// If we've gotten to this point, we can try to put the pieces
|
1882 |
+
// back together.
|
1883 |
+
$ret = '';
|
1884 |
+
if (isset($uri_parts['scheme'])) $ret .= $uri_parts['scheme'].':';
|
1885 |
+
if (isset($uri_parts['user'])) {
|
1886 |
+
$ret .= $uri_parts['user'];
|
1887 |
+
if (isset($uri_parts['pass'])) $ret .= ':'.$uri_parts['parts'];
|
1888 |
+
$ret .= '@';
|
1889 |
+
}
|
1890 |
+
if (isset($uri_parts['host'])) {
|
1891 |
+
$ret .= '//'.$uri_parts['host'];
|
1892 |
+
if (isset($uri_parts['port'])) $ret .= ':'.$uri_parts['port'];
|
1893 |
+
}
|
1894 |
+
$ret .= $uri_parts['path'];
|
1895 |
+
if (isset($uri_parts['query'])) $ret .= '?'.$uri_parts['query'];
|
1896 |
+
if (isset($uri_parts['fragment'])) $ret .= '#'.$uri_parts['fragment'];
|
1897 |
+
|
1898 |
+
return $ret;
|
1899 |
+
}
|
1900 |
+
|
1901 |
+
/**
|
1902 |
+
* Parse URL
|
1903 |
+
*
|
1904 |
+
* Regular expression grabbed from RFC 2396 Appendix B.
|
1905 |
+
* This is a replacement for PHPs builtin parse_url().
|
1906 |
+
* @param string $url
|
1907 |
+
* @access private
|
1908 |
+
* @return array
|
1909 |
+
*/
|
1910 |
+
function _parse_url($url)
|
1911 |
+
{
|
1912 |
+
// I'm using this pattern instead of parse_url() as there's a few strings where parse_url()
|
1913 |
+
// generates a warning.
|
1914 |
+
if (preg_match('!^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?!', $url, $match)) {
|
1915 |
+
$parts = array();
|
1916 |
+
if ($match[1] != '') $parts['scheme'] = $match[2];
|
1917 |
+
if ($match[3] != '') $parts['auth'] = $match[4];
|
1918 |
+
// parse auth
|
1919 |
+
if (isset($parts['auth'])) {
|
1920 |
+
// store user info
|
1921 |
+
if (($at_pos = strpos($parts['auth'], '@')) !== false) {
|
1922 |
+
$userinfo = explode(':', substr($parts['auth'], 0, $at_pos), 2);
|
1923 |
+
$parts['user'] = $userinfo[0];
|
1924 |
+
if (isset($userinfo[1])) $parts['pass'] = $userinfo[1];
|
1925 |
+
$parts['auth'] = substr($parts['auth'], $at_pos+1);
|
1926 |
+
}
|
1927 |
+
// get port number
|
1928 |
+
if ($port_pos = strrpos($parts['auth'], ':')) {
|
1929 |
+
$parts['host'] = substr($parts['auth'], 0, $port_pos);
|
1930 |
+
$parts['port'] = (int)substr($parts['auth'], $port_pos+1);
|
1931 |
+
if ($parts['port'] < 1) $parts['port'] = null;
|
1932 |
+
} else {
|
1933 |
+
$parts['host'] = $parts['auth'];
|
1934 |
+
}
|
1935 |
+
}
|
1936 |
+
unset($parts['auth']);
|
1937 |
+
$parts['path'] = $match[5];
|
1938 |
+
if (isset($match[6]) && ($match[6] != '')) $parts['query'] = $match[7];
|
1939 |
+
if (isset($match[8]) && ($match[8] != '')) $parts['fragment'] = $match[9];
|
1940 |
+
return $parts;
|
1941 |
+
}
|
1942 |
+
// shouldn't reach here
|
1943 |
+
return array('path'=>'');
|
1944 |
+
}
|
1945 |
+
|
1946 |
+
function _encode($string)
|
1947 |
+
{
|
1948 |
+
static $replace = array();
|
1949 |
+
if (!count($replace)) {
|
1950 |
+
$find = array(32, 34, 60, 62, 123, 124, 125, 91, 92, 93, 94, 96, 127);
|
1951 |
+
$find = array_merge(range(0, 31), $find);
|
1952 |
+
$find = array_map('chr', $find);
|
1953 |
+
foreach ($find as $char) {
|
1954 |
+
$replace[$char] = '%'.bin2hex($char);
|
1955 |
+
}
|
1956 |
+
}
|
1957 |
+
// escape control characters and a few other characters
|
1958 |
+
$encoded = strtr($string, $replace);
|
1959 |
+
// remove any character outside the hex range: 21 - 7E (see www.asciitable.com)
|
1960 |
+
return preg_replace('/[^\x21-\x7e]/', '', $encoded);
|
1961 |
+
}
|
1962 |
+
} // class Relative_URI
|
1963 |
+
}
|
1964 |
+
|
1965 |
################################################################################
|
1966 |
## WordPress: wp_rss(), get_rss() ##############################################
|
1967 |
################################################################################
|
README.text
CHANGED
@@ -2,7 +2,7 @@ FeedWordPress
|
|
2 |
=============
|
3 |
|
4 |
* Author: [Charles Johnson](http://radgeek.com/contact)
|
5 |
-
* Version: 0.
|
6 |
* Project URI: <http://projects.radgeek.com/feedwordpress>
|
7 |
* License: GPL 2. See License below for copyright jots and tittles.
|
8 |
|
@@ -20,76 +20,86 @@ originally developed it because I needed a more flexible replacement for
|
|
20 |
|
21 |
FeedWordPress is designed with flexibility, ease of use, and ease of
|
22 |
configuration in mind. You'll need a working installation of WordPress (version
|
23 |
-
[2.1][], [2.0][] or [1.5][]), and also FTP or SFTP access to
|
24 |
-
ability to create cron jobs on your web host would be very
|
25 |
-
absolutely necessary. You *don't* need to tweak any
|
26 |
-
files and you *don't* need shell access to your web
|
27 |
-
(Although, I should point out, web hosts that *don't*
|
28 |
-
*bad web hosts*.)
|
29 |
-
|
30 |
-
[2.
|
31 |
-
[2.
|
32 |
-
[1
|
|
|
|
|
33 |
|
34 |
Installation
|
35 |
------------
|
36 |
### Requirements ###
|
37 |
|
38 |
-
To use version 0.
|
39 |
|
40 |
-
1.
|
41 |
-
(FeedWordPress currently *will not work* with older
|
42 |
-
WordPress, or with WordPress MU.)
|
43 |
|
44 |
2. FTP or SFTP access to your web host
|
45 |
|
46 |
-
And you'll probably also want to have either:
|
47 |
-
|
48 |
-
1. the ability to create cron jobs on your web host, or at least
|
49 |
-
|
50 |
-
2. a computer of your own and always-on Internet access
|
51 |
-
|
52 |
### Installation ###
|
53 |
|
54 |
#### Upgrades ####
|
55 |
|
56 |
-
To *upgrade* an existing installation of FeedWordPress to version 0.
|
57 |
|
58 |
1. Download the FeedWordPress archive in zip or gzipped tar format and
|
59 |
-
extract the files on your computer.
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
65 |
in to the WordPress Dashboard, and go to Options --> Syndicated. Follow
|
66 |
the directions to launch the database upgrade procedure. The new
|
67 |
versions of FeedWordPress incorporate some long-needed improvements, but
|
68 |
old meta-data needs to be updated to prevent duplicate posts and other
|
69 |
possible maladies. If you're upgrading an existing installation, updates
|
70 |
and FeedWordPress template functions *will not work* until you've done
|
71 |
-
the upgrade.
|
|
|
|
|
72 |
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
XML-RPC pings, or command-line PHP, to do scheduled updates. It *does*
|
80 |
-
affect you if you used curl or some other tool to send HTTP requests to
|
81 |
-
`update-feeds.php`: your old cron job will probably not work anymore.
|
82 |
-
See [Setting Up Feed Updates][] below to get scheduled updates back on
|
83 |
-
track.
|
84 |
|
85 |
5. Enjoy your new installation of FeedWordPress.
|
86 |
|
87 |
#### New Installations ####
|
88 |
|
89 |
-
1.
|
90 |
-
|
91 |
-
|
92 |
-
2.
|
|
|
|
|
|
|
|
|
|
|
|
|
93 |
installing the new `rss.php` and `rss-functions.php` (archived in
|
94 |
`OPTIONAL/wp-includes`) into your WordPress `wp-includes` directory.
|
95 |
Upgrading MagpieRSS is necessary if you want to take advantage of
|
@@ -101,107 +111,91 @@ To *upgrade* an existing installation of FeedWordPress to version 0.981:
|
|
101 |
your installation of PHP is up-to-date and that you keep a copy of
|
102 |
the old MagpieRSS around to compare results.)
|
103 |
|
104 |
-
|
105 |
plugin.
|
106 |
|
107 |
-
|
108 |
-
go to
|
109 |
FeedWordPress will syndicate links from (by default, "Contributors"),
|
110 |
-
and (2)
|
111 |
-
|
112 |
-
"Update all the feeds" at will to your FeedWordPress installation.
|
113 |
|
114 |
-
5. Go to
|
115 |
-
|
116 |
-
|
117 |
-
you may prefer to export them to an OPML file and use WordPress's
|
118 |
-
--> Import to import them into the contributors
|
|
|
119 |
|
120 |
#### Setting Up Feed Updates ####
|
121 |
|
122 |
-
FeedWordPress is now ready to accept posts from its syndication sources.
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
25 * * * * curl --user login:pass http://www.zyx.com/blog/wp-content/update-feeds.php -d update=quiet
|
190 |
-
|
191 |
-
The `-d update=quiet` switch ensures that (1) `update-feeds.php` will
|
192 |
-
receive an HTTP POST request rather than an HTTP GET request (which
|
193 |
-
is important, since it won't take any actions with side-effects -- such
|
194 |
-
as checking for new posts -- unless it receives an HTTP POST); it also
|
195 |
-
tells it to suppress the HTML output that it would generate for normal
|
196 |
-
web browsers, and only to output text if it encounters errors (this will
|
197 |
-
keep the number of e-mails you receive from the Cron Daemon to a
|
198 |
-
minimum).
|
199 |
-
|
200 |
-
If you are using Windows XP and have a version of curl (such as the
|
201 |
-
version included in [Cygwin][]), you can create a Scheduled Task to
|
202 |
-
similar effect.
|
203 |
-
|
204 |
-
[Cygwin]: http://www.cygwin.com/
|
205 |
|
206 |
Basic Concepts
|
207 |
--------------
|
@@ -485,8 +479,8 @@ For more information, see <http://projects.radgeek.com/feedwordpress/api>.
|
|
485 |
|
486 |
License
|
487 |
-------
|
488 |
-
The FeedWordPress plugin is copyright (c) 2005 by Charles Johnson. It uses
|
489 |
-
derived or translated from:
|
490 |
|
491 |
- [wp-rss-aggregate.php][] by [Kellan Elliot-McCrea](kellan@protest.net)
|
492 |
- [MagpieRSS][] by [Kellan Elliot-McCrea](kellan@protest.net)
|
2 |
=============
|
3 |
|
4 |
* Author: [Charles Johnson](http://radgeek.com/contact)
|
5 |
+
* Version: 0.99
|
6 |
* Project URI: <http://projects.radgeek.com/feedwordpress>
|
7 |
* License: GPL 2. See License below for copyright jots and tittles.
|
8 |
|
20 |
|
21 |
FeedWordPress is designed with flexibility, ease of use, and ease of
|
22 |
configuration in mind. You'll need a working installation of WordPress (version
|
23 |
+
[2.3][], [2.2][], [2.1][], [2.0][] or [1.5][]), and also FTP or SFTP access to
|
24 |
+
your web host. The ability to create cron jobs on your web host would be very
|
25 |
+
helpful but it's not absolutely necessary. You *don't* need to tweak any
|
26 |
+
plain-text configuration files and you *don't* need shell access to your web
|
27 |
+
host to make it work. (Although, I should point out, web hosts that *don't*
|
28 |
+
offer shell access are *bad web hosts*.)
|
29 |
+
|
30 |
+
[2.3]: http://codex.wordpress.org/Version_2.3
|
31 |
+
[2.2]: http://codex.wordpress.org/Version_2.2
|
32 |
+
[2.1]: http://codex.wordpress.org/Version_2.1
|
33 |
+
[2.0]: http://codex.wordpress.org/Version_2.0
|
34 |
+
[1.5]: http://codex.wordpress.org/Version_1.5
|
35 |
|
36 |
Installation
|
37 |
------------
|
38 |
### Requirements ###
|
39 |
|
40 |
+
To use version 0.99 of FeedWordPress, you will need:
|
41 |
|
42 |
+
1. an installed and configured copy of WordPress 2.3.x, 2.2.x, 2.1.x,
|
43 |
+
2.0.x, or 1.5.x. (FeedWordPress currently *will not work* with older
|
44 |
+
versions of WordPress, or with WordPress MU.)
|
45 |
|
46 |
2. FTP or SFTP access to your web host
|
47 |
|
|
|
|
|
|
|
|
|
|
|
|
|
48 |
### Installation ###
|
49 |
|
50 |
#### Upgrades ####
|
51 |
|
52 |
+
To *upgrade* an existing installation of FeedWordPress to version 0.99:
|
53 |
|
54 |
1. Download the FeedWordPress archive in zip or gzipped tar format and
|
55 |
+
extract the files on your computer.
|
56 |
+
|
57 |
+
2. If you are upgrading from version 0.98 or earlier, then you need to
|
58 |
+
create a new directory named `feedwordpress` in the `wp-content/plugins`
|
59 |
+
directory of your WordPress installation, and you also need to *delete*
|
60 |
+
your existing `wp-content/update-feeds.php` and
|
61 |
+
`wp-content/plugins/feedwordpress.php` files. The file structure for
|
62 |
+
FeedWordPress has changed and the files from your old version will not
|
63 |
+
be overwritten, which could cause conflicts if you leave them in place.
|
64 |
+
|
65 |
+
3. Upload the new PHP files to `wp-content/plugins/feedwordpress`,
|
66 |
+
overwriting any existing FeedWordPress files that are there. Also be
|
67 |
+
sure to upgrade `wp-includes/rss.php` and
|
68 |
+
`wp-includes/rss-functions.php` if you use the optional MagpieRSS
|
69 |
+
upgrade, or don't use it yet but do want to syndicate Atom 1.0 feeds.
|
70 |
+
|
71 |
+
3. If you are upgrading from version 0.96 or earlier, **immediately** log
|
72 |
in to the WordPress Dashboard, and go to Options --> Syndicated. Follow
|
73 |
the directions to launch the database upgrade procedure. The new
|
74 |
versions of FeedWordPress incorporate some long-needed improvements, but
|
75 |
old meta-data needs to be updated to prevent duplicate posts and other
|
76 |
possible maladies. If you're upgrading an existing installation, updates
|
77 |
and FeedWordPress template functions *will not work* until you've done
|
78 |
+
the upgrade. Then take a coffee break while the upgrade runs. It should,
|
79 |
+
hopefully, finish within a few minutes even on relatively large
|
80 |
+
databases.
|
81 |
|
82 |
+
4. If you are upgrading from version 0.98 or earlier, note that the old
|
83 |
+
`update-feeds.php` has been eliminated in favor of a (hopefully) more
|
84 |
+
humane method for automatic updating. If you used a cron job for
|
85 |
+
scheduled updates, it will not work anymore, but there is another,
|
86 |
+
simpler method which will. See [Setting Up Feed Updates][] below to get
|
87 |
+
scheduled updates back on track.
|
|
|
|
|
|
|
|
|
|
|
88 |
|
89 |
5. Enjoy your new installation of FeedWordPress.
|
90 |
|
91 |
#### New Installations ####
|
92 |
|
93 |
+
1. Download the FeedWordPress archive in zip or gzipped tar format and
|
94 |
+
extract the files on your computer.
|
95 |
+
|
96 |
+
2. Create a new directory named `feedwordpress` in the `wp-content/plugins`
|
97 |
+
directory of your WordPress installation. Use an FTP or SFTP client to
|
98 |
+
upload the contents of the `wp-content/plugins/feedwordpress` directory
|
99 |
+
in the FeedWordPress archive to the new directory that you just created
|
100 |
+
on your web host.
|
101 |
+
|
102 |
+
3. (Optional) Upgrade the copy of MagpieRSS packaged with WordPress by
|
103 |
installing the new `rss.php` and `rss-functions.php` (archived in
|
104 |
`OPTIONAL/wp-includes`) into your WordPress `wp-includes` directory.
|
105 |
Upgrading MagpieRSS is necessary if you want to take advantage of
|
111 |
your installation of PHP is up-to-date and that you keep a copy of
|
112 |
the old MagpieRSS around to compare results.)
|
113 |
|
114 |
+
4. Log in to the WordPress Dashboard and activate the FeedWordPress
|
115 |
plugin.
|
116 |
|
117 |
+
5. While you're at the Dashboard, once the plugin is activated, you can
|
118 |
+
go to **Syndication --> Options** and set (1) the link category that
|
119 |
FeedWordPress will syndicate links from (by default, "Contributors"),
|
120 |
+
and (2) whether FeedWordPress will use automatic updates or only
|
121 |
+
manual updates.
|
|
|
122 |
|
123 |
+
5. Go to the main **Syndication** page to set up the list of sites that
|
124 |
+
you want FeedWordPress to syndicate onto your blog. (If you have the
|
125 |
+
feeds you want to aggregate in a service such as Bloglines,
|
126 |
+
you may prefer to export them to an OPML file and use WordPress's
|
127 |
+
**Blogroll --> Import Links** to import them into the contributors
|
128 |
+
category.)
|
129 |
|
130 |
#### Setting Up Feed Updates ####
|
131 |
|
132 |
+
FeedWordPress is now ready to accept posts from its syndication sources. The
|
133 |
+
next thing to do is to make sure it knows *when* to go get them.
|
134 |
+
|
135 |
+
**N.B.:** If you are upgrading from version 0.981 or earlier of FeedWordPress,
|
136 |
+
the system for checking for new posts has been overhauled, hopefully making it
|
137 |
+
more humane, and also easier to use for people who do not have access to task
|
138 |
+
scheduling tools such as `cron`. You will need to re-read this section and
|
139 |
+
change your set-up accordingly.
|
140 |
+
|
141 |
+
FeedWordPress allows you to choose whether it will check for new posts
|
142 |
+
automatically, or only when you manually request for it to check. By default,
|
143 |
+
FeedWordPress opts for the **manual** option -- so that you can get your feeds
|
144 |
+
set up properly before FeedWordPress begins importing new posts. If you want
|
145 |
+
to use automatically scheduled updates, remember to enable them in
|
146 |
+
**Syndication --> Options** after you finish setting up FeedWordPress.
|
147 |
+
|
148 |
+
##### Manual Feed Updates #####
|
149 |
+
|
150 |
+
To manually check for new posts, log in to the WordPress Dashboard and go to the
|
151 |
+
main page under **Syndication**. You can use the "Update feeds now" button to
|
152 |
+
check for new posts on feeds that are due for a scheduled update, or use the
|
153 |
+
checkboxes and "Update Checked Feeds" button to force FeedWordPress to check one
|
154 |
+
or more specific feeds for new posts. FeedWordPress will check the selected
|
155 |
+
feed or feeds for new posts, and import any new content available.
|
156 |
+
|
157 |
+
##### Automatic Feed Updates #####
|
158 |
+
|
159 |
+
If you choose an automatic update schedule, then FeedWordPress will
|
160 |
+
automatically check for new posts based on a schedule you determine. When
|
161 |
+
automatic updates are enabled, FeedWordPress will check for new posts when
|
162 |
+
(1) at least ten minutes have passed since the last update, and (2) a viewer
|
163 |
+
visits your FeedWordPress-enabled blog. (If you want the interval of time to
|
164 |
+
be shorter or longer, you can change the interval in the Dashboard under
|
165 |
+
**Syndication --> Options**.)
|
166 |
+
|
167 |
+
Note that this is not quite the same thing as precisely scheduled updating.
|
168 |
+
If you get at least one viewer every ten minutes, then FeedWordPress will be
|
169 |
+
regularly checking for new posts on schedule; if not, not. But for a relatively
|
170 |
+
active aggregator blog this is probably close enough for government work.
|
171 |
+
|
172 |
+
However, if you want to ensure regular updates, and you have access to a
|
173 |
+
task-scheduling tool such as `cron`, you can use it to schedule regular
|
174 |
+
checks for updates on a fixed schedule. For example, using `cron`, you can
|
175 |
+
easily ensure that FeedWordPress checks for new posts regularly by adding the
|
176 |
+
following line to your crontab, substituting the actual address of your
|
177 |
+
WordPress installation for "http://www.zyx.com/blog/":
|
178 |
+
|
179 |
+
*/15 * * * * curl http://www.zyx.com/blog/ > /dev/null
|
180 |
+
|
181 |
+
If you don't have direct access to `cron` or a similar scheduling tool, you
|
182 |
+
can use online tools such as [WebCron](http://www.webcron.org/?lang=en) to
|
183 |
+
schedule a regular fetch of your blog's front page to much the same effect.
|
184 |
+
|
185 |
+
##### Feed Updates using XML-RPC #####
|
186 |
+
|
187 |
+
FeedWordPress also allows syndicated blogs to notify you of updates using the
|
188 |
+
XML-RPC "recently updated" pings (in the standard format accepted by
|
189 |
+
Weblogs.com, Ping-O-Matic, Technorati, and other blogging services). Most
|
190 |
+
blogging software allows users to add a URI to the list of URIs that get pinged
|
191 |
+
with each new update -- see, for example, **Options --> Writing --> Update
|
192 |
+
Services** in WordPress, or **Configuration --> Preferences --> Publicity /
|
193 |
+
Remote Interfaces / TrackBack** in Movable Type. If you can get a contributor
|
194 |
+
to add your XML-RPC URI to her list of update services to ping, then whenever
|
195 |
+
she updates her blog, her blogging software will notify your FeedWordPress
|
196 |
+
installation, and FeedWordPress will look up her feed to grab the new posts off
|
197 |
+
of it. (If you have WordPress installed at <http://www.zyx.com/blog>, say, the
|
198 |
+
URI for her to ping should be <http://www.zyx.com/blog/xmlrpc.php>).
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
199 |
|
200 |
Basic Concepts
|
201 |
--------------
|
479 |
|
480 |
License
|
481 |
-------
|
482 |
+
The FeedWordPress plugin is copyright (c) 2005-2007 by Charles Johnson. It uses
|
483 |
+
code derived or translated from:
|
484 |
|
485 |
- [wp-rss-aggregate.php][] by [Kellan Elliot-McCrea](kellan@protest.net)
|
486 |
- [MagpieRSS][] by [Kellan Elliot-McCrea](kellan@protest.net)
|
wp-content/plugins/{feedwordpress.php → feedwordpress/feedwordpress.php}
RENAMED
@@ -3,11 +3,11 @@
|
|
3 |
Plugin Name: FeedWordPress
|
4 |
Plugin URI: http://projects.radgeek.com/feedwordpress
|
5 |
Description: simple and flexible Atom/RSS syndication for WordPress
|
6 |
-
Version: 0.
|
7 |
Author: Charles Johnson
|
8 |
Author URI: http://radgeek.com/
|
9 |
License: GPL
|
10 |
-
Last modified: 2007-
|
11 |
*/
|
12 |
|
13 |
# This uses code derived from:
|
@@ -26,15 +26,38 @@ Last modified: 2007-02-17 4:23pm EST
|
|
26 |
# <http://www.zyx.com/blog/xmlrpc.php>), or see `update-feeds.php`
|
27 |
|
28 |
# -- Don't change these unless you know what you're doing...
|
29 |
-
|
30 |
-
define ('FEEDWORDPRESS_VERSION', '0.
|
|
|
31 |
define ('DEFAULT_SYNDICATION_CATEGORY', 'Contributors');
|
32 |
|
|
|
|
|
33 |
define ('FEEDWORDPRESS_CAT_SEPARATOR_PATTERN', '/[:\n]/');
|
34 |
define ('FEEDWORDPRESS_CAT_SEPARATOR', "\n");
|
35 |
|
36 |
define ('FEEDVALIDATOR_URI', 'http://feedvalidator.org/check.cgi');
|
37 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
38 |
// Note that the rss-functions.php that comes prepackaged with WordPress is
|
39 |
// old & busted. For the new hotness, drop a copy of rss.php from
|
40 |
// this archive into wp-includes/rss.php
|
@@ -45,9 +68,25 @@ else :
|
|
45 |
require_once (ABSPATH . WPINC . '/rss-functions.php');
|
46 |
endif;
|
47 |
|
48 |
-
if (isset($wp_db_version)
|
49 |
-
|
50 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
51 |
endif;
|
52 |
|
53 |
// Is this being loaded from within WordPress 1.5 or later?
|
@@ -81,11 +120,17 @@ if (isset($wp_version) and $wp_version >= 1.5):
|
|
81 |
add_filter('xmlrpc_methods', 'feedwordpress_xmlrpc_hook');
|
82 |
|
83 |
# Outbound XML-RPC ping reform
|
84 |
-
remove_action('publish_post', 'generic_ping');
|
85 |
-
|
86 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
87 |
# Hook in logging functions only if the logging option is ON
|
88 |
-
$update_logging =
|
89 |
if ($update_logging == 'yes') :
|
90 |
add_action('post_syndicated_item', 'log_feedwordpress_post', 100);
|
91 |
add_action('update_syndicated_item', 'log_feedwordpress_update_post', 100);
|
@@ -93,12 +138,22 @@ if (isset($wp_version) and $wp_version >= 1.5):
|
|
93 |
add_action('feedwordpress_check_feed', 'log_feedwordpress_check_feed', 100);
|
94 |
add_action('feedwordpress_update_complete', 'log_feedwordpress_update_complete', 100);
|
95 |
endif;
|
|
|
|
|
|
|
96 |
else :
|
97 |
# Hook in the menus, which will just point to the upgrade interface
|
98 |
add_action('admin_menu', 'fwp_add_pages');
|
99 |
endif; // if (!FeedWordPress::needs_upgrade())
|
100 |
endif;
|
101 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
102 |
################################################################################
|
103 |
## LOGGING FUNCTIONS: log status updates to error_log if you want it ###########
|
104 |
################################################################################
|
@@ -140,6 +195,11 @@ function log_feedwordpress_update_complete ($delta) {
|
|
140 |
## LEGACY API: Replicate or mock up functions for legacy support purposes ######
|
141 |
################################################################################
|
142 |
|
|
|
|
|
|
|
|
|
|
|
143 |
if (!function_exists('current_user_can')) {
|
144 |
$legacy_capability_hack = true;
|
145 |
function current_user_can ($task) {
|
@@ -191,20 +251,16 @@ function get_feed_meta ($key) {
|
|
191 |
$ret = NULL;
|
192 |
if (strlen($feed_id) > 0):
|
193 |
if (isset($feedwordpress_linkcache[$feed_id])) :
|
194 |
-
$
|
195 |
else :
|
196 |
-
$
|
197 |
-
|
198 |
-
WHERE (link_id = '".$wpdb->escape($feed_id)."')"
|
199 |
-
);
|
200 |
-
$feedwordpress_linkcache[$feed_id] = $result;
|
201 |
endif;
|
202 |
|
203 |
-
$
|
204 |
-
|
205 |
-
endif; /* if */
|
206 |
return $ret;
|
207 |
-
}
|
208 |
|
209 |
function get_syndication_permalink () {
|
210 |
list($u) = get_post_custom_values('syndication_permalink'); return $u;
|
@@ -241,7 +297,7 @@ function feedwordpress_restore_syndicated_content ($text) {
|
|
241 |
}
|
242 |
|
243 |
function syndication_permalink ($permalink = '') {
|
244 |
-
if (
|
245 |
$uri = get_syndication_permalink();
|
246 |
return ((strlen($uri) > 0) ? $uri : $permalink);
|
247 |
else:
|
@@ -254,9 +310,9 @@ function syndication_permalink ($permalink = '') {
|
|
254 |
################################################################################
|
255 |
|
256 |
function fwp_upgrade_page () {
|
257 |
-
if (isset($
|
258 |
-
$ver =
|
259 |
-
if (
|
260 |
echo "<div class=\"wrap\">\n";
|
261 |
echo "<h2>Upgrading FeedWordPress...</h2>";
|
262 |
|
@@ -315,235 +371,12 @@ function fwp_add_pages () {
|
|
315 |
$manage_options = 'manage_options';
|
316 |
endif;
|
317 |
|
318 |
-
add_submenu_page('
|
319 |
-
|
|
|
|
|
320 |
} // function fwp_add_pages () */
|
321 |
|
322 |
-
function fwp_syndication_options_page () {
|
323 |
-
global $wpdb, $wp_db_version;
|
324 |
-
|
325 |
-
if (FeedWordPress::needs_upgrade()) :
|
326 |
-
fwp_upgrade_page();
|
327 |
-
return;
|
328 |
-
endif;
|
329 |
-
|
330 |
-
$caption = 'Save Changes';
|
331 |
-
if (isset($_POST['action']) and $_POST['action']==$caption):
|
332 |
-
check_admin_referer();
|
333 |
-
|
334 |
-
if (!current_user_can('manage_options')):
|
335 |
-
die (__("Cheatin' uh ?"));
|
336 |
-
else:
|
337 |
-
update_option('feedwordpress_rpc_secret', $_REQUEST['rpc_secret']);
|
338 |
-
update_option('feedwordpress_cat_id', $_REQUEST['syndication_category']);
|
339 |
-
update_option('feedwordpress_munge_permalink', $_REQUEST['munge_permalink']);
|
340 |
-
update_option('feedwordpress_update_logging', $_REQUEST['update_logging']);
|
341 |
-
update_option('feedwordpress_unfamiliar_author', $_REQUEST['unfamiliar_author']);
|
342 |
-
update_option('feedwordpress_unfamiliar_category', $_REQUEST['unfamiliar_category']);
|
343 |
-
update_option('feedwordpress_syndicated_post_status', $_REQUEST['post_status']);
|
344 |
-
|
345 |
-
// Categories
|
346 |
-
$cats = array();
|
347 |
-
if (isset($_POST['post_category'])) :
|
348 |
-
$cat_set = "(".implode(",", $_POST['post_category']).")";
|
349 |
-
$cats = $wpdb->get_col(
|
350 |
-
"SELECT cat_name
|
351 |
-
FROM $wpdb->categories
|
352 |
-
WHERE cat_ID IN {$cat_set}
|
353 |
-
");
|
354 |
-
endif;
|
355 |
-
|
356 |
-
if (!empty($cats)) :
|
357 |
-
update_option('feedwordpress_syndication_cats', implode("\n", $cats));
|
358 |
-
else :
|
359 |
-
delete_option('feedwordpress_syndication_cats');
|
360 |
-
endif;
|
361 |
-
|
362 |
-
if (isset($_REQUEST['comment_status']) and ($_REQUEST['comment_status'] == 'open')) :
|
363 |
-
update_option('feedwordpress_syndicated_comment_status', 'open');
|
364 |
-
else :
|
365 |
-
update_option('feedwordpress_syndicated_comment_status', 'closed');
|
366 |
-
endif;
|
367 |
-
|
368 |
-
if (isset($_REQUEST['ping_status']) and ($_REQUEST['ping_status'] == 'open')) :
|
369 |
-
update_option('feedwordpress_syndicated_ping_status', 'open');
|
370 |
-
else :
|
371 |
-
update_option('feedwordpress_syndicated_ping_status', 'closed');
|
372 |
-
endif;
|
373 |
-
|
374 |
-
if (isset($_REQUEST['hardcode_name']) and ($_REQUEST['hardcode_name'] == 'no')) :
|
375 |
-
update_option('feedwordpress_hardcode_name', 'no');
|
376 |
-
else :
|
377 |
-
update_option('feedwordpress_hardcode_name', 'yes');
|
378 |
-
endif;
|
379 |
-
|
380 |
-
if (isset($_REQUEST['hardcode_description']) and ($_REQUEST['hardcode_description'] == 'no')) :
|
381 |
-
update_option('feedwordpress_hardcode_description', 'no');
|
382 |
-
else :
|
383 |
-
update_option('feedwordpress_hardcode_description', 'yes');
|
384 |
-
endif;
|
385 |
-
|
386 |
-
if (isset($_REQUEST['hardcode_url']) and ($_REQUEST['hardcode_url'] == 'no')) :
|
387 |
-
update_option('feedwordpress_hardcode_url', 'no');
|
388 |
-
else :
|
389 |
-
update_option('feedwordpress_hardcode_url', 'yes');
|
390 |
-
endif;
|
391 |
-
?>
|
392 |
-
<div class="updated">
|
393 |
-
<p><?php _e('Options saved.')?></p>
|
394 |
-
</div>
|
395 |
-
<?php
|
396 |
-
endif;
|
397 |
-
endif;
|
398 |
-
|
399 |
-
$cat_id = FeedWordPress::link_category_id();
|
400 |
-
$rpc_secret = FeedWordPress::rpc_secret();
|
401 |
-
$munge_permalink = get_settings('feedwordpress_munge_permalink');
|
402 |
-
$update_logging = get_settings('feedwordpress_update_logging');
|
403 |
-
|
404 |
-
$hardcode_name = get_settings('feedwordpress_hardcode_name');
|
405 |
-
$hardcode_description = get_settings('feedwordpress_hardcode_description');
|
406 |
-
$hardcode_url = get_settings('feedwordpress_hardcode_url');
|
407 |
-
|
408 |
-
$post_status = FeedWordPress::syndicated_status('post', array(), 'publish');
|
409 |
-
$comment_status = FeedWordPress::syndicated_status('comment', array(), 'closed');
|
410 |
-
$ping_status = FeedWordPress::syndicated_status('ping', array(), 'closed');
|
411 |
-
|
412 |
-
$unfamiliar_author = array ('create' => '','default' => '','filter' => '');
|
413 |
-
$ua = FeedWordPress::on_unfamiliar('author');
|
414 |
-
if (is_string($ua) and array_key_exists($ua, $unfamiliar_author)) :
|
415 |
-
$unfamiliar_author[$ua] = ' checked="checked"';
|
416 |
-
endif;
|
417 |
-
$unfamiliar_category = array ('create'=>'','default'=>'','filter'=>'');
|
418 |
-
$uc = FeedWordPress::on_unfamiliar('category');
|
419 |
-
if (is_string($uc) and array_key_exists($uc, $unfamiliar_category)) :
|
420 |
-
$unfamiliar_category[$uc] = ' checked="checked"';
|
421 |
-
endif;
|
422 |
-
|
423 |
-
if (isset($wp_db_version) and $wp_db_version >= 4772) :
|
424 |
-
$results = get_categories('type=link');
|
425 |
-
else :
|
426 |
-
$results = $wpdb->get_results("SELECT cat_id, cat_name, auto_toggle FROM $wpdb->linkcategories ORDER BY cat_id");
|
427 |
-
endif;
|
428 |
-
|
429 |
-
$cats = get_settings('feedwordpress_syndication_cats');
|
430 |
-
$dogs = get_nested_categories(-1, 0);
|
431 |
-
$cats = array_map('strtolower',
|
432 |
-
array_map('trim',
|
433 |
-
preg_split(FEEDWORDPRESS_CAT_SEPARATOR_PATTERN, $cats)
|
434 |
-
));
|
435 |
-
|
436 |
-
foreach ($dogs as $tag => $dog) :
|
437 |
-
if (in_array(strtolower(trim($dog['cat_name'])), $cats)) :
|
438 |
-
$dogs[$tag]['checked'] = true;
|
439 |
-
endif;
|
440 |
-
endforeach;
|
441 |
-
|
442 |
-
?>
|
443 |
-
<div class="wrap">
|
444 |
-
<h2>Syndication Options</h2>
|
445 |
-
<form action="" method="post">
|
446 |
-
<fieldset class="options">
|
447 |
-
<legend>Syndicated Feeds</legend>
|
448 |
-
<table class="editform" width="100%" cellspacing="2" cellpadding="5">
|
449 |
-
<tr>
|
450 |
-
<th width="33%" scope="row">Syndicate links in category:</th>
|
451 |
-
<td width="67%"><?php
|
452 |
-
echo "\n<select name=\"syndication_category\" size=\"1\">";
|
453 |
-
foreach ($results as $row) {
|
454 |
-
if (!isset($row->cat_id)) { $row->cat_id = $row->cat_ID; }
|
455 |
-
|
456 |
-
echo "\n\t<option value=\"$row->cat_id\"";
|
457 |
-
if ($row->cat_id == $cat_id)
|
458 |
-
echo " selected='selected'";
|
459 |
-
echo ">$row->cat_id: ".wp_specialchars($row->cat_name);
|
460 |
-
if ('Y' == $row->auto_toggle)
|
461 |
-
echo ' (auto toggle)';
|
462 |
-
echo "</option>\n";
|
463 |
-
}
|
464 |
-
echo "\n</select>\n";
|
465 |
-
?></td>
|
466 |
-
</tr>
|
467 |
-
|
468 |
-
<tr><th width="33%" scope="row" style="vertical-align:top">Update live from feed:</th>
|
469 |
-
<td width="67%"><ul style="margin:0;list-style:none">
|
470 |
-
<li><input type="checkbox" name="hardcode_name" value="no"<?php echo (($hardcode_name=='yes')?'':' checked="checked"');?>/> Contributor name (feed title)</li>
|
471 |
-
<li><input type="checkbox" name="hardcode_description" value="no"<?php echo (($hardcode_description=='yes')?'':' checked="checked"');?>/> Contributor description (feed tagline)</li>
|
472 |
-
<li><input type="checkbox" name="hardcode_url" value="no"<?php echo (($hardcode_url=='yes')?'':' checked="checked"');?>/> Homepage (feed link)</li>
|
473 |
-
</ul></td></tr>
|
474 |
-
</table>
|
475 |
-
</fieldset>
|
476 |
-
|
477 |
-
<fieldset class="options">
|
478 |
-
<legend>Syndicated Posts</legend>
|
479 |
-
|
480 |
-
<?php fwp_category_box($dogs, '<em>all syndicated posts</em>'); ?>
|
481 |
-
|
482 |
-
<table class="editform" width="75%" cellspacing="2" cellpadding="5">
|
483 |
-
<tr style="vertical-align: top"><th width="33%" scope="row">Publication:</th>
|
484 |
-
<td width="67%"><ul style="margin: 0; padding: 0; list-style:none">
|
485 |
-
<li><label><input type="radio" name="post_status" value="publish"<?php echo ($post_status=='publish')?' checked="checked"':''; ?> /> Publish syndicated posts immediately</label></li>
|
486 |
-
<li><label><input type="radio" name="post_status" value="draft"<?php echo ($post_status=='draft')?' checked="checked"':''; ?> /> Hold syndicated posts as drafts</label></li>
|
487 |
-
<li><label><input type="radio" name="post_status" value="private"<?php echo ($post_status=='private')?' checked="checked"':''; ?> /> Hold syndicated posts as private posts</label></li>
|
488 |
-
</ul></td></tr>
|
489 |
-
|
490 |
-
<tr style="vertical-align: top"><th width="33%" scope="row">Comments:</th>
|
491 |
-
<td width="67%"><ul style="margin: 0; padding: 0; list-style:none">
|
492 |
-
<li><label><input type="radio" name="comment_status" value="open"<?php echo ($comment_status=='open')?' checked="checked"':''; ?> /> Allow comments on syndicated posts</label></li>
|
493 |
-
<li><label><input type="radio" name="comment_status" value="closed"<?php echo ($comment_status!='open')?' checked="checked"':''; ?> /> Don't allow comments on syndicated posts</label></li>
|
494 |
-
</ul></td></tr>
|
495 |
-
|
496 |
-
<tr style="vertical-align: top"><th width="33%" scope="row">Trackback and Pingback:</th>
|
497 |
-
<td width="67%"><ul style="margin:0; padding: 0; list-style:none">
|
498 |
-
<li><label><input type="radio" name="ping_status" value="open"<?php echo ($ping_status=='open')?' checked="checked"':''; ?> /> Accept pings on syndicated posts</label></li>
|
499 |
-
<li><label><input type="radio" name="ping_status" value="closed"<?php echo ($ping_status!='open')?' checked="checked"':''; ?> /> Don't accept pings on syndicated posts</label></li>
|
500 |
-
</ul></td></tr>
|
501 |
-
|
502 |
-
<tr style="vertical-align: top"><th width="33%" scope="row" style="vertical-align:top">Unfamiliar authors:</th>
|
503 |
-
<td width="67%"><ul style="margin: 0; padding: 0; list-style:none">
|
504 |
-
<li><label><input type="radio" name="unfamiliar_author" value="create"<?php echo $unfamiliar_author['create']; ?>/> create a new author account</label></li>
|
505 |
-
<li><label><input type="radio" name="unfamiliar_author" value="default"<?php echo $unfamiliar_author['default']; ?> /> attribute the post to the default author</label></li>
|
506 |
-
<li><label><input type="radio" name="unfamiliar_author" value="filter"<?php echo $unfamiliar_author['filter']; ?> /> don't syndicate the post</label></li>
|
507 |
-
</ul></td></tr>
|
508 |
-
<tr style="vertical-align: top"><th width="33%" scope="row" style="vertical-align:top">Unfamiliar categories:</th>
|
509 |
-
<td width="67%"><ul style="margin: 0; padding:0; list-style:none">
|
510 |
-
<li><label><input type="radio" name="unfamiliar_category" value="create"<?php echo $unfamiliar_category['create']; ?>/> create any categories the post is in</label></li>
|
511 |
-
<li><label><input type="radio" name="unfamiliar_category" value="default"<?php echo $unfamiliar_category['default']; ?>/> don't create new categories</li>
|
512 |
-
<li><label><input type="radio" name="unfamiliar_category" value="filter"<?php echo $unfamiliar_category['filter']; ?>/> don't create new categories and don't syndicate posts unless they match at least one familiar category</label></li>
|
513 |
-
</ul></td></tr>
|
514 |
-
|
515 |
-
<tr style="vertical-align: top"><th width="33%" scope="row">Permalinks point to:</th>
|
516 |
-
<td width="67%"><select name="munge_permalink" size="1">
|
517 |
-
<option value="yes"<?php echo ($munge_permalink=='yes')?' selected="selected"':''; ?>>original website</option>
|
518 |
-
<option value="no"<?php echo ($munge_permalink=='no')?' selected="selected"':''; ?>>this website</option>
|
519 |
-
</select></td></tr>
|
520 |
-
</table>
|
521 |
-
<div class="submit"><input type="submit" name="action" value="<?php echo $caption; ?>" /></div>
|
522 |
-
</fieldset>
|
523 |
-
|
524 |
-
<fieldset class="options">
|
525 |
-
<legend>Back-end Options</legend>
|
526 |
-
<table class="editform" width="100%" cellspacing="2" cellpadding="5">
|
527 |
-
<tr>
|
528 |
-
<th width="33%" scope="row">XML-RPC update secret word:</th>
|
529 |
-
<td width="67%"><input id="rpc_secret" name="rpc_secret" value="<?php echo $rpc_secret; ?>" />
|
530 |
-
</td>
|
531 |
-
</tr>
|
532 |
-
<tr>
|
533 |
-
<th scope="row">Write update notices to PHP logs:</th>
|
534 |
-
<td><select name="update_logging" size="1">
|
535 |
-
<option value="yes"<?php echo (($update_logging=='yes')?' selected="selected"':''); ?>>yes</option>
|
536 |
-
<option value="no"<?php echo (($update_logging!='yes')?' selected="selected"':''); ?>>no</option>
|
537 |
-
</select></td>
|
538 |
-
</tr>
|
539 |
-
</table>
|
540 |
-
<div class="submit"><input type="submit" name="action" value="<?php echo $caption; ?>" /></div>
|
541 |
-
</fieldset>
|
542 |
-
</form>
|
543 |
-
</div>
|
544 |
-
<?php
|
545 |
-
}
|
546 |
-
|
547 |
function fwp_category_box ($checked, $object) {
|
548 |
global $wp_db_version;
|
549 |
|
@@ -575,6 +408,12 @@ function fwp_category_box ($checked, $object) {
|
|
575 |
endif;
|
576 |
}
|
577 |
|
|
|
|
|
|
|
|
|
|
|
|
|
578 |
function fwp_syndication_manage_page () {
|
579 |
global $wpdb;
|
580 |
|
@@ -589,7 +428,7 @@ if (isset($_REQUEST['action'])):
|
|
589 |
if ($_REQUEST['action'] == 'feedfinder') : $cont = fwp_feedfinder_page();
|
590 |
elseif ($_REQUEST['action'] == 'switchfeed') : $cont = fwp_switchfeed_page();
|
591 |
elseif ($_REQUEST['action'] == 'linkedit') : $cont = fwp_linkedit_page();
|
592 |
-
elseif ($_REQUEST['action'] == 'Unsubscribe from Checked' or $_REQUEST['action'] == 'Unsubscribe') : $cont = fwp_multidelete_page();
|
593 |
endif;
|
594 |
endif;
|
595 |
|
@@ -597,20 +436,74 @@ if ($cont):
|
|
597 |
?>
|
598 |
<?php
|
599 |
$links = FeedWordPress::syndicated_links();
|
600 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
601 |
<div class="wrap">
|
602 |
-
<form action="
|
603 |
-
<h2>
|
604 |
-
<
|
605 |
-
|
606 |
-
|
607 |
-
<
|
608 |
-
</
|
609 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
610 |
</form>
|
611 |
-
</div>
|
612 |
|
613 |
-
<form action="
|
614 |
<div class="wrap">
|
615 |
<h2>Syndicated Sites</h2>
|
616 |
<?php $alt_row = true;
|
@@ -626,7 +519,7 @@ if ($cont):
|
|
626 |
<?php foreach ($links as $link):
|
627 |
$alt_row = !$alt_row; ?>
|
628 |
<tr<?php echo ($alt_row?' class="alternate"':''); ?>>
|
629 |
-
<td><a href="<?php echo wp_specialchars($link->link_url); ?>"><?php echo wp_specialchars($link->link_name); ?></a></td>
|
630 |
<?php
|
631 |
if (strlen($link->link_rss) > 0):
|
632 |
$caption='Switch Feed';
|
@@ -641,7 +534,7 @@ if ($cont):
|
|
641 |
if (strlen($display_uri) > 32) : $display_uri = substr($display_uri, 0, 32).'…'; endif;
|
642 |
?>
|
643 |
<td>
|
644 |
-
<strong><a href="<?php echo $link->link_rss; ?>"><?php echo wp_specialchars($display_uri); ?></a></strong></td>
|
645 |
<?php
|
646 |
else:
|
647 |
$caption='Find Feed';
|
@@ -651,9 +544,9 @@ if ($cont):
|
|
651 |
<?php
|
652 |
endif;
|
653 |
?>
|
654 |
-
<td><a href="
|
655 |
-
<td><a href="
|
656 |
-
<td><a href="
|
657 |
<td><input type="checkbox" name="link_ids[]" value="<?php echo $link->link_id; ?>" /></td>
|
658 |
<?php
|
659 |
echo "\n\t</tr>";
|
@@ -665,15 +558,24 @@ if ($cont):
|
|
665 |
|
666 |
<?php endif; ?>
|
667 |
</table>
|
668 |
-
|
669 |
-
|
|
|
|
|
|
|
|
|
|
|
670 |
<div class="wrap">
|
671 |
-
<
|
672 |
-
<
|
673 |
-
<
|
674 |
-
|
|
|
|
|
675 |
</div>
|
|
|
676 |
</form>
|
|
|
677 |
<?php
|
678 |
endif;
|
679 |
}
|
@@ -685,10 +587,12 @@ function fwp_feedfinder_page () {
|
|
685 |
|
686 |
if (isset($_REQUEST['link_id']) and ($_REQUEST['link_id']!=0)):
|
687 |
$link_id = $_REQUEST['link_id'];
|
|
|
|
|
688 |
$link = $wpdb->get_row("SELECT * FROM $wpdb->links WHERE link_id='".$wpdb->escape($link_id)."'");
|
689 |
if (is_object($link)):
|
690 |
if (is_null($lookup)) $lookup = $link->link_url;
|
691 |
-
$name = wp_specialchars($link->link_name);
|
692 |
else:
|
693 |
die (__("Cheatin' uh ?"));
|
694 |
endif;
|
@@ -709,17 +613,17 @@ function fwp_feedfinder_page () {
|
|
709 |
$feed_title = isset($rss->channel['title'])?$rss->channel['title']:$rss->channel['link'];
|
710 |
$feed_link = isset($rss->channel['link'])?$rss->channel['link']:'';
|
711 |
?>
|
712 |
-
<form action="
|
713 |
<fieldset style="clear: both">
|
714 |
<legend><?php echo $rss->feed_type; ?> <?php echo $rss->feed_version; ?> feed</legend>
|
715 |
|
716 |
<?php if ($link_id===0): ?>
|
717 |
-
<input type="hidden" name="feed_title" value="<?php echo wp_specialchars($feed_title); ?>" />
|
718 |
-
<input type="hidden" name="feed_link" value="<?php echo wp_specialchars($feed_link); ?>" />
|
719 |
<?php endif; ?>
|
720 |
|
721 |
<input type="hidden" name="link_id" value="<?php echo $link_id; ?>" />
|
722 |
-
<input type="hidden" name="feed" value="<?php echo wp_specialchars($f); ?>" />
|
723 |
<input type="hidden" name="action" value="switchfeed" />
|
724 |
|
725 |
<div>
|
@@ -744,9 +648,9 @@ function fwp_feedfinder_page () {
|
|
744 |
<h3>Feed Information</h3>
|
745 |
<ul>
|
746 |
<li><strong>Website:</strong> <a href="<?php echo $feed_link; ?>"><?php echo is_null($feed_title)?'<em>Unknown</em>':$feed_title; ?></a></li>
|
747 |
-
<li><strong>Feed URI:</strong> <a href="<?php echo wp_specialchars($f); ?>"><?php echo wp_specialchars($f); ?></a> <a title="Check feed <<?php echo wp_specialchars($f); ?>> for validity" href="http://feedvalidator.org/check.cgi?url=<?php echo urlencode($f); ?>"><img src="../wp-images/smilies/icon_arrow.gif" alt="(→)" /></a></li>
|
748 |
-
<li><strong>Encoding:</strong> <?php echo isset($rss->encoding)?wp_specialchars($rss->encoding):"<em>Unknown</em>"; ?></li>
|
749 |
-
<li><strong>Description:</strong> <?php echo isset($rss->channel['description'])?wp_specialchars($rss->channel['description']):"<em>Unknown</em>"; ?></li>
|
750 |
</ul>
|
751 |
<div class="submit"><input type="submit" name="Use" value="« Use this feed" /></div>
|
752 |
<div class="submit"><input type="submit" name="Cancel" value="« Cancel" /></div>
|
@@ -762,7 +666,7 @@ function fwp_feedfinder_page () {
|
|
762 |
?>
|
763 |
</div>
|
764 |
|
765 |
-
<form action="
|
766 |
<div class="wrap">
|
767 |
<h2>Use another feed</h2>
|
768 |
<div><label>Feed:</label>
|
@@ -786,10 +690,10 @@ function fwp_switchfeed_page () {
|
|
786 |
elseif (isset($_REQUEST['link_id']) and ($_REQUEST['link_id']==0)):
|
787 |
$link_id = FeedWordPress::syndicate_link($_REQUEST['feed_title'], $_REQUEST['feed_link'], $_REQUEST['feed']);
|
788 |
if ($link_id): ?>
|
789 |
-
<div class="updated"><p><a href="<?php echo $_REQUEST['feed_link']; ?>"><?php echo wp_specialchars($_REQUEST['feed_title']); ?></a>
|
790 |
-
has been added as a contributing site, using the newsfeed at <<a href="<?php echo $_REQUEST['feed']; ?>"><?php echo wp_specialchars($_REQUEST['feed']); ?></a>>.</p></div>
|
791 |
<?php else: ?>
|
792 |
-
<div class="updated"><p>There was a problem adding the newsfeed. [SQL: <?php echo wp_specialchars(mysql_error()); ?>]</p></div>
|
793 |
<?php endif;
|
794 |
elseif (isset($_REQUEST['link_id'])):
|
795 |
// Update link_rss
|
@@ -806,8 +710,8 @@ has been added as a contributing site, using the newsfeed at <<a href="<?php
|
|
806 |
WHERE link_id = '".$wpdb->escape($_REQUEST['link_id'])."'
|
807 |
");
|
808 |
?>
|
809 |
-
<div class="updated"><p>Feed for <a href="<?php echo $result->link_url; ?>"><?php echo wp_specialchars($result->link_name); ?></a>
|
810 |
-
updated to <<a href="<?php echo $_REQUEST['feed']; ?>"><?php echo wp_specialchars($_REQUEST['feed']); ?></a>>.</p></div>
|
811 |
<?php else: ?>
|
812 |
<div class="updated"><p>Nothing was changed.</p></div>
|
813 |
<?php endif;
|
@@ -823,6 +727,7 @@ function fwp_linkedit_page () {
|
|
823 |
|
824 |
$special_settings = array ( /* Regular expression syntax is OK here */
|
825 |
'cats',
|
|
|
826 |
'hardcode name',
|
827 |
'hardcode url',
|
828 |
'hardcode description',
|
@@ -843,21 +748,19 @@ function fwp_linkedit_page () {
|
|
843 |
return fwp_feedfinder_page(); // re-route to Feed Finder page
|
844 |
else :
|
845 |
$link_id = (int) $_REQUEST['link_id'];
|
846 |
-
$
|
847 |
-
SELECT * FROM $wpdb->links WHERE link_id = $link_id
|
848 |
-
");
|
849 |
|
850 |
-
if ($
|
851 |
-
if (isset($
|
852 |
$alter = array ();
|
853 |
|
854 |
-
$meta =
|
855 |
if (isset($meta['cats'])):
|
856 |
$meta['cats'] = preg_split(FEEDWORDPRESS_CAT_SEPARATOR_PATTERN, $meta['cats']);
|
857 |
endif;
|
858 |
|
859 |
// custom feed settings first
|
860 |
-
foreach ($
|
861 |
$mn['key0'] = trim($mn['key0']);
|
862 |
$mn['key1'] = trim($mn['key1']);
|
863 |
if (preg_match("\007^(("
|
@@ -878,41 +781,36 @@ function fwp_linkedit_page () {
|
|
878 |
|
879 |
// now stuff through the web form
|
880 |
// hardcoded feed info
|
881 |
-
if (isset($
|
882 |
-
$meta['hardcode name'] = $
|
883 |
if (FeedWordPress::affirmative($meta, 'hardcode name')) :
|
884 |
-
$alter[] = "link_name = '".$wpdb->escape($
|
885 |
endif;
|
886 |
endif;
|
887 |
-
if (isset($
|
888 |
-
$meta['hardcode description'] = $
|
889 |
if (FeedWordPress::affirmative($meta, 'hardcode description')) :
|
890 |
-
$alter[] = "link_description = '".$wpdb->escape($
|
891 |
endif;
|
892 |
endif;
|
893 |
-
if (isset($
|
894 |
-
$meta['hardcode url'] = $
|
895 |
if (FeedWordPress::affirmative($meta, 'hardcode url')) :
|
896 |
-
$alter[] = "link_url = '".$wpdb->escape($
|
897 |
endif;
|
898 |
endif;
|
899 |
|
900 |
// Update scheduling
|
901 |
-
if (isset($
|
902 |
-
$meta['update/hold'] = $
|
903 |
endif;
|
904 |
|
905 |
// Categories
|
906 |
-
if (isset($
|
907 |
-
$
|
908 |
-
$
|
909 |
-
|
910 |
-
|
911 |
-
WHERE cat_ID IN {$cat_set}
|
912 |
-
");
|
913 |
-
if (count($meta['cats']) == 0) :
|
914 |
-
unset($meta['cats']);
|
915 |
-
endif;
|
916 |
else :
|
917 |
unset($meta['cats']);
|
918 |
endif;
|
@@ -920,11 +818,11 @@ function fwp_linkedit_page () {
|
|
920 |
// Post status, comment status, ping status
|
921 |
foreach (array('post', 'comment', 'ping') as $what) :
|
922 |
$sfield = "feed_{$what}_status";
|
923 |
-
if (isset($
|
924 |
-
if ($
|
925 |
unset($meta["{$what} status"]);
|
926 |
else :
|
927 |
-
$meta["{$what} status"] = $
|
928 |
endif;
|
929 |
endif;
|
930 |
endforeach;
|
@@ -932,22 +830,30 @@ function fwp_linkedit_page () {
|
|
932 |
// Unfamiliar author, unfamiliar categories
|
933 |
foreach (array("author", "category") as $what) :
|
934 |
$sfield = "unfamiliar_{$what}";
|
935 |
-
if (isset($
|
936 |
-
if ($
|
937 |
unset($meta["unfamiliar {$what}"]);
|
938 |
else :
|
939 |
-
$meta["unfamiliar {$what}"] = $
|
940 |
endif;
|
941 |
endif;
|
942 |
endforeach;
|
943 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
944 |
if (is_array($meta['cats'])) :
|
945 |
$meta['cats'] = implode(FEEDWORDPRESS_CAT_SEPARATOR, $meta['cats']);
|
946 |
endif;
|
947 |
|
948 |
$notes = '';
|
949 |
foreach ($meta as $key => $value) :
|
950 |
-
$notes .= $key . ": ". addcslashes($value, "\0..\37") . "\n";
|
951 |
endforeach;
|
952 |
$alter[] = "link_notes = '".$wpdb->escape($notes)."'";
|
953 |
|
@@ -962,27 +868,23 @@ function fwp_linkedit_page () {
|
|
962 |
$updated_link = true;
|
963 |
|
964 |
// reload link information from DB
|
965 |
-
$
|
966 |
-
SELECT * FROM $wpdb->links WHERE link_id = $link_id
|
967 |
-
");
|
968 |
else :
|
969 |
$updated_link = false;
|
970 |
endif;
|
971 |
|
972 |
-
$
|
973 |
-
$
|
974 |
-
$
|
975 |
-
$
|
976 |
-
$
|
977 |
-
$
|
978 |
-
|
979 |
-
$
|
980 |
-
$
|
981 |
-
$
|
982 |
-
$
|
983 |
|
984 |
-
$meta = FeedWordPress::notes_to_settings($row->link_notes);
|
985 |
-
|
986 |
$status['post'] = array('publish' => '', 'private' => '', 'draft' => '', 'site-default' => '');
|
987 |
$status['comment'] = array('open' => '', 'closed' => '', 'site-default' => '');
|
988 |
$status['ping'] = array('open' => '', 'closed' => '', 'site-default' => '');
|
@@ -1009,13 +911,22 @@ function fwp_linkedit_page () {
|
|
1009 |
endforeach;
|
1010 |
|
1011 |
$dogs = get_nested_categories(-1, 0);
|
1012 |
-
|
1013 |
-
array_map('
|
1014 |
-
|
1015 |
-
|
|
|
|
|
|
|
|
|
1016 |
|
1017 |
foreach ($dogs as $tag => $dog) :
|
1018 |
-
|
|
|
|
|
|
|
|
|
|
|
1019 |
$dogs[$tag]['checked'] = true;
|
1020 |
endif;
|
1021 |
endforeach;
|
@@ -1039,7 +950,7 @@ function fwp_linkedit_page () {
|
|
1039 |
<div class="updated"><p>Syndicated feed settings updated.</p></div>
|
1040 |
<?php endif; ?>
|
1041 |
|
1042 |
-
<form action="
|
1043 |
<div class="wrap">
|
1044 |
<input type="hidden" name="link_id" value="<?php echo $link_id; ?>" />
|
1045 |
<input type="hidden" name="action" value="linkedit" />
|
@@ -1050,9 +961,9 @@ function fwp_linkedit_page () {
|
|
1050 |
<table class="editform" width="100%" cellspacing="2" cellpadding="5">
|
1051 |
<tr>
|
1052 |
<th scope="row" width="20%"><?php _e('Feed URI:') ?></th>
|
1053 |
-
<td width="60%"><a href="<?php echo wp_specialchars($link_rss_uri); ?>"><?php echo $link_rss_uri; ?></a>
|
1054 |
<a href="<?php echo FEEDVALIDATOR_URI; ?>?url=<?php echo urlencode($link_rss_uri); ?>"
|
1055 |
-
title="Check feed <<?php echo wp_specialchars($link_rss_uri); ?>> for validity"><img src="../wp-images/smilies/icon_arrow.gif" alt="→" /></a>
|
1056 |
</td>
|
1057 |
<td width="20%"><input type="submit" name="feedfinder" value="switch →" style="font-size:smaller" /></td>
|
1058 |
</tr>
|
@@ -1064,8 +975,8 @@ value="<?php echo $link_name; ?>" style="width: 95%" />
|
|
1064 |
</td>
|
1065 |
<td>
|
1066 |
<select id="basics-hardcode-name" onchange="flip_hardcode('name')" name="hardcode_name">
|
1067 |
-
<option value="no" <?php echo
|
1068 |
-
<option value="yes" <?php echo
|
1069 |
</select>
|
1070 |
</td>
|
1071 |
</tr>
|
@@ -1078,8 +989,8 @@ value="<?php echo $link_name; ?>" style="width: 95%" />
|
|
1078 |
<td>
|
1079 |
<select id="basics-hardcode-description" onchange="flip_hardcode('description')"
|
1080 |
name="hardcode_description">
|
1081 |
-
<option value="no" <?php echo
|
1082 |
-
<option value="yes" <?php echo
|
1083 |
</select></td>
|
1084 |
</tr>
|
1085 |
<tr>
|
@@ -1089,8 +1000,8 @@ name="hardcode_description">
|
|
1089 |
<a id="basics-url-view" href="<?php echo $link_url; ?>"><?php echo $link_url; ?></a></td>
|
1090 |
<td>
|
1091 |
<select id="basics-hardcode-url" onchange="flip_hardcode('url')" name="hardcode_url">
|
1092 |
-
<option value="no"<?php echo
|
1093 |
-
<option value="yes"<?php echo
|
1094 |
</select></td></tr>
|
1095 |
|
1096 |
<tr>
|
@@ -1146,12 +1057,12 @@ flip_hardcode('url');
|
|
1146 |
|
1147 |
<?php fwp_category_box($dogs, 'all syndicated posts from this feed'); ?>
|
1148 |
|
1149 |
-
<table class="editform" width="
|
1150 |
-
<tr><th width="
|
1151 |
-
<td width="
|
1152 |
<li><label><input type="radio" name="feed_post_status" value="site-default"
|
1153 |
-
<?php echo $status['post']['site-default']; ?> /> Use site-wide setting from <a href="
|
1154 |
-
(currently: <strong><?php echo
|
1155 |
<li><label><input type="radio" name="feed_post_status" value="publish"
|
1156 |
<?php echo $status['post']['publish']; ?> /> Publish posts from this feed immediately</label></li>
|
1157 |
<li><label><input type="radio" name="feed_post_status" value="private"
|
@@ -1161,11 +1072,11 @@ flip_hardcode('url');
|
|
1161 |
</ul></td>
|
1162 |
</tr>
|
1163 |
|
1164 |
-
<tr><th width="
|
1165 |
-
<td width="
|
1166 |
<li><label><input type="radio" name="feed_comment_status" value="site-default"
|
1167 |
-
<?php echo $status['comment']['site-default']; ?> /> Use site-wide setting from <a href="
|
1168 |
-
(currently: <strong><?php echo
|
1169 |
<li><label><input type="radio" name="feed_comment_status" value="open"
|
1170 |
<?php echo $status['comment']['open']; ?> /> Allow comments on syndicated posts from this feed</label></li>
|
1171 |
<li><label><input type="radio" name="feed_comment_status" value="closed"
|
@@ -1173,11 +1084,11 @@ flip_hardcode('url');
|
|
1173 |
</ul></td>
|
1174 |
</tr>
|
1175 |
|
1176 |
-
<tr><th width="
|
1177 |
-
<td width="
|
1178 |
<li><label><input type="radio" name="feed_ping_status" value="site-default"
|
1179 |
-
<?php echo $status['ping']['site-default']; ?> /> Use site-wide setting from <a href="
|
1180 |
-
(currently: <strong><?php echo
|
1181 |
<li><label><input type="radio" name="feed_ping_status" value="open"
|
1182 |
<?php echo $status['ping']['open']; ?> /> Accept pings on syndicated posts from this feed</label></li>
|
1183 |
<li><label><input type="radio" name="feed_ping_status" value="closed"
|
@@ -1197,7 +1108,7 @@ flip_hardcode('url');
|
|
1197 |
<tr>
|
1198 |
<th width="20%" scope="row" style="vertical-align:top">Unfamiliar authors:</th>
|
1199 |
<td width="80%"><ul style="margin: 0; list-style:none">
|
1200 |
-
<li><label><input type="radio" name="unfamiliar_author" value="site-default"<?php echo $unfamiliar['author']['site-default']; ?> /> use site-wide setting from <a href="
|
1201 |
(currently <strong><?php echo FeedWordPress::on_unfamiliar('author');; ?></strong>)</label></li>
|
1202 |
<li><label><input type="radio" name="unfamiliar_author" value="create"<?php echo $unfamiliar['author']['create']; ?>/> create a new author account</label></li>
|
1203 |
<li><label><input type="radio" name="unfamiliar_author" value="default"<?php echo $unfamiliar['author']['default']; ?> /> attribute the post to the default author</label></li>
|
@@ -1208,13 +1119,26 @@ flip_hardcode('url');
|
|
1208 |
<tr>
|
1209 |
<th width="20%" scope="row" style="vertical-align:top">Unfamiliar categories:</th>
|
1210 |
<td width="80%"><ul style="margin: 0; list-style:none">
|
1211 |
-
<li><label><input type="radio" name="unfamiliar_category" value="site-default"<?php echo $unfamiliar['category']['site-default']; ?> /> use site-wide setting from <a href="
|
1212 |
(currently <strong><?php echo FeedWordPress::on_unfamiliar('category');; ?></strong>)</label></li>
|
1213 |
<li><label><input type="radio" name="unfamiliar_category" value="create"<?php echo $unfamiliar['category']['create']; ?> /> create any categories the post is in</label></li>
|
1214 |
<li><label><input type="radio" name="unfamiliar_category" value="default"<?php echo $unfamiliar['category']['default']; ?> /> don't create new categories</label></li>
|
1215 |
<li><label><input type="radio" name="unfamiliar_category" value="filter"<?php echo $unfamiliar['category']['filter']; ?> /> don't create new categories and don't syndicate posts unless they match at least one familiar category</label></li>
|
1216 |
</ul></td>
|
1217 |
-
</tr
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1218 |
</fieldset>
|
1219 |
|
1220 |
<p class="submit">
|
@@ -1237,9 +1161,9 @@ flip_hardcode('url');
|
|
1237 |
if (!preg_match("\007^((".implode(')|(', $special_settings)."))$\007i", $key)) :
|
1238 |
?>
|
1239 |
<tr style="vertical-align:top">
|
1240 |
-
<th width="30%" scope="row"><input type="hidden" name="notes[<?php echo $i; ?>][key0]" value="<?php echo wp_specialchars($key); ?>" />
|
1241 |
-
<input id="notes-<?php echo $i; ?>-key" name="notes[<?php echo $i; ?>][key1]" value="<?php echo wp_specialchars($key); ?>" /></th>
|
1242 |
-
<td width="60%"><textarea rows="2" cols="40" id="notes-<?php echo $i; ?>-value" name="notes[<?php echo $i; ?>][value]"><?php echo wp_specialchars($value); ?></textarea></td>
|
1243 |
<td width="10%"><select name="notes[<?php echo $i; ?>][action]">
|
1244 |
<option value="update">save changes</option>
|
1245 |
<option value="delete">delete this setting</option>
|
@@ -1278,8 +1202,8 @@ function fwp_multidelete_page () {
|
|
1278 |
|
1279 |
if (!current_user_can('manage_links')):
|
1280 |
die (__("Cheatin' uh ?"));
|
1281 |
-
elseif (isset($
|
1282 |
-
foreach ($
|
1283 |
$do_it[$what][] = $link_id;
|
1284 |
endforeach;
|
1285 |
|
@@ -1359,7 +1283,7 @@ function fwp_multidelete_page () {
|
|
1359 |
WHERE link_id IN (".implode(",",$link_ids).")
|
1360 |
");
|
1361 |
?>
|
1362 |
-
<form action="
|
1363 |
<div class="wrap">
|
1364 |
<input type="hidden" name="action" value="Unsubscribe" />
|
1365 |
<input type="hidden" name="confirm" value="Delete" />
|
@@ -1368,9 +1292,8 @@ function fwp_multidelete_page () {
|
|
1368 |
<?php foreach ($targets as $link) :
|
1369 |
$link_url = wp_specialchars($link->link_url, 1);
|
1370 |
$link_name = wp_specialchars($link->link_name, 1);
|
1371 |
-
$link_description = wp_specialchars($link->link_description);
|
1372 |
-
$link_rss = wp_specialchars($link->link_rss);
|
1373 |
-
$meta = FeedWordPress::notes_to_settings($link->link_notes);
|
1374 |
?>
|
1375 |
<fieldset>
|
1376 |
<legend><?php echo $link_name; ?></legend>
|
@@ -1433,20 +1356,46 @@ function fwp_hold_pings () {
|
|
1433 |
function fwp_release_pings () {
|
1434 |
global $fwp_held_ping;
|
1435 |
if ($fwp_held_ping):
|
1436 |
-
|
|
|
|
|
|
|
|
|
1437 |
endif;
|
1438 |
$fwp_held_ping = NULL; // NULL: not holding pings anymore
|
1439 |
}
|
1440 |
|
1441 |
-
function
|
1442 |
-
|
1443 |
-
if (!is_null($fwp_held_ping) and $post_id):
|
1444 |
$fwp_held_ping = $post_id;
|
1445 |
-
|
|
|
|
|
1446 |
generic_ping($fwp_held_ping);
|
1447 |
endif;
|
1448 |
}
|
1449 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1450 |
################################################################################
|
1451 |
## class FeedWordPress #########################################################
|
1452 |
################################################################################
|
@@ -1485,120 +1434,30 @@ class FeedWordPress {
|
|
1485 |
array('script', 'src')
|
1486 |
);
|
1487 |
|
1488 |
-
var $_base = NULL;
|
1489 |
var $feeds = NULL;
|
1490 |
|
1491 |
-
# function FeedWordPress (): Contructor;
|
1492 |
-
#
|
1493 |
-
# To keep things compact and editable from within WordPress, we use a
|
1494 |
-
# category of the WordPress "Links" for our list of feeds to syndicate
|
1495 |
-
# By default, we use all the links in the "Contributors" category.
|
1496 |
-
# Fields used are:
|
1497 |
-
#
|
1498 |
-
# * link_rss: the URI of the Atom/RSS feed to syndicate
|
1499 |
-
#
|
1500 |
-
# * link_notes: user-configurable options, with keys and values
|
1501 |
-
# like so:
|
1502 |
-
#
|
1503 |
-
# key: value
|
1504 |
-
# cats: computers\nweb
|
1505 |
-
# feed/key: value
|
1506 |
-
#
|
1507 |
-
# Keys that start with "feed/" are gleaned from the data supplied
|
1508 |
-
# by the feed itself, and will be overwritten with each update.
|
1509 |
-
#
|
1510 |
-
# Values have linebreak characters escaped with C-style
|
1511 |
-
# backslashes (so, for example, a newline becomes "\n").
|
1512 |
-
#
|
1513 |
-
# The value of `cats` is used as a newline-separated list of
|
1514 |
-
# default categories for any post coming from a particular feed.
|
1515 |
-
# (In the example above, any posts from this feed will be placed
|
1516 |
-
# in the "computers" and "web" categories--*in addition to* any
|
1517 |
-
# categories that may already be applied to the posts.)
|
1518 |
-
#
|
1519 |
-
# Values of keys in link_notes are accessible from templates using
|
1520 |
-
# the function `get_feed_meta($key)` if this plugin is activated.
|
1521 |
-
|
1522 |
function FeedWordPress () {
|
1523 |
-
$
|
1524 |
-
|
1525 |
-
$
|
1526 |
-
|
1527 |
-
if (strlen($link->link_rss) > 0):
|
1528 |
-
$sec = FeedWordPress::notes_to_settings($link->link_notes);
|
1529 |
-
$sec['link/uri'] = $link->link_rss;
|
1530 |
-
$sec['link/name'] = $link->link_name;
|
1531 |
-
$sec['link/id'] = $link->link_id;
|
1532 |
-
|
1533 |
-
// `hardcode categories` is deprecated in favor
|
1534 |
-
// of `unfamiliar categories`
|
1535 |
-
if (
|
1536 |
-
FeedWordPress::affirmative($sec, 'hardcode categories')
|
1537 |
-
and !isset($sec['unfamiliar categories'])
|
1538 |
-
) :
|
1539 |
-
$sec['unfamiliar categories'] = 'default';
|
1540 |
-
endif;
|
1541 |
-
|
1542 |
-
if (isset($sec['cats'])):
|
1543 |
-
$sec['cats'] = preg_split(FEEDWORDPRESS_CAT_SEPARATOR_PATTERN, $sec['cats']);
|
1544 |
-
endif;
|
1545 |
-
|
1546 |
-
$feeds[] = $sec;
|
1547 |
-
endif;
|
1548 |
endforeach; endif;
|
1549 |
-
|
1550 |
-
$this->feeds = $feeds;
|
1551 |
} // FeedWordPress::FeedWordPress ()
|
1552 |
|
1553 |
-
# function notes_to_settings (): Convert WordPress Link Notes to array
|
1554 |
-
# of feed-level settings
|
1555 |
-
#
|
1556 |
-
# Arguments:
|
1557 |
-
# ----------
|
1558 |
-
# * $link_notes (string): the text from the Link Notes section of a link
|
1559 |
-
#
|
1560 |
-
# Returns:
|
1561 |
-
# --------
|
1562 |
-
# An associative array of settings stored in the Link Notes field. (For
|
1563 |
-
# the `unfamiliar authors` setting, for example, simply look up the
|
1564 |
-
# value of $meta['unfamiliar authors'], if $meta contains the value
|
1565 |
-
# returned by `notes_to_settings()`.
|
1566 |
-
#
|
1567 |
-
# Values in FeedWordPress feed settings are escaped using C-style
|
1568 |
-
# slashes. The escaped characters will already have been processed and
|
1569 |
-
# converted in the returned array.
|
1570 |
-
function notes_to_settings ($link_notes) {
|
1571 |
-
$notes = explode("\n", $link_notes);
|
1572 |
-
|
1573 |
-
$sec = array ();
|
1574 |
-
foreach ($notes as $note):
|
1575 |
-
list($key, $value) = explode(": ", $note, 2);
|
1576 |
-
|
1577 |
-
if (strlen($key) > 0) :
|
1578 |
-
// Unescape and trim() off the whitespace.
|
1579 |
-
// Thanks to Ray Lischner for pointing out the
|
1580 |
-
// need to trim off whitespace.
|
1581 |
-
$sec[$key] = stripcslashes (trim($value));
|
1582 |
-
endif;
|
1583 |
-
endforeach;
|
1584 |
-
return $sec;
|
1585 |
-
} // FeedWordPress::notes_to_settings ()
|
1586 |
-
|
1587 |
# function update (): polls for updates on one or more Contributor feeds
|
1588 |
#
|
1589 |
# Arguments:
|
1590 |
# ----------
|
1591 |
# * $uri (string): either the URI of the feed to poll, the URI of the
|
1592 |
-
#
|
1593 |
-
# "magic" tag: URI composed of the URI in the constant `RPC_MAGIC`
|
1594 |
-
# and a "secret word" set in the FeedWordPress Options.
|
1595 |
#
|
1596 |
-
# If
|
1597 |
-
#
|
1598 |
-
#
|
1599 |
-
#
|
1600 |
-
#
|
1601 |
-
#
|
1602 |
#
|
1603 |
# Returns:
|
1604 |
# --------
|
@@ -1608,9 +1467,7 @@ class FeedWordPress {
|
|
1608 |
# are zero, there was no change since the last poll on that URI.
|
1609 |
#
|
1610 |
# * Returns NULL if URI it was passed was not a URI that this
|
1611 |
-
# installation of FeedWordPress syndicates
|
1612 |
-
# of this error is attempts to poll all feeds, lacking, or using
|
1613 |
-
# an incorrect, "secret word."
|
1614 |
#
|
1615 |
# Effects:
|
1616 |
# --------
|
@@ -1637,39 +1494,30 @@ class FeedWordPress {
|
|
1637 |
# * Updates to existing posts since the last poll are mirrored in the
|
1638 |
# WordPress store.
|
1639 |
#
|
1640 |
-
function update ($uri) {
|
1641 |
global $wpdb;
|
1642 |
|
1643 |
-
$uri = trim($uri);
|
1644 |
-
|
1645 |
if (FeedWordPress::needs_upgrade()) : // Will make duplicate posts if we don't hold off
|
1646 |
return NULL;
|
1647 |
endif;
|
|
|
|
|
|
|
|
|
|
|
|
|
1648 |
|
1649 |
do_action('feedwordpress_update', $uri);
|
1650 |
|
1651 |
-
// Secret voodoo tag: URI for updating *everything*.
|
1652 |
-
$secret = RPC_MAGIC.FeedWordPress::rpc_secret();
|
1653 |
-
|
1654 |
-
fwp_hold_pings(); // Only send out one ping for the whole to-do
|
1655 |
-
|
1656 |
// Loop through and check for new posts
|
1657 |
-
$delta = NULL;
|
1658 |
foreach ($this->feeds as $feed) :
|
1659 |
-
$pinged_that = in_array($uri, array($
|
1660 |
|
1661 |
-
if ($uri
|
1662 |
-
$timely = true;
|
1663 |
-
elseif (isset($feed['update/hold']) and ($feed['update/hold']=='ping')) :
|
1664 |
-
$timely = false;
|
1665 |
-
elseif (isset($feed['update/hold']) and ($feed['update/hold']=='next')) :
|
1666 |
-
$timely = true;
|
1667 |
-
elseif (!isset($feed['update/ttl']) or !isset($feed['update/last'])) :
|
1668 |
$timely = true;
|
1669 |
else :
|
1670 |
-
$
|
1671 |
-
+((int) $feed['update/ttl'] * 60);
|
1672 |
-
$timely = (time() >= $after);
|
1673 |
endif;
|
1674 |
|
1675 |
if ($pinged_that and is_null($delta)) : // If at least one feed was hit for updating...
|
@@ -1677,375 +1525,352 @@ class FeedWordPress {
|
|
1677 |
endif;
|
1678 |
|
1679 |
if ($pinged_that and $timely) :
|
1680 |
-
do_action('feedwordpress_check_feed', $feed);
|
1681 |
-
$added = $
|
1682 |
if (isset($added['new'])) : $delta['new'] += $added['new']; endif;
|
1683 |
if (isset($added['updated'])) : $delta['updated'] += $added['updated']; endif;
|
1684 |
endif;
|
1685 |
endforeach;
|
1686 |
|
1687 |
do_action('feedwordpress_update_complete', $delta);
|
1688 |
-
fwp_release_pings(); // Now that we're done, send the one ping
|
1689 |
|
1690 |
return $delta;
|
1691 |
}
|
1692 |
|
1693 |
-
function
|
1694 |
-
|
1695 |
-
|
1696 |
-
|
1697 |
-
$this->update_feed($wpdb, $feed->channel, $f);
|
1698 |
-
|
1699 |
-
if (is_array($feed->items)) :
|
1700 |
-
foreach ($feed->items as $item) :
|
1701 |
-
$post = $this->item_to_post($wpdb, $item, $feed, $f);
|
1702 |
-
if (!is_null($post)) :
|
1703 |
-
$new = $this->add_post($wpdb, $post);
|
1704 |
-
if ( $new !== false ) $new_count[$new]++;
|
1705 |
-
endif;
|
1706 |
-
endforeach;
|
1707 |
-
endif;
|
1708 |
-
return $new_count;
|
1709 |
-
} // function feed2wp ()
|
1710 |
|
1711 |
-
|
1712 |
-
|
1713 |
-
|
1714 |
-
|
1715 |
-
|
1716 |
-
|
1717 |
-
|
1718 |
-
|
1719 |
-
|
1720 |
-
|
1721 |
-
$ret = array ();
|
1722 |
-
if (is_array($arr)) :
|
1723 |
-
foreach ($arr as $key => $value) :
|
1724 |
-
if (is_scalar($value)) :
|
1725 |
-
$ret[$prefix.$key] = $value;
|
1726 |
-
else :
|
1727 |
-
$ret = array_merge($ret, $this->flatten_array($value, $prefix.$key.$separator, $separator));
|
1728 |
endif;
|
1729 |
-
|
1730 |
-
|
1731 |
-
|
1732 |
-
|
1733 |
-
|
1734 |
-
|
1735 |
-
|
1736 |
-
|
1737 |
-
|
1738 |
-
function hardcode ($what, $f) {
|
1739 |
-
$default = get_settings("feedwordpress_hardcode_$what");
|
1740 |
-
if ( $default === 'yes' ) :
|
1741 |
-
// If the default is to hardcode, then we want the
|
1742 |
-
// negation of negative(): TRUE by default and FALSE if
|
1743 |
-
// the setting is explicitly "no"
|
1744 |
-
$ret = !FeedWordPress::negative($f, "hardcode $what");
|
1745 |
-
else :
|
1746 |
-
// If the default is NOT to hardcode, then we want
|
1747 |
-
// affirmative(): FALSE by default and TRUE if the
|
1748 |
-
// setting is explicitly "yes"
|
1749 |
-
$ret = FeedWordPress::affirmative($f, "hardcode $what");
|
1750 |
endif;
|
1751 |
return $ret;
|
1752 |
}
|
1753 |
|
1754 |
-
function
|
1755 |
global $wpdb;
|
1756 |
|
1757 |
-
|
1758 |
-
|
1759 |
-
|
1760 |
-
|
1761 |
-
|
1762 |
-
|
1763 |
-
|
1764 |
-
|
1765 |
-
|
1766 |
-
|
1767 |
-
|
1768 |
-
|
1769 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1770 |
|
1771 |
-
function
|
1772 |
-
$
|
1773 |
-
return (isset($f[$setting]) and in_array(strtolower($f[$setting]), $affirmo));
|
1774 |
-
}
|
1775 |
-
|
1776 |
-
function feed_ttl ($channel) {
|
1777 |
-
if (isset($channel['ttl'])) :
|
1778 |
-
// "ttl stands for time to live. It's a number of
|
1779 |
-
// minutes that indicates how long a channel can be
|
1780 |
-
// cached before refreshing from the source."
|
1781 |
-
// <http://blogs.law.harvard.edu/tech/rss#ltttlgtSubelementOfLtchannelgt>
|
1782 |
-
$ret = $channel['ttl'];
|
1783 |
-
elseif (isset($channel['sy']['updatefrequency']) or isset($channel['sy']['updateperiod'])) :
|
1784 |
-
$period_minutes = array (
|
1785 |
-
'hourly' => 60, /* minutes in an hour */
|
1786 |
-
'daily' => 1440, /* minutes in a day */
|
1787 |
-
'weekly' => 10080, /* minutes in a week */
|
1788 |
-
'monthly' => 43200, /* minutes in a month */
|
1789 |
-
'yearly' => 525600, /* minutes in a year */
|
1790 |
-
);
|
1791 |
|
1792 |
-
|
1793 |
-
|
1794 |
-
|
1795 |
-
|
1796 |
-
|
1797 |
-
else : $period = 'daily';
|
1798 |
-
endif;
|
1799 |
-
|
1800 |
-
// "sy:updateFrequency: Used to describe the frequency
|
1801 |
-
// of updates in relation to the update period. A
|
1802 |
-
// positive integer indicates how many times in that
|
1803 |
-
// period the channel is updated. ... If omitted a value
|
1804 |
-
// of 1 is assumed." <http://web.resource.org/rss/1.0/modules/syndication/>
|
1805 |
-
if (isset($channel['sy']['updatefrequency'])) : $freq = (int) $channel['sy']['updatefrequency'];
|
1806 |
-
else : $freq = 1;
|
1807 |
endif;
|
1808 |
-
|
1809 |
-
$ret = (int) ($period_minutes[$period] / $freq);
|
1810 |
-
else :
|
1811 |
-
$ret = NULL;
|
1812 |
endif;
|
1813 |
-
return $ret;
|
1814 |
-
}
|
1815 |
|
1816 |
-
|
1817 |
-
|
1818 |
|
1819 |
-
|
1820 |
-
|
|
|
|
|
|
|
|
|
1821 |
endif;
|
|
|
|
|
1822 |
|
1823 |
-
|
1824 |
-
|
1825 |
-
$update[] = "link_url = '".$wpdb->escape($channel['link'])."'";
|
1826 |
-
endif;
|
1827 |
|
1828 |
-
|
1829 |
-
|
1830 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1831 |
|
1832 |
-
|
1833 |
-
|
1834 |
-
|
1835 |
-
|
1836 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1837 |
endif;
|
1838 |
-
endif;
|
1839 |
|
1840 |
-
|
1841 |
-
$f['cats'] = implode(FEEDWORDPRESS_CAT_SEPARATOR, $f['cats']);
|
1842 |
endif;
|
|
|
|
|
1843 |
|
1844 |
-
|
1845 |
-
|
1846 |
-
$
|
1847 |
-
$
|
1848 |
-
|
1849 |
-
|
1850 |
-
|
1851 |
-
|
1852 |
-
$
|
1853 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1854 |
endif;
|
|
|
|
|
1855 |
|
1856 |
-
|
1857 |
-
|
1858 |
-
endif;
|
1859 |
|
1860 |
-
|
1861 |
-
unset($f['link/id']); unset($f['link/uri']);
|
1862 |
-
unset($f['link/name']);
|
1863 |
-
unset($f['hardcode categories']); // Deprecated
|
1864 |
|
1865 |
-
$
|
1866 |
-
|
1867 |
-
|
1868 |
-
endforeach;
|
1869 |
-
$update[] = "link_notes = '".$wpdb->escape($notes)."'";
|
1870 |
|
1871 |
-
|
1872 |
-
|
1873 |
-
|
1874 |
-
|
1875 |
-
|
1876 |
-
|
1877 |
-
|
1878 |
-
|
1879 |
-
|
1880 |
-
|
1881 |
-
|
1882 |
-
|
1883 |
-
|
1884 |
-
|
1885 |
-
|
1886 |
-
|
1887 |
-
|
1888 |
-
|
1889 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1890 |
}
|
1891 |
|
1892 |
-
function
|
1893 |
-
|
1894 |
-
|
1895 |
-
|
1896 |
-
$guid = $item['atom']['id'];
|
1897 |
-
elseif (isset($item['guid'])) : // RSS 2.0
|
1898 |
-
$guid = $item['guid'];
|
1899 |
-
elseif (isset($item['dc']['identifier'])) : // yeah, right
|
1900 |
-
$guid = $item['dc']['identifier'];
|
1901 |
-
else :
|
1902 |
-
// The feed does not seem to have provided us with a
|
1903 |
-
// unique identifier, so we'll have to cobble together
|
1904 |
-
// a tag: URI that might work for us. The base of the
|
1905 |
-
// URI will be the host name of the feed source ...
|
1906 |
-
$bits = parse_url($feed['link/uri']);
|
1907 |
-
$guid = 'tag:'.$bits['host'];
|
1908 |
|
1909 |
-
|
1910 |
-
|
1911 |
-
|
1912 |
-
|
1913 |
-
|
1914 |
-
|
1915 |
-
|
1916 |
-
|
1917 |
-
|
1918 |
-
|
1919 |
-
|
1920 |
-
|
1921 |
-
|
1922 |
-
|
1923 |
-
// this is about the best we can do.
|
1924 |
-
else :
|
1925 |
-
$guid .= '://'.md5($item['link'].'/'.$item['title']);
|
1926 |
-
endif;
|
1927 |
-
endif;
|
1928 |
-
return $guid;
|
1929 |
}
|
|
|
1930 |
|
1931 |
-
|
1932 |
-
|
1933 |
-
|
1934 |
-
|
1935 |
-
|
1936 |
-
|
1937 |
-
|
1938 |
-
|
1939 |
-
|
1940 |
-
|
1941 |
-
|
1942 |
-
|
1943 |
-
|
1944 |
-
|
1945 |
-
|
1946 |
-
|
1947 |
-
|
1948 |
-
|
1949 |
-
|
1950 |
-
|
1951 |
-
|
1952 |
-
|
1953 |
-
|
1954 |
-
|
1955 |
-
|
1956 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
1957 |
global $fwp_channel, $fwp_feedmeta;
|
1958 |
-
$fwp_channel = $
|
1959 |
-
|
1960 |
-
$
|
1961 |
-
|
1962 |
-
|
1963 |
-
|
1964 |
-
|
|
|
|
|
|
|
|
|
1965 |
else :
|
1966 |
-
|
|
|
|
|
|
|
1967 |
|
1968 |
-
$post['
|
1969 |
-
|
1970 |
-
if (isset($item['author_name'])):
|
1971 |
-
$post['named']['author']['name'] = $item['author_name'];
|
1972 |
-
elseif (isset($item['dc']['creator'])):
|
1973 |
-
$post['named']['author']['name'] = $item['dc']['creator'];
|
1974 |
-
elseif (isset($item['dc']['contributor'])):
|
1975 |
-
$post['named']['author']['name'] = $item['dc']['contributor'];
|
1976 |
-
elseif (isset($channel['dc']['creator'])) :
|
1977 |
-
$post['named']['author']['name'] = $channel['dc']['creator'];
|
1978 |
-
elseif (isset($channel['dc']['contributor'])) :
|
1979 |
-
$post['named']['author']['name'] = $channel['dc']['contributor'];
|
1980 |
-
elseif (isset($channel['author_name'])) :
|
1981 |
-
$post['named']['author']['name'] = $channel['author_name'];
|
1982 |
-
elseif ($rss->is_rss() and isset($item['author'])) :
|
1983 |
-
// The author element in RSS is allegedly an
|
1984 |
-
// e-mail address, but lots of people don't use
|
1985 |
-
// it that way. So let's make of it what we can.
|
1986 |
-
$post['named']['author'] = parse_email_with_realname($item['author']);
|
1987 |
-
|
1988 |
-
if (!isset($post['named']['author']['name'])) :
|
1989 |
-
if (isset($post['named']['author']['email'])) :
|
1990 |
-
$post['named']['author']['name'] = $post['named']['author']['email'];
|
1991 |
-
else :
|
1992 |
-
$post['named']['author']['name'] = $channel['title'];
|
1993 |
-
endif;
|
1994 |
-
endif;
|
1995 |
-
else :
|
1996 |
-
$post['named']['author']['name'] = $channel['title'];
|
1997 |
-
endif;
|
1998 |
-
|
1999 |
-
if (isset($item['author_email'])):
|
2000 |
-
$post['named']['author']['email'] = $item['author_email'];
|
2001 |
-
elseif (isset($channel['author_email'])) :
|
2002 |
-
$post['named']['author']['email'] = $channel['author_email'];
|
2003 |
-
endif;
|
2004 |
-
|
2005 |
-
if (isset($item['author_url'])):
|
2006 |
-
$post['named']['author']['uri'] = $item['author_url'];
|
2007 |
-
elseif (isset($channel['author_url'])) :
|
2008 |
-
$post['named']['author']['uri'] = $item['author_url'];
|
2009 |
-
else:
|
2010 |
-
$post['named']['author']['uri'] = $channel['link'];
|
2011 |
-
endif;
|
2012 |
|
2013 |
-
//
|
2014 |
-
//
|
2015 |
-
//
|
2016 |
-
|
2017 |
|
2018 |
# Identify content and sanitize it.
|
2019 |
# ---------------------------------
|
2020 |
-
if (isset($item['xhtml']['body'])) :
|
2021 |
-
$content = $item['xhtml']['body'];
|
2022 |
-
elseif (isset($item['xhtml']['div'])) :
|
2023 |
-
$content = $item['xhtml']['div'];
|
2024 |
-
elseif (isset($item['content']['encoded']) and $item['content']['encoded']):
|
2025 |
-
$content = $item['content']['encoded'];
|
2026 |
else:
|
2027 |
-
$content = $item['description'];
|
2028 |
endif;
|
2029 |
|
2030 |
-
#
|
|
|
|
|
|
|
2031 |
#
|
2032 |
-
#
|
2033 |
-
#
|
2034 |
-
# in the feed, and if it's in the content itself we'd have
|
2035 |
-
# to do yet more XML parsing to do things right. For now
|
2036 |
-
# this will have to do.
|
2037 |
-
|
2038 |
-
$this->_base = $item['link']; // Reset the base for resolving relative URIs
|
2039 |
-
foreach ($this->uri_attrs as $pair):
|
2040 |
-
list($tag,$attr) = $pair;
|
2041 |
-
$content = preg_replace_callback (
|
2042 |
-
":(<$tag [^>]*$attr=\")([^\">]*)(\"[^>]*>):i",
|
2043 |
-
array(&$this,'resolve_relative_uri'),
|
2044 |
-
$content
|
2045 |
-
);
|
2046 |
-
endforeach;
|
2047 |
-
|
2048 |
-
# Sanitize problematic attributes
|
2049 |
foreach ($this->strip_attrs as $pair):
|
2050 |
list($tag,$attr) = $pair;
|
2051 |
$content = preg_replace (
|
@@ -2057,8 +1882,8 @@ class FeedWordPress {
|
|
2057 |
|
2058 |
# Identify and sanitize excerpt
|
2059 |
$excerpt = NULL;
|
2060 |
-
if ( isset($item['description']) and $item['description'] ) :
|
2061 |
-
$excerpt = $item['description'];
|
2062 |
elseif ( isset($content) and $content ) :
|
2063 |
$excerpt = strip_tags($content);
|
2064 |
if (strlen($excerpt) > 255) :
|
@@ -2066,193 +1891,211 @@ class FeedWordPress {
|
|
2066 |
endif;
|
2067 |
endif;
|
2068 |
|
2069 |
-
$post['post_content'] = $
|
2070 |
|
2071 |
if (!is_null($excerpt)):
|
2072 |
-
$post['post_excerpt'] = $
|
2073 |
endif;
|
2074 |
|
2075 |
-
|
2076 |
-
|
2077 |
-
|
2078 |
-
# --- cut here ---
|
2079 |
-
|
2080 |
-
# RSS is a fucking mess. Figure out whether we have a date in
|
2081 |
-
# dc:date, <issued>, <pubDate>, etc., and get it into Unix epoch
|
2082 |
-
# format for reformatting. If you can't find anything, use the
|
2083 |
-
# current time.
|
2084 |
-
if (isset($item['dc']['date'])):
|
2085 |
-
$post['epoch']['issued'] = parse_w3cdtf($item['dc']['date']);
|
2086 |
-
elseif (isset($item['dcterms']['issued'])) :
|
2087 |
-
$post['epoch']['issued'] = parse_w3cdtf($item['dcterms']['issued']);
|
2088 |
-
elseif (isset($item['published'])) : // Atom 1.0
|
2089 |
-
$post['epoch']['issued'] = parse_w3cdtf($item['published']);
|
2090 |
-
elseif (isset($item['issued'])): // Atom 0.3
|
2091 |
-
$post['epoch']['issued'] = parse_w3cdtf($item['issued']);
|
2092 |
-
elseif (isset($item['pubdate'])): // RSS 2.0
|
2093 |
-
$post['epoch']['issued'] = strtotime($item['pubdate']);
|
2094 |
-
else:
|
2095 |
-
$post['epoch']['issued'] = null;
|
2096 |
endif;
|
2097 |
|
2098 |
-
|
2099 |
-
$post['epoch']['created'] =
|
2100 |
-
|
2101 |
-
# As far as I know, only atom currently has a reliable way to
|
2102 |
-
# specify when something was *modified* last
|
2103 |
-
if (isset($item['dc']['modified'])) : // Not really correct
|
2104 |
-
$post['epoch']['modified'] = @parse_w3cdtf($item['dc']['modified']);
|
2105 |
-
elseif (isset($item['dcterms']['modified'])) : // Dublin Core extensions
|
2106 |
-
$post['epoch']['modified'] = @parse_w3cdtf($item['dcterms']['modified']);
|
2107 |
-
elseif (isset($item['modified'])): // Atom 0.3
|
2108 |
-
$post['epoch']['modified'] = @parse_w3cdtf($item['modified']);
|
2109 |
-
elseif (isset($item['updated'])): // Atom 1.0
|
2110 |
-
$post['epoch']['modified'] = @parse_w3cdtf($item['updated']);
|
2111 |
-
elseif (isset($post['epoch']['issued'])) : // Fall back to issued / dc:date
|
2112 |
-
$post['epoch']['modified'] = $post['epoch']['issued'];
|
2113 |
-
else :
|
2114 |
-
$post['epoch']['modified'] = time();
|
2115 |
-
endif;
|
2116 |
|
2117 |
-
|
2118 |
-
$
|
2119 |
-
$post['
|
2120 |
-
$post['
|
|
|
|
|
2121 |
|
2122 |
-
|
2123 |
-
$post['post_status'] =
|
2124 |
-
$post['comment_status'] =
|
2125 |
-
$post['ping_status'] =
|
2126 |
|
2127 |
// Unique ID (hopefully a unique tag: URI); failing that, the permalink
|
2128 |
-
$post['guid'] = $
|
2129 |
|
2130 |
// RSS 2.0 / Atom 1.0 enclosure support
|
2131 |
-
if ( isset($item['enclosure#']) ) :
|
2132 |
-
for ($i = 1; $i <= $item['enclosure#']; $i++) :
|
2133 |
$eid = (($i > 1) ? "#{$id}" : "");
|
2134 |
-
$post['meta']['enclosure'][] =
|
2135 |
-
$item["enclosure{$eid}@url"]."\n".
|
2136 |
-
$item["enclosure{$eid}@length"]."\n".
|
2137 |
-
$item["enclosure{$eid}@type"];
|
2138 |
endfor;
|
2139 |
endif;
|
2140 |
|
2141 |
// In case you want to point back to the blog this was syndicated from
|
2142 |
-
if (isset($channel['title']))
|
2143 |
-
|
|
|
|
|
|
|
|
|
2144 |
|
2145 |
// Store information on human-readable and machine-readable comment URIs
|
2146 |
-
if (isset($item['comments'])) :
|
2147 |
-
|
|
|
|
|
|
|
|
|
2148 |
|
2149 |
// Store information to identify the feed that this came from
|
2150 |
-
$post['meta']['syndication_feed'] = $
|
2151 |
-
$post['meta']['syndication_feed_id'] = $
|
2152 |
|
2153 |
// In case you want to know the external permalink...
|
2154 |
-
$post['meta']['syndication_permalink'] = $item['link'];
|
2155 |
|
2156 |
// Feed-by-feed options for author and category creation
|
2157 |
-
$post['named']['unfamiliar']['author'] = $
|
2158 |
-
$post['named']['unfamiliar']['category'] = $
|
2159 |
|
2160 |
-
// Categories: start with default categories
|
2161 |
-
$fc =
|
2162 |
-
if ($fc) :
|
2163 |
-
|
|
|
|
|
2164 |
endif;
|
2165 |
-
|
2166 |
-
|
|
|
2167 |
endif;
|
2168 |
|
2169 |
// Now add categories from the post, if we have 'em
|
2170 |
-
$post['named']['category'] = array();
|
2171 |
-
if ( isset($item['category#']) ) :
|
2172 |
-
for ($i = 1; $i <= $item['category#']; $i++) :
|
2173 |
$cat_idx = (($i > 1) ? "#{$i}" : "");
|
2174 |
-
$cat = $item["category{$cat_idx}"];
|
2175 |
|
2176 |
-
if (
|
2177 |
-
$
|
2178 |
-
|
2179 |
-
|
|
|
2180 |
endif;
|
2181 |
endfor;
|
2182 |
endif;
|
2183 |
endif;
|
2184 |
-
|
2185 |
-
|
2186 |
-
|
2187 |
-
|
2188 |
-
|
2189 |
-
|
2190 |
-
|
2191 |
-
|
2192 |
-
|
2193 |
-
|
2194 |
-
|
2195 |
-
$freshness = 2; // New content
|
2196 |
-
elseif ($post['epoch']['modified'] > $result->modified) :
|
2197 |
-
$freshness = 1; // Updated content
|
2198 |
-
else :
|
2199 |
-
$freshness = 0;
|
2200 |
endif;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2201 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2202 |
if ($freshness > 0) :
|
2203 |
# -- Look up, or create, numeric ID for author
|
2204 |
-
$post['post_author'] = $this->
|
2205 |
-
$
|
2206 |
-
$post['named']['author']['name'],
|
2207 |
-
$post['named']['author']['email'],
|
2208 |
-
$post['named']['author']['uri'],
|
2209 |
-
FeedWordPress::on_unfamiliar('author', $post['named']['unfamiliar']['author'])
|
2210 |
);
|
2211 |
|
2212 |
-
if (is_null($post['post_author'])) :
|
2213 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2214 |
else :
|
2215 |
-
|
2216 |
-
$post['post_category'] =
|
2217 |
-
$
|
2218 |
-
$
|
2219 |
-
|
|
|
|
|
2220 |
);
|
2221 |
-
|
2222 |
-
if (
|
2223 |
-
$
|
2224 |
-
else : // filter mode off or at least one match; now add on the feed and global presets
|
2225 |
-
$post['post_category'] = array_merge (
|
2226 |
-
$post['post_category'],
|
2227 |
-
$this->lookup_categories (
|
2228 |
-
$wpdb,
|
2229 |
-
$post['named']['preset/category'],
|
2230 |
-
'default'
|
2231 |
-
)
|
2232 |
-
);
|
2233 |
endif;
|
2234 |
endif;
|
2235 |
-
|
2236 |
-
unset($post['named']);
|
2237 |
endif;
|
2238 |
|
2239 |
-
if ($freshness > 0) :
|
2240 |
-
$post
|
2241 |
-
|
2242 |
endif;
|
2243 |
|
2244 |
-
if ($freshness == 2) :
|
2245 |
// The item has not yet been added. So let's add it.
|
2246 |
-
$
|
2247 |
-
$this->add_rss_meta(
|
2248 |
-
do_action('post_syndicated_item', $
|
2249 |
|
2250 |
$ret = 'new';
|
2251 |
-
elseif ($freshness == 1) :
|
2252 |
-
$post['ID'] = $
|
2253 |
-
$this->
|
2254 |
-
$this->add_rss_meta(
|
2255 |
-
do_action('update_syndicated_item', $
|
2256 |
|
2257 |
$ret = 'updated';
|
2258 |
else :
|
@@ -2260,108 +2103,155 @@ class FeedWordPress {
|
|
2260 |
endif;
|
2261 |
|
2262 |
return $ret;
|
2263 |
-
} // function
|
2264 |
-
|
2265 |
-
function
|
2266 |
-
global $wpdb;
|
2267 |
|
2268 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2269 |
|
2270 |
-
|
2271 |
-
|
2272 |
-
|
2273 |
-
|
2274 |
-
|
2275 |
-
|
2276 |
-
|
2277 |
-
|
2278 |
-
|
2279 |
-
|
2280 |
-
|
2281 |
-
|
2282 |
-
|
2283 |
-
|
2284 |
-
|
2285 |
-
|
2286 |
-
|
2287 |
-
|
2288 |
-
|
2289 |
-
|
2290 |
-
|
2291 |
-
|
2292 |
-
|
2293 |
-
|
2294 |
-
|
2295 |
-
|
2296 |
-
.
|
2297 |
-
|
2298 |
-
|
2299 |
-
|
2300 |
-
|
2301 |
-
|
2302 |
-
|
2303 |
-
|
2304 |
-
|
2305 |
-
|
2306 |
-
|
2307 |
-
|
2308 |
-
|
2309 |
-
|
2310 |
-
|
2311 |
-
|
2312 |
-
|
2313 |
-
|
2314 |
-
|
2315 |
-
|
2316 |
-
|
2317 |
-
|
2318 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2319 |
|
2320 |
-
function
|
2321 |
global $wpdb;
|
2322 |
-
|
2323 |
-
$guid = $post['guid'];
|
2324 |
-
$postId = $post['ID'];
|
2325 |
-
|
2326 |
-
$result = $wpdb->query("
|
2327 |
-
UPDATE $wpdb->posts
|
2328 |
-
SET
|
2329 |
-
post_author = '".$post['post_author']."',
|
2330 |
-
post_content = '".$post['post_content']."',
|
2331 |
-
post_title = '".$post['post_title']."',
|
2332 |
-
post_name = '".$post['post_name']."',
|
2333 |
-
post_modified = '".$post['post_modified']."',
|
2334 |
-
post_modified_gmt = '".$post['post_modified_gmt']."'
|
2335 |
-
WHERE guid='$guid'
|
2336 |
-
");
|
2337 |
-
$this->add_to_category($wpdb, $postId, $post['post_category']);
|
2338 |
-
|
2339 |
-
// Since we are not going through official channels, we need to
|
2340 |
-
// manually tell WordPress that we've published a new post.
|
2341 |
-
// We need to make sure to do this in order for FeedWordPress
|
2342 |
-
// to play well with the staticize-reloaded plugin (something
|
2343 |
-
// that a large aggregator website is going to *want* to be
|
2344 |
-
// able to use).
|
2345 |
-
do_action('edit_post', $postId);
|
2346 |
-
} /* FeedWordPress::update_existing_post() */
|
2347 |
-
|
2348 |
-
# function FeedWordPress::add_to_category ()
|
2349 |
-
#
|
2350 |
-
# If there is a way to properly hook in to wp_insert_post, then this
|
2351 |
-
# function will no longer be needed. In the meantime, here it is.
|
2352 |
-
# --- cut here ---
|
2353 |
-
function add_to_category($wpdb, $postId, $post_categories) {
|
2354 |
-
global $wp_db_version; // test for WordPress 2.0 database schema
|
2355 |
|
2356 |
-
//
|
2357 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2358 |
|
2359 |
-
|
2360 |
-
|
2361 |
-
|
2362 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
2363 |
|
2364 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2365 |
// using the space for custom keys. The set of keys and values to add is
|
2366 |
// specified by the keys and values of $post['meta']. This is used to
|
2367 |
// store anything that the WordPress user might want to access from a
|
@@ -2370,9 +2260,21 @@ class FeedWordPress {
|
|
2370 |
// syndicated post other than author, title, timestamp, categories, and
|
2371 |
// guid). It's also used to hook into WordPress's support for
|
2372 |
// enclosures.
|
2373 |
-
function add_rss_meta (
|
2374 |
-
|
2375 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2376 |
|
2377 |
$key = $wpdb->escape($key);
|
2378 |
|
@@ -2397,12 +2299,17 @@ class FeedWordPress {
|
|
2397 |
endforeach;
|
2398 |
endforeach;
|
2399 |
endif;
|
2400 |
-
} /*
|
2401 |
|
2402 |
-
//
|
2403 |
// the feed. Create the author if necessary.
|
2404 |
-
function
|
2405 |
-
global $wp_db_version; // test for WordPress 2.0 database schema
|
|
|
|
|
|
|
|
|
|
|
2406 |
|
2407 |
// Never can be too careful...
|
2408 |
$nice_author = sanitize_title($author);
|
@@ -2429,7 +2336,7 @@ class FeedWordPress {
|
|
2429 |
(
|
2430 |
LOWER(user_description)
|
2431 |
RLIKE CONCAT(
|
2432 |
-
'(^|\\n)a
|
2433 |
LCASE('$reg_author'),
|
2434 |
'( |\\t|\\r)*(\\n|\$)'
|
2435 |
)
|
@@ -2459,7 +2366,7 @@ class FeedWordPress {
|
|
2459 |
meta_key = 'description'
|
2460 |
AND LCASE(meta_value)
|
2461 |
RLIKE CONCAT(
|
2462 |
-
'(^|\\n)a
|
2463 |
LCASE('$reg_author'),
|
2464 |
'( |\\t|\\r)*(\\n|\$)'
|
2465 |
)
|
@@ -2492,7 +2399,7 @@ class FeedWordPress {
|
|
2492 |
#-- user table data
|
2493 |
$userdata['ID'] = NULL; // new user
|
2494 |
$userdata['user_login'] = $author;
|
2495 |
-
$userdata['user_pass'] =
|
2496 |
$userdata['user_email'] = $email;
|
2497 |
$userdata['user_url'] = $url;
|
2498 |
$userdata['display_name'] = $author;
|
@@ -2504,326 +2411,571 @@ class FeedWordPress {
|
|
2504 |
endif;
|
2505 |
endif;
|
2506 |
return $id;
|
2507 |
-
} // function
|
2508 |
|
2509 |
// look up (and create) category ids from a list of categories
|
2510 |
-
function
|
2511 |
-
|
2512 |
-
|
2513 |
-
//
|
|
|
|
|
2514 |
// <http://dev.mysql.com/doc/mysql/en/char.html>), and (2)
|
2515 |
// because I doubt most people want to make a semantic
|
2516 |
// distinction between 'Computers' and 'Computers '
|
2517 |
$cats = array_map('trim', $cats);
|
2518 |
|
2519 |
$cat_ids = array ();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2520 |
|
2521 |
-
if (
|
2522 |
-
|
2523 |
-
|
2524 |
-
|
2525 |
-
|
2526 |
-
|
2527 |
-
|
2528 |
-
|
2529 |
-
|
2530 |
-
|
2531 |
-
|
2532 |
-
|
2533 |
-
|
2534 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2535 |
|
2536 |
-
|
2537 |
-
|
2538 |
|
2539 |
-
|
2540 |
-
|
2541 |
-
|
2542 |
-
|
2543 |
-
|
2544 |
-
|
2545 |
-
|
2546 |
-
|
2547 |
-
|
2548 |
-
$
|
2549 |
-
|
2550 |
-
|
2551 |
-
|
2552 |
-
|
2553 |
-
|
2554 |
-
|
2555 |
-
|
2556 |
-
|
2557 |
-
// Add name to list of categories not to
|
2558 |
-
// create afresh. Normalizing case with
|
2559 |
-
// strtolower() avoids mismatches in
|
2560 |
-
// VARCHAR comparison between PHP (which
|
2561 |
-
// has case-sensitive comparisons) and
|
2562 |
-
// MySQL (which has case-insensitive
|
2563 |
-
// comparisons for the field types used
|
2564 |
-
// by WordPress)
|
2565 |
-
$found[] = strtolower(trim($row->cat_name));
|
2566 |
-
|
2567 |
-
// Add name of any aliases to list of
|
2568 |
-
// categories not to create afresh.
|
2569 |
-
if (preg_match_all('/^a.k.a. \s* :? \s* (.*\S) \s*$/mx',
|
2570 |
-
$row->category_description, $aka,
|
2571 |
-
PREG_PATTERN_ORDER)) :
|
2572 |
-
$found = array_merge (
|
2573 |
-
$found,
|
2574 |
-
array_map('strtolower',
|
2575 |
-
array_map('trim',
|
2576 |
-
$aka[1]
|
2577 |
-
))
|
2578 |
-
);
|
2579 |
-
endif;
|
2580 |
-
endforeach;
|
2581 |
-
endif;
|
2582 |
|
2583 |
-
|
2584 |
-
|
2585 |
-
|
2586 |
-
|
2587 |
-
|
2588 |
-
|
2589 |
-
|
2590 |
-
category_nicename='%s'
|
2591 |
-
", $wpdb->escape($new_cat), $nice_cat));
|
2592 |
-
$cat_ids[] = $wpdb->insert_id;
|
2593 |
-
endif;
|
2594 |
-
endforeach;
|
2595 |
|
2596 |
-
|
2597 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2598 |
endif;
|
2599 |
endif;
|
2600 |
-
return $
|
2601 |
-
}
|
2602 |
|
2603 |
-
function
|
2604 |
-
|
2605 |
-
|
2606 |
-
|
2607 |
-
|
2608 |
-
|
2609 |
-
|
2610 |
-
|
2611 |
-
|
2612 |
-
|
2613 |
-
|
2614 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2615 |
endif;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2616 |
endif;
|
2617 |
|
2618 |
-
return $
|
2619 |
-
} //
|
2620 |
-
|
2621 |
-
function syndicated_links () {
|
2622 |
-
$contributors = FeedWordPress::link_category_id();
|
2623 |
-
if (function_exists('get_bookmarks')) {
|
2624 |
-
$links = get_bookmarks(array("category" => $contributors));
|
2625 |
-
} else {
|
2626 |
-
$links = get_linkobjects($contributors); // deprecated as of WP 2.1
|
2627 |
-
} // if
|
2628 |
-
return $links;
|
2629 |
-
} // function syndicated_links()
|
2630 |
-
|
2631 |
-
function syndicate_link ($name, $uri, $rss) {
|
2632 |
-
global $wpdb;
|
2633 |
-
|
2634 |
-
// Get the category ID#
|
2635 |
-
$cat_id = FeedWordPress::link_category_id();
|
2636 |
|
2637 |
-
|
2638 |
-
|
2639 |
-
|
2640 |
-
|
2641 |
-
|
2642 |
-
|
2643 |
-
|
2644 |
-
|
2645 |
-
|
2646 |
-
|
2647 |
-
|
2648 |
-
|
2649 |
-
|
2650 |
-
|
2651 |
-
|
2652 |
-
|
2653 |
-
|
2654 |
-
|
2655 |
-
|
2656 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2657 |
|
2658 |
-
|
2659 |
-
|
2660 |
-
|
2661 |
-
|
2662 |
-
|
2663 |
-
$ct = $wpdb->linkcategories;
|
2664 |
-
} else {
|
2665 |
-
// WordPress 2.1 has a unified category table for both
|
2666 |
-
$ct = $wpdb->categories;
|
2667 |
-
}
|
2668 |
-
return $wpdb->get_var("SELECT cat_id FROM $ct WHERE cat_name='$name'");
|
2669 |
-
}
|
2670 |
|
2671 |
-
function
|
2672 |
-
global $
|
2673 |
|
2674 |
-
if (
|
2675 |
-
$
|
2676 |
-
|
2677 |
-
|
2678 |
-
|
2679 |
-
|
2680 |
-
|
2681 |
-
|
2682 |
-
|
2683 |
-
|
2684 |
-
|
2685 |
-
|
2686 |
-
|
2687 |
-
|
2688 |
-
// Why the fuck is this API function only available in a wp-admin module?
|
2689 |
-
$cat_id = wp_insert_category(array('cat_name' => $name));
|
2690 |
-
}
|
2691 |
-
}
|
2692 |
|
2693 |
-
|
2694 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2695 |
|
2696 |
-
|
2697 |
-
|
2698 |
-
|
2699 |
-
|
2700 |
-
$cat = $wpdb->escape(DEFAULT_SYNDICATION_CATEGORY);
|
2701 |
|
2702 |
-
//
|
2703 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2704 |
|
2705 |
-
|
2706 |
-
|
2707 |
-
|
2708 |
-
|
|
|
|
|
|
|
|
|
|
|
2709 |
|
2710 |
-
|
2711 |
-
|
2712 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2713 |
}
|
2714 |
|
2715 |
-
function
|
2716 |
-
global $wpdb
|
2717 |
|
2718 |
-
$
|
|
|
2719 |
|
2720 |
-
|
2721 |
-
|
2722 |
-
// WordPress 1.5 and 2.0.x
|
2723 |
-
$cat_name = $wpdb->get_var("
|
2724 |
-
SELECT cat_name FROM $wpdb->linkcategories
|
2725 |
-
WHERE cat_id='$cat_id'
|
2726 |
-
");
|
2727 |
-
} else {
|
2728 |
-
// WordPress 2.1
|
2729 |
-
$category = get_category($cat_id);
|
2730 |
-
$cat_name = $category->cat_name;
|
2731 |
-
}
|
2732 |
-
return $cat_name;
|
2733 |
-
}
|
2734 |
|
2735 |
-
|
2736 |
-
|
2737 |
-
|
2738 |
-
|
2739 |
-
|
2740 |
-
|
2741 |
-
|
2742 |
-
|
2743 |
-
|
2744 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2745 |
else :
|
2746 |
-
|
2747 |
-
$
|
2748 |
-
|
2749 |
-
|
2750 |
-
|
2751 |
-
|
2752 |
-
|
2753 |
-
|
2754 |
-
|
2755 |
-
|
2756 |
-
|
2757 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2758 |
endif;
|
2759 |
-
|
2760 |
endif;
|
2761 |
endif;
|
2762 |
-
return $
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2763 |
}
|
2764 |
|
|
|
|
|
|
|
|
|
|
|
|
|
2765 |
|
2766 |
-
|
2767 |
-
|
2768 |
-
|
2769 |
-
|
2770 |
-
|
2771 |
-
|
2772 |
-
|
2773 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
2774 |
|
2775 |
-
|
2776 |
-
|
2777 |
-
//
|
2778 |
-
|
2779 |
-
|
2780 |
-
|
2781 |
-
|
2782 |
-
CREATE TEMPORARY TABLE tmp_custom_values
|
2783 |
-
SELECT
|
2784 |
-
NULL AS meta_id,
|
2785 |
-
post_id,
|
2786 |
-
'syndication_feed_id' AS meta_key,
|
2787 |
-
link_id AS meta_value
|
2788 |
-
FROM `{$wpdb->postmeta}`, `{$wpdb->links}`
|
2789 |
-
WHERE
|
2790 |
-
meta_key='syndication_feed'
|
2791 |
-
AND meta_value=link_rss
|
2792 |
-
AND link_category = {$cat_id}
|
2793 |
-
");
|
2794 |
-
|
2795 |
-
// Now attach them to their posts
|
2796 |
-
$wpdb->query("INSERT INTO `{$wpdb->postmeta}` SELECT * FROM tmp_custom_values");
|
2797 |
|
2798 |
-
//
|
2799 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
2800 |
|
2801 |
-
|
2802 |
-
|
2803 |
-
|
2804 |
-
|
2805 |
-
|
2806 |
-
|
2807 |
-
|
2808 |
-
|
2809 |
-
|
2810 |
-
|
2811 |
-
|
2812 |
-
|
2813 |
-
|
2814 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2815 |
endif;
|
2816 |
-
echo "<strong>complete.</strong></li>\n";
|
2817 |
endforeach;
|
2818 |
-
|
|
|
|
|
2819 |
|
2820 |
-
|
2821 |
-
|
2822 |
-
|
2823 |
-
|
2824 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2825 |
|
2826 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2827 |
|
2828 |
################################################################################
|
2829 |
## XML-RPC HOOKS: accept XML-RPC update pings from Contributors ################
|
@@ -2885,7 +3037,6 @@ class FeedFinder {
|
|
2885 |
$ret = array($this->uri);
|
2886 |
} else {
|
2887 |
// Assume that we have HTML or XHTML (even if we don't, who's it gonna hurt?)
|
2888 |
-
|
2889 |
// Autodiscovery is the preferred method
|
2890 |
$href = $this->_link_rel_feeds();
|
2891 |
|
@@ -2918,6 +3069,7 @@ class FeedFinder {
|
|
2918 |
|
2919 |
function is_feed ($uri = NULL) {
|
2920 |
$data = $this->data($uri);
|
|
|
2921 |
return (
|
2922 |
preg_match (
|
2923 |
"\007(".implode('|',$this->_feed_markers).")\007i",
|
@@ -2966,7 +3118,7 @@ class FeedFinder {
|
|
2966 |
} /* if */
|
2967 |
} /* if */
|
2968 |
} /* for */
|
2969 |
-
return $href;
|
2970 |
}
|
2971 |
|
2972 |
function _a_href_feeds ($obvious = TRUE) {
|
@@ -2991,7 +3143,6 @@ class FeedFinder {
|
|
2991 |
// search through the HTML, save all <link> tags
|
2992 |
// and store each link's attributes in an associative array
|
2993 |
preg_match_all('/<'.$tag.'\s+(.*?)\s*\/?>/si', $html, $matches);
|
2994 |
-
|
2995 |
$links = $matches[1];
|
2996 |
$ret = array();
|
2997 |
$link_count = count($links);
|
@@ -3017,179 +3168,184 @@ class FeedFinder {
|
|
3017 |
# for FeedWordPress's purposes. The class has been stripped down to a single
|
3018 |
# public method: Relative_URI::resolve($url, $base), which resolves the URI in
|
3019 |
# $url relative to the URI in $base
|
|
|
|
|
|
|
|
|
3020 |
|
3021 |
-
class Relative_URI
|
3022 |
-
{
|
3023 |
-
// Resolve relative URI in $url against the base URI in $base. If $base
|
3024 |
-
// is not supplied, then we use the REQUEST_URI of this script.
|
3025 |
-
//
|
3026 |
-
// I'm hoping this method reflects RFC 2396 Section 5.2
|
3027 |
-
function resolve ($url, $base = NULL)
|
3028 |
{
|
3029 |
-
|
3030 |
-
|
3031 |
-
|
3032 |
-
|
3033 |
-
$base =
|
3034 |
-
|
3035 |
-
|
3036 |
-
|
3037 |
-
|
3038 |
-
|
3039 |
-
|
3040 |
-
|
3041 |
-
|
3042 |
-
|
3043 |
-
|
3044 |
-
|
3045 |
-
|
3046 |
-
|
3047 |
-
|
3048 |
-
|
3049 |
-
//
|
3050 |
-
return $url;
|
3051 |
-
} elseif (isset($parts['host'])) {
|
3052 |
-
$uri_parts['host'] = $parts['host'];
|
3053 |
-
$uri_parts['path'] = $parts['path'];
|
3054 |
-
} else {
|
3055 |
-
// We have a relative path but not a host.
|
3056 |
-
|
3057 |
-
// start ugly fix:
|
3058 |
-
// prepend slash to path if base host is set, base path is not set, and url path is not absolute
|
3059 |
-
if ($uri_parts['host'] && ($uri_parts['path'] == '')
|
3060 |
-
&& (strlen($parts['path']) > 0)
|
3061 |
-
&& (substr($parts['path'], 0, 1) != '/')) {
|
3062 |
-
$parts['path'] = '/'.$parts['path'];
|
3063 |
-
} // end ugly fix
|
3064 |
|
3065 |
-
if (
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3066 |
$uri_parts['path'] = $parts['path'];
|
3067 |
} else {
|
3068 |
-
//
|
3069 |
-
|
3070 |
-
//
|
3071 |
-
|
3072 |
-
|
3073 |
-
|
3074 |
-
|
3075 |
-
|
3076 |
-
}
|
3077 |
-
|
3078 |
-
if (substr($
|
3079 |
-
|
3080 |
-
}
|
3081 |
-
|
3082 |
-
|
3083 |
-
|
3084 |
-
|
3085 |
-
|
3086 |
-
|
3087 |
-
|
3088 |
-
|
3089 |
-
|
3090 |
-
|
3091 |
-
|
3092 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3093 |
}
|
3094 |
-
|
3095 |
-
|
|
|
3096 |
}
|
3097 |
-
$buffer = (count($segment) == 1) ? '/' : implode('/', $segment);
|
3098 |
-
$uri_parts['path'] = $buffer;
|
3099 |
-
|
3100 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3101 |
}
|
3102 |
-
|
3103 |
-
|
3104 |
-
|
3105 |
-
|
3106 |
-
|
3107 |
-
|
3108 |
-
|
3109 |
-
|
3110 |
-
|
3111 |
-
|
3112 |
-
|
3113 |
-
|
3114 |
-
|
|
|
3115 |
}
|
3116 |
-
|
3117 |
-
|
3118 |
-
|
3119 |
-
|
3120 |
-
|
3121 |
-
|
3122 |
-
|
3123 |
-
/**
|
3124 |
-
* Parse URL
|
3125 |
-
*
|
3126 |
-
* Regular expression grabbed from RFC 2396 Appendix B.
|
3127 |
-
* This is a replacement for PHPs builtin parse_url().
|
3128 |
-
* @param string $url
|
3129 |
-
* @access private
|
3130 |
-
* @return array
|
3131 |
-
*/
|
3132 |
-
function _parse_url($url)
|
3133 |
-
{
|
3134 |
-
// I'm using this pattern instead of parse_url() as there's a few strings where parse_url()
|
3135 |
-
// generates a warning.
|
3136 |
-
if (preg_match('!^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?!', $url, $match)) {
|
3137 |
-
$parts = array();
|
3138 |
-
if ($match[1] != '') $parts['scheme'] = $match[2];
|
3139 |
-
if ($match[3] != '') $parts['auth'] = $match[4];
|
3140 |
-
// parse auth
|
3141 |
-
if (isset($parts['auth'])) {
|
3142 |
-
// store user info
|
3143 |
-
if (($at_pos = strpos($parts['auth'], '@')) !== false) {
|
3144 |
-
$userinfo = explode(':', substr($parts['auth'], 0, $at_pos), 2);
|
3145 |
-
$parts['user'] = $userinfo[0];
|
3146 |
-
if (isset($userinfo[1])) $parts['pass'] = $userinfo[1];
|
3147 |
-
$parts['auth'] = substr($parts['auth'], $at_pos+1);
|
3148 |
-
}
|
3149 |
-
// get port number
|
3150 |
-
if ($port_pos = strrpos($parts['auth'], ':')) {
|
3151 |
-
$parts['host'] = substr($parts['auth'], 0, $port_pos);
|
3152 |
-
$parts['port'] = (int)substr($parts['auth'], $port_pos+1);
|
3153 |
-
if ($parts['port'] < 1) $parts['port'] = null;
|
3154 |
-
} else {
|
3155 |
-
$parts['host'] = $parts['auth'];
|
3156 |
-
}
|
3157 |
-
}
|
3158 |
-
unset($parts['auth']);
|
3159 |
-
$parts['path'] = $match[5];
|
3160 |
-
if (isset($match[6]) && ($match[6] != '')) $parts['query'] = $match[7];
|
3161 |
-
if (isset($match[8]) && ($match[8] != '')) $parts['fragment'] = $match[9];
|
3162 |
-
return $parts;
|
3163 |
-
}
|
3164 |
-
// shouldn't reach here
|
3165 |
-
return array('path'=>'');
|
3166 |
-
}
|
3167 |
-
|
3168 |
-
function _encode($string)
|
3169 |
-
{
|
3170 |
-
static $replace = array();
|
3171 |
-
if (!count($replace)) {
|
3172 |
-
$find = array(32, 34, 60, 62, 123, 124, 125, 91, 92, 93, 94, 96, 127);
|
3173 |
-
$find = array_merge(range(0, 31), $find);
|
3174 |
-
$find = array_map('chr', $find);
|
3175 |
-
foreach ($find as $char) {
|
3176 |
-
$replace[$char] = '%'.bin2hex($char);
|
3177 |
-
}
|
3178 |
-
}
|
3179 |
-
// escape control characters and a few other characters
|
3180 |
-
$encoded = strtr($string, $replace);
|
3181 |
-
// remove any character outside the hex range: 21 - 7E (see www.asciitable.com)
|
3182 |
-
return preg_replace('/[^\x21-\x7e]/', '', $encoded);
|
3183 |
-
}
|
3184 |
}
|
3185 |
|
3186 |
// take your best guess at the realname and e-mail, given a string
|
3187 |
define('FWP_REGEX_EMAIL_ADDY', '([^@"(<\s]+@[^"@(<\s]+\.[^"@(<\s]+)');
|
3188 |
define('FWP_REGEX_EMAIL_NAME', '("([^"]*)"|([^"<(]+\S))');
|
3189 |
-
define('FWP_REGEX_EMAIL_POSTFIX_NAME',
|
3190 |
-
define('FWP_REGEX_EMAIL_PREFIX_NAME',
|
3191 |
-
define('FWP_REGEX_EMAIL_JUST_ADDY',
|
3192 |
-
define('FWP_REGEX_EMAIL_JUST_NAME',
|
3193 |
|
3194 |
function parse_email_with_realname ($email) {
|
3195 |
if (preg_match(FWP_REGEX_EMAIL_POSTFIX_NAME, $email, $matches)) :
|
@@ -3208,5 +3364,4 @@ function parse_email_with_realname ($email) {
|
|
3208 |
endif;
|
3209 |
return $ret;
|
3210 |
}
|
3211 |
-
|
3212 |
?>
|
3 |
Plugin Name: FeedWordPress
|
4 |
Plugin URI: http://projects.radgeek.com/feedwordpress
|
5 |
Description: simple and flexible Atom/RSS syndication for WordPress
|
6 |
+
Version: 0.99
|
7 |
Author: Charles Johnson
|
8 |
Author URI: http://radgeek.com/
|
9 |
License: GPL
|
10 |
+
Last modified: 2007-09-16 11:13 PDT
|
11 |
*/
|
12 |
|
13 |
# This uses code derived from:
|
26 |
# <http://www.zyx.com/blog/xmlrpc.php>), or see `update-feeds.php`
|
27 |
|
28 |
# -- Don't change these unless you know what you're doing...
|
29 |
+
|
30 |
+
define ('FEEDWORDPRESS_VERSION', '0.99');
|
31 |
+
define ('FEEDWORDPRESS_AUTHOR_CONTACT', 'http://radgeek.com/contact');
|
32 |
define ('DEFAULT_SYNDICATION_CATEGORY', 'Contributors');
|
33 |
|
34 |
+
define ('FEEDWORDPRESS_DEBUG', false);
|
35 |
+
|
36 |
define ('FEEDWORDPRESS_CAT_SEPARATOR_PATTERN', '/[:\n]/');
|
37 |
define ('FEEDWORDPRESS_CAT_SEPARATOR', "\n");
|
38 |
|
39 |
define ('FEEDVALIDATOR_URI', 'http://feedvalidator.org/check.cgi');
|
40 |
|
41 |
+
define ('FEEDWORDPRESS_FRESHNESS_INTERVAL', 10*60); // Every ten minutes
|
42 |
+
|
43 |
+
define ('FWP_SCHEMA_20', 3308); // Database schema # for WP 2.0
|
44 |
+
define ('FWP_SCHEMA_21', 4772); // Database schema # for WP 2.1
|
45 |
+
define ('FWP_SCHEMA_23', 5495); // Database schema # for WP 2.3
|
46 |
+
|
47 |
+
if (FEEDWORDPRESS_DEBUG) :
|
48 |
+
// Help us to pick out errors, if any.
|
49 |
+
ini_set('error_reporting', E_ALL & ~E_NOTICE);
|
50 |
+
ini_set('display_errors', true);
|
51 |
+
define('MAGPIE_DEBUG', true);
|
52 |
+
|
53 |
+
// When testing we don't want cache issues to interfere. But this is
|
54 |
+
// a VERY BAD SETTING for a production server. Webmasters will eat your
|
55 |
+
// face for breakfast if you use it, and the baby Jesus will cry. So
|
56 |
+
// make sure FEEDWORDPRESS_DEBUG is FALSE for any site that will be
|
57 |
+
// used for more than testing purposes!
|
58 |
+
define('MAGPIE_CACHE_AGE', 1);
|
59 |
+
endif;
|
60 |
+
|
61 |
// Note that the rss-functions.php that comes prepackaged with WordPress is
|
62 |
// old & busted. For the new hotness, drop a copy of rss.php from
|
63 |
// this archive into wp-includes/rss.php
|
68 |
require_once (ABSPATH . WPINC . '/rss-functions.php');
|
69 |
endif;
|
70 |
|
71 |
+
if (isset($wp_db_version)) :
|
72 |
+
if ($wp_db_version >= FWP_SCHEMA_23) :
|
73 |
+
require_once (ABSPATH . WPINC . '/registration.php'); // for wp_insert_user
|
74 |
+
elseif ($wp_db_version >= FWP_SCHEMA_21) : // WordPress 2.1 and 2.2, but not 2.3
|
75 |
+
require_once (ABSPATH . WPINC . '/registration.php'); // for wp_insert_user
|
76 |
+
require_once (ABSPATH . 'wp-admin/admin-db.php'); // for wp_insert_category
|
77 |
+
elseif ($wp_db_version >= 3308) : // WordPress 2.0
|
78 |
+
require_once (ABSPATH . WPINC . '/registration-functions.php'); // for wp_insert_user
|
79 |
+
require_once (ABSPATH . 'wp-admin/admin-db.php'); // for wp_insert_category
|
80 |
+
endif;
|
81 |
+
endif;
|
82 |
+
|
83 |
+
if (function_exists('wp_enqueue_script')) :
|
84 |
+
wp_enqueue_script( 'ajaxcat' );
|
85 |
+
endif;
|
86 |
+
|
87 |
+
// Magic quotes are just about the stupidest thing ever.
|
88 |
+
if (is_array($_POST)) :
|
89 |
+
$fwp_post = stripslashes_deep($_POST);
|
90 |
endif;
|
91 |
|
92 |
// Is this being loaded from within WordPress 1.5 or later?
|
120 |
add_filter('xmlrpc_methods', 'feedwordpress_xmlrpc_hook');
|
121 |
|
122 |
# Outbound XML-RPC ping reform
|
123 |
+
remove_action('publish_post', 'generic_ping'); // WP 1.5.x
|
124 |
+
remove_action('do_pings', 'do_all_pings', 10, 1); // WP 2.1, 2.2
|
125 |
+
remove_action('publish_post', '_publish_post_hook', 5, 1); // WP 2.3
|
126 |
+
|
127 |
+
add_action('publish_post', 'fwp_publish_post_hook', 5, 1);
|
128 |
+
add_action('do_pings', 'fwp_do_pings', 10, 1);
|
129 |
+
add_action('feedwordpress_update', 'fwp_hold_pings');
|
130 |
+
add_action('feedwordpress_update_complete', 'fwp_release_pings');
|
131 |
+
|
132 |
# Hook in logging functions only if the logging option is ON
|
133 |
+
$update_logging = get_option('feedwordpress_update_logging');
|
134 |
if ($update_logging == 'yes') :
|
135 |
add_action('post_syndicated_item', 'log_feedwordpress_post', 100);
|
136 |
add_action('update_syndicated_item', 'log_feedwordpress_update_post', 100);
|
138 |
add_action('feedwordpress_check_feed', 'log_feedwordpress_check_feed', 100);
|
139 |
add_action('feedwordpress_update_complete', 'log_feedwordpress_update_complete', 100);
|
140 |
endif;
|
141 |
+
|
142 |
+
# Cron-less auto-update. Hooray!
|
143 |
+
add_action('init', 'feedwordpress_auto_update');
|
144 |
else :
|
145 |
# Hook in the menus, which will just point to the upgrade interface
|
146 |
add_action('admin_menu', 'fwp_add_pages');
|
147 |
endif; // if (!FeedWordPress::needs_upgrade())
|
148 |
endif;
|
149 |
|
150 |
+
function feedwordpress_auto_update () {
|
151 |
+
if (FeedWordPress::stale()) :
|
152 |
+
$feedwordpress =& new FeedWordPress;
|
153 |
+
$feedwordpress->update();
|
154 |
+
endif;
|
155 |
+
} /* feedwordpress_auto_update () */
|
156 |
+
|
157 |
################################################################################
|
158 |
## LOGGING FUNCTIONS: log status updates to error_log if you want it ###########
|
159 |
################################################################################
|
195 |
## LEGACY API: Replicate or mock up functions for legacy support purposes ######
|
196 |
################################################################################
|
197 |
|
198 |
+
if (!function_exists('get_option')) {
|
199 |
+
function get_option ($option) {
|
200 |
+
return get_settings($option);
|
201 |
+
}
|
202 |
+
}
|
203 |
if (!function_exists('current_user_can')) {
|
204 |
$legacy_capability_hack = true;
|
205 |
function current_user_can ($task) {
|
251 |
$ret = NULL;
|
252 |
if (strlen($feed_id) > 0):
|
253 |
if (isset($feedwordpress_linkcache[$feed_id])) :
|
254 |
+
$link = $feedwordpress_linkcache[$feed_id];
|
255 |
else :
|
256 |
+
$link =& new SyndicatedLink($feed_id);
|
257 |
+
$feedwordpress_linkcache[$feed_id] = $link;
|
|
|
|
|
|
|
258 |
endif;
|
259 |
|
260 |
+
$ret = $link->settings[$key];
|
261 |
+
endif;
|
|
|
262 |
return $ret;
|
263 |
+
} /* get_feed_meta() */
|
264 |
|
265 |
function get_syndication_permalink () {
|
266 |
list($u) = get_post_custom_values('syndication_permalink'); return $u;
|
297 |
}
|
298 |
|
299 |
function syndication_permalink ($permalink = '') {
|
300 |
+
if (get_option('feedwordpress_munge_permalink') != 'no'):
|
301 |
$uri = get_syndication_permalink();
|
302 |
return ((strlen($uri) > 0) ? $uri : $permalink);
|
303 |
else:
|
310 |
################################################################################
|
311 |
|
312 |
function fwp_upgrade_page () {
|
313 |
+
if (isset($GLOBALS['fwp_post']['action']) and $GLOBALS['fwp_post']['action']=='Upgrade') :
|
314 |
+
$ver = get_option('feedwordpress_version');
|
315 |
+
if (get_option('feedwordpress_version') != FEEDWORDPRESS_VERSION) :
|
316 |
echo "<div class=\"wrap\">\n";
|
317 |
echo "<h2>Upgrading FeedWordPress...</h2>";
|
318 |
|
371 |
$manage_options = 'manage_options';
|
372 |
endif;
|
373 |
|
374 |
+
//add_submenu_page('plugins.php', 'Akismet Configuration', 'Akismet Configuration', 'manage_options', 'syndication-manage-page', 'fwp_syndication_manage_page');
|
375 |
+
add_menu_page('Syndicated Sites', 'Syndication', $manage_links, 'feedwordpress/'.basename(__FILE__), 'fwp_syndication_manage_page');
|
376 |
+
add_submenu_page('feedwordpress/'.basename(__FILE__), 'Syndication Options', 'Options', $manage_options, 'feedwordpress/syndication-options.php');
|
377 |
+
add_options_page('Syndication Options', 'Syndication', $manage_options, 'feedwordpress/syndication-options.php');
|
378 |
} // function fwp_add_pages () */
|
379 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
380 |
function fwp_category_box ($checked, $object) {
|
381 |
global $wp_db_version;
|
382 |
|
408 |
endif;
|
409 |
}
|
410 |
|
411 |
+
function update_feeds_mention ($feed) {
|
412 |
+
echo "<li>Updating <cite>".$feed['link/name']."</cite> from <<a href=\""
|
413 |
+
.$feed['link/uri']."\">".$feed['link/uri']."</a>> ...</li>\n";
|
414 |
+
flush();
|
415 |
+
}
|
416 |
+
|
417 |
function fwp_syndication_manage_page () {
|
418 |
global $wpdb;
|
419 |
|
428 |
if ($_REQUEST['action'] == 'feedfinder') : $cont = fwp_feedfinder_page();
|
429 |
elseif ($_REQUEST['action'] == 'switchfeed') : $cont = fwp_switchfeed_page();
|
430 |
elseif ($_REQUEST['action'] == 'linkedit') : $cont = fwp_linkedit_page();
|
431 |
+
elseif ($_REQUEST['action'] == 'Unsubscribe from Checked Links' or $_REQUEST['action'] == 'Unsubscribe') : $cont = fwp_multidelete_page();
|
432 |
endif;
|
433 |
endif;
|
434 |
|
436 |
?>
|
437 |
<?php
|
438 |
$links = FeedWordPress::syndicated_links();
|
439 |
+
|
440 |
+
if (isset($_POST['update']) or isset($_POST['action']) or isset($_POST['update_uri'])) :
|
441 |
+
$fwp_update_invoke = 'post';
|
442 |
+
else :
|
443 |
+
$fwp_update_invoke = 'get';
|
444 |
+
endif;
|
445 |
+
|
446 |
+
$update_set = array();
|
447 |
+
if (isset($_POST['link_ids']) and is_array($_POST['link_ids']) and ($_POST['action']=='Update Checked Links')) :
|
448 |
+
$targets = $wpdb->get_results("
|
449 |
+
SELECT * FROM $wpdb->links
|
450 |
+
WHERE link_id IN (".implode(",",$_POST['link_ids']).")
|
451 |
+
");
|
452 |
+
if (is_array($targets)) :
|
453 |
+
foreach ($targets as $target) :
|
454 |
+
$update_set[] = $target->link_rss;
|
455 |
+
endforeach;
|
456 |
+
else : // This should never happen
|
457 |
+
FeedWordPress::critical_bug('fwp_syndication_manage_page::targets', $targets, __LINE__);
|
458 |
+
endif;
|
459 |
+
elseif (isset($_POST['update_uri'])) :
|
460 |
+
$update_set[] = $_POST['update_uri'];
|
461 |
+
endif;
|
462 |
+
|
463 |
+
if ($fwp_update_invoke != 'get' and count($update_set) > 0) : // Only do things with side-effects for HTTP POST or command line
|
464 |
+
$feedwordpress =& new FeedWordPress;
|
465 |
+
add_action('feedwordpress_check_feed', 'update_feeds_mention');
|
466 |
+
|
467 |
+
echo "<div class=\"updated\">\n";
|
468 |
+
echo "<ul>\n";
|
469 |
+
foreach ($update_set as $uri) :
|
470 |
+
if ($uri == '*') : $uri = NULL; endif;
|
471 |
+
$delta = $feedwordpress->update($uri);
|
472 |
+
endforeach;
|
473 |
+
echo "</ul>\n";
|
474 |
+
|
475 |
+
if (is_null($delta)) :
|
476 |
+
echo "<p><strong>Error:</strong> I don't syndicate <a href=\"$uri\">$uri</a></p>\n";
|
477 |
+
else :
|
478 |
+
$mesg = array();
|
479 |
+
if (isset($delta['new'])) : $mesg[] = ' '.$delta['new'].' new posts were syndicated'; endif;
|
480 |
+
if (isset($delta['updated'])) : $mesg[] = ' '.$delta['updated'].' existing posts were updated'; endif;
|
481 |
+
echo "<p>Update complete.".implode(' and', $mesg)."</p>";
|
482 |
+
echo "\n"; flush();
|
483 |
+
endif;
|
484 |
+
echo "</div> <!-- class=\"updated\" -->\n";
|
485 |
+
endif;
|
486 |
+
|
487 |
+
?>
|
488 |
<div class="wrap">
|
489 |
+
<form action="" method="POST">
|
490 |
+
<h2>Update feeds now</h2>
|
491 |
+
<p>Check currently scheduled feeds for new and updated posts.</p>
|
492 |
+
|
493 |
+
<?php if (!get_option('feedwordpress_automatic_updates')) : ?>
|
494 |
+
<p><strong>Note:</strong> Automatic updates are currently turned
|
495 |
+
<strong>off</strong>. New posts from your feeds will not be syndicated
|
496 |
+
until you manually check for them here. You can turn on automatic
|
497 |
+
updates under <a href="admin.php?page=feedwordpress/syndication-options.php">Syndication
|
498 |
+
Options</a>.</p>
|
499 |
+
<?php endif; ?>
|
500 |
+
|
501 |
+
|
502 |
+
<div class="submit"><input type="hidden" name="update_uri" value="*" /><input type="submit" name="update" value="Update" /></div>
|
503 |
</form>
|
504 |
+
</div> <!-- class="wrap" -->
|
505 |
|
506 |
+
<form action="admin.php?page=feedwordpress/<?php echo basename(__FILE__); ?>" method="post">
|
507 |
<div class="wrap">
|
508 |
<h2>Syndicated Sites</h2>
|
509 |
<?php $alt_row = true;
|
519 |
<?php foreach ($links as $link):
|
520 |
$alt_row = !$alt_row; ?>
|
521 |
<tr<?php echo ($alt_row?' class="alternate"':''); ?>>
|
522 |
+
<td><a href="<?php echo wp_specialchars($link->link_url, 'both'); ?>"><?php echo wp_specialchars($link->link_name, 'both'); ?></a></td>
|
523 |
<?php
|
524 |
if (strlen($link->link_rss) > 0):
|
525 |
$caption='Switch Feed';
|
534 |
if (strlen($display_uri) > 32) : $display_uri = substr($display_uri, 0, 32).'…'; endif;
|
535 |
?>
|
536 |
<td>
|
537 |
+
<strong><a href="<?php echo $link->link_rss; ?>"><?php echo wp_specialchars($display_uri, 'both'); ?></a></strong></td>
|
538 |
<?php
|
539 |
else:
|
540 |
$caption='Find Feed';
|
544 |
<?php
|
545 |
endif;
|
546 |
?>
|
547 |
+
<td><a href="admin.php?page=feedwordpress/<?php echo basename(__FILE__); ?>&link_id=<?php echo $link->link_id; ?>&action=linkedit" class="edit"><?php _e('Edit')?></a></td>
|
548 |
+
<td><a href="admin.php?page=feedwordpress/<?php echo basename(__FILE__); ?>&link_id=<?php echo $link->link_id; ?>&action=feedfinder" class="edit"><?php echo $caption; ?></a></td>
|
549 |
+
<td><a href="admin.php?page=feedwordpress/<?php echo basename(__FILE__); ?>&link_id=<?php echo $link->link_id; ?>&action=Unsubscribe" class="delete"><?php _e('Unsubscribe'); ?></a></td>
|
550 |
<td><input type="checkbox" name="link_ids[]" value="<?php echo $link->link_id; ?>" /></td>
|
551 |
<?php
|
552 |
echo "\n\t</tr>";
|
558 |
|
559 |
<?php endif; ?>
|
560 |
</table>
|
561 |
+
|
562 |
+
<br/><hr/>
|
563 |
+
<div class="submit"><input type="submit" class="delete" name="action" value="Unsubscribe from Checked Links" />
|
564 |
+
<input type="submit" name="action" value="Update Checked Links" /></div>
|
565 |
+
</div> <!-- class="wrap" -->
|
566 |
+
</form>
|
567 |
+
|
568 |
<div class="wrap">
|
569 |
+
<form action="admin.php?page=feedwordpress/<?php echo basename(__FILE__); ?>" method="post">
|
570 |
+
<h2>Add a new syndicated site:</h2>
|
571 |
+
<div>
|
572 |
+
<label for="add-uri">Website or newsfeed:</label>
|
573 |
+
<input type="text" name="lookup" id="add-uri" value="URI" size="64" />
|
574 |
+
<input type="hidden" name="action" value="feedfinder" />
|
575 |
</div>
|
576 |
+
<div class="submit"><input type="submit" value="Syndicate »" /></div>
|
577 |
</form>
|
578 |
+
</div> <!-- class="wrap" -->
|
579 |
<?php
|
580 |
endif;
|
581 |
}
|
587 |
|
588 |
if (isset($_REQUEST['link_id']) and ($_REQUEST['link_id']!=0)):
|
589 |
$link_id = $_REQUEST['link_id'];
|
590 |
+
if (!is_numeric($link_id)) : FeedWordPress::critical_bug('fwp_feedfinder_page::link_id', $link_id, __LINE__); endif;
|
591 |
+
|
592 |
$link = $wpdb->get_row("SELECT * FROM $wpdb->links WHERE link_id='".$wpdb->escape($link_id)."'");
|
593 |
if (is_object($link)):
|
594 |
if (is_null($lookup)) $lookup = $link->link_url;
|
595 |
+
$name = wp_specialchars($link->link_name, 'both');
|
596 |
else:
|
597 |
die (__("Cheatin' uh ?"));
|
598 |
endif;
|
613 |
$feed_title = isset($rss->channel['title'])?$rss->channel['title']:$rss->channel['link'];
|
614 |
$feed_link = isset($rss->channel['link'])?$rss->channel['link']:'';
|
615 |
?>
|
616 |
+
<form action="admin.php?page=feedwordpress/<?php echo basename(__FILE__); ?>" method="post">
|
617 |
<fieldset style="clear: both">
|
618 |
<legend><?php echo $rss->feed_type; ?> <?php echo $rss->feed_version; ?> feed</legend>
|
619 |
|
620 |
<?php if ($link_id===0): ?>
|
621 |
+
<input type="hidden" name="feed_title" value="<?php echo wp_specialchars($feed_title, 'both'); ?>" />
|
622 |
+
<input type="hidden" name="feed_link" value="<?php echo wp_specialchars($feed_link, 'both'); ?>" />
|
623 |
<?php endif; ?>
|
624 |
|
625 |
<input type="hidden" name="link_id" value="<?php echo $link_id; ?>" />
|
626 |
+
<input type="hidden" name="feed" value="<?php echo wp_specialchars($f, 'both'); ?>" />
|
627 |
<input type="hidden" name="action" value="switchfeed" />
|
628 |
|
629 |
<div>
|
648 |
<h3>Feed Information</h3>
|
649 |
<ul>
|
650 |
<li><strong>Website:</strong> <a href="<?php echo $feed_link; ?>"><?php echo is_null($feed_title)?'<em>Unknown</em>':$feed_title; ?></a></li>
|
651 |
+
<li><strong>Feed URI:</strong> <a href="<?php echo wp_specialchars($f, 'both'); ?>"><?php echo wp_specialchars($f, 'both'); ?></a> <a title="Check feed <<?php echo wp_specialchars($f, 'both'); ?>> for validity" href="http://feedvalidator.org/check.cgi?url=<?php echo urlencode($f); ?>"><img src="../wp-images/smilies/icon_arrow.gif" alt="(→)" /></a></li>
|
652 |
+
<li><strong>Encoding:</strong> <?php echo isset($rss->encoding)?wp_specialchars($rss->encoding, 'both'):"<em>Unknown</em>"; ?></li>
|
653 |
+
<li><strong>Description:</strong> <?php echo isset($rss->channel['description'])?wp_specialchars($rss->channel['description'], 'both'):"<em>Unknown</em>"; ?></li>
|
654 |
</ul>
|
655 |
<div class="submit"><input type="submit" name="Use" value="« Use this feed" /></div>
|
656 |
<div class="submit"><input type="submit" name="Cancel" value="« Cancel" /></div>
|
666 |
?>
|
667 |
</div>
|
668 |
|
669 |
+
<form action="admin.php?page=feedwordpress/<?php echo basename(__FILE__); ?>" method="post">
|
670 |
<div class="wrap">
|
671 |
<h2>Use another feed</h2>
|
672 |
<div><label>Feed:</label>
|
690 |
elseif (isset($_REQUEST['link_id']) and ($_REQUEST['link_id']==0)):
|
691 |
$link_id = FeedWordPress::syndicate_link($_REQUEST['feed_title'], $_REQUEST['feed_link'], $_REQUEST['feed']);
|
692 |
if ($link_id): ?>
|
693 |
+
<div class="updated"><p><a href="<?php echo $_REQUEST['feed_link']; ?>"><?php echo wp_specialchars($_REQUEST['feed_title'], 'both'); ?></a>
|
694 |
+
has been added as a contributing site, using the newsfeed at <<a href="<?php echo $_REQUEST['feed']; ?>"><?php echo wp_specialchars($_REQUEST['feed'], 'both'); ?></a>>.</p></div>
|
695 |
<?php else: ?>
|
696 |
+
<div class="updated"><p>There was a problem adding the newsfeed. [SQL: <?php echo wp_specialchars(mysql_error(), 'both'); ?>]</p></div>
|
697 |
<?php endif;
|
698 |
elseif (isset($_REQUEST['link_id'])):
|
699 |
// Update link_rss
|
710 |
WHERE link_id = '".$wpdb->escape($_REQUEST['link_id'])."'
|
711 |
");
|
712 |
?>
|
713 |
+
<div class="updated"><p>Feed for <a href="<?php echo $result->link_url; ?>"><?php echo wp_specialchars($result->link_name, 'both'); ?></a>
|
714 |
+
updated to <<a href="<?php echo $_REQUEST['feed']; ?>"><?php echo wp_specialchars($_REQUEST['feed'], 'both'); ?></a>>.</p></div>
|
715 |
<?php else: ?>
|
716 |
<div class="updated"><p>Nothing was changed.</p></div>
|
717 |
<?php endif;
|
727 |
|
728 |
$special_settings = array ( /* Regular expression syntax is OK here */
|
729 |
'cats',
|
730 |
+
'cat_split',
|
731 |
'hardcode name',
|
732 |
'hardcode url',
|
733 |
'hardcode description',
|
748 |
return fwp_feedfinder_page(); // re-route to Feed Finder page
|
749 |
else :
|
750 |
$link_id = (int) $_REQUEST['link_id'];
|
751 |
+
$link =& new SyndicatedLink($link_id);
|
|
|
|
|
752 |
|
753 |
+
if ($link->found()) :
|
754 |
+
if (isset($GLOBALS['fwp_post']['save'])) :
|
755 |
$alter = array ();
|
756 |
|
757 |
+
$meta = $link->settings;
|
758 |
if (isset($meta['cats'])):
|
759 |
$meta['cats'] = preg_split(FEEDWORDPRESS_CAT_SEPARATOR_PATTERN, $meta['cats']);
|
760 |
endif;
|
761 |
|
762 |
// custom feed settings first
|
763 |
+
foreach ($GLOBALS['fwp_post']['notes'] as $mn) :
|
764 |
$mn['key0'] = trim($mn['key0']);
|
765 |
$mn['key1'] = trim($mn['key1']);
|
766 |
if (preg_match("\007^(("
|
781 |
|
782 |
// now stuff through the web form
|
783 |
// hardcoded feed info
|
784 |
+
if (isset($GLOBALS['fwp_post']['hardcode_name'])) :
|
785 |
+
$meta['hardcode name'] = $GLOBALS['fwp_post']['hardcode_name'];
|
786 |
if (FeedWordPress::affirmative($meta, 'hardcode name')) :
|
787 |
+
$alter[] = "link_name = '".$wpdb->escape($GLOBALS['fwp_post']['name'])."'";
|
788 |
endif;
|
789 |
endif;
|
790 |
+
if (isset($GLOBALS['fwp_post']['hardcode_description'])) :
|
791 |
+
$meta['hardcode description'] = $GLOBALS['fwp_post']['hardcode_description'];
|
792 |
if (FeedWordPress::affirmative($meta, 'hardcode description')) :
|
793 |
+
$alter[] = "link_description = '".$wpdb->escape($GLOBALS['fwp_post']['description'])."'";
|
794 |
endif;
|
795 |
endif;
|
796 |
+
if (isset($GLOBALS['fwp_post']['hardcode_url'])) :
|
797 |
+
$meta['hardcode url'] = $GLOBALS['fwp_post']['hardcode_url'];
|
798 |
if (FeedWordPress::affirmative($meta, 'hardcode url')) :
|
799 |
+
$alter[] = "link_url = '".$wpdb->escape($GLOBALS['fwp_post']['linkurl'])."'";
|
800 |
endif;
|
801 |
endif;
|
802 |
|
803 |
// Update scheduling
|
804 |
+
if (isset($GLOBALS['fwp_post']['update_schedule'])) :
|
805 |
+
$meta['update/hold'] = $GLOBALS['fwp_post']['update_schedule'];
|
806 |
endif;
|
807 |
|
808 |
// Categories
|
809 |
+
if (isset($GLOBALS['fwp_post']['post_category'])) :
|
810 |
+
$meta['cats'] = array();
|
811 |
+
foreach ($GLOBALS['fwp_post']['post_category'] as $cat_id) :
|
812 |
+
$meta['cats'][] = '{#'.$cat_id.'}';
|
813 |
+
endforeach;
|
|
|
|
|
|
|
|
|
|
|
814 |
else :
|
815 |
unset($meta['cats']);
|
816 |
endif;
|
818 |
// Post status, comment status, ping status
|
819 |
foreach (array('post', 'comment', 'ping') as $what) :
|
820 |
$sfield = "feed_{$what}_status";
|
821 |
+
if (isset($GLOBALS['fwp_post'][$sfield])) :
|
822 |
+
if ($GLOBALS['fwp_post'][$sfield]=='site-default') :
|
823 |
unset($meta["{$what} status"]);
|
824 |
else :
|
825 |
+
$meta["{$what} status"] = $GLOBALS['fwp_post'][$sfield];
|
826 |
endif;
|
827 |
endif;
|
828 |
endforeach;
|
830 |
// Unfamiliar author, unfamiliar categories
|
831 |
foreach (array("author", "category") as $what) :
|
832 |
$sfield = "unfamiliar_{$what}";
|
833 |
+
if (isset($GLOBALS['fwp_post'][$sfield])) :
|
834 |
+
if ($GLOBALS['fwp_post'][$sfield]=='site-default') :
|
835 |
unset($meta["unfamiliar {$what}"]);
|
836 |
else :
|
837 |
+
$meta["unfamiliar {$what}"] = $GLOBALS['fwp_post'][$sfield];
|
838 |
endif;
|
839 |
endif;
|
840 |
endforeach;
|
841 |
|
842 |
+
if (isset($GLOBALS['fwp_post']['cat_split'])) :
|
843 |
+
if (strlen(trim($GLOBALS['fwp_post']['cat_split'])) > 0) :
|
844 |
+
$meta['cat_split'] = trim($GLOBALS['fwp_post']['cat_split']);
|
845 |
+
else :
|
846 |
+
unset($meta['cat_split']);
|
847 |
+
endif;
|
848 |
+
endif;
|
849 |
+
|
850 |
if (is_array($meta['cats'])) :
|
851 |
$meta['cats'] = implode(FEEDWORDPRESS_CAT_SEPARATOR, $meta['cats']);
|
852 |
endif;
|
853 |
|
854 |
$notes = '';
|
855 |
foreach ($meta as $key => $value) :
|
856 |
+
$notes .= $key . ": ". addcslashes($value, "\0..\37".'\\') . "\n";
|
857 |
endforeach;
|
858 |
$alter[] = "link_notes = '".$wpdb->escape($notes)."'";
|
859 |
|
868 |
$updated_link = true;
|
869 |
|
870 |
// reload link information from DB
|
871 |
+
$link =& new SyndicatedLink($link_id);
|
|
|
|
|
872 |
else :
|
873 |
$updated_link = false;
|
874 |
endif;
|
875 |
|
876 |
+
$db_link = $link->link;
|
877 |
+
$link_url = wp_specialchars($db_link->link_url, 1);
|
878 |
+
$link_name = wp_specialchars($db_link->link_name, 1);
|
879 |
+
$link_description = wp_specialchars($db_link->link_description, 'both');
|
880 |
+
$link_notes = wp_specialchars($db_link->link_notes, 'both');
|
881 |
+
$link_rss_uri = wp_specialchars($db_link->link_rss, 'both');
|
882 |
+
|
883 |
+
$meta = $link->settings;
|
884 |
+
$post_status_global = get_option('feedwordpress_syndicated_post_status');
|
885 |
+
$comment_status_global = get_option('feedwordpress_syndicated_comment_status');
|
886 |
+
$ping_status_global = get_option('feedwordpress_syndicated_ping_status');
|
887 |
|
|
|
|
|
888 |
$status['post'] = array('publish' => '', 'private' => '', 'draft' => '', 'site-default' => '');
|
889 |
$status['comment'] = array('open' => '', 'closed' => '', 'site-default' => '');
|
890 |
$status['ping'] = array('open' => '', 'closed' => '', 'site-default' => '');
|
911 |
endforeach;
|
912 |
|
913 |
$dogs = get_nested_categories(-1, 0);
|
914 |
+
if (is_array($meta['cats'])) :
|
915 |
+
$cats = array_map('strtolower',
|
916 |
+
array_map('trim',
|
917 |
+
$meta['cats']
|
918 |
+
));
|
919 |
+
else:
|
920 |
+
$cats = array();
|
921 |
+
endif;
|
922 |
|
923 |
foreach ($dogs as $tag => $dog) :
|
924 |
+
$found_by_name = in_array(strtolower(trim($dog['cat_name'])), $cats);
|
925 |
+
|
926 |
+
if (isset($dog['cat_ID'])) : $dog['cat_id'] = $dog['cat_ID']; endif;
|
927 |
+
$found_by_id = in_array('{#'.trim($dog['cat_id']).'}', $cats);
|
928 |
+
|
929 |
+
if ($found_by_name or $found_by_id) :
|
930 |
$dogs[$tag]['checked'] = true;
|
931 |
endif;
|
932 |
endforeach;
|
950 |
<div class="updated"><p>Syndicated feed settings updated.</p></div>
|
951 |
<?php endif; ?>
|
952 |
|
953 |
+
<form action="admin.php?page=feedwordpress/<?php echo basename(__FILE__); ?>" method="post">
|
954 |
<div class="wrap">
|
955 |
<input type="hidden" name="link_id" value="<?php echo $link_id; ?>" />
|
956 |
<input type="hidden" name="action" value="linkedit" />
|
961 |
<table class="editform" width="100%" cellspacing="2" cellpadding="5">
|
962 |
<tr>
|
963 |
<th scope="row" width="20%"><?php _e('Feed URI:') ?></th>
|
964 |
+
<td width="60%"><a href="<?php echo wp_specialchars($link_rss_uri, 'both'); ?>"><?php echo $link_rss_uri; ?></a>
|
965 |
<a href="<?php echo FEEDVALIDATOR_URI; ?>?url=<?php echo urlencode($link_rss_uri); ?>"
|
966 |
+
title="Check feed <<?php echo wp_specialchars($link_rss_uri, 'both'); ?>> for validity"><img src="../wp-images/smilies/icon_arrow.gif" alt="→" /></a>
|
967 |
</td>
|
968 |
<td width="20%"><input type="submit" name="feedfinder" value="switch →" style="font-size:smaller" /></td>
|
969 |
</tr>
|
975 |
</td>
|
976 |
<td>
|
977 |
<select id="basics-hardcode-name" onchange="flip_hardcode('name')" name="hardcode_name">
|
978 |
+
<option value="no" <?php echo $link->hardcode('name')?'':'selected="selected"'; ?>>update automatically</option>
|
979 |
+
<option value="yes" <?php echo $link->hardcode('name')?'selected="selected"':''; ?>>edit manually</option>
|
980 |
</select>
|
981 |
</td>
|
982 |
</tr>
|
989 |
<td>
|
990 |
<select id="basics-hardcode-description" onchange="flip_hardcode('description')"
|
991 |
name="hardcode_description">
|
992 |
+
<option value="no" <?php echo $link->hardcode('description')?'':'selected="selected"'; ?>>update automatically</option>
|
993 |
+
<option value="yes" <?php echo $link->hardcode('description')?'selected="selected"':''; ?>>edit manually</option>
|
994 |
</select></td>
|
995 |
</tr>
|
996 |
<tr>
|
1000 |
<a id="basics-url-view" href="<?php echo $link_url; ?>"><?php echo $link_url; ?></a></td>
|
1001 |
<td>
|
1002 |
<select id="basics-hardcode-url" onchange="flip_hardcode('url')" name="hardcode_url">
|
1003 |
+
<option value="no"<?php echo $link->hardcode('url')?'':' selected="selected"'; ?>>update automatically</option>
|
1004 |
+
<option value="yes"<?php echo $link->hardcode('url')?' selected="selected"':''; ?>>edit manually</option>
|
1005 |
</select></td></tr>
|
1006 |
|
1007 |
<tr>
|
1057 |
|
1058 |
<?php fwp_category_box($dogs, 'all syndicated posts from this feed'); ?>
|
1059 |
|
1060 |
+
<table class="editform" width="75%" cellspacing="2" cellpadding="5">
|
1061 |
+
<tr><th width="27%" scope="row" style="vertical-align:top">Publication:</th>
|
1062 |
+
<td width="73%" style="vertical-align:top"><ul style="margin:0; list-style:none">
|
1063 |
<li><label><input type="radio" name="feed_post_status" value="site-default"
|
1064 |
+
<?php echo $status['post']['site-default']; ?> /> Use site-wide setting from <a href="admin.php?page=feedwordpress/syndication-options.php">Syndication Options</a>
|
1065 |
+
(currently: <strong><?php echo ($post_status_global ? $post_status_global : 'publish'); ?></strong>)</label></li>
|
1066 |
<li><label><input type="radio" name="feed_post_status" value="publish"
|
1067 |
<?php echo $status['post']['publish']; ?> /> Publish posts from this feed immediately</label></li>
|
1068 |
<li><label><input type="radio" name="feed_post_status" value="private"
|
1072 |
</ul></td>
|
1073 |
</tr>
|
1074 |
|
1075 |
+
<tr><th width="27%" scope="row" style="vertical-align:top">Comments:</th>
|
1076 |
+
<td width="73%"><ul style="margin:0; list-style:none">
|
1077 |
<li><label><input type="radio" name="feed_comment_status" value="site-default"
|
1078 |
+
<?php echo $status['comment']['site-default']; ?> /> Use site-wide setting from <a href="admin.php?page=feedwordpress/syndication-options.php">Syndication Options</a>
|
1079 |
+
(currently: <strong><?php echo ($comment_status_global ? $comment_status_global : 'closed'); ?>)</strong></label></li>
|
1080 |
<li><label><input type="radio" name="feed_comment_status" value="open"
|
1081 |
<?php echo $status['comment']['open']; ?> /> Allow comments on syndicated posts from this feed</label></li>
|
1082 |
<li><label><input type="radio" name="feed_comment_status" value="closed"
|
1084 |
</ul></td>
|
1085 |
</tr>
|
1086 |
|
1087 |
+
<tr><th width="27%" scope="row" style="vertical-align:top">Trackback and Pingback:</th>
|
1088 |
+
<td width="73%"><ul style="margin:0; list-style:none">
|
1089 |
<li><label><input type="radio" name="feed_ping_status" value="site-default"
|
1090 |
+
<?php echo $status['ping']['site-default']; ?> /> Use site-wide setting from <a href="admin.php?page=feedwordpress/syndication-options.php">Syndication Options</a>
|
1091 |
+
(currently: <strong><?php echo ($ping_status_global ? $ping_status_global : 'closed'); ?>)</strong></label></li>
|
1092 |
<li><label><input type="radio" name="feed_ping_status" value="open"
|
1093 |
<?php echo $status['ping']['open']; ?> /> Accept pings on syndicated posts from this feed</label></li>
|
1094 |
<li><label><input type="radio" name="feed_ping_status" value="closed"
|
1108 |
<tr>
|
1109 |
<th width="20%" scope="row" style="vertical-align:top">Unfamiliar authors:</th>
|
1110 |
<td width="80%"><ul style="margin: 0; list-style:none">
|
1111 |
+
<li><label><input type="radio" name="unfamiliar_author" value="site-default"<?php echo $unfamiliar['author']['site-default']; ?> /> use site-wide setting from <a href="admin.php?page=feedwordpress/syndication-options.php">Syndication Options</a>
|
1112 |
(currently <strong><?php echo FeedWordPress::on_unfamiliar('author');; ?></strong>)</label></li>
|
1113 |
<li><label><input type="radio" name="unfamiliar_author" value="create"<?php echo $unfamiliar['author']['create']; ?>/> create a new author account</label></li>
|
1114 |
<li><label><input type="radio" name="unfamiliar_author" value="default"<?php echo $unfamiliar['author']['default']; ?> /> attribute the post to the default author</label></li>
|
1119 |
<tr>
|
1120 |
<th width="20%" scope="row" style="vertical-align:top">Unfamiliar categories:</th>
|
1121 |
<td width="80%"><ul style="margin: 0; list-style:none">
|
1122 |
+
<li><label><input type="radio" name="unfamiliar_category" value="site-default"<?php echo $unfamiliar['category']['site-default']; ?> /> use site-wide setting from <a href="admin.php?page=feedwordpress/syndication-options.php">Syndication Options</a>
|
1123 |
(currently <strong><?php echo FeedWordPress::on_unfamiliar('category');; ?></strong>)</label></li>
|
1124 |
<li><label><input type="radio" name="unfamiliar_category" value="create"<?php echo $unfamiliar['category']['create']; ?> /> create any categories the post is in</label></li>
|
1125 |
<li><label><input type="radio" name="unfamiliar_category" value="default"<?php echo $unfamiliar['category']['default']; ?> /> don't create new categories</label></li>
|
1126 |
<li><label><input type="radio" name="unfamiliar_category" value="filter"<?php echo $unfamiliar['category']['filter']; ?> /> don't create new categories and don't syndicate posts unless they match at least one familiar category</label></li>
|
1127 |
</ul></td>
|
1128 |
+
</tr>
|
1129 |
+
|
1130 |
+
<tr>
|
1131 |
+
<th width="20%" scope="row" style="vertical-align:top">Multiple categories:</th>
|
1132 |
+
<td width="80%">
|
1133 |
+
<input type="text" size="20" id="cat_split" name="cat_split" value="<?php if (isset($meta['cat_split'])) : echo htmlspecialchars($meta['cat_split']); endif; ?>" /><br/>
|
1134 |
+
Enter a <a href="http://us.php.net/manual/en/reference.pcre.pattern.syntax.php">Perl-compatible regular expression</a> here if the feed provides multiple
|
1135 |
+
categories in a single category element. The regular expression should match
|
1136 |
+
the characters used to separate one category from the next. If the feed uses
|
1137 |
+
spaces (like <a href="http://del.icio.us/">del.icio.us</a>), use the pattern "\s".
|
1138 |
+
If the feed does not provide multiple categories in a single element, leave this
|
1139 |
+
blank.</td>
|
1140 |
+
</tr>
|
1141 |
+
</table>
|
1142 |
</fieldset>
|
1143 |
|
1144 |
<p class="submit">
|
1161 |
if (!preg_match("\007^((".implode(')|(', $special_settings)."))$\007i", $key)) :
|
1162 |
?>
|
1163 |
<tr style="vertical-align:top">
|
1164 |
+
<th width="30%" scope="row"><input type="hidden" name="notes[<?php echo $i; ?>][key0]" value="<?php echo wp_specialchars($key, 'both'); ?>" />
|
1165 |
+
<input id="notes-<?php echo $i; ?>-key" name="notes[<?php echo $i; ?>][key1]" value="<?php echo wp_specialchars($key, 'both'); ?>" /></th>
|
1166 |
+
<td width="60%"><textarea rows="2" cols="40" id="notes-<?php echo $i; ?>-value" name="notes[<?php echo $i; ?>][value]"><?php echo wp_specialchars($value, 'both'); ?></textarea></td>
|
1167 |
<td width="10%"><select name="notes[<?php echo $i; ?>][action]">
|
1168 |
<option value="update">save changes</option>
|
1169 |
<option value="delete">delete this setting</option>
|
1202 |
|
1203 |
if (!current_user_can('manage_links')):
|
1204 |
die (__("Cheatin' uh ?"));
|
1205 |
+
elseif (isset($GLOBALS['fwp_post']['confirm']) and $GLOBALS['fwp_post']['confirm']=='Delete'):
|
1206 |
+
foreach ($GLOBALS['fwp_post']['link_action'] as $link_id => $what) :
|
1207 |
$do_it[$what][] = $link_id;
|
1208 |
endforeach;
|
1209 |
|
1283 |
WHERE link_id IN (".implode(",",$link_ids).")
|
1284 |
");
|
1285 |
?>
|
1286 |
+
<form action="admin.php?page=feedwordpress/<?php echo basename(__FILE__); ?>" method="post">
|
1287 |
<div class="wrap">
|
1288 |
<input type="hidden" name="action" value="Unsubscribe" />
|
1289 |
<input type="hidden" name="confirm" value="Delete" />
|
1292 |
<?php foreach ($targets as $link) :
|
1293 |
$link_url = wp_specialchars($link->link_url, 1);
|
1294 |
$link_name = wp_specialchars($link->link_name, 1);
|
1295 |
+
$link_description = wp_specialchars($link->link_description, 'both');
|
1296 |
+
$link_rss = wp_specialchars($link->link_rss, 'both');
|
|
|
1297 |
?>
|
1298 |
<fieldset>
|
1299 |
<legend><?php echo $link_name; ?></legend>
|
1356 |
function fwp_release_pings () {
|
1357 |
global $fwp_held_ping;
|
1358 |
if ($fwp_held_ping):
|
1359 |
+
if (function_exists('wp_schedule_single_event')) :
|
1360 |
+
wp_schedule_single_event(time(), 'do_pings');
|
1361 |
+
else :
|
1362 |
+
generic_ping($fwp_held_ping);
|
1363 |
+
endif;
|
1364 |
endif;
|
1365 |
$fwp_held_ping = NULL; // NULL: not holding pings anymore
|
1366 |
}
|
1367 |
|
1368 |
+
function fwp_do_pings () {
|
1369 |
+
if (!is_null($fwp_held_ping) and $post_id) : // Defer until we're done updating
|
|
|
1370 |
$fwp_held_ping = $post_id;
|
1371 |
+
elseif (function_exists('do_all_pings')) :
|
1372 |
+
do_all_pings();
|
1373 |
+
else :
|
1374 |
generic_ping($fwp_held_ping);
|
1375 |
endif;
|
1376 |
}
|
1377 |
|
1378 |
+
function fwp_publish_post_hook ($post_id) {
|
1379 |
+
global $fwp_held_ping;
|
1380 |
+
|
1381 |
+
if (!is_null($fwp_held_ping)) : // Syndicated post. Don't mark with _pingme
|
1382 |
+
if ( defined('XMLRPC_REQUEST') )
|
1383 |
+
do_action('xmlrpc_publish_post', $post_id);
|
1384 |
+
if ( defined('APP_REQUEST') )
|
1385 |
+
do_action('app_publish_post', $post_id);
|
1386 |
+
|
1387 |
+
if ( defined('WP_IMPORTING') )
|
1388 |
+
return;
|
1389 |
+
|
1390 |
+
// Defer sending out pings until we finish updating
|
1391 |
+
$fwp_held_ping = $post_id;
|
1392 |
+
else :
|
1393 |
+
if (function_exists('_publish_post_hook')) : // WordPress 2.3
|
1394 |
+
_publish_post_hook($post_id);
|
1395 |
+
endif;
|
1396 |
+
endif;
|
1397 |
+
}
|
1398 |
+
|
1399 |
################################################################################
|
1400 |
## class FeedWordPress #########################################################
|
1401 |
################################################################################
|
1434 |
array('script', 'src')
|
1435 |
);
|
1436 |
|
|
|
1437 |
var $feeds = NULL;
|
1438 |
|
1439 |
+
# function FeedWordPress (): Contructor; retrieve a list of feeds
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1440 |
function FeedWordPress () {
|
1441 |
+
$this->feeds = array ();
|
1442 |
+
$links = FeedWordPress::syndicated_links();
|
1443 |
+
if ($links): foreach ($links as $link):
|
1444 |
+
$this->feeds[] =& new SyndicatedLink($link);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1445 |
endforeach; endif;
|
|
|
|
|
1446 |
} // FeedWordPress::FeedWordPress ()
|
1447 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1448 |
# function update (): polls for updates on one or more Contributor feeds
|
1449 |
#
|
1450 |
# Arguments:
|
1451 |
# ----------
|
1452 |
# * $uri (string): either the URI of the feed to poll, the URI of the
|
1453 |
+
# (human-readable) website whose feed you want to poll, or NULL.
|
|
|
|
|
1454 |
#
|
1455 |
+
# If $uri is NULL, then FeedWordPress will poll any feeds that are
|
1456 |
+
# ready for polling. It will not poll feeds that are marked as
|
1457 |
+
# "Invisible" Links (signifying that the subscription has been
|
1458 |
+
# de-activated), or feeds that are not yet stale according to their
|
1459 |
+
# TTL setting (which is either set in the feed, or else set
|
1460 |
+
# randomly within a window of 30 minutes - 2 hours).
|
1461 |
#
|
1462 |
# Returns:
|
1463 |
# --------
|
1467 |
# are zero, there was no change since the last poll on that URI.
|
1468 |
#
|
1469 |
# * Returns NULL if URI it was passed was not a URI that this
|
1470 |
+
# installation of FeedWordPress syndicates.
|
|
|
|
|
1471 |
#
|
1472 |
# Effects:
|
1473 |
# --------
|
1494 |
# * Updates to existing posts since the last poll are mirrored in the
|
1495 |
# WordPress store.
|
1496 |
#
|
1497 |
+
function update ($uri = null) {
|
1498 |
global $wpdb;
|
1499 |
|
|
|
|
|
1500 |
if (FeedWordPress::needs_upgrade()) : // Will make duplicate posts if we don't hold off
|
1501 |
return NULL;
|
1502 |
endif;
|
1503 |
+
|
1504 |
+
if (!is_null($uri)) :
|
1505 |
+
$uri = trim($uri);
|
1506 |
+
else : // Update all
|
1507 |
+
update_option('feedwordpress_last_update_all', time());
|
1508 |
+
endif;
|
1509 |
|
1510 |
do_action('feedwordpress_update', $uri);
|
1511 |
|
|
|
|
|
|
|
|
|
|
|
1512 |
// Loop through and check for new posts
|
1513 |
+
$delta = NULL;
|
1514 |
foreach ($this->feeds as $feed) :
|
1515 |
+
$pinged_that = (is_null($uri) or in_array($uri, array($feed->uri(), $feed->homepage())));
|
1516 |
|
1517 |
+
if (!is_null($uri)) : // A site-specific ping always updates
|
|
|
|
|
|
|
|
|
|
|
|
|
1518 |
$timely = true;
|
1519 |
else :
|
1520 |
+
$timely = $feed->stale();
|
|
|
|
|
1521 |
endif;
|
1522 |
|
1523 |
if ($pinged_that and is_null($delta)) : // If at least one feed was hit for updating...
|
1525 |
endif;
|
1526 |
|
1527 |
if ($pinged_that and $timely) :
|
1528 |
+
do_action('feedwordpress_check_feed', $feed->settings);
|
1529 |
+
$added = $feed->poll();
|
1530 |
if (isset($added['new'])) : $delta['new'] += $added['new']; endif;
|
1531 |
if (isset($added['updated'])) : $delta['updated'] += $added['updated']; endif;
|
1532 |
endif;
|
1533 |
endforeach;
|
1534 |
|
1535 |
do_action('feedwordpress_update_complete', $delta);
|
|
|
1536 |
|
1537 |
return $delta;
|
1538 |
}
|
1539 |
|
1540 |
+
function stale () {
|
1541 |
+
if (get_option('feedwordpress_automatic_updates')) :
|
1542 |
+
$last = get_option('feedwordpress_last_update_all');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1543 |
|
1544 |
+
// If we haven't updated all yet, give it a time window
|
1545 |
+
if (false === $last) :
|
1546 |
+
$ret = false;
|
1547 |
+
update_option('feedwordpress_last_update_all', time());
|
1548 |
+
|
1549 |
+
// Otherwise, check against freshness interval
|
1550 |
+
elseif (is_numeric($last)) : // Expect a timestamp
|
1551 |
+
$freshness = get_option('feedwordpress_freshness');
|
1552 |
+
if (false === $freshness) : // Use default
|
1553 |
+
$freshness = FEEDWORDPRESS_FRESHNESS_INTERVAL;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1554 |
endif;
|
1555 |
+
$ret = ( (time() - $last) > $freshness);
|
1556 |
+
|
1557 |
+
// This should never happen.
|
1558 |
+
else :
|
1559 |
+
FeedWordPress::critical_bug('FeedWordPress::stale::last', $last, __LINE__);
|
1560 |
+
endif;
|
1561 |
+
else :
|
1562 |
+
$ret = false;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1563 |
endif;
|
1564 |
return $ret;
|
1565 |
}
|
1566 |
|
1567 |
+
function syndicate_link ($name, $uri, $rss) {
|
1568 |
global $wpdb;
|
1569 |
|
1570 |
+
// Get the category ID#
|
1571 |
+
$cat_id = FeedWordPress::link_category_id();
|
1572 |
+
|
1573 |
+
// WordPress gets cranky if there's no homepage URI
|
1574 |
+
if (!isset($uri) or strlen($uri)<1) : $uri = $rss; endif;
|
1575 |
+
|
1576 |
+
if (function_exists('wp_insert_link')) { // WordPress 2.x
|
1577 |
+
$link_id = wp_insert_link(array(
|
1578 |
+
"link_name" => $name,
|
1579 |
+
"link_url" => $uri,
|
1580 |
+
"link_category" => array($cat_id),
|
1581 |
+
"link_rss" => $rss
|
1582 |
+
));
|
1583 |
+
} else { // WordPress 1.5.x
|
1584 |
+
$result = $wpdb->query("
|
1585 |
+
INSERT INTO $wpdb->links
|
1586 |
+
SET
|
1587 |
+
link_name = '".$wpdb->escape($name)."',
|
1588 |
+
link_url = '".$wpdb->escape($uri)."',
|
1589 |
+
link_category = '".$wpdb->escape($cat_id)."',
|
1590 |
+
link_rss = '".$wpdb->escape($rss)."'
|
1591 |
+
");
|
1592 |
+
$link_id = $wpdb->insert_id;
|
1593 |
+
} // if
|
1594 |
+
return $link_id;
|
1595 |
+
} // function FeedWordPress::syndicate_link()
|
1596 |
|
1597 |
+
function on_unfamiliar ($what = 'author', $override = NULL) {
|
1598 |
+
$set = array('create', 'default', 'filter');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1599 |
|
1600 |
+
$ret = strtolower($override);
|
1601 |
+
if (!in_array($ret, $set)) :
|
1602 |
+
$ret = get_option('feedwordpress_unfamiliar_'.$what);
|
1603 |
+
if (!in_array($ret, $set)) :
|
1604 |
+
$ret = 'create';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1605 |
endif;
|
|
|
|
|
|
|
|
|
1606 |
endif;
|
|
|
|
|
1607 |
|
1608 |
+
return $ret;
|
1609 |
+
} // function FeedWordPress::on_unfamiliar()
|
1610 |
|
1611 |
+
function syndicated_links () {
|
1612 |
+
$contributors = FeedWordPress::link_category_id();
|
1613 |
+
if (function_exists('get_bookmarks')) :
|
1614 |
+
$links = get_bookmarks(array("category" => $contributors));
|
1615 |
+
else:
|
1616 |
+
$links = get_linkobjects($contributors); // deprecated as of WP 2.1
|
1617 |
endif;
|
1618 |
+
return $links;
|
1619 |
+
} // function FeedWordPress::syndicated_links()
|
1620 |
|
1621 |
+
function link_category_id () {
|
1622 |
+
global $wpdb, $wp_db_version;
|
|
|
|
|
1623 |
|
1624 |
+
$cat_id = get_option('feedwordpress_cat_id');
|
1625 |
+
|
1626 |
+
// If we don't yet *have* the category, we'll have to create it
|
1627 |
+
if ($cat_id === false) :
|
1628 |
+
$cat = $wpdb->escape(DEFAULT_SYNDICATION_CATEGORY);
|
1629 |
+
|
1630 |
+
// Look for something with the right name...
|
1631 |
+
// -----------------------------------------
|
1632 |
+
|
1633 |
+
// WordPress 2.3 introduces a new taxonomy/term API
|
1634 |
+
if (function_exists('is_term')) :
|
1635 |
+
$cat_id = is_term($cat, 'link_category');
|
1636 |
+
// WordPress 2.1 and 2.2 use a common table for both link and post categories
|
1637 |
+
elseif (isset($wp_db_version) and ($wp_db_version >= FWP_SCHEMA_21 and $wp_db_version < FWP_SCHEMA_23) ) :
|
1638 |
+
$cat_id = $wpdb->get_var("SELECT cat_id FROM {$wpdb->categories} WHERE cat_name='$cat'");
|
1639 |
+
// WordPress 1.5 and 2.0.x have a separate table for link categories
|
1640 |
+
elseif (!isset($wp_db_version) or $wp_db_version < FWP_SCHEMA_21) :
|
1641 |
+
$cat_id = $wpdb->get_var("SELECT cat_id FROM {$wpdb->linkcategories} WHERE cat_name='$cat'");
|
1642 |
+
// This should never happen.
|
1643 |
+
else :
|
1644 |
+
FeedWordPress::critical_bug('FeedWordPress::link_category_id::wp_db_version', $wp_db_version, __LINE__);
|
1645 |
+
endif;
|
1646 |
|
1647 |
+
// If you still can't find anything, make it for yourself.
|
1648 |
+
// -------------------------------------------------------
|
1649 |
+
if (!$cat_id) :
|
1650 |
+
// WordPress 2.3+ term/taxonomy API
|
1651 |
+
if (function_exists('wp_insert_term')) :
|
1652 |
+
$term = wp_insert_term($cat, 'link_category');
|
1653 |
+
$cat_id = $term['term_id'];
|
1654 |
+
// WordPress 2.1, 2.2 category API. By the way, why the fuck is this API function only available in a wp-admin module?
|
1655 |
+
elseif (function_exists('wp_insert_category')) :
|
1656 |
+
$cat_id = wp_insert_category(array('cat_name' => $cat));
|
1657 |
+
// WordPress 1.5 and 2.0.x
|
1658 |
+
elseif (!isset($wp_db_version) or $wp_db_version < FWP_SCHEMA_21) :
|
1659 |
+
$result = $wpdb->query("
|
1660 |
+
INSERT INTO $wpdb->linkcategories
|
1661 |
+
SET
|
1662 |
+
cat_id = 0,
|
1663 |
+
cat_name='$cat',
|
1664 |
+
show_images='N',
|
1665 |
+
show_description='N',
|
1666 |
+
show_rating='N',
|
1667 |
+
show_updated='N',
|
1668 |
+
sort_order='name'
|
1669 |
+
");
|
1670 |
+
$cat_id = $wpdb->insert_id;
|
1671 |
+
// This should never happen.
|
1672 |
+
else :
|
1673 |
+
FeedWordPress::critical_bug('FeedWordPress::link_category_id::wp_db_version', $wp_db_version, __LINE__);
|
1674 |
+
endif;
|
1675 |
endif;
|
|
|
1676 |
|
1677 |
+
update_option('feedwordpress_cat_id', $cat_id);
|
|
|
1678 |
endif;
|
1679 |
+
return $cat_id;
|
1680 |
+
} // function FeedWordPress::link_category_id()
|
1681 |
|
1682 |
+
# Upgrades and maintenance...
|
1683 |
+
function needs_upgrade () {
|
1684 |
+
global $wpdb;
|
1685 |
+
$fwp_db_version = get_option('feedwordpress_version');
|
1686 |
+
$ret = false; // innocent until proven guilty
|
1687 |
+
if (!$fwp_db_version or $fwp_db_version < FEEDWORDPRESS_VERSION) :
|
1688 |
+
// This is an older version or a fresh install. Does it
|
1689 |
+
// require a database upgrade or database initialization?
|
1690 |
+
if ($fwp_db_version > 0.96) :
|
1691 |
+
// No. Just brand it with the new version.
|
1692 |
+
update_option('feedwordpress_version', FEEDWORDPRESS_VERSION);
|
1693 |
+
else :
|
1694 |
+
// Yes. Check to see whether this is a fresh install or an upgrade.
|
1695 |
+
$syn = $wpdb->get_col("
|
1696 |
+
SELECT post_id
|
1697 |
+
FROM $wpdb->postmeta
|
1698 |
+
WHERE meta_key = 'syndication_feed'
|
1699 |
+
");
|
1700 |
+
if (count($syn) > 0) : // contains at least one syndicated post
|
1701 |
+
$ret = true;
|
1702 |
+
else : // fresh install; brand it as ours
|
1703 |
+
update_option('feedwordpress_version', FEEDWORDPRESS_VERSION);
|
1704 |
+
endif;
|
1705 |
+
endif;
|
1706 |
endif;
|
1707 |
+
return $ret;
|
1708 |
+
}
|
1709 |
|
1710 |
+
function upgrade_database ($from = NULL) {
|
1711 |
+
global $wpdb;
|
|
|
1712 |
|
1713 |
+
if (is_null($from) or $from <= 0.96) : $from = 0.96; endif;
|
|
|
|
|
|
|
1714 |
|
1715 |
+
switch ($from) :
|
1716 |
+
case 0.96: // account for changes to syndication custom values and guid
|
1717 |
+
echo "<p>Upgrading database from {$from} to ".FEEDWORDPRESS_VERSION."...</p>\n";
|
|
|
|
|
1718 |
|
1719 |
+
$cat_id = FeedWordPress::link_category_id();
|
1720 |
+
|
1721 |
+
// Avoid duplicates
|
1722 |
+
$wpdb->query("DELETE FROM `{$wpdb->postmeta}` WHERE meta_key = 'syndication_feed_id'");
|
1723 |
+
|
1724 |
+
// Look up all the link IDs
|
1725 |
+
$wpdb->query("
|
1726 |
+
CREATE TEMPORARY TABLE tmp_custom_values
|
1727 |
+
SELECT
|
1728 |
+
NULL AS meta_id,
|
1729 |
+
post_id,
|
1730 |
+
'syndication_feed_id' AS meta_key,
|
1731 |
+
link_id AS meta_value
|
1732 |
+
FROM `{$wpdb->postmeta}`, `{$wpdb->links}`
|
1733 |
+
WHERE
|
1734 |
+
meta_key='syndication_feed'
|
1735 |
+
AND meta_value=link_rss
|
1736 |
+
AND link_category = {$cat_id}
|
1737 |
+
");
|
1738 |
+
|
1739 |
+
// Now attach them to their posts
|
1740 |
+
$wpdb->query("INSERT INTO `{$wpdb->postmeta}` SELECT * FROM tmp_custom_values");
|
1741 |
+
|
1742 |
+
// And clean up after ourselves.
|
1743 |
+
$wpdb->query("DROP TABLE tmp_custom_values");
|
1744 |
+
|
1745 |
+
// Now fix the guids to avoid duplicate posts
|
1746 |
+
echo "<ul>";
|
1747 |
+
foreach ($this->feeds as $feed) :
|
1748 |
+
echo "<li>Fixing post meta-data for <cite>".$feed['link/name']."</cite> … "; flush();
|
1749 |
+
$rss = @fetch_rss($feed['link/uri']);
|
1750 |
+
if (is_array($rss->items)) :
|
1751 |
+
foreach ($rss->items as $item) :
|
1752 |
+
$guid = $wpdb->escape(FeedWordPress::guid($item, $feed)); // new GUID algorithm
|
1753 |
+
$link = $wpdb->escape($item['link']);
|
1754 |
+
|
1755 |
+
$wpdb->query("
|
1756 |
+
UPDATE `{$wpdb->posts}` SET guid='{$guid}' WHERE guid='{$link}'
|
1757 |
+
");
|
1758 |
+
endforeach;
|
1759 |
+
endif;
|
1760 |
+
echo "<strong>complete.</strong></li>\n";
|
1761 |
+
endforeach;
|
1762 |
+
echo "</ul>\n";
|
1763 |
+
|
1764 |
+
// Mark the upgrade as successful.
|
1765 |
+
update_option('feedwordpress_version', FEEDWORDPRESS_VERSION);
|
1766 |
+
endswitch;
|
1767 |
+
echo "<p>Upgrade complete. FeedWordPress is now ready to use again.</p>";
|
1768 |
+
} /* FeedWordPress::upgrade_database() */
|
1769 |
+
|
1770 |
+
# Utility functions for handling text settings
|
1771 |
+
function negative ($f, $setting) {
|
1772 |
+
$nego = array ('n', 'no', 'f', 'false');
|
1773 |
+
return (isset($f[$setting]) and in_array(strtolower($f[$setting]), $nego));
|
1774 |
}
|
1775 |
|
1776 |
+
function affirmative ($f, $setting) {
|
1777 |
+
$affirmo = array ('y', 'yes', 't', 'true', 1);
|
1778 |
+
return (isset($f[$setting]) and in_array(strtolower($f[$setting]), $affirmo));
|
1779 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1780 |
|
1781 |
+
|
1782 |
+
# Internal debugging functions
|
1783 |
+
function critical_bug ($varname, $var, $line) {
|
1784 |
+
global $wp_version;
|
1785 |
+
|
1786 |
+
echo '<p>There may be a bug in FeedWordPress. Please <a href="'.FEEDWORDPRESS_AUTHOR_CONTACT.'">contact the author</a> and paste the following information into your e-mail:</p>';
|
1787 |
+
echo "\n<plaintext>";
|
1788 |
+
echo "Triggered at line # ".$line."\n";
|
1789 |
+
echo "FeedWordPress version: ".FEEDWORDPRESS_VERSION."\n";
|
1790 |
+
echo "WordPress version: $wp_version\n";
|
1791 |
+
echo "PHP version: ".phpversion()."\n";
|
1792 |
+
echo "\n";
|
1793 |
+
echo $varname.": "; var_dump($var); echo "\n";
|
1794 |
+
die;
|
|
|
|
|
|
|
|
|
|
|
|
|
1795 |
}
|
1796 |
+
} // class FeedWordPress
|
1797 |
|
1798 |
+
class SyndicatedPost {
|
1799 |
+
var $item = null;
|
1800 |
+
|
1801 |
+
var $link = null;
|
1802 |
+
var $feed = null;
|
1803 |
+
var $feedmeta = null;
|
1804 |
+
|
1805 |
+
var $post = array ();
|
1806 |
+
var $_base = null;
|
1807 |
+
|
1808 |
+
var $_freshness = null;
|
1809 |
+
var $_wp_id = null;
|
1810 |
+
|
1811 |
+
var $strip_attrs = array (
|
1812 |
+
array('[a-z]+', 'style'),
|
1813 |
+
array('[a-z]+', 'target'),
|
1814 |
+
);
|
1815 |
+
|
1816 |
+
function SyndicatedPost ($item, $link) {
|
1817 |
+
global $wpdb;
|
1818 |
+
|
1819 |
+
$this->link = $link;
|
1820 |
+
$feedmeta = $link->settings;
|
1821 |
+
$feed = $link->magpie;
|
1822 |
+
|
1823 |
+
# This is ugly as all hell. I'd like to use apply_filters()'s
|
1824 |
+
# alleged support for a variable argument count, but this seems
|
1825 |
+
# to have been broken in WordPress 1.5. It'll be fixed somehow
|
1826 |
+
# in WP 1.5.1, but I'm aiming at WP 1.5 compatibility across
|
1827 |
+
# the board here.
|
1828 |
+
#
|
1829 |
+
# Cf.: <http://mosquito.wordpress.org/view.php?id=901>
|
1830 |
global $fwp_channel, $fwp_feedmeta;
|
1831 |
+
$fwp_channel = $feed; $fwp_feedmeta = $feedmeta;
|
1832 |
+
|
1833 |
+
$this->feed = $feed;
|
1834 |
+
$this->feedmeta = $feedmeta;
|
1835 |
+
|
1836 |
+
$this->item = $item;
|
1837 |
+
$this->item = apply_filters('syndicated_item', $this->item, $this);
|
1838 |
+
|
1839 |
+
# Filters can halt further processing by returning NULL
|
1840 |
+
if (is_null($this->item)) :
|
1841 |
+
$this->post = NULL;
|
1842 |
else :
|
1843 |
+
# Note that nothing is run through $wpdb->escape() here.
|
1844 |
+
# That's deliberate. The escaping is done at the point
|
1845 |
+
# of insertion, not here, to avoid double-escaping and
|
1846 |
+
# to avoid screwing with syndicated_post filters
|
1847 |
|
1848 |
+
$this->post['post_title'] = $this->item['title'];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1849 |
|
1850 |
+
// This just gives usan alphanumeric representation of
|
1851 |
+
// the author. We will look up (or create) the numeric
|
1852 |
+
// ID for the author in SyndicatedPost::add()
|
1853 |
+
$this->post['named']['author'] = $this->author();
|
1854 |
|
1855 |
# Identify content and sanitize it.
|
1856 |
# ---------------------------------
|
1857 |
+
if (isset($this->item['xhtml']['body'])) :
|
1858 |
+
$content = $this->item['xhtml']['body'];
|
1859 |
+
elseif (isset($this->item['xhtml']['div'])) :
|
1860 |
+
$content = $this->item['xhtml']['div'];
|
1861 |
+
elseif (isset($this->item['content']['encoded']) and $this->item['content']['encoded']):
|
1862 |
+
$content = $this->item['content']['encoded'];
|
1863 |
else:
|
1864 |
+
$content = $this->item['description'];
|
1865 |
endif;
|
1866 |
|
1867 |
+
# FeedWordPress used to resolve URIs relative to the
|
1868 |
+
# feed URI. It now relies on the xml:base support
|
1869 |
+
# baked in to the MagpieRSS upgrade. So all we do here
|
1870 |
+
# now is to sanitize problematic attributes.
|
1871 |
#
|
1872 |
+
# This kind of sucks. I intend to replace it with
|
1873 |
+
# lib_filter sometime soon.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1874 |
foreach ($this->strip_attrs as $pair):
|
1875 |
list($tag,$attr) = $pair;
|
1876 |
$content = preg_replace (
|
1882 |
|
1883 |
# Identify and sanitize excerpt
|
1884 |
$excerpt = NULL;
|
1885 |
+
if ( isset($this->item['description']) and $this->item['description'] ) :
|
1886 |
+
$excerpt = $this->item['description'];
|
1887 |
elseif ( isset($content) and $content ) :
|
1888 |
$excerpt = strip_tags($content);
|
1889 |
if (strlen($excerpt) > 255) :
|
1891 |
endif;
|
1892 |
endif;
|
1893 |
|
1894 |
+
$this->post['post_content'] = $content;
|
1895 |
|
1896 |
if (!is_null($excerpt)):
|
1897 |
+
$this->post['post_excerpt'] = $excerpt;
|
1898 |
endif;
|
1899 |
|
1900 |
+
// This is unnecessary if we use wp_insert_post
|
1901 |
+
if (!$this->use_api('wp_insert_post')) :
|
1902 |
+
$this->post['post_name'] = sanitize_title($this->post['post_title']);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1903 |
endif;
|
1904 |
|
1905 |
+
$this->post['epoch']['issued'] = $this->published();
|
1906 |
+
$this->post['epoch']['created'] = $this->created();
|
1907 |
+
$this->post['epoch']['modified'] = $this->updated();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1908 |
|
1909 |
+
// Dealing with timestamps in WordPress is so fucking fucked.
|
1910 |
+
$offset = (int) get_option('gmt_offset') * 60 * 60;
|
1911 |
+
$this->post['post_date'] = gmdate('Y-m-d H:i:s', $this->published() + $offset);
|
1912 |
+
$this->post['post_modified'] = gmdate('Y-m-d H:i:s', $this->updated() + $offset);
|
1913 |
+
$this->post['post_date_gmt'] = gmdate('Y-m-d H:i:s', $this->published());
|
1914 |
+
$this->post['post_modified_gmt'] = gmdate('Y-m-d H:i:s', $this->updated());
|
1915 |
|
1916 |
+
// Use feed-level preferences or the global default.
|
1917 |
+
$this->post['post_status'] = $this->link->syndicated_status('post', 'publish');
|
1918 |
+
$this->post['comment_status'] = $this->link->syndicated_status('comment', 'closed');
|
1919 |
+
$this->post['ping_status'] = $this->link->syndicated_status('ping', 'closed');
|
1920 |
|
1921 |
// Unique ID (hopefully a unique tag: URI); failing that, the permalink
|
1922 |
+
$this->post['guid'] = $this->guid();
|
1923 |
|
1924 |
// RSS 2.0 / Atom 1.0 enclosure support
|
1925 |
+
if ( isset($this->item['enclosure#']) ) :
|
1926 |
+
for ($i = 1; $i <= $this->item['enclosure#']; $i++) :
|
1927 |
$eid = (($i > 1) ? "#{$id}" : "");
|
1928 |
+
$this->post['meta']['enclosure'][] =
|
1929 |
+
$this->item["enclosure{$eid}@url"]."\n".
|
1930 |
+
$this->item["enclosure{$eid}@length"]."\n".
|
1931 |
+
$this->item["enclosure{$eid}@type"];
|
1932 |
endfor;
|
1933 |
endif;
|
1934 |
|
1935 |
// In case you want to point back to the blog this was syndicated from
|
1936 |
+
if (isset($this->feed->channel['title'])) :
|
1937 |
+
$this->post['meta']['syndication_source'] = $this->feed->channel['title'];
|
1938 |
+
endif;
|
1939 |
+
if (isset($this->feed->channel['link'])) :
|
1940 |
+
$this->post['meta']['syndication_source_uri'] = $this->feed->channel['link'];
|
1941 |
+
endif;
|
1942 |
|
1943 |
// Store information on human-readable and machine-readable comment URIs
|
1944 |
+
if (isset($this->item['comments'])) :
|
1945 |
+
$this->post['meta']['rss:comments'] = $this->item['comments'];
|
1946 |
+
endif;
|
1947 |
+
if (isset($this->item['wfw']['commentrss'])) :
|
1948 |
+
$this->post['meta']['wfw:commentRSS'] = $this->item['wfw']['commentrss'];
|
1949 |
+
endif;
|
1950 |
|
1951 |
// Store information to identify the feed that this came from
|
1952 |
+
$this->post['meta']['syndication_feed'] = $this->feedmeta['link/uri'];
|
1953 |
+
$this->post['meta']['syndication_feed_id'] = $this->feedmeta['link/id'];
|
1954 |
|
1955 |
// In case you want to know the external permalink...
|
1956 |
+
$this->post['meta']['syndication_permalink'] = $this->item['link'];
|
1957 |
|
1958 |
// Feed-by-feed options for author and category creation
|
1959 |
+
$this->post['named']['unfamiliar']['author'] = $this->feedmeta['unfamiliar author'];
|
1960 |
+
$this->post['named']['unfamiliar']['category'] = $this->feedmeta['unfamiliar categories'];
|
1961 |
|
1962 |
+
// Categories: start with default categories, if any
|
1963 |
+
$fc = get_option("feedwordpress_syndication_cats");
|
1964 |
+
if ($fc) :
|
1965 |
+
$this->post['named']['preset/category'] = explode("\n", $fc);
|
1966 |
+
else :
|
1967 |
+
$this->post['named']['preset/category'] = array();
|
1968 |
endif;
|
1969 |
+
|
1970 |
+
if (is_array($this->feedmeta['cats'])) :
|
1971 |
+
$this->post['named']['preset/category'] = array_merge($this->post['named']['preset/category'], $this->feedmeta['cats']);
|
1972 |
endif;
|
1973 |
|
1974 |
// Now add categories from the post, if we have 'em
|
1975 |
+
$this->post['named']['category'] = array();
|
1976 |
+
if ( isset($this->item['category#']) ) :
|
1977 |
+
for ($i = 1; $i <= $this->item['category#']; $i++) :
|
1978 |
$cat_idx = (($i > 1) ? "#{$i}" : "");
|
1979 |
+
$cat = $this->item["category{$cat_idx}"];
|
1980 |
|
1981 |
+
if ( isset($this->feedmeta['cat_split']) and strlen($this->feedmeta['cat_split']) > 0) :
|
1982 |
+
$pcre = "\007".$this->feedmeta['cat_split']."\007";
|
1983 |
+
$this->post['named']['category'] = array_merge($this->post['named']['category'], preg_split($pcre, $cat, -1 /*=no limit*/, PREG_SPLIT_NO_EMPTY));
|
1984 |
+
else :
|
1985 |
+
$this->post['named']['category'][] = $cat;
|
1986 |
endif;
|
1987 |
endfor;
|
1988 |
endif;
|
1989 |
endif;
|
1990 |
+
} // SyndicatedPost::SyndicatedPost()
|
1991 |
+
|
1992 |
+
function filtered () {
|
1993 |
+
return is_null($this->post);
|
1994 |
+
}
|
1995 |
+
|
1996 |
+
function freshness () {
|
1997 |
+
global $wpdb;
|
1998 |
+
|
1999 |
+
if ($this->filtered()) : // This should never happen.
|
2000 |
+
FeedWordPress::critical_bug('SyndicatedPost', $this, __LINE__);
|
|
|
|
|
|
|
|
|
|
|
2001 |
endif;
|
2002 |
+
|
2003 |
+
if (is_null($this->_freshness)) :
|
2004 |
+
$guid = $wpdb->escape($this->guid());
|
2005 |
+
|
2006 |
+
$result = $wpdb->get_row("
|
2007 |
+
SELECT id, guid, post_modified_gmt
|
2008 |
+
FROM $wpdb->posts WHERE guid='$guid'
|
2009 |
+
");
|
2010 |
|
2011 |
+
preg_match('/([0-9]+)-([0-9]+)-([0-9]+) ([0-9]+):([0-9]+):([0-9]+)/', $result->post_modified_gmt, $backref);
|
2012 |
+
$updated = gmmktime($backref[4], $backref[5], $backref[6], $backref[2], $backref[3], $backref[1]);
|
2013 |
+
if (!$result) :
|
2014 |
+
$this->_freshness = 2; // New content
|
2015 |
+
elseif ($this->updated() > $updated) :
|
2016 |
+
$this->_freshness = 1; // Updated content
|
2017 |
+
$this->_wp_id = $result->id;
|
2018 |
+
else :
|
2019 |
+
$this->_freshness = 0; // Same old, same old
|
2020 |
+
$this->_wp_id = $result->id;
|
2021 |
+
endif;
|
2022 |
+
endif;
|
2023 |
+
return $this->_freshness;
|
2024 |
+
}
|
2025 |
+
|
2026 |
+
function wp_id () {
|
2027 |
+
if ($this->filtered()) : // This should never happen.
|
2028 |
+
FeedWordPress::critical_bug('SyndicatedPost', $this, __LINE__);
|
2029 |
+
endif;
|
2030 |
+
|
2031 |
+
if (is_null($this->_wp_id) and is_null($this->_freshness)) :
|
2032 |
+
$fresh = $this->freshness(); // sets WP DB id in the process
|
2033 |
+
endif;
|
2034 |
+
return $this->_wp_id;
|
2035 |
+
}
|
2036 |
+
|
2037 |
+
function store () {
|
2038 |
+
global $wpdb;
|
2039 |
+
|
2040 |
+
if ($this->filtered()) : // This should never happen.
|
2041 |
+
FeedWordPress::critical_bug('SyndicatedPost', $this, __LINE__);
|
2042 |
+
endif;
|
2043 |
+
|
2044 |
+
$freshness = $this->freshness();
|
2045 |
if ($freshness > 0) :
|
2046 |
# -- Look up, or create, numeric ID for author
|
2047 |
+
$this->post['post_author'] = $this->author_id (
|
2048 |
+
FeedWordPress::on_unfamiliar('author', $this->post['named']['unfamiliar']['author'])
|
|
|
|
|
|
|
|
|
2049 |
);
|
2050 |
|
2051 |
+
if (is_null($this->post['post_author'])) :
|
2052 |
+
$this->post = NULL;
|
2053 |
+
endif;
|
2054 |
+
endif;
|
2055 |
+
|
2056 |
+
if (!$this->filtered() and $freshness > 0) :
|
2057 |
+
# -- Look up, or create, numeric ID for categories
|
2058 |
+
$this->post['post_category'] = $this->category_ids (
|
2059 |
+
$this->post['named']['category'],
|
2060 |
+
FeedWordPress::on_unfamiliar('category', $this->post['named']['unfamiliar']['category'])
|
2061 |
+
);
|
2062 |
+
|
2063 |
+
if (is_null($this->post['post_category'])) :
|
2064 |
+
// filter mode on, no matching categories; drop the post
|
2065 |
+
$this->post = NULL;
|
2066 |
else :
|
2067 |
+
// filter mode off or at least one match; now add on the feed and global presets
|
2068 |
+
$this->post['post_category'] = array_merge (
|
2069 |
+
$this->post['post_category'],
|
2070 |
+
$this->category_ids (
|
2071 |
+
$this->post['named']['preset/category'],
|
2072 |
+
'default'
|
2073 |
+
)
|
2074 |
);
|
2075 |
+
|
2076 |
+
if (count($this->post['post_category']) < 1) :
|
2077 |
+
$this->post['post_category'][] = 1; // Default to category 1 ("Uncategorized" / "General") if nothing else
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2078 |
endif;
|
2079 |
endif;
|
|
|
|
|
2080 |
endif;
|
2081 |
|
2082 |
+
if (!$this->filtered() and $freshness > 0) :
|
2083 |
+
unset($this->post['named']);
|
2084 |
+
$this->post = apply_filters('syndicated_post', $this->post, $this);
|
2085 |
endif;
|
2086 |
|
2087 |
+
if (!$this->filtered() and $freshness == 2) :
|
2088 |
// The item has not yet been added. So let's add it.
|
2089 |
+
$this->insert_new();
|
2090 |
+
$this->add_rss_meta();
|
2091 |
+
do_action('post_syndicated_item', $this->wp_id());
|
2092 |
|
2093 |
$ret = 'new';
|
2094 |
+
elseif (!$this->filtered() and $freshness == 1) :
|
2095 |
+
$this->post['ID'] = $this->wp_id();
|
2096 |
+
$this->update_existing();
|
2097 |
+
$this->add_rss_meta();
|
2098 |
+
do_action('update_syndicated_item', $this->wp_id());
|
2099 |
|
2100 |
$ret = 'updated';
|
2101 |
else :
|
2103 |
endif;
|
2104 |
|
2105 |
return $ret;
|
2106 |
+
} // function SyndicatedPost::store ()
|
2107 |
+
|
2108 |
+
function insert_new () {
|
2109 |
+
global $wpdb, $wp_db_version;
|
2110 |
|
2111 |
+
// Why the fuck doesn't wp_insert_post already do this?
|
2112 |
+
foreach ($this->post as $key => $value) :
|
2113 |
+
if (is_string($value)) :
|
2114 |
+
$dbpost[$key] = $wpdb->escape($value);
|
2115 |
+
else :
|
2116 |
+
$dbpost[$key] = $value;
|
2117 |
+
endif;
|
2118 |
+
endforeach;
|
2119 |
|
2120 |
+
if ($this->use_api('wp_insert_post')) :
|
2121 |
+
$dbpost['post_pingback'] = false; // Tell WP 2.1 and 2.2 not to process for pingbacks
|
2122 |
+
$this->_wp_id = wp_insert_post($dbpost);
|
2123 |
+
|
2124 |
+
// This should never happen.
|
2125 |
+
if (!is_numeric($this->_wp_id) or ($this->_wp_id == 0)) :
|
2126 |
+
FeedWordPress::critical_bug('SyndicatedPost::_wp_id', $this->_wp_id, __LINE__);
|
2127 |
+
endif;
|
2128 |
+
|
2129 |
+
// Unfortunately, as of WordPress 2.3, wp_insert_post()
|
2130 |
+
// *still* offers no way to use a guid of your choice,
|
2131 |
+
// and munges your post modified timestamp, too.
|
2132 |
+
$result = $wpdb->query("
|
2133 |
+
UPDATE $wpdb->posts
|
2134 |
+
SET
|
2135 |
+
guid='{$dbpost['guid']}',
|
2136 |
+
post_modified='{$dbpost['post_modified']}',
|
2137 |
+
post_modified_gmt='{$dbpost['post_modified_gmt']}'
|
2138 |
+
WHERE ID='{$this->_wp_id}'
|
2139 |
+
");
|
2140 |
+
else :
|
2141 |
+
# The right way to do this is the above. But, alas,
|
2142 |
+
# in earlier versions of WordPress, wp_insert_post has
|
2143 |
+
# too much behavior (mainly related to pings) that can't
|
2144 |
+
# be overridden. In WordPress 1.5, it's enough of a
|
2145 |
+
# resource hog to make PHP segfault after inserting
|
2146 |
+
# 50-100 posts. This can get pretty annoying, especially
|
2147 |
+
# if you are trying to update your feeds for the first
|
2148 |
+
# time.
|
2149 |
+
|
2150 |
+
$result = $wpdb->query("
|
2151 |
+
INSERT INTO $wpdb->posts
|
2152 |
+
SET
|
2153 |
+
guid = '{$dbpost['guid']}',
|
2154 |
+
post_author = '{$dbpost['post_author']}',
|
2155 |
+
post_date = '{$dbpost['post_date']}',
|
2156 |
+
post_date_gmt = '{$dbpost['post_date_gmt']}',
|
2157 |
+
post_content = '{$dbpost['post_content']}',"
|
2158 |
+
.(isset($dbpost['post_excerpt']) ? "post_excerpt = '{$dbpost['post_excerpt']}'," : "")."
|
2159 |
+
post_title = '{$dbpost['post_title']}',
|
2160 |
+
post_name = '{$dbpost['post_name']}',
|
2161 |
+
post_modified = '{$dbpost['post_modified']}',
|
2162 |
+
post_modified_gmt = '{$dbpost['post_modified_gmt']}',
|
2163 |
+
comment_status = '{$dbpost['comment_status']}',
|
2164 |
+
ping_status = '{$dbpost['ping_status']}',
|
2165 |
+
post_status = '{$dbpost['post_status']}'
|
2166 |
+
");
|
2167 |
+
$this->_wp_id = $wpdb->insert_id;
|
2168 |
+
|
2169 |
+
// This should never happen.
|
2170 |
+
if (!is_numeric($this->_wp_id) or ($this->_wp_id == 0)) :
|
2171 |
+
FeedWordPress::critical_bug('SyndicatedPost::_wp_id', $this->_wp_id, __LINE__);
|
2172 |
+
endif;
|
2173 |
+
|
2174 |
+
// WordPress 1.5.x - 2.0.x
|
2175 |
+
wp_set_post_cats('1', $this->wp_id(), $this->post['post_category']);
|
2176 |
+
|
2177 |
+
// Since we are not going through official channels, we need to
|
2178 |
+
// manually tell WordPress that we've published a new post.
|
2179 |
+
// We need to make sure to do this in order for FeedWordPress
|
2180 |
+
// to play well with the staticize-reloaded plugin (something
|
2181 |
+
// that a large aggregator website is going to *want* to be
|
2182 |
+
// able to use).
|
2183 |
+
do_action('publish_post', $this->_wp_id);
|
2184 |
+
endif;
|
2185 |
+
} /* SyndicatedPost::insert_new() */
|
2186 |
|
2187 |
+
function update_existing () {
|
2188 |
global $wpdb;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2189 |
|
2190 |
+
// Why the fuck doesn't wp_insert_post already do this?
|
2191 |
+
$dbpost = array();
|
2192 |
+
foreach ($this->post as $key => $value) :
|
2193 |
+
if (is_string($value)) :
|
2194 |
+
$dbpost[$key] = $wpdb->escape($value);
|
2195 |
+
else :
|
2196 |
+
$dbpost[$key] = $value;
|
2197 |
+
endif;
|
2198 |
+
endforeach;
|
2199 |
+
|
2200 |
+
if ($this->use_api('wp_insert_post')) :
|
2201 |
+
$dbpost['post_pingback'] = false; // Tell WP 2.1 and 2.2 not to process for pingbacks
|
2202 |
+
$this->_wp_id = wp_insert_post($dbpost);
|
2203 |
+
|
2204 |
+
// This should never happen.
|
2205 |
+
if (!is_numeric($this->_wp_id) or ($this->_wp_id == 0)) :
|
2206 |
+
FeedWordPress::critical_bug('SyndicatedPost::_wp_id', $this->_wp_id, __LINE__);
|
2207 |
+
endif;
|
2208 |
|
2209 |
+
// Unfortunately, as of WordPress 2.3, wp_insert_post()
|
2210 |
+
// munges your post modified timestamp.
|
2211 |
+
$result = $wpdb->query("
|
2212 |
+
UPDATE $wpdb->posts
|
2213 |
+
SET
|
2214 |
+
post_modified='{$dbpost['post_modified']}',
|
2215 |
+
post_modified_gmt='{$dbpost['post_modified_gmt']}'
|
2216 |
+
WHERE ID='{$this->_wp_id}'
|
2217 |
+
");
|
2218 |
+
else :
|
2219 |
|
2220 |
+
$result = $wpdb->query("
|
2221 |
+
UPDATE $wpdb->posts
|
2222 |
+
SET
|
2223 |
+
post_author = '{$dbpost['post_author']}',
|
2224 |
+
post_content = '{$dbpost['post_content']}',"
|
2225 |
+
.(isset($dbpost['post_excerpt']) ? "post_excerpt = '{$dbpost['post_excerpt']}'," : "")."
|
2226 |
+
post_title = '{$dbpost['post_title']}',
|
2227 |
+
post_name = '{$dbpost['post_name']}',
|
2228 |
+
post_modified = '{$dbpost['post_modified']}',
|
2229 |
+
post_modified_gmt = '{$dbpost['post_modified_gmt']}'
|
2230 |
+
WHERE guid='{$dbpost['guid']}'
|
2231 |
+
");
|
2232 |
+
|
2233 |
+
// WordPress 2.1.x and up
|
2234 |
+
if (function_exists('wp_set_post_categories')) :
|
2235 |
+
wp_set_post_categories($this->wp_id(), $this->post['post_category']);
|
2236 |
+
// WordPress 1.5.x - 2.0.x
|
2237 |
+
elseif (function_exists('wp_set_post_cats')) :
|
2238 |
+
wp_set_post_cats('1', $this->wp_id(), $this->post['post_category']);
|
2239 |
+
// This should never happen.
|
2240 |
+
else :
|
2241 |
+
FeedWordPress::critical_bug('SyndicatedPost::insert_new::wp_version', $GLOBALS['wp_version'], __LINE__);
|
2242 |
+
endif;
|
2243 |
+
|
2244 |
+
// Since we are not going through official channels, we need to
|
2245 |
+
// manually tell WordPress that we've published a new post.
|
2246 |
+
// We need to make sure to do this in order for FeedWordPress
|
2247 |
+
// to play well with the staticize-reloaded plugin (something
|
2248 |
+
// that a large aggregator website is going to *want* to be
|
2249 |
+
// able to use).
|
2250 |
+
do_action('edit_post', $this->post['ID']);
|
2251 |
+
endif;
|
2252 |
+
} /* SyndicatedPost::update_existing() */
|
2253 |
+
|
2254 |
+
// SyndicatedPost::add_rss_meta: adds interesting meta-data to each entry
|
2255 |
// using the space for custom keys. The set of keys and values to add is
|
2256 |
// specified by the keys and values of $post['meta']. This is used to
|
2257 |
// store anything that the WordPress user might want to access from a
|
2260 |
// syndicated post other than author, title, timestamp, categories, and
|
2261 |
// guid). It's also used to hook into WordPress's support for
|
2262 |
// enclosures.
|
2263 |
+
function add_rss_meta () {
|
2264 |
+
global $wpdb;
|
2265 |
+
if ( is_array($this->post) and isset($this->post['meta']) and is_array($this->post['meta']) ) :
|
2266 |
+
$postId = $this->wp_id();
|
2267 |
+
|
2268 |
+
// Aggregated posts should NOT send out pingbacks.
|
2269 |
+
// WordPress 2.1-2.2 claim you can tell them not to
|
2270 |
+
// using $post_pingback, but they don't listen, so we
|
2271 |
+
// make sure here.
|
2272 |
+
$result = $wpdb->query("
|
2273 |
+
DELETE FROM $wpdb->postmeta
|
2274 |
+
WHERE post_id='$postId' AND meta_key='_pingme'
|
2275 |
+
");
|
2276 |
+
|
2277 |
+
foreach ( $this->post['meta'] as $key => $values ) :
|
2278 |
|
2279 |
$key = $wpdb->escape($key);
|
2280 |
|
2299 |
endforeach;
|
2300 |
endforeach;
|
2301 |
endif;
|
2302 |
+
} /* SyndicatedPost::add_rss_meta () */
|
2303 |
|
2304 |
+
// SyndicatedPost::author_id (): get the ID for an author name from
|
2305 |
// the feed. Create the author if necessary.
|
2306 |
+
function author_id ($unfamiliar_author = 'create') {
|
2307 |
+
global $wpdb, $wp_db_version; // test for WordPress 2.0 database schema
|
2308 |
+
|
2309 |
+
$a = $this->author();
|
2310 |
+
$author = $a['name'];
|
2311 |
+
$email = $a['email'];
|
2312 |
+
$url = $a['uri'];
|
2313 |
|
2314 |
// Never can be too careful...
|
2315 |
$nice_author = sanitize_title($author);
|
2336 |
(
|
2337 |
LOWER(user_description)
|
2338 |
RLIKE CONCAT(
|
2339 |
+
'(^|\\n)a\\.?k\\.?a\\.?( |\\t)*:?( |\\t)*',
|
2340 |
LCASE('$reg_author'),
|
2341 |
'( |\\t|\\r)*(\\n|\$)'
|
2342 |
)
|
2366 |
meta_key = 'description'
|
2367 |
AND LCASE(meta_value)
|
2368 |
RLIKE CONCAT(
|
2369 |
+
'(^|\\n)a\\.?k\\.?a\\.?( |\\t)*:?( |\\t)*',
|
2370 |
LCASE('$reg_author'),
|
2371 |
'( |\\t|\\r)*(\\n|\$)'
|
2372 |
)
|
2399 |
#-- user table data
|
2400 |
$userdata['ID'] = NULL; // new user
|
2401 |
$userdata['user_login'] = $author;
|
2402 |
+
$userdata['user_pass'] = substr(md5(uniqid(microtime())), 0, 6); // just something random to lock it up
|
2403 |
$userdata['user_email'] = $email;
|
2404 |
$userdata['user_url'] = $url;
|
2405 |
$userdata['display_name'] = $author;
|
2411 |
endif;
|
2412 |
endif;
|
2413 |
return $id;
|
2414 |
+
} // function SyndicatedPost::author_id ()
|
2415 |
|
2416 |
// look up (and create) category ids from a list of categories
|
2417 |
+
function category_ids ($cats, $unfamiliar_category = 'create') {
|
2418 |
+
global $wpdb;
|
2419 |
+
|
2420 |
+
// We need to normalize whitespace because (1) trailing
|
2421 |
+
// whitespace can cause PHP and MySQL not to see eye to eye on
|
2422 |
+
// VARCHAR comparisons for some versions of MySQL (cf.
|
2423 |
// <http://dev.mysql.com/doc/mysql/en/char.html>), and (2)
|
2424 |
// because I doubt most people want to make a semantic
|
2425 |
// distinction between 'Computers' and 'Computers '
|
2426 |
$cats = array_map('trim', $cats);
|
2427 |
|
2428 |
$cat_ids = array ();
|
2429 |
+
foreach ($cats as $cat_name) :
|
2430 |
+
if (preg_match('/{#([0-9]+)}/', $cat_name, $backref)) :
|
2431 |
+
$cat_id = (int) $backref[1];
|
2432 |
+
if (function_exists('is_term') and is_term($cat_id, 'category')) :
|
2433 |
+
$cat_ids[] = $cat_id;
|
2434 |
+
elseif (get_category($cat_id)) :
|
2435 |
+
$cat_ids[] = $cat_id;
|
2436 |
+
endif;
|
2437 |
+
else :
|
2438 |
+
$esc = $wpdb->escape($cat_name);
|
2439 |
+
$resc = $wpdb->escape(preg_quote($cat_name));
|
2440 |
+
|
2441 |
+
// WordPress 2.3+
|
2442 |
+
if (function_exists('is_term')) :
|
2443 |
+
$cat_id = is_term($cat_name, 'category');
|
2444 |
+
if ($cat_id) :
|
2445 |
+
$cat_ids[] = $cat_id['term_id'];
|
2446 |
+
// There must be a better way to do this...
|
2447 |
+
elseif ($results = $wpdb->get_results(
|
2448 |
+
"SELECT term_id
|
2449 |
+
FROM $wpdb->term_taxonomy
|
2450 |
+
WHERE
|
2451 |
+
LOWER(description) RLIKE
|
2452 |
+
CONCAT('(^|\\n)a\\.?k\\.?a\\.?( |\\t)*:?( |\\t)*', LOWER('{$resc}'), '( |\\t|\\r)*(\\n|\$)')"
|
2453 |
+
)) :
|
2454 |
+
foreach ($results AS $term) :
|
2455 |
+
$cat_ids[] = (int) $term->term_id;
|
2456 |
+
endforeach;
|
2457 |
+
elseif ('create'===$unfamiliar_category) :
|
2458 |
+
$term = wp_insert_term($cat_name, 'category');
|
2459 |
+
$cat_ids[] = $term['term_id'];
|
2460 |
+
endif;
|
2461 |
+
|
2462 |
+
// WordPress 1.5.x - 2.2.x
|
2463 |
+
else :
|
2464 |
+
$results = $wpdb->get_results(
|
2465 |
+
"SELECT cat_ID
|
2466 |
+
FROM $wpdb->categories
|
2467 |
+
WHERE
|
2468 |
+
(LOWER(cat_name) = LOWER('$esc'))
|
2469 |
+
OR (LOWER(category_description)
|
2470 |
+
RLIKE CONCAT('(^|\\n)a\\.?k\\.?a\\.?( |\\t)*:?( |\\t)*', LOWER('{$resc}'), '( |\\t|\\r)*(\\n|\$)'))
|
2471 |
+
");
|
2472 |
+
if ($results) :
|
2473 |
+
foreach ($results as $term) :
|
2474 |
+
$cat_ids[] = (int) $term->cat_ID;
|
2475 |
+
endforeach;
|
2476 |
+
elseif ('create'===$unfamiliar_category) :
|
2477 |
+
if (function_exists('wp_insert_category')) :
|
2478 |
+
$cat_id = wp_insert_category(array('cat_name' => $cat_name));
|
2479 |
+
// And into the database we go.
|
2480 |
+
else :
|
2481 |
+
$nice_kitty = sanitize_title($cat_name);
|
2482 |
+
$wpdb->query(sprintf("
|
2483 |
+
INSERT INTO $wpdb->categories
|
2484 |
+
SET
|
2485 |
+
cat_name='%s',
|
2486 |
+
category_nicename='%s'
|
2487 |
+
", $wpdb->escape($cat_name), $nice_kitty
|
2488 |
+
));
|
2489 |
+
$cat_id = $wpdb->insert_id;
|
2490 |
+
endif;
|
2491 |
+
$cat_ids[] = $cat_id;
|
2492 |
+
endif;
|
2493 |
+
endif;
|
2494 |
+
endif;
|
2495 |
+
endforeach;
|
2496 |
|
2497 |
+
if ((count($cat_ids) == 0) and ($unfamiliar_category === 'filter')) :
|
2498 |
+
$cat_ids = NULL; // Drop the post
|
2499 |
+
else :
|
2500 |
+
$cat_ids = array_unique($cat_ids);
|
2501 |
+
endif;
|
2502 |
+
return $cat_ids;
|
2503 |
+
} // function SyndicatedPost::category_ids ()
|
2504 |
+
|
2505 |
+
function use_api ($tag) {
|
2506 |
+
global $wp_db_version;
|
2507 |
+
if ('wp_insert_post'==$tag) :
|
2508 |
+
// Before 2.2, wp_insert_post does too much of the wrong stuff to use it
|
2509 |
+
// In 1.5 it was such a resource hog it would make PHP segfault on big updates
|
2510 |
+
$ret = (isset($wp_db_version) and $wp_db_version > FWP_SCHEMA_21);
|
2511 |
+
endif;
|
2512 |
+
return $ret;
|
2513 |
+
} // function SyndicatedPost::use_api ()
|
2514 |
+
|
2515 |
+
#### EXTRACT DATA FROM FEED ITEM ####
|
2516 |
+
|
2517 |
+
function created () {
|
2518 |
+
$epoch = null;
|
2519 |
+
if (isset($this->item['dc']['created'])) :
|
2520 |
+
$epoch = @parse_w3cdtf($this->item['dc']['created']);
|
2521 |
+
elseif (isset($this->item['dcterms']['created'])) :
|
2522 |
+
$epoch = @parse_w3cdtf($this->item['dcterms']['created']);
|
2523 |
+
elseif (isset($this->item['created'])): // Atom 0.3
|
2524 |
+
$epoch = @parse_w3cdtf($this->item['created']);
|
2525 |
+
endif;
|
2526 |
+
return $epoch;
|
2527 |
+
}
|
2528 |
+
function published ($fallback = true) {
|
2529 |
+
$epoch = null;
|
2530 |
+
|
2531 |
+
# RSS is a fucking mess. Figure out whether we have a date in
|
2532 |
+
# <dc:date>, <issued>, <pubDate>, etc., and get it into Unix
|
2533 |
+
# epoch format for reformatting. If we can't find anything,
|
2534 |
+
# we'll use the last-updated time.
|
2535 |
+
if (isset($this->item['dc']['date'])): // Dublin Core
|
2536 |
+
$epoch = @parse_w3cdtf($this->item['dc']['date']);
|
2537 |
+
elseif (isset($this->item['dcterms']['issued'])) : // Dublin Core extensions
|
2538 |
+
$epoch = @parse_w3cdtf($this->item['dcterms']['issued']);
|
2539 |
+
elseif (isset($this->item['published'])) : // Atom 1.0
|
2540 |
+
$epoch = @parse_w3cdtf($this->item['published']);
|
2541 |
+
elseif (isset($this->item['issued'])): // Atom 0.3
|
2542 |
+
$epoch = @parse_w3cdtf($this->item['issued']);
|
2543 |
+
elseif (isset($this->item['pubdate'])): // RSS 2.0
|
2544 |
+
$epoch = strtotime($this->item['pubdate']);
|
2545 |
+
elseif ($fallback) : // Fall back to <updated> / <modified> if present
|
2546 |
+
$epoch = $this->updated(/*fallback=*/ false);
|
2547 |
+
endif;
|
2548 |
+
|
2549 |
+
# If everything failed, then default to the current time.
|
2550 |
+
if (is_null($epoch)) :
|
2551 |
+
$epoch = time();
|
2552 |
+
endif;
|
2553 |
+
|
2554 |
+
return $epoch;
|
2555 |
+
}
|
2556 |
+
function updated ($fallback = true) {
|
2557 |
+
$epoch = null;
|
2558 |
+
|
2559 |
+
# As far as I know, only dcterms and Atom have reliable ways to
|
2560 |
+
# specify when something was *modified* last. If neither is
|
2561 |
+
# available, then we'll try to get the time of publication.
|
2562 |
+
if (isset($this->item['dc']['modified'])) : // Not really correct
|
2563 |
+
$epoch = @parse_w3cdtf($this->item['dc']['modified']);
|
2564 |
+
elseif (isset($this->item['dcterms']['modified'])) : // Dublin Core extensions
|
2565 |
+
$epoch = @parse_w3cdtf($this->item['dcterms']['modified']);
|
2566 |
+
elseif (isset($this->item['modified'])): // Atom 0.3
|
2567 |
+
$epoch = @parse_w3cdtf($this->item['modified']);
|
2568 |
+
elseif (isset($this->item['updated'])): // Atom 1.0
|
2569 |
+
$epoch = @parse_w3cdtf($this->item['updated']);
|
2570 |
+
elseif ($fallback) : // Fall back to issued / dc:date
|
2571 |
+
$epoch = $this->published(/*fallback=*/ false);
|
2572 |
+
endif;
|
2573 |
+
|
2574 |
+
# If everything failed, then default to the current time.
|
2575 |
+
if (is_null($epoch)) :
|
2576 |
+
$epoch = time();
|
2577 |
+
endif;
|
2578 |
|
2579 |
+
return $epoch;
|
2580 |
+
}
|
2581 |
|
2582 |
+
function guid () {
|
2583 |
+
$guid = null;
|
2584 |
+
if (isset($this->item['id'])): // Atom 0.3 / 1.0
|
2585 |
+
$guid = $this->item['id'];
|
2586 |
+
elseif (isset($this->item['atom']['id'])) : // Namespaced Atom
|
2587 |
+
$guid = $this->item['atom']['id'];
|
2588 |
+
elseif (isset($this->item['guid'])) : // RSS 2.0
|
2589 |
+
$guid = $this->item['guid'];
|
2590 |
+
elseif (isset($this->item['dc']['identifier'])) :// yeah, right
|
2591 |
+
$guid = $this->item['dc']['identifier'];
|
2592 |
+
else :
|
2593 |
+
// The feed does not seem to have provided us with a
|
2594 |
+
// unique identifier, so we'll have to cobble together
|
2595 |
+
// a tag: URI that might work for us. The base of the
|
2596 |
+
// URI will be the host name of the feed source ...
|
2597 |
+
$bits = parse_url($this->feedmeta['link/uri']);
|
2598 |
+
$guid = 'tag:'.$bits['host'];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2599 |
|
2600 |
+
// If we have a date of creation, then we can use that
|
2601 |
+
// to uniquely identify the item. (On the other hand, if
|
2602 |
+
// the feed producer was consicentious enough to
|
2603 |
+
// generate dates of creation, she probably also was
|
2604 |
+
// conscientious enough to generate unique identifiers.)
|
2605 |
+
if (!is_null($this->created())) :
|
2606 |
+
$guid .= '://post.'.date('YmdHis', $this->created());
|
|
|
|
|
|
|
|
|
|
|
2607 |
|
2608 |
+
// Otherwise, use both the URI of the item, *and* the
|
2609 |
+
// item's title. We have to use both because titles are
|
2610 |
+
// often not unique, and sometimes links aren't unique
|
2611 |
+
// either (e.g. Bitch (S)HITLIST, Mozilla Dot Org news,
|
2612 |
+
// some podcasts). But it's rare to have *both* the same
|
2613 |
+
// title *and* the same link for two different items. So
|
2614 |
+
// this is about the best we can do.
|
2615 |
+
else :
|
2616 |
+
$guid .= '://'.md5($this->item['link'].'/'.$this->item['title']);
|
2617 |
endif;
|
2618 |
endif;
|
2619 |
+
return $guid;
|
2620 |
+
}
|
2621 |
|
2622 |
+
function author () {
|
2623 |
+
$author = array ();
|
2624 |
+
|
2625 |
+
if (isset($this->item['author_name'])):
|
2626 |
+
$author['name'] = $this->item['author_name'];
|
2627 |
+
elseif (isset($this->item['dc']['creator'])):
|
2628 |
+
$author['name'] = $this->item['dc']['creator'];
|
2629 |
+
elseif (isset($this->item['dc']['contributor'])):
|
2630 |
+
$author['name'] = $this->item['dc']['contributor'];
|
2631 |
+
elseif (isset($this->feed->channel['dc']['creator'])) :
|
2632 |
+
$author['name'] = $this->feed->channel['dc']['creator'];
|
2633 |
+
elseif (isset($this->feed->channel['dc']['contributor'])) :
|
2634 |
+
$author['name'] = $this->feed->channel['dc']['contributor'];
|
2635 |
+
elseif (isset($this->feed->channel['author_name'])) :
|
2636 |
+
$author['name'] = $this->feed->channel['author_name'];
|
2637 |
+
elseif ($this->feed->is_rss() and isset($this->item['author'])) :
|
2638 |
+
// The author element in RSS is allegedly an
|
2639 |
+
// e-mail address, but lots of people don't use
|
2640 |
+
// it that way. So let's make of it what we can.
|
2641 |
+
$author = parse_email_with_realname($this->item['author']);
|
2642 |
+
|
2643 |
+
if (!isset($author['name'])) :
|
2644 |
+
if (isset($author['email'])) :
|
2645 |
+
$author['name'] = $author['email'];
|
2646 |
+
else :
|
2647 |
+
$author['name'] = $this->feed->channel['title'];
|
2648 |
+
endif;
|
2649 |
endif;
|
2650 |
+
else :
|
2651 |
+
$author['name'] = $this->feed->channel['title'];
|
2652 |
+
endif;
|
2653 |
+
|
2654 |
+
if (isset($this->item['author_email'])):
|
2655 |
+
$author['email'] = $this->item['author_email'];
|
2656 |
+
elseif (isset($this->feed->channel['author_email'])) :
|
2657 |
+
$author['email'] = $this->feed->channel['author_email'];
|
2658 |
+
endif;
|
2659 |
+
|
2660 |
+
if (isset($this->item['author_url'])):
|
2661 |
+
$author['uri'] = $this->item['author_url'];
|
2662 |
+
elseif (isset($this->feed->channel['author_url'])) :
|
2663 |
+
$author['uri'] = $this->item['author_url'];
|
2664 |
+
else:
|
2665 |
+
$author['uri'] = $this->feed->channel['link'];
|
2666 |
endif;
|
2667 |
|
2668 |
+
return $author;
|
2669 |
+
} // SyndicatedPost::author()
|
2670 |
+
} // class SyndicatedPost
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2671 |
|
2672 |
+
# class SyndicatedLink: represents a syndication feed stored within the
|
2673 |
+
# WordPress database
|
2674 |
+
#
|
2675 |
+
# To keep things compact and editable from within WordPress, we use all the
|
2676 |
+
# links under a particular category in the WordPress "Blogroll" for the list of
|
2677 |
+
# feeds to syndicate. "Contributors" is the category used by default; you can
|
2678 |
+
# configure that under Options --> Syndication.
|
2679 |
+
#
|
2680 |
+
# Fields used are:
|
2681 |
+
#
|
2682 |
+
# * link_rss: the URI of the Atom/RSS feed to syndicate
|
2683 |
+
#
|
2684 |
+
# * link_notes: user-configurable options, with keys and values
|
2685 |
+
# like so:
|
2686 |
+
#
|
2687 |
+
# key: value
|
2688 |
+
# cats: computers\nweb
|
2689 |
+
# feed/key: value
|
2690 |
+
#
|
2691 |
+
# Keys that start with "feed/" are gleaned from the data supplied
|
2692 |
+
# by the feed itself, and will be overwritten with each update.
|
2693 |
+
#
|
2694 |
+
# Values have linebreak characters escaped with C-style
|
2695 |
+
# backslashes (so, for example, a newline becomes "\n").
|
2696 |
+
#
|
2697 |
+
# The value of `cats` is used as a newline-separated list of
|
2698 |
+
# default categories for any post coming from a particular feed.
|
2699 |
+
# (In the example above, any posts from this feed will be placed
|
2700 |
+
# in the "computers" and "web" categories--*in addition to* any
|
2701 |
+
# categories that may already be applied to the posts.)
|
2702 |
+
#
|
2703 |
+
# Values of keys in link_notes are accessible from templates using
|
2704 |
+
# the function `get_feed_meta($key)` if this plugin is activated.
|
2705 |
|
2706 |
+
class SyndicatedLink {
|
2707 |
+
var $id = null;
|
2708 |
+
var $link = null;
|
2709 |
+
var $settings = array ();
|
2710 |
+
var $magpie = null;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2711 |
|
2712 |
+
function SyndicatedLink ($link) {
|
2713 |
+
global $wpdb;
|
2714 |
|
2715 |
+
if (is_object($link)) :
|
2716 |
+
$this->link = $link;
|
2717 |
+
$this->id = $link->link_id;
|
2718 |
+
else :
|
2719 |
+
$this->id = $link;
|
2720 |
+
if (function_exists('get_bookmark')) : // WP 2.1+
|
2721 |
+
$this->link = get_bookmark($link);
|
2722 |
+
else :
|
2723 |
+
$this->link = $wpdb->get_row("
|
2724 |
+
SELECT * FROM $wpdb->links
|
2725 |
+
WHERE (link_id = '".$wpdb->escape($link)."')"
|
2726 |
+
);
|
2727 |
+
endif;
|
2728 |
+
endif;
|
|
|
|
|
|
|
|
|
2729 |
|
2730 |
+
if (strlen($this->link->link_rss) > 0) :
|
2731 |
+
// Read off feed settings from link_notes
|
2732 |
+
$notes = explode("\n", $this->link->link_notes);
|
2733 |
+
foreach ($notes as $note):
|
2734 |
+
list($key, $value) = explode(": ", $note, 2);
|
2735 |
+
|
2736 |
+
if (strlen($key) > 0) :
|
2737 |
+
// Unescape and trim() off the whitespace.
|
2738 |
+
// Thanks to Ray Lischner for pointing out the
|
2739 |
+
// need to trim off whitespace.
|
2740 |
+
$this->settings[$key] = stripcslashes (trim($value));
|
2741 |
+
endif;
|
2742 |
+
endforeach;
|
2743 |
|
2744 |
+
// "Magic" feed settings
|
2745 |
+
$this->settings['link/uri'] = $this->link->link_rss;
|
2746 |
+
$this->settings['link/name'] = $this->link->link_name;
|
2747 |
+
$this->settings['link/id'] = $this->link->link_id;
|
|
|
2748 |
|
2749 |
+
// `hardcode categories` is deprecated in favor of `unfamiliar categories`
|
2750 |
+
if (
|
2751 |
+
FeedWordPress::affirmative($this->settings, 'hardcode categories')
|
2752 |
+
and !isset($this->settings['unfamiliar categories'])
|
2753 |
+
) :
|
2754 |
+
$this->settings['unfamiliar categories'] = 'default';
|
2755 |
+
endif;
|
2756 |
+
|
2757 |
+
// Set this up automagically for del.icio.us
|
2758 |
+
if (!isset($this->settings['cat_split']) and false !== strpos($this->link->link_rss, 'del.icio.us')) :
|
2759 |
+
$this->settings['cat_split'] = '\s'; // Whitespace separates multiple tags in del.icio.us RSS feeds
|
2760 |
+
endif;
|
2761 |
|
2762 |
+
if (isset($this->settings['cats'])):
|
2763 |
+
$this->settings['cats'] = preg_split(FEEDWORDPRESS_CAT_SEPARATOR_PATTERN, $this->settings['cats']);
|
2764 |
+
endif;
|
2765 |
+
endif;
|
2766 |
+
} // SyndicatedLink::SyndicatedLink ()
|
2767 |
+
|
2768 |
+
function found () {
|
2769 |
+
return is_object($this->link);
|
2770 |
+
}
|
2771 |
|
2772 |
+
function stale () {
|
2773 |
+
$stale = true;
|
2774 |
+
if (isset($this->settings['update/hold']) and ($this->settings['update/hold']=='ping')) :
|
2775 |
+
$stale = false; // don't update on any timed updates; pings only
|
2776 |
+
elseif (isset($this->settings['update/hold']) and ($this->settings['update/hold']=='next')) :
|
2777 |
+
$stale = true; // update on the next timed update
|
2778 |
+
elseif (!isset($this->settings['update/ttl']) or !isset($this->settings['update/last'])) :
|
2779 |
+
$stale = true; // initial update
|
2780 |
+
else :
|
2781 |
+
$after = ((int) $this->settings['update/last'])
|
2782 |
+
+((int) $this->settings['update/ttl'] * 60);
|
2783 |
+
$stale = (time() >= $after);
|
2784 |
+
endif;
|
2785 |
+
return $stale;
|
2786 |
}
|
2787 |
|
2788 |
+
function poll () {
|
2789 |
+
global $wpdb;
|
2790 |
|
2791 |
+
$this->magpie = fetch_rss($this->link->link_rss);
|
2792 |
+
$new_count = NULL;
|
2793 |
|
2794 |
+
if (is_object($this->magpie)) :
|
2795 |
+
$new_count = array('new' => 0, 'updated' => 0);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2796 |
|
2797 |
+
# -- Update Link metadata live from feed
|
2798 |
+
$channel = $this->magpie->channel;
|
2799 |
+
|
2800 |
+
if (!isset($channel['id'])) :
|
2801 |
+
$channel['id'] = $this->link->link_rss;
|
2802 |
+
endif;
|
2803 |
+
|
2804 |
+
$update = array();
|
2805 |
+
if (!$this->hardcode('url') and isset($channel['link'])) :
|
2806 |
+
$update[] = "link_url = '".$wpdb->escape($channel['link'])."'";
|
2807 |
+
endif;
|
2808 |
+
|
2809 |
+
if (!$this->hardcode('name') and isset($channel['title'])) :
|
2810 |
+
$update[] = "link_name = '".$wpdb->escape($channel['title'])."'";
|
2811 |
+
endif;
|
2812 |
+
|
2813 |
+
if (!$this->hardcode('description')) :
|
2814 |
+
if (isset($channel['tagline'])) :
|
2815 |
+
$update[] = "link_description = '".$wpdb->escape($channel['tagline'])."'";
|
2816 |
+
elseif (isset($channel['description'])) :
|
2817 |
+
$update[] = "link_description = '".$wpdb->escape($channel['description'])."'";
|
2818 |
+
endif;
|
2819 |
+
endif;
|
2820 |
+
|
2821 |
+
$this->settings = array_merge($this->settings, $this->flatten_array($channel));
|
2822 |
+
|
2823 |
+
$this->settings['update/last'] = time(); $ttl = $this->ttl();
|
2824 |
+
if (!is_null($ttl)) :
|
2825 |
+
$this->settings['update/ttl'] = $ttl;
|
2826 |
+
$this->settings['update/timed'] = 'feed';
|
2827 |
else :
|
2828 |
+
$this->settings['update/ttl'] = rand(30, 120); // spread over time interval for staggered updates
|
2829 |
+
$this->settings['update/timed'] = 'automatically';
|
2830 |
+
endif;
|
2831 |
+
|
2832 |
+
if (!isset($this->settings['update/hold']) or $this->settings['update/hold']!='ping') :
|
2833 |
+
$this->settings['update/hold'] = 'scheduled';
|
2834 |
+
endif;
|
2835 |
+
|
2836 |
+
// Copy back without a few things that we don't want to save in the notes
|
2837 |
+
$to_notes = $this->settings;
|
2838 |
+
|
2839 |
+
if (is_array($to_notes['cats'])) :
|
2840 |
+
$to_notes['cats'] = implode(FEEDWORDPRESS_CAT_SEPARATOR, $to_notes['cats']);
|
2841 |
+
endif;
|
2842 |
+
unset($to_notes['link/id']); unset($to_notes['link/uri']);
|
2843 |
+
unset($to_notes['link/name']);
|
2844 |
+
unset($to_notes['hardcode categories']); // Deprecated
|
2845 |
+
|
2846 |
+
$notes = '';
|
2847 |
+
foreach ($to_notes as $key => $value) :
|
2848 |
+
$notes .= $key . ": ". addcslashes($value, "\0..\37".'\\') . "\n";
|
2849 |
+
endforeach;
|
2850 |
+
$update[] = "link_notes = '".$wpdb->escape($notes)."'";
|
2851 |
+
|
2852 |
+
$update_set = implode(',', $update);
|
2853 |
+
|
2854 |
+
// Update the properties of the link from the feed information
|
2855 |
+
$result = $wpdb->query("
|
2856 |
+
UPDATE $wpdb->links
|
2857 |
+
SET $update_set
|
2858 |
+
WHERE link_id='$this->id'
|
2859 |
+
");
|
2860 |
+
|
2861 |
+
# -- Add new posts from feed and update any updated posts
|
2862 |
+
if (is_array($this->magpie->items)) :
|
2863 |
+
foreach ($this->magpie->items as $item) :
|
2864 |
+
$post =& new SyndicatedPost($item, $this);
|
2865 |
+
if (!$post->filtered()) :
|
2866 |
+
$new = $post->store();
|
2867 |
+
if ( $new !== false ) $new_count[$new]++;
|
2868 |
endif;
|
2869 |
+
endforeach;
|
2870 |
endif;
|
2871 |
endif;
|
2872 |
+
return $new_count;
|
2873 |
+
} /* SyndicatedLink::poll() */
|
2874 |
+
|
2875 |
+
function uri () {
|
2876 |
+
return (is_object($this->link) ? $this->link->link_rss : NULL);
|
2877 |
+
}
|
2878 |
+
function homepage () {
|
2879 |
+
return (isset($this->settings['feed/link']) ? $this->settings['feed/link'] : NULL);
|
2880 |
}
|
2881 |
|
2882 |
+
function ttl () {
|
2883 |
+
if (is_object($this->magpie)) :
|
2884 |
+
$channel = $this->magpie->channel;
|
2885 |
+
else :
|
2886 |
+
$channel = array();
|
2887 |
+
endif;
|
2888 |
|
2889 |
+
if (isset($channel['ttl'])) :
|
2890 |
+
// "ttl stands for time to live. It's a number of
|
2891 |
+
// minutes that indicates how long a channel can be
|
2892 |
+
// cached before refreshing from the source."
|
2893 |
+
// <http://blogs.law.harvard.edu/tech/rss#ltttlgtSubelementOfLtchannelgt>
|
2894 |
+
$ret = $channel['ttl'];
|
2895 |
+
elseif (isset($channel['sy']['updatefrequency']) or isset($channel['sy']['updateperiod'])) :
|
2896 |
+
$period_minutes = array (
|
2897 |
+
'hourly' => 60, /* minutes in an hour */
|
2898 |
+
'daily' => 1440, /* minutes in a day */
|
2899 |
+
'weekly' => 10080, /* minutes in a week */
|
2900 |
+
'monthly' => 43200, /* minutes in a month */
|
2901 |
+
'yearly' => 525600, /* minutes in a year */
|
2902 |
+
);
|
2903 |
|
2904 |
+
// "sy:updatePeriod: Describes the period over which the
|
2905 |
+
// channel format is updated. Acceptable values are:
|
2906 |
+
// hourly, daily, weekly, monthly, yearly. If omitted,
|
2907 |
+
// daily is assumed." <http://web.resource.org/rss/1.0/modules/syndication/>
|
2908 |
+
if (isset($channel['sy']['updateperiod'])) : $period = $channel['sy']['updateperiod'];
|
2909 |
+
else : $period = 'daily';
|
2910 |
+
endif;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2911 |
|
2912 |
+
// "sy:updateFrequency: Used to describe the frequency
|
2913 |
+
// of updates in relation to the update period. A
|
2914 |
+
// positive integer indicates how many times in that
|
2915 |
+
// period the channel is updated. ... If omitted a value
|
2916 |
+
// of 1 is assumed." <http://web.resource.org/rss/1.0/modules/syndication/>
|
2917 |
+
if (isset($channel['sy']['updatefrequency'])) : $freq = (int) $channel['sy']['updatefrequency'];
|
2918 |
+
else : $freq = 1;
|
2919 |
+
endif;
|
2920 |
|
2921 |
+
$ret = (int) ($period_minutes[$period] / $freq);
|
2922 |
+
else :
|
2923 |
+
$ret = NULL;
|
2924 |
+
endif;
|
2925 |
+
return $ret;
|
2926 |
+
} /* SyndicatedLink::ttl() */
|
2927 |
+
|
2928 |
+
// SyndicatedLink:flatten_array (): flatten an array. Useful for
|
2929 |
+
// hierarchical and namespaced elements.
|
2930 |
+
//
|
2931 |
+
// Given an array which may contain array or object elements in it,
|
2932 |
+
// return a "flattened" array: a one-dimensional array of scalars
|
2933 |
+
// containing each of the scalar elements contained within the array
|
2934 |
+
// structure. Thus, for example, if $a['b']['c']['d'] == 'e', then the
|
2935 |
+
// returned array for FeedWordPress::flatten_array($a) will contain a key
|
2936 |
+
// $a['feed/b/c/d'] with value 'e'.
|
2937 |
+
function flatten_array ($arr, $prefix = 'feed/', $separator = '/') {
|
2938 |
+
$ret = array ();
|
2939 |
+
if (is_array($arr)) :
|
2940 |
+
foreach ($arr as $key => $value) :
|
2941 |
+
if (is_scalar($value)) :
|
2942 |
+
$ret[$prefix.$key] = $value;
|
2943 |
+
else :
|
2944 |
+
$ret = array_merge($ret, $this->flatten_array($value, $prefix.$key.$separator, $separator));
|
2945 |
endif;
|
|
|
2946 |
endforeach;
|
2947 |
+
endif;
|
2948 |
+
return $ret;
|
2949 |
+
} // function SyndicatedLink::flatten_array ()
|
2950 |
|
2951 |
+
function hardcode ($what) {
|
2952 |
+
$default = get_option("feedwordpress_hardcode_$what");
|
2953 |
+
if ( $default === 'yes' ) :
|
2954 |
+
// If the default is to hardcode, then we want the
|
2955 |
+
// negation of negative(): TRUE by default and FALSE if
|
2956 |
+
// the setting is explicitly "no"
|
2957 |
+
$ret = !FeedWordPress::negative($this->settings, "hardcode $what");
|
2958 |
+
else :
|
2959 |
+
// If the default is NOT to hardcode, then we want
|
2960 |
+
// affirmative(): FALSE by default and TRUE if the
|
2961 |
+
// setting is explicitly "yes"
|
2962 |
+
$ret = FeedWordPress::affirmative($this->settings, "hardcode $what");
|
2963 |
+
endif;
|
2964 |
+
return $ret;
|
2965 |
+
} // function SyndicatedLink::hardcode ()
|
2966 |
|
2967 |
+
function syndicated_status ($what, $default) {
|
2968 |
+
global $wpdb;
|
2969 |
+
|
2970 |
+
$ret = get_option("feedwordpress_syndicated_{$what}_status");
|
2971 |
+
if ( isset($this->settings["$what status"]) ) :
|
2972 |
+
$ret = $this->settings["$what status"];
|
2973 |
+
elseif (!$ret) :
|
2974 |
+
$ret = $default;
|
2975 |
+
endif;
|
2976 |
+
return $wpdb->escape(trim(strtolower($ret)));
|
2977 |
+
} // function SyndicatedLink:syndicated_status ()
|
2978 |
+
} // class SyndicatedLink
|
2979 |
|
2980 |
################################################################################
|
2981 |
## XML-RPC HOOKS: accept XML-RPC update pings from Contributors ################
|
3037 |
$ret = array($this->uri);
|
3038 |
} else {
|
3039 |
// Assume that we have HTML or XHTML (even if we don't, who's it gonna hurt?)
|
|
|
3040 |
// Autodiscovery is the preferred method
|
3041 |
$href = $this->_link_rel_feeds();
|
3042 |
|
3069 |
|
3070 |
function is_feed ($uri = NULL) {
|
3071 |
$data = $this->data($uri);
|
3072 |
+
|
3073 |
return (
|
3074 |
preg_match (
|
3075 |
"\007(".implode('|',$this->_feed_markers).")\007i",
|
3118 |
} /* if */
|
3119 |
} /* if */
|
3120 |
} /* for */
|
3121 |
+
return $href;
|
3122 |
}
|
3123 |
|
3124 |
function _a_href_feeds ($obvious = TRUE) {
|
3143 |
// search through the HTML, save all <link> tags
|
3144 |
// and store each link's attributes in an associative array
|
3145 |
preg_match_all('/<'.$tag.'\s+(.*?)\s*\/?>/si', $html, $matches);
|
|
|
3146 |
$links = $matches[1];
|
3147 |
$ret = array();
|
3148 |
$link_count = count($links);
|
3168 |
# for FeedWordPress's purposes. The class has been stripped down to a single
|
3169 |
# public method: Relative_URI::resolve($url, $base), which resolves the URI in
|
3170 |
# $url relative to the URI in $base
|
3171 |
+
#
|
3172 |
+
# The upgraded MagpieRSS also uses this class. So if we have it loaded
|
3173 |
+
# in, don't load it again.
|
3174 |
+
if (!class_exists('Relative_URI')) {
|
3175 |
|
3176 |
+
class Relative_URI
|
|
|
|
|
|
|
|
|
|
|
|
|
3177 |
{
|
3178 |
+
// Resolve relative URI in $url against the base URI in $base. If $base
|
3179 |
+
// is not supplied, then we use the REQUEST_URI of this script.
|
3180 |
+
//
|
3181 |
+
// I'm hoping this method reflects RFC 2396 Section 5.2
|
3182 |
+
function resolve ($url, $base = NULL)
|
3183 |
+
{
|
3184 |
+
if (is_null($base)):
|
3185 |
+
$base = 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
|
3186 |
+
endif;
|
3187 |
+
|
3188 |
+
$base = Relative_URI::_encode(trim($base));
|
3189 |
+
$uri_parts = Relative_URI::_parse_url($base);
|
3190 |
+
|
3191 |
+
$url = Relative_URI::_encode(trim($url));
|
3192 |
+
$parts = Relative_URI::_parse_url($url);
|
3193 |
+
|
3194 |
+
$uri_parts['fragment'] = (isset($parts['fragment']) ? $parts['fragment'] : null);
|
3195 |
+
$uri_parts['query'] = (isset($parts['query']) ? $parts['query'] : null);
|
3196 |
+
|
3197 |
+
// if path is empty, and scheme, host, and query are undefined,
|
3198 |
+
// the URL is referring the base URL
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3199 |
|
3200 |
+
if (($parts['path'] == '') && !isset($parts['scheme']) && !isset($parts['host']) && !isset($parts['query'])) {
|
3201 |
+
// If the URI is empty or only a fragment, return the base URI
|
3202 |
+
return $base . (isset($parts['fragment']) ? '#'.$parts['fragment'] : '');
|
3203 |
+
} elseif (isset($parts['scheme'])) {
|
3204 |
+
// If the scheme is set, then the URI is absolute.
|
3205 |
+
return $url;
|
3206 |
+
} elseif (isset($parts['host'])) {
|
3207 |
+
$uri_parts['host'] = $parts['host'];
|
3208 |
$uri_parts['path'] = $parts['path'];
|
3209 |
} else {
|
3210 |
+
// We have a relative path but not a host.
|
3211 |
+
|
3212 |
+
// start ugly fix:
|
3213 |
+
// prepend slash to path if base host is set, base path is not set, and url path is not absolute
|
3214 |
+
if ($uri_parts['host'] && ($uri_parts['path'] == '')
|
3215 |
+
&& (strlen($parts['path']) > 0)
|
3216 |
+
&& (substr($parts['path'], 0, 1) != '/')) {
|
3217 |
+
$parts['path'] = '/'.$parts['path'];
|
3218 |
+
} // end ugly fix
|
3219 |
+
|
3220 |
+
if (substr($parts['path'], 0, 1) == '/') {
|
3221 |
+
$uri_parts['path'] = $parts['path'];
|
3222 |
+
} else {
|
3223 |
+
// copy base path excluding any characters after the last (right-most) slash character
|
3224 |
+
$buffer = substr($uri_parts['path'], 0, (int)strrpos($uri_parts['path'], '/')+1);
|
3225 |
+
// append relative path
|
3226 |
+
$buffer .= $parts['path'];
|
3227 |
+
// remove "./" where "." is a complete path segment.
|
3228 |
+
$buffer = str_replace('/./', '/', $buffer);
|
3229 |
+
if (substr($buffer, 0, 2) == './') {
|
3230 |
+
$buffer = substr($buffer, 2);
|
3231 |
+
}
|
3232 |
+
// if buffer ends with "." as a complete path segment, remove it
|
3233 |
+
if (substr($buffer, -2) == '/.') {
|
3234 |
+
$buffer = substr($buffer, 0, -1);
|
3235 |
+
}
|
3236 |
+
// remove "<segment>/../" where <segment> is a complete path segment not equal to ".."
|
3237 |
+
$search_finished = false;
|
3238 |
+
$segment = explode('/', $buffer);
|
3239 |
+
while (!$search_finished) {
|
3240 |
+
for ($x=0; $x+1 < count($segment);) {
|
3241 |
+
if (($segment[$x] != '') && ($segment[$x] != '..') && ($segment[$x+1] == '..')) {
|
3242 |
+
if ($x+2 == count($segment)) $segment[] = '';
|
3243 |
+
unset($segment[$x], $segment[$x+1]);
|
3244 |
+
$segment = array_values($segment);
|
3245 |
+
continue 2;
|
3246 |
+
} else {
|
3247 |
+
$x++;
|
3248 |
+
}
|
3249 |
+
}
|
3250 |
+
$search_finished = true;
|
3251 |
}
|
3252 |
+
$buffer = (count($segment) == 1) ? '/' : implode('/', $segment);
|
3253 |
+
$uri_parts['path'] = $buffer;
|
3254 |
+
|
3255 |
}
|
|
|
|
|
|
|
3256 |
}
|
3257 |
+
|
3258 |
+
// If we've gotten to this point, we can try to put the pieces
|
3259 |
+
// back together.
|
3260 |
+
$ret = '';
|
3261 |
+
if (isset($uri_parts['scheme'])) $ret .= $uri_parts['scheme'].':';
|
3262 |
+
if (isset($uri_parts['user'])) {
|
3263 |
+
$ret .= $uri_parts['user'];
|
3264 |
+
if (isset($uri_parts['pass'])) $ret .= ':'.$uri_parts['parts'];
|
3265 |
+
$ret .= '@';
|
3266 |
+
}
|
3267 |
+
if (isset($uri_parts['host'])) {
|
3268 |
+
$ret .= '//'.$uri_parts['host'];
|
3269 |
+
if (isset($uri_parts['port'])) $ret .= ':'.$uri_parts['port'];
|
3270 |
+
}
|
3271 |
+
$ret .= $uri_parts['path'];
|
3272 |
+
if (isset($uri_parts['query'])) $ret .= '?'.$uri_parts['query'];
|
3273 |
+
if (isset($uri_parts['fragment'])) $ret .= '#'.$uri_parts['fragment'];
|
3274 |
+
|
3275 |
+
return $ret;
|
3276 |
+
}
|
3277 |
+
|
3278 |
+
/**
|
3279 |
+
* Parse URL
|
3280 |
+
*
|
3281 |
+
* Regular expression grabbed from RFC 2396 Appendix B.
|
3282 |
+
* This is a replacement for PHPs builtin parse_url().
|
3283 |
+
* @param string $url
|
3284 |
+
* @access private
|
3285 |
+
* @return array
|
3286 |
+
*/
|
3287 |
+
function _parse_url($url)
|
3288 |
+
{
|
3289 |
+
// I'm using this pattern instead of parse_url() as there's a few strings where parse_url()
|
3290 |
+
// generates a warning.
|
3291 |
+
if (preg_match('!^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?!', $url, $match)) {
|
3292 |
+
$parts = array();
|
3293 |
+
if ($match[1] != '') $parts['scheme'] = $match[2];
|
3294 |
+
if ($match[3] != '') $parts['auth'] = $match[4];
|
3295 |
+
// parse auth
|
3296 |
+
if (isset($parts['auth'])) {
|
3297 |
+
// store user info
|
3298 |
+
if (($at_pos = strpos($parts['auth'], '@')) !== false) {
|
3299 |
+
$userinfo = explode(':', substr($parts['auth'], 0, $at_pos), 2);
|
3300 |
+
$parts['user'] = $userinfo[0];
|
3301 |
+
if (isset($userinfo[1])) $parts['pass'] = $userinfo[1];
|
3302 |
+
$parts['auth'] = substr($parts['auth'], $at_pos+1);
|
3303 |
+
}
|
3304 |
+
// get port number
|
3305 |
+
if ($port_pos = strrpos($parts['auth'], ':')) {
|
3306 |
+
$parts['host'] = substr($parts['auth'], 0, $port_pos);
|
3307 |
+
$parts['port'] = (int)substr($parts['auth'], $port_pos+1);
|
3308 |
+
if ($parts['port'] < 1) $parts['port'] = null;
|
3309 |
+
} else {
|
3310 |
+
$parts['host'] = $parts['auth'];
|
3311 |
+
}
|
3312 |
+
}
|
3313 |
+
unset($parts['auth']);
|
3314 |
+
$parts['path'] = $match[5];
|
3315 |
+
if (isset($match[6]) && ($match[6] != '')) $parts['query'] = $match[7];
|
3316 |
+
if (isset($match[8]) && ($match[8] != '')) $parts['fragment'] = $match[9];
|
3317 |
+
return $parts;
|
3318 |
}
|
3319 |
+
// shouldn't reach here
|
3320 |
+
return array('path'=>'');
|
3321 |
+
}
|
3322 |
+
|
3323 |
+
function _encode($string)
|
3324 |
+
{
|
3325 |
+
static $replace = array();
|
3326 |
+
if (!count($replace)) {
|
3327 |
+
$find = array(32, 34, 60, 62, 123, 124, 125, 91, 92, 93, 94, 96, 127);
|
3328 |
+
$find = array_merge(range(0, 31), $find);
|
3329 |
+
$find = array_map('chr', $find);
|
3330 |
+
foreach ($find as $char) {
|
3331 |
+
$replace[$char] = '%'.bin2hex($char);
|
3332 |
+
}
|
3333 |
}
|
3334 |
+
// escape control characters and a few other characters
|
3335 |
+
$encoded = strtr($string, $replace);
|
3336 |
+
// remove any character outside the hex range: 21 - 7E (see www.asciitable.com)
|
3337 |
+
return preg_replace('/[^\x21-\x7e]/', '', $encoded);
|
3338 |
+
}
|
3339 |
+
} // class Relative_URI
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3340 |
}
|
3341 |
|
3342 |
// take your best guess at the realname and e-mail, given a string
|
3343 |
define('FWP_REGEX_EMAIL_ADDY', '([^@"(<\s]+@[^"@(<\s]+\.[^"@(<\s]+)');
|
3344 |
define('FWP_REGEX_EMAIL_NAME', '("([^"]*)"|([^"<(]+\S))');
|
3345 |
+
define('FWP_REGEX_EMAIL_POSTFIX_NAME', '/^\s*'.FWP_REGEX_EMAIL_ADDY."\s+\(".FWP_REGEX_EMAIL_NAME.'\)\s*$/');
|
3346 |
+
define('FWP_REGEX_EMAIL_PREFIX_NAME', '/^\s*'.FWP_REGEX_EMAIL_NAME.'\s*<'.FWP_REGEX_EMAIL_ADDY.'>\s*$/');
|
3347 |
+
define('FWP_REGEX_EMAIL_JUST_ADDY', '/^\s*'.FWP_REGEX_EMAIL_ADDY.'\s*$/');
|
3348 |
+
define('FWP_REGEX_EMAIL_JUST_NAME', '/^\s*'.FWP_REGEX_EMAIL_NAME.'\s*$/');
|
3349 |
|
3350 |
function parse_email_with_realname ($email) {
|
3351 |
if (preg_match(FWP_REGEX_EMAIL_POSTFIX_NAME, $email, $matches)) :
|
3364 |
endif;
|
3365 |
return $ret;
|
3366 |
}
|
|
|
3367 |
?>
|
wp-content/plugins/feedwordpress/syndication-options.php
ADDED
@@ -0,0 +1,252 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
function fwp_syndication_options_page () {
|
3 |
+
global $wpdb, $wp_db_version;
|
4 |
+
|
5 |
+
if (FeedWordPress::needs_upgrade()) :
|
6 |
+
fwp_upgrade_page();
|
7 |
+
return;
|
8 |
+
endif;
|
9 |
+
|
10 |
+
$caption = 'Save Changes';
|
11 |
+
if (isset($_POST['action']) and $_POST['action']==$caption):
|
12 |
+
check_admin_referer();
|
13 |
+
|
14 |
+
if (!current_user_can('manage_options')):
|
15 |
+
die (__("Cheatin' uh ?"));
|
16 |
+
else:
|
17 |
+
update_option('feedwordpress_cat_id', $_REQUEST['syndication_category']);
|
18 |
+
update_option('feedwordpress_munge_permalink', $_REQUEST['munge_permalink']);
|
19 |
+
update_option('feedwordpress_update_logging', $_REQUEST['update_logging']);
|
20 |
+
update_option('feedwordpress_unfamiliar_author', $_REQUEST['unfamiliar_author']);
|
21 |
+
update_option('feedwordpress_unfamiliar_category', $_REQUEST['unfamiliar_category']);
|
22 |
+
update_option('feedwordpress_syndicated_post_status', $_REQUEST['post_status']);
|
23 |
+
update_option('feedwordpress_automatic_updates', ($_POST['automatic_updates']=='yes'));
|
24 |
+
update_option('feedwordpress_freshness', ($_POST['freshness_interval']*60));
|
25 |
+
|
26 |
+
// Categories
|
27 |
+
$cats = array();
|
28 |
+
if (isset($_POST['post_category'])) :
|
29 |
+
$cats = array();
|
30 |
+
foreach ($_POST['post_category'] as $cat_id) :
|
31 |
+
$cats[] = '{#'.$cat_id.'}';
|
32 |
+
endforeach;
|
33 |
+
endif;
|
34 |
+
|
35 |
+
if (!empty($cats)) :
|
36 |
+
update_option('feedwordpress_syndication_cats', implode("\n", $cats));
|
37 |
+
else :
|
38 |
+
delete_option('feedwordpress_syndication_cats');
|
39 |
+
endif;
|
40 |
+
|
41 |
+
if (isset($_REQUEST['comment_status']) and ($_REQUEST['comment_status'] == 'open')) :
|
42 |
+
update_option('feedwordpress_syndicated_comment_status', 'open');
|
43 |
+
else :
|
44 |
+
update_option('feedwordpress_syndicated_comment_status', 'closed');
|
45 |
+
endif;
|
46 |
+
|
47 |
+
if (isset($_REQUEST['ping_status']) and ($_REQUEST['ping_status'] == 'open')) :
|
48 |
+
update_option('feedwordpress_syndicated_ping_status', 'open');
|
49 |
+
else :
|
50 |
+
update_option('feedwordpress_syndicated_ping_status', 'closed');
|
51 |
+
endif;
|
52 |
+
|
53 |
+
if (isset($_REQUEST['hardcode_name']) and ($_REQUEST['hardcode_name'] == 'no')) :
|
54 |
+
update_option('feedwordpress_hardcode_name', 'no');
|
55 |
+
else :
|
56 |
+
update_option('feedwordpress_hardcode_name', 'yes');
|
57 |
+
endif;
|
58 |
+
|
59 |
+
if (isset($_REQUEST['hardcode_description']) and ($_REQUEST['hardcode_description'] == 'no')) :
|
60 |
+
update_option('feedwordpress_hardcode_description', 'no');
|
61 |
+
else :
|
62 |
+
update_option('feedwordpress_hardcode_description', 'yes');
|
63 |
+
endif;
|
64 |
+
|
65 |
+
if (isset($_REQUEST['hardcode_url']) and ($_REQUEST['hardcode_url'] == 'no')) :
|
66 |
+
update_option('feedwordpress_hardcode_url', 'no');
|
67 |
+
else :
|
68 |
+
update_option('feedwordpress_hardcode_url', 'yes');
|
69 |
+
endif;
|
70 |
+
?>
|
71 |
+
<div class="updated">
|
72 |
+
<p><?php _e('Options saved.')?></p>
|
73 |
+
</div>
|
74 |
+
<?php
|
75 |
+
endif;
|
76 |
+
endif;
|
77 |
+
|
78 |
+
$cat_id = FeedWordPress::link_category_id();
|
79 |
+
$munge_permalink = get_option('feedwordpress_munge_permalink');
|
80 |
+
$update_logging = get_option('feedwordpress_update_logging');
|
81 |
+
|
82 |
+
$automatic_updates = get_option('feedwordpress_automatic_updates');
|
83 |
+
|
84 |
+
$freshness_interval = get_option('feedwordpress_freshness');
|
85 |
+
if (false === $freshness_interval) :
|
86 |
+
$freshness_interval = FEEDWORDPRESS_FRESHNESS_INTERVAL;
|
87 |
+
endif;
|
88 |
+
$freshness_interval = $freshness_interval / 60; // convert to minutes
|
89 |
+
|
90 |
+
$hardcode_name = get_option('feedwordpress_hardcode_name');
|
91 |
+
$hardcode_description = get_option('feedwordpress_hardcode_description');
|
92 |
+
$hardcode_url = get_option('feedwordpress_hardcode_url');
|
93 |
+
|
94 |
+
$post_status = get_option("feedwordpress_syndicated_post_status"); // default="publish"
|
95 |
+
$comment_status = get_option("feedwordpress_syndicated_comment_status"); // default="closed"
|
96 |
+
$ping_status = get_option("feedwordpress_syndicated_ping_status"); // default="closed"
|
97 |
+
|
98 |
+
$unfamiliar_author = array ('create' => '','default' => '','filter' => '');
|
99 |
+
$ua = FeedWordPress::on_unfamiliar('author');
|
100 |
+
if (is_string($ua) and array_key_exists($ua, $unfamiliar_author)) :
|
101 |
+
$unfamiliar_author[$ua] = ' checked="checked"';
|
102 |
+
endif;
|
103 |
+
$unfamiliar_category = array ('create'=>'','default'=>'','filter'=>'');
|
104 |
+
$uc = FeedWordPress::on_unfamiliar('category');
|
105 |
+
if (is_string($uc) and array_key_exists($uc, $unfamiliar_category)) :
|
106 |
+
$unfamiliar_category[$uc] = ' checked="checked"';
|
107 |
+
endif;
|
108 |
+
|
109 |
+
if (isset($wp_db_version) and $wp_db_version >= 4772) :
|
110 |
+
$results = get_categories('type=link');
|
111 |
+
|
112 |
+
// Guarantee that the Contributors category will be in the drop-down chooser, even if it is empty.
|
113 |
+
$found_link_category_id = false;
|
114 |
+
foreach ($results as $row) :
|
115 |
+
if ($row->cat_id == $cat_id) : $found_link_category_id = true; endif;
|
116 |
+
endforeach;
|
117 |
+
|
118 |
+
if (!$found_link_category_id) : $results[] = get_category($cat_id); endif;
|
119 |
+
else :
|
120 |
+
$results = $wpdb->get_results("SELECT cat_id, cat_name, auto_toggle FROM $wpdb->linkcategories ORDER BY cat_id");
|
121 |
+
endif;
|
122 |
+
|
123 |
+
$cats = get_option('feedwordpress_syndication_cats');
|
124 |
+
$dogs = get_nested_categories(-1, 0);
|
125 |
+
$cats = array_map('strtolower',
|
126 |
+
array_map('trim',
|
127 |
+
preg_split(FEEDWORDPRESS_CAT_SEPARATOR_PATTERN, $cats)
|
128 |
+
));
|
129 |
+
|
130 |
+
foreach ($dogs as $tag => $dog) :
|
131 |
+
$found_by_name = in_array(strtolower(trim($dog['cat_name'])), $cats);
|
132 |
+
if (isset($dog['cat_ID'])) : $dog['cat_id'] = $dog['cat_ID']; endif;
|
133 |
+
$found_by_id = in_array('{#'.trim($dog['cat_id']).'}', $cats);
|
134 |
+
|
135 |
+
if ($found_by_name or $found_by_id) :
|
136 |
+
$dogs[$tag]['checked'] = true;
|
137 |
+
endif;
|
138 |
+
endforeach;
|
139 |
+
|
140 |
+
?>
|
141 |
+
<div class="wrap">
|
142 |
+
<h2>Syndication Options</h2>
|
143 |
+
<form action="" method="post">
|
144 |
+
<fieldset class="options">
|
145 |
+
<legend>Syndicated Feeds</legend>
|
146 |
+
<table class="editform" width="100%" cellspacing="2" cellpadding="5">
|
147 |
+
<tr>
|
148 |
+
<th width="33%" scope="row">Syndicated Link category:</th>
|
149 |
+
<td width="67%"><?php
|
150 |
+
echo "\n<select name=\"syndication_category\" size=\"1\">";
|
151 |
+
foreach ($results as $row) {
|
152 |
+
if (!isset($row->cat_id)) { $row->cat_id = $row->cat_ID; }
|
153 |
+
|
154 |
+
echo "\n\t<option value=\"$row->cat_id\"";
|
155 |
+
if ($row->cat_id == $cat_id)
|
156 |
+
echo " selected='selected'";
|
157 |
+
echo ">$row->cat_id: ".wp_specialchars($row->cat_name);
|
158 |
+
if ('Y' == $row->auto_toggle)
|
159 |
+
echo ' (auto toggle)';
|
160 |
+
echo "</option>\n";
|
161 |
+
}
|
162 |
+
echo "\n</select>\n";
|
163 |
+
?></td>
|
164 |
+
</tr>
|
165 |
+
|
166 |
+
<tr>
|
167 |
+
<th width="33%" scope="row">Check for new posts:</th>
|
168 |
+
<td width="67%"><select name="automatic_updates" size="1" onchange="if (this.value=='yes') { disp = 'inline'; } else { disp = 'none'; }; el=document.getElementById('automatic-update-interval-span'); if (el) el.style.display=disp;">
|
169 |
+
<option value="yes"<?php echo ($automatic_updates)?' selected="selected"':''; ?>>automatically</option>
|
170 |
+
<option value="no"<?php echo (!$automatic_updates)?' selected="selected"':''; ?>>only when I request</option>
|
171 |
+
</select>
|
172 |
+
<span id="automatic-update-interval-span" style="display: <?php echo $automatic_updates?'inline':'none';?>"><label for="automatic-update-interval">every</label> <input id="automatic-update-interval" name="freshness_interval" value="<?php echo $freshness_interval; ?>" size="4" /> minutes.</span>
|
173 |
+
</td>
|
174 |
+
</tr>
|
175 |
+
|
176 |
+
<tr><th width="33%" scope="row" style="vertical-align:top">Feed information:</th>
|
177 |
+
<td width="67%"><ul style="margin:0;padding:0;list-style:none">
|
178 |
+
<li><input type="checkbox" name="hardcode_name" value="no"<?php echo (($hardcode_name=='yes')?'':' checked="checked"');?>/> Update the contributor title when the feed title changes</li>
|
179 |
+
<li><input type="checkbox" name="hardcode_description" value="no"<?php echo (($hardcode_description=='yes')?'':' checked="checked"');?>/> Update when contributor description if the feed tagline changes</li>
|
180 |
+
<li><input type="checkbox" name="hardcode_url" value="no"<?php echo (($hardcode_url=='yes')?'':' checked="checked"');?>/> Update the contributor homepage when the feed link changes</li>
|
181 |
+
</ul></td></tr>
|
182 |
+
</table>
|
183 |
+
<div class="submit"><input type="submit" name="action" value="<?php echo $caption; ?>" /></div>
|
184 |
+
</fieldset>
|
185 |
+
|
186 |
+
<fieldset class="options">
|
187 |
+
<legend>Syndicated Posts</legend>
|
188 |
+
|
189 |
+
<?php fwp_category_box($dogs, '<em>all syndicated posts</em>'); ?>
|
190 |
+
|
191 |
+
<table class="editform" width="75%" cellspacing="2" cellpadding="5">
|
192 |
+
<tr style="vertical-align: top"><th width="44%" scope="row">Publication:</th>
|
193 |
+
<td width="56%"><ul style="margin: 0; padding: 0; list-style:none">
|
194 |
+
<li><label><input type="radio" name="post_status" value="publish"<?php echo (!$post_status or $post_status=='publish')?' checked="checked"':''; ?> /> Publish syndicated posts immediately</label></li>
|
195 |
+
<li><label><input type="radio" name="post_status" value="draft"<?php echo ($post_status=='draft')?' checked="checked"':''; ?> /> Hold syndicated posts as drafts</label></li>
|
196 |
+
<li><label><input type="radio" name="post_status" value="private"<?php echo ($post_status=='private')?' checked="checked"':''; ?> /> Hold syndicated posts as private posts</label></li>
|
197 |
+
</ul></td></tr>
|
198 |
+
|
199 |
+
<tr style="vertical-align: top"><th width="44%" scope="row">Comments:</th>
|
200 |
+
<td width="56%"><ul style="margin: 0; padding: 0; list-style:none">
|
201 |
+
<li><label><input type="radio" name="comment_status" value="open"<?php echo ($comment_status=='open')?' checked="checked"':''; ?> /> Allow comments on syndicated posts</label></li>
|
202 |
+
<li><label><input type="radio" name="comment_status" value="closed"<?php echo ($comment_status!='open')?' checked="checked"':''; ?> /> Don't allow comments on syndicated posts</label></li>
|
203 |
+
</ul></td></tr>
|
204 |
+
|
205 |
+
<tr style="vertical-align: top"><th width="44%" scope="row">Trackback and Pingback:</th>
|
206 |
+
<td width="56%"><ul style="margin:0; padding: 0; list-style:none">
|
207 |
+
<li><label><input type="radio" name="ping_status" value="open"<?php echo ($ping_status=='open')?' checked="checked"':''; ?> /> Accept pings on syndicated posts</label></li>
|
208 |
+
<li><label><input type="radio" name="ping_status" value="closed"<?php echo ($ping_status!='open')?' checked="checked"':''; ?> /> Don't accept pings on syndicated posts</label></li>
|
209 |
+
</ul></td></tr>
|
210 |
+
|
211 |
+
<tr style="vertical-align: top"><th width="44%" scope="row" style="vertical-align:top">Unfamiliar authors:</th>
|
212 |
+
<td width="56%"><ul style="margin: 0; padding: 0; list-style:none">
|
213 |
+
<li><label><input type="radio" name="unfamiliar_author" value="create"<?php echo $unfamiliar_author['create']; ?>/> create a new author account</label></li>
|
214 |
+
<li><label><input type="radio" name="unfamiliar_author" value="default"<?php echo $unfamiliar_author['default']; ?> /> attribute the post to the default author</label></li>
|
215 |
+
<li><label><input type="radio" name="unfamiliar_author" value="filter"<?php echo $unfamiliar_author['filter']; ?> /> don't syndicate the post</label></li>
|
216 |
+
</ul></td></tr>
|
217 |
+
|
218 |
+
<tr style="vertical-align: top"><th width="44%" scope="row" style="vertical-align:top">Unfamiliar categories:</th>
|
219 |
+
<td width="56%"><ul style="margin: 0; padding:0; list-style:none">
|
220 |
+
<li><label><input type="radio" name="unfamiliar_category" value="create"<?php echo $unfamiliar_category['create']; ?>/> create any categories the post is in</label></li>
|
221 |
+
<li><label><input type="radio" name="unfamiliar_category" value="default"<?php echo $unfamiliar_category['default']; ?>/> don't create new categories</li>
|
222 |
+
<li><label><input type="radio" name="unfamiliar_category" value="filter"<?php echo $unfamiliar_category['filter']; ?>/> don't create new categories and don't syndicate posts unless they match at least one familiar category</label></li>
|
223 |
+
</ul></td></tr>
|
224 |
+
|
225 |
+
<tr style="vertical-align: top"><th width="44%" scope="row">Permalinks point to:</th>
|
226 |
+
<td width="56%"><select name="munge_permalink" size="1">
|
227 |
+
<option value="yes"<?php echo ($munge_permalink=='yes')?' selected="selected"':''; ?>>original website</option>
|
228 |
+
<option value="no"<?php echo ($munge_permalink=='no')?' selected="selected"':''; ?>>this website</option>
|
229 |
+
</select></td></tr>
|
230 |
+
</table>
|
231 |
+
<div class="submit"><input type="submit" name="action" value="<?php echo $caption; ?>" /></div>
|
232 |
+
</fieldset>
|
233 |
+
|
234 |
+
<fieldset class="options">
|
235 |
+
<legend>Back-end Options</legend>
|
236 |
+
<table class="editform" width="100%" cellspacing="2" cellpadding="5">
|
237 |
+
<th width="33%" scope="row">Write update notices to PHP logs:</th>
|
238 |
+
<td width="67%"><select name="update_logging" size="1">
|
239 |
+
<option value="yes"<?php echo (($update_logging=='yes')?' selected="selected"':''); ?>>yes</option>
|
240 |
+
<option value="no"<?php echo (($update_logging!='yes')?' selected="selected"':''); ?>>no</option>
|
241 |
+
</select></td>
|
242 |
+
</tr>
|
243 |
+
</table>
|
244 |
+
<div class="submit"><input type="submit" name="action" value="<?php echo $caption; ?>" /></div>
|
245 |
+
</fieldset>
|
246 |
+
</form>
|
247 |
+
</div>
|
248 |
+
<?php
|
249 |
+
}
|
250 |
+
|
251 |
+
fwp_syndication_options_page();
|
252 |
+
?>
|
wp-content/update-feeds.php
DELETED
@@ -1,205 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
# update-feeds.php: Instruct FeedWordPress to scan for fresh content
|
3 |
-
#
|
4 |
-
# Project: FeedWordPress
|
5 |
-
# URI: <http://projects.radgeek.com/feedwordpress>
|
6 |
-
# Author: Charles Johnson <technophilia@radgeek.com>
|
7 |
-
# License: GPL
|
8 |
-
# Version: 2005.11.06
|
9 |
-
#
|
10 |
-
# USAGE
|
11 |
-
# -----
|
12 |
-
# update-feeds.php is a useful script for instructing the FeedWordPress plugin
|
13 |
-
# to scan for fresh content on the feeds that it syndicates. This is handy if
|
14 |
-
# you want your syndication site to actually syndicate content, and you can't
|
15 |
-
# rely on all your contributors to send you an XML-RPC ping when they update.
|
16 |
-
#
|
17 |
-
# 1. Install FeedWordPress and activate the FeedWordPress plugin. (See
|
18 |
-
# <http://projects.radgeek.com/feedwordpress/install> if you need a guide
|
19 |
-
# for the perplexed.)
|
20 |
-
#
|
21 |
-
# 2. If you want to manually update one or more of your feeds, you can do
|
22 |
-
# so by pointing your web browser to the URI
|
23 |
-
# <http://xyz.com/wp-content/update-feeds.php>, where `http://xyz.com/` is
|
24 |
-
# replaced by the URI to your installation of WordPress. Log in as any
|
25 |
-
# user in your WordPress database and use the form to update.
|
26 |
-
#
|
27 |
-
# 3. To keep content up-to-date automatically, set up a cron job to run
|
28 |
-
# update-feeds.php locally:
|
29 |
-
#
|
30 |
-
# cd /path/to/wordpress/wp-content ; php update-feeds.php
|
31 |
-
#
|
32 |
-
# where `/path/to/wordpress` is replaced by the filesystem path to your
|
33 |
-
# installation of WordPress; or, if you don't have, or don't want to use,
|
34 |
-
# command-line PHP, you can send an HTTP POST request to the appropriate
|
35 |
-
# URI:
|
36 |
-
#
|
37 |
-
# curl --user user:pass http://xyz.com/wp-content/update-feeds.php -d update=quiet
|
38 |
-
#
|
39 |
-
# `user` and `pass` should be replaced by the username and password of
|
40 |
-
# a user in your WordPress database (you can create a dummy user for
|
41 |
-
# updates if you want; that's what I do). `http://xyz.com/` should be
|
42 |
-
# replaced by the URI to your installation of WordPress.
|
43 |
-
#
|
44 |
-
# Don't be afraid to run this cron job frequently. FeedWordPress staggers
|
45 |
-
# updates over time rather than checking all of the feeds every time the
|
46 |
-
# cron job runs, so even if the cron job runs every 10 minutes, each feed
|
47 |
-
# will, on average only be polled for updates once an hour or so (or less
|
48 |
-
# frequently if the feed author requests less frequent updates using
|
49 |
-
# the RSS <ttl> element or the syndication module elements).
|
50 |
-
#
|
51 |
-
# 4. If you want to update *one* of the feeds rather than *all* of them, then
|
52 |
-
# pass the URI and title as command-line arguments:
|
53 |
-
#
|
54 |
-
# $ php update-feeds.php http://radgeek.com
|
55 |
-
#
|
56 |
-
# or in the POST request:
|
57 |
-
#
|
58 |
-
# $ curl --user login:password http://xyz.com/wp-content/update-feeds.php -d uri=http://www.radgeek.com\&update=quiet
|
59 |
-
#
|
60 |
-
// Help us to pick out errors, if any.
|
61 |
-
ini_set('error_reporting', E_ALL & ~E_NOTICE);
|
62 |
-
ini_set('display_errors', true);
|
63 |
-
define('MAGPIE_DEBUG', true);
|
64 |
-
|
65 |
-
// Are we running from a web request or from the command line?
|
66 |
-
if (!isset($_SERVER['REQUEST_URI'])) :
|
67 |
-
$update_feeds_display = 'text/plain';
|
68 |
-
$update_feeds_invoke = 'cmd';
|
69 |
-
elseif (isset($_POST['update'])) :
|
70 |
-
if ($_POST['update'] == 'quiet') :
|
71 |
-
$update_feeds_display = 'text/plain';
|
72 |
-
$update_feeds_invoke = 'post';
|
73 |
-
$update_feeds_verbose = false;
|
74 |
-
elseif ($_POST['update'] == 'verbose') :
|
75 |
-
$update_feeds_display = 'text/plain';
|
76 |
-
$update_feeds_invoke = 'post';
|
77 |
-
$update_feeds_verbose = true;
|
78 |
-
else :
|
79 |
-
$update_feeds_display = 'text/html';
|
80 |
-
$update_feeds_invoke = 'post';
|
81 |
-
endif;
|
82 |
-
else :
|
83 |
-
$update_feeds_display = 'text/html';
|
84 |
-
$update_feeds_invoke = 'get';
|
85 |
-
endif;
|
86 |
-
|
87 |
-
require_once ('../wp-blog-header.php');
|
88 |
-
|
89 |
-
function update_feeds_mention ($feed) {
|
90 |
-
global $update_feeds_display;
|
91 |
-
|
92 |
-
if ($update_feeds_display=='text/html') :
|
93 |
-
echo "<li>Updating <cite>".$feed['link/name']."</cite> from <<a href=\""
|
94 |
-
.$feed['link/uri']."\">".$feed['link/uri']."</a>> ...</li>\n";
|
95 |
-
else :
|
96 |
-
echo "* Updating ".$feed['link/name']." from <".$feed['link/uri']."> ...\n";
|
97 |
-
endif;
|
98 |
-
flush();
|
99 |
-
}
|
100 |
-
|
101 |
-
# -- Don't change these unless you know what you're doing...
|
102 |
-
define ('RPC_MAGIC', 'tag:radgeek.com/projects/feedwordpress/'); // update all
|
103 |
-
|
104 |
-
// Query secret word from database
|
105 |
-
$rpc_secret = get_settings('feedwordpress_rpc_secret');
|
106 |
-
|
107 |
-
header("Content-Type: {$update_feeds_display}; charset=utf-8");
|
108 |
-
|
109 |
-
# -- Are we running from an HTTP GET, HTTP POST, or from the command line?
|
110 |
-
if ($update_feeds_invoke != 'cmd') : // We're acessing this from HTTP GET or HTTP POST
|
111 |
-
// Authenticate the user, if possible ...
|
112 |
-
if (isset($_SERVER['PHP_AUTH_USER']) and isset($_SERVER['PHP_AUTH_PW'])) : // try HTTP authentication
|
113 |
-
$login = $_SERVER['PHP_AUTH_USER']; $pass = $_SERVER['PHP_AUTH_PW'];
|
114 |
-
elseif (isset($_POST['log']) and isset($_POST['pwd'])) : // try POST data
|
115 |
-
$login = $_REQUEST['log']; $pass = $_REQUEST['pwd'];
|
116 |
-
endif;
|
117 |
-
|
118 |
-
if (empty($login) or empty($pass) or !wp_login($login, $pass)) :
|
119 |
-
if ($update_feeds_display=='text/html') :
|
120 |
-
auth_redirect(); // try authentication cookies; if all else fails, redirect to wp-login.php
|
121 |
-
else :
|
122 |
-
echo "update-feeds (".date('Y-m-d H:i:s')."): ERROR: Could not log in as '$login' (password: '$pass')\n";
|
123 |
-
die;
|
124 |
-
endif;
|
125 |
-
endif;
|
126 |
-
|
127 |
-
// Henceforward, we can proceed on the assumption that we have an authenticated user
|
128 |
-
$uri = (isset($_REQUEST['uri']) ? $_REQUEST['uri'] : RPC_MAGIC.$rpc_secret);
|
129 |
-
|
130 |
-
if ($update_feeds_display=='text/html') :
|
131 |
-
echo <<<EOHTML
|
132 |
-
<?xml version="1.0" encoding="utf-8"?>
|
133 |
-
<html>
|
134 |
-
<head>
|
135 |
-
<title>update-feeds :: FeedWordPress</title>
|
136 |
-
</head>
|
137 |
-
|
138 |
-
<body>
|
139 |
-
<h1>update-feeds: make FeedWordPress check for new syndicated content</h1>
|
140 |
-
|
141 |
-
EOHTML;
|
142 |
-
endif;
|
143 |
-
else :
|
144 |
-
// update-feeds has been invoked from the command line; no further
|
145 |
-
// authentication is necessary. (If PAM hasn't already done the
|
146 |
-
// necessary screening for you, you have bigger problems than their
|
147 |
-
// access to FeedWordPress...)
|
148 |
-
$uri = (isset($_SERVER['argv'][1]) ? $_SERVER['argv'][1] : RPC_MAGIC.$rpc_secret);
|
149 |
-
endif;
|
150 |
-
|
151 |
-
$feedwordpress =& new FeedWordPress;
|
152 |
-
|
153 |
-
if ($update_feeds_display=='text/html' or $update_feeds_verbose) :
|
154 |
-
add_action('feedwordpress_check_feed', 'update_feeds_mention');
|
155 |
-
endif;
|
156 |
-
|
157 |
-
if ($update_feeds_display=='text/html') : // HTTP GET or HTTP POST: add some web niceties
|
158 |
-
|
159 |
-
echo "<form action=\"\" method=\"POST\">\n";
|
160 |
-
echo "<select name=\"uri\">\n";
|
161 |
-
echo "<option value=\"".RPC_MAGIC.$rpc_secret."\">All feeds</option>\n";
|
162 |
-
foreach ($feedwordpress->feeds as $feed) :
|
163 |
-
echo "<option value=\"{$feed['link/uri']}\"";
|
164 |
-
if ($feed['link/uri']==$_REQUEST['uri']) : echo ' selected="selected"'; endif;
|
165 |
-
echo ">{$feed['link/name']}</option>\n";
|
166 |
-
endforeach;
|
167 |
-
echo "</select> ";
|
168 |
-
echo "<input type=\"submit\" name=\"update\" value=\"Update\" />\n";
|
169 |
-
echo "</form>\n";
|
170 |
-
endif;
|
171 |
-
|
172 |
-
if ($update_feeds_invoke != 'get') : // Only do things with side-effects for HTTP POST or command line
|
173 |
-
if ($update_feeds_display == 'text/html') : echo "<ul>\n"; endif;
|
174 |
-
$delta = @$feedwordpress->update($uri);
|
175 |
-
if ($update_feeds_display == 'text/html') : echo "</ul>\n"; endif;
|
176 |
-
|
177 |
-
if (is_null($delta)) :
|
178 |
-
if ($update_feeds_invoke == 'cmd') :
|
179 |
-
$stderr = fopen('php://stderr', 'w');
|
180 |
-
fputs($stderr, "update-feeds (".date('Y-m-d H:i:s')."): ERROR: I don't syndicate <$uri>\n");
|
181 |
-
elseif ($update_feeds_display == 'text/plain') :
|
182 |
-
echo "update-feeds (".date('Y-m-d H:i:s')."): ERROR: I don't syndicate <$uri>\n";
|
183 |
-
else :
|
184 |
-
echo "<p><strong>Error:</strong> I don't syndicate <a href=\"$uri\">$uri</a></p>\n";
|
185 |
-
endif;
|
186 |
-
elseif ($update_feeds_display=='text/html' or $update_feeds_verbose) :
|
187 |
-
$mesg = array();
|
188 |
-
if (isset($delta['new'])) : $mesg[] = ' '.$delta['new'].' new posts were syndicated'; endif;
|
189 |
-
if (isset($delta['updated'])) : $mesg[] = ' '.$delta['updated'].' existing posts were updated'; endif;
|
190 |
-
if ($update_feeds_display=='text/html') : echo "<p>"; endif;
|
191 |
-
echo "Update complete.".implode(' and', $mesg);
|
192 |
-
if ($update_feeds_display=='text/html') : echo "</p>"; endif;
|
193 |
-
echo "\n"; flush();
|
194 |
-
endif;
|
195 |
-
endif;
|
196 |
-
|
197 |
-
if ($update_feeds_display=='text/html') : // HTTP GET or HTTP POST: close off web niceties
|
198 |
-
echo <<<EOHTML
|
199 |
-
|
200 |
-
<p><a href="../wp-admin">← Return to WordPress Dashboard</a></p>
|
201 |
-
</body>
|
202 |
-
</html>
|
203 |
-
EOHTML;
|
204 |
-
endif;
|
205 |
-
?>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|