PluginProbe
FeedWordPress / 2011.0721
FeedWordPress v2011.0721
trunk 0.8 0.9 0.91 0.95 0.96 0.97 0.98 0.981 0.99 0.991 0.992 0.993 2008.1030 2008.1101 2008.1105 2008.1214 2009.0612 2009.0613 2009.0618 2009.0707 2009.1111 2009.1112 2010.0127 2010.0528 All 65 releases
← All changes | syndicatedlink.class.php +432 -47 2009.06182011.0721 View file →
@@ -32,12 +32,15 @@
32 32 #
33 33 # Values of keys in link_notes are accessible from templates using
34 34 # the function `get_feed_meta($key)` if this plugin is activated.
35 35
36 +require_once(dirname(__FILE__).'/magpiefromsimplepie.class.php');
37 +
36 38 class SyndicatedLink {
37 39 var $id = null;
38 40 var $link = null;
39 41 var $settings = array ();
42 + var $simplepie = null;
40 43 var $magpie = null;
41 44
42 45 function SyndicatedLink ($link) {
43 46 global $wpdb;
@@ -97,14 +100,48 @@
97 100 if (!isset($this->settings['cat_split']) and in_array($bits['host'], $tagspacers)) :
98 101 $this->settings['cat_split'] = '\s'; // Whitespace separates multiple tags in del.icio.us RSS feeds
99 102 endif;
100 103
101 - if (isset($this->settings['cats'])):
102 - $this->settings['cats'] = preg_split(FEEDWORDPRESS_CAT_SEPARATOR_PATTERN, $this->settings['cats']);
104 + // Simple lists
105 + foreach ($this->imploded_settings() as $what) :
106 + if (isset($this->settings[$what])):
107 + $this->settings[$what] = explode(
108 + FEEDWORDPRESS_CAT_SEPARATOR,
109 + $this->settings[$what]
110 + );
111 + endif;
112 + endforeach;
113 +
114 + if (isset($this->settings['terms'])) :
115 + // Look for new format
116 + $this->settings['terms'] = maybe_unserialize($this->settings['terms']);
117 +
118 + if (!is_array($this->settings['terms'])) :
119 + // Deal with old format instead. Ugh.
120 +
121 + // Split on two *or more* consecutive breaks
122 + // because in the old format, a taxonomy
123 + // without any associated terms would
124 + // produce tax_name#1\n\n\ntax_name#2\nterm,
125 + // and the naive split on the first \n\n
126 + // would screw up the tax_name#2 list.
127 + //
128 + // Props to David Morris for pointing this
129 + // out.
130 +
131 + $this->settings['terms'] = preg_split(
132 + "/".FEEDWORDPRESS_CAT_SEPARATOR."{2,}/",
133 + $this->settings['terms']
134 + );
135 + $terms = array();
136 + foreach ($this->settings['terms'] as $line) :
137 + $line = explode(FEEDWORDPRESS_CAT_SEPARATOR, $line);
138 + $tax = array_shift($line);
139 + $terms[$tax] = $line;
140 + endforeach;
141 + $this->settings['terms'] = $terms;
142 + endif;
103 143 endif;
104 - if (isset($this->settings['tags'])):
105 - $this->settings['tags'] = preg_split(FEEDWORDPRESS_CAT_SEPARATOR_PATTERN, $this->settings['tags']);
106 - endif;
107 144
108 145 if (isset($this->settings['map authors'])) :
109 146 $author_rules = explode("\n\n", $this->settings['map authors']);
110 147 $ma = array();
@@ -123,22 +160,29 @@
123 160 endif;
124 161 } /* SyndicatedLink::SyndicatedLink () */
125 162
126 163 function found () {
127 - return is_object($this->link);
164 + return is_object($this->link) and !is_wp_error($this->link);
128 165 } /* SyndicatedLink::found () */
129 166
130 167 function stale () {
168 + global $feedwordpress;
169 +
131 170 $stale = true;
132 - if (isset($this->settings['update/hold']) and ($this->settings['update/hold']=='ping')) :
171 + if ($this->setting('update/hold')=='ping') :
133 172 $stale = false; // don't update on any timed updates; pings only
134 - elseif (isset($this->settings['update/hold']) and ($this->settings['update/hold']=='next')) :
173 + elseif ($this->setting('update/hold')=='next') :
135 174 $stale = true; // update on the next timed update
136 - elseif (!isset($this->settings['update/ttl']) or !isset($this->settings['update/last'])) :
175 + elseif ( !$this->setting('update/last') ) :
137 176 $stale = true; // initial update
177 + elseif ($feedwordpress->force_update_all()) :
178 + $stale = true; // forced general updating
138 179 else :
139 - $after = ((int) $this->settings['update/last'])
140 - +((int) $this->settings['update/ttl'] * 60);
180 + $after = (
181 + (int) $this->setting('update/last')
182 + + (int) $this->setting('update/fudge')
183 + + ((int) $this->setting('update/ttl') * 60)
184 + );
141 185 $stale = (time() >= $after);
142 186 endif;
143 187 return $stale;
144 188 } /* SyndicatedLink::stale () */
@@ -145,9 +189,26 @@
145 189
146 190 function poll ($crash_ts = NULL) {
147 191 global $wpdb;
148 192
149 - $this->magpie = fetch_rss($this->link->link_rss);
193 + $url = $this->uri(array('add_params' => true));
194 + FeedWordPress::diagnostic('updated_feeds', 'Polling feed ['.$url.']');
195 +
196 + $timeout = $this->setting('fetch timeout', 'feedwordpress_fetch_timeout', FEEDWORDPRESS_FETCH_TIMEOUT_DEFAULT);
197 +
198 + $this->simplepie = apply_filters(
199 + 'syndicated_feed',
200 + FeedWordPress::fetch($url, array('timeout' => $timeout)),
201 + $this
202 + );
203 +
204 + // Filter compatibility mode
205 + if (is_wp_error($this->simplepie)) :
206 + $this->magpie = $this->simplepie;
207 + else :
208 + $this->magpie = new MagpieFromSimplePie($this->simplepie, NULL);
209 + endif;
210 +
150 211 $new_count = NULL;
151 212
152 213 $resume = FeedWordPress::affirmative($this->settings, 'update/unfinished');
153 214 if ($resume) :
@@ -157,9 +218,46 @@
157 218 // begin at the beginning
158 219 $processed = array();
159 220 endif;
160 221
161 - if (is_object($this->magpie)) :
222 + if (is_wp_error($this->simplepie)) :
223 + $new_count = $this->simplepie;
224 + // Error; establish an error setting.
225 + $theError = array();
226 + $theError['ts'] = time();
227 + $theError['since'] = time();
228 + $theError['object'] = $this->simplepie;
229 +
230 + $oldError = $this->setting('update/error', NULL, NULL);
231 + if (is_string($oldError)) :
232 + $oldError = unserialize($oldError);
233 + endif;
234 +
235 + if (!is_null($oldError)) :
236 + // Copy over the in-error-since timestamp
237 + $theError['since'] = $oldError['since'];
238 +
239 + // If this is a repeat error, then we should take
240 + // a step back before we try to fetch it again.
241 + $this->settings['update/last'] = time();
242 + $this->settings['update/ttl'] = $this->automatic_ttl();
243 + $this->settings['update/ttl'] = apply_filters('syndicated_feed_ttl', $this->settings['update/ttl'], $this);
244 + $this->settings['update/ttl'] = apply_filters('syndicated_feed_ttl_from_error', $this->settings['update/ttl'], $this);
245 +
246 + $this->settings['update/timed'] = 'automatically';
247 + endif;
248 +
249 + do_action('syndicated_feed_error', $theError, $oldError, $this);
250 +
251 + $this->settings['update/error'] = serialize($theError);
252 + $this->save_settings(/*reload=*/ true);
253 +
254 + elseif (is_object($this->simplepie)) :
255 + // Success; clear out error setting, if any.
256 + if (isset($this->settings['update/error'])) :
257 + unset($this->settings['update/error']);
258 + endif;
259 +
162 260 $new_count = array('new' => 0, 'updated' => 0);
163 261
164 262 # -- Update Link metadata live from feed
165 263 $channel = $this->magpie->channel;
@@ -186,18 +284,25 @@
186 284 endif;
187 285
188 286 $this->settings = array_merge($this->settings, $this->flatten_array($channel));
189 287
190 - $this->settings['update/last'] = time(); $ttl = $this->ttl();
288 + $this->settings['update/last'] = time();
289 + list($ttl, $xml) = $this->ttl(/*return element=*/ true);
290 +
191 291 if (!is_null($ttl)) :
192 292 $this->settings['update/ttl'] = $ttl;
293 + $this->settings['update/xml'] = $xml;
193 294 $this->settings['update/timed'] = 'feed';
194 295 else :
195 - $this->settings['update/ttl'] = rand(30, 120); // spread over time interval for staggered updates
296 + $ttl = $this->automatic_ttl();
297 + $this->settings['update/ttl'] = $ttl;
298 + $this->settings['update/xml'] = NULL;
196 299 $this->settings['update/timed'] = 'automatically';
197 300 endif;
301 + $this->settings['update/fudge'] = rand(0, ($ttl/3))*60;
302 + $this->settings['update/ttl'] = apply_filters('syndicated_feed_ttl', $this->setting('update/ttl'), $this);
198 303
199 - if (!isset($this->settings['update/hold']) or $this->settings['update/hold']!='ping') :
304 + if (!$this->setting('update/hold') != 'ping') :
200 305 $this->settings['update/hold'] = 'scheduled';
201 306 endif;
202 307
203 308 $this->settings['update/unfinished'] = 'yes';
@@ -211,15 +316,25 @@
211 316 UPDATE $wpdb->links
212 317 SET $update_set
213 318 WHERE link_id='$this->id'
214 319 ");
320 + do_action('update_syndicated_feed', $this->id, $this);
215 321
216 322 # -- Add new posts from feed and update any updated posts
217 323 $crashed = false;
218 324
219 - if (is_array($this->magpie->items)) :
220 - foreach ($this->magpie->items as $item) :
221 - $post =& new SyndicatedPost($item, $this);
325 + $posts = apply_filters(
326 + 'syndicated_feed_items',
327 + $this->simplepie->get_items(),
328 + &$this
329 + );
330 +
331 + $this->magpie->originals = $posts;
332 +
333 + if (is_array($posts)) :
334 + foreach ($posts as $key => $item) :
335 + $post = new SyndicatedPost($item, $this);
336 +
222 337 if (!$resume or !in_array(trim($post->guid()), $processed)) :
223 338 $processed[] = $post->guid();
224 339 if (!$post->filtered()) :
225 340 $new = $post->store();
@@ -230,11 +345,15 @@
230 345 $crashed = true;
231 346 break;
232 347 endif;
233 348 endif;
349 + unset($post);
234 350 endforeach;
235 351 endif;
236 -
352 + $suffix = ($crashed ? 'crashed' : 'completed');
353 + do_action('update_syndicated_feed_items', $this->id, $this);
354 + do_action("update_syndicated_feed_items_${suffix}", $this->id, $this);
355 +
237 356 // Copy back any changes to feed settings made in the course of updating (e.g. new author rules)
238 357 $to_notes = $this->settings;
239 358
240 359 $this->settings['update/processed'] = $processed;
@@ -249,29 +368,103 @@
249 368 UPDATE $wpdb->links
250 369 SET $update_set
251 370 WHERE link_id='$this->id'
252 371 ");
372 +
373 + do_action("update_syndicated_feed_completed", $this->id, $this);
253 374 endif;
254 375
376 + // All done; let's clean up.
377 + $this->magpie = NULL;
378 +
379 + // Avoid circular-reference memory leak in PHP < 5.3.
380 + // Cf. <http://simplepie.org/wiki/faq/i_m_getting_memory_leaks>
381 + if (method_exists($this->simplepie, '__destruct')) :
382 + $this->simplepie->__destruct();
383 + endif;
384 + $this->simplepie = NULL;
385 +
255 386 return $new_count;
256 387 } /* SyndicatedLink::poll() */
257 388
389 + /**
390 + * Updates the URL for the feed syndicated by this link.
391 + *
392 + * @param string $url The new feed URL to use for this source.
393 + * @return bool TRUE on success, FALSE on failure.
394 + */
395 + function set_uri ($url) {
396 + global $wpdb;
397 +
398 + if ($this->found()) :
399 + // Update link_rss
400 + $result = $wpdb->query("
401 + UPDATE $wpdb->links
402 + SET
403 + link_rss = '".$wpdb->escape($url)."'
404 + WHERE link_id = '".$wpdb->escape($this->id)."'
405 + ");
406 +
407 + $ret = ($result ? true : false);
408 + else :
409 + $ret = false;
410 + endif;
411 + return $ret;
412 + } /* SyndicatedLink::set_uri () */
413 +
414 + function deactivate () {
415 + global $wpdb;
416 +
417 + $wpdb->query($wpdb->prepare("
418 + UPDATE $wpdb->links SET link_visible = 'N' WHERE link_id = %d
419 + ", (int) $this->id));
420 + } /* SyndicatedLink::deactivate () */
421 +
422 + function delete () {
423 + global $wpdb;
424 +
425 + $wpdb->query($wpdb->prepare("
426 + DELETE FROM $wpdb->postmeta WHERE meta_key='syndication_feed_id'
427 + AND meta_value = '%s'
428 + ", $this->id));
429 +
430 + $wpdb->query($wpdb->prepare("
431 + DELETE FROM $wpdb->links WHERE link_id = %d
432 + ", (int) $this->id));
433 +
434 + $this->id = NULL;
435 + } /* SyndicatedLink::delete () */
436 +
437 + function nuke () {
438 + global $wpdb;
439 +
440 + // Make a list of the items syndicated from this feed...
441 + $post_ids = $wpdb->get_col($wpdb->prepare("
442 + SELECT post_id FROM $wpdb->postmeta
443 + WHERE meta_key = 'syndication_feed_id'
444 + AND meta_value = '%s'
445 + ", $this->id));
446 +
447 + // ... and kill them all
448 + if (count($post_ids) > 0) :
449 + foreach ($post_ids as $post_id) :
450 + // Force scrubbing of deleted post
451 + // rather than sending to Trashcan
452 + wp_delete_post(
453 + /*postid=*/ $post_id,
454 + /*force_delete=*/ true
455 + );
456 + endforeach;
457 + endif;
458 +
459 + $this->delete();
460 + } /* SyndicatedLink::nuke () */
461 +
258 462 function map_name_to_new_user ($name, $newuser_name) {
259 463 global $wpdb;
260 464
261 465 if (strlen($newuser_name) > 0) :
262 - $userdata = array();
263 - $userdata['ID'] = NULL;
264 -
265 - $userdata['user_login'] = sanitize_user($newuser_name);
266 - $userdata['user_login'] = apply_filters('pre_user_login', $userdata['user_login']);
267 -
268 - $userdata['user_nicename'] = sanitize_title($newuser_name);
269 - $userdata['user_nicename'] = apply_filters('pre_user_nicename', $userdata['user_nicename']);
270 -
271 - $userdata['display_name'] = $wpdb->escape($newuser_name);
272 -
273 - $newuser_id = wp_insert_user($userdata);
466 + $newuser_id = fwp_insert_new_user($newuser_name);
274 467 if (is_numeric($newuser_id)) :
275 468 if (is_null($name)) : // Unfamiliar author
276 469 $this->settings['unfamiliar author'] = $newuser_id;
277 470 else :
@@ -284,8 +477,11 @@
284 477 // TODO: Add some error reporting
285 478 endif;
286 479 } /* SyndicatedLink::map_name_to_new_user () */
287 480
481 + function imploded_settings () {
482 + return array('cats', 'tags', 'match/cats', 'match/tags', 'match/filter');
483 + }
288 484 function settings_to_notes () {
289 485 $to_notes = $this->settings;
290 486
291 487 unset($to_notes['link/id']); // Magic setting; don't save
@@ -298,15 +494,22 @@
298 494 if (isset($to_notes['update/processed']) and (is_array($to_notes['update/processed']))) :
299 495 $to_notes['update/processed'] = implode("\n", $to_notes['update/processed']);
300 496 endif;
301 497
302 - if (isset($to_notes['cats']) and is_array($to_notes['cats'])) :
303 - $to_notes['cats'] = implode(FEEDWORDPRESS_CAT_SEPARATOR, $to_notes['cats']);
498 + foreach ($this->imploded_settings() as $what) :
499 + if (isset($to_notes[$what]) and is_array($to_notes[$what])) :
500 + $to_notes[$what] = implode(
501 + FEEDWORDPRESS_CAT_SEPARATOR,
502 + $to_notes[$what]
503 + );
504 + endif;
505 + endforeach;
506 +
507 + if (isset($to_notes['terms']) and is_array($to_notes['terms'])) :
508 + // Serialize it.
509 + $to_notes['terms'] = serialize($to_notes['terms']);
304 510 endif;
305 - if (isset($to_notes['tags']) and is_array($to_notes['tags'])) :
306 - $to_notes['tags'] = implode(FEEDWORDPRESS_CAT_SEPARATOR, $to_notes['tags']);
307 - endif;
308 -
511 +
309 512 // Collapse the author mapping rule structure back into a flat string
310 513 if (isset($to_notes['map authors'])) :
311 514 $ma = array();
312 515 foreach ($to_notes['map authors'] as $rule_type => $author_rules) :
@@ -323,17 +526,161 @@
323 526 endforeach;
324 527 return $notes;
325 528 } /* SyndicatedLink::settings_to_notes () */
326 529
327 - function uri () {
328 - return (is_object($this->link) ? $this->link->link_rss : NULL);
530 + function save_settings ($reload = false) {
531 + global $wpdb;
532 +
533 + // Save channel-level meta-data
534 + foreach (array('link_name', 'link_description', 'link_url') as $what) :
535 + $alter[] = "{$what} = '".$wpdb->escape($this->link->{$what})."'";
536 + endforeach;
537 +
538 + // Save settings to the notes field
539 + $alter[] = "link_notes = '".$wpdb->escape($this->settings_to_notes())."'";
540 +
541 + // Update the properties of the link from settings changes, etc.
542 + $update_set = implode(", ", $alter);
543 +
544 + $result = $wpdb->query("
545 + UPDATE $wpdb->links
546 + SET $update_set
547 + WHERE link_id='$this->id'
548 + ");
549 +
550 + if ($reload) :
551 + // force reload of link information from DB
552 + if (function_exists('clean_bookmark_cache')) :
553 + clean_bookmark_cache($this->id);
554 + endif;
555 + endif;
556 + } /* SyndicatedLink::save_settings () */
557 +
558 + /**
559 + * Retrieves the value of a setting, allowing for a global setting to be
560 + * used as a fallback, or a constant value, or both.
561 + *
562 + * @param string $name The link setting key
563 + * @param mixed $fallback_global If the link setting is nonexistent or marked as a use-default value, fall back to the value of this global setting.
564 + * @param mixed $fallback_value If the link setting and the global setting are nonexistent or marked as a use-default value, fall back to this constant value.
565 + * @return bool TRUE on success, FALSE on failure.
566 + */
567 + function setting ($name, $fallback_global = NULL, $fallback_value = NULL, $default = 'default') {
568 + $ret = NULL;
569 + if (isset($this->settings[$name])) :
570 + $ret = $this->settings[$name];
571 + endif;
572 +
573 + $no_value = (
574 + is_null($ret)
575 + or (is_string($ret) and strtolower($ret)==$default)
576 + );
577 +
578 + if ($no_value and !is_null($fallback_global)) :
579 + // Avoid duplication of this correction
580 + $fallback_global = preg_replace('/^feedwordpress_/', '', $fallback_global);
581 +
582 + $ret = get_option('feedwordpress_'.$fallback_global, /*default=*/ NULL);
583 + endif;
584 +
585 + $no_value = (
586 + is_null($ret)
587 + or (is_string($ret) and strtolower($ret)==$default)
588 + );
589 +
590 + if ($no_value and !is_null($fallback_value)) :
591 + $ret = $fallback_value;
592 + endif;
593 + return $ret;
594 + } /* SyndicatedLink::setting () */
595 +
596 + function update_setting ($name, $value, $default = 'default') {
597 + if (!is_null($value) and $value != $default) :
598 + $this->settings[$name] = $value;
599 + else : // Zap it.
600 + unset($this->settings[$name]);
601 + endif;
602 + } /* SyndicatedLink::update_setting () */
603 +
604 + function uri ($params = array()) {
605 + $params = shortcode_atts(array(
606 + 'add_params' => false,
607 + ), $params);
608 +
609 + $uri = (is_object($this->link) ? $this->link->link_rss : NULL);
610 + if (!is_null($uri) and strlen($uri) > 0 and $params['add_params']) :
611 + $qp = maybe_unserialize($this->setting('query parameters', array()));
612 +
613 + // For high-tech HTTP feed request kung fu
614 + $qp = apply_filters('syndicated_feed_parameters', $qp, $uri, $this);
615 +
616 + $q = array();
617 + if (is_array($qp) and count($qp) > 0) :
618 + foreach ($qp as $pair) :
619 + $q[] = urlencode($pair[0]).'='.urlencode($pair[1]);
620 + endforeach;
621 +
622 + // Are we appending to a URI that already has params?
623 + $sep = ((strpos('?', $uri)===false) ? '?' : '&');
624 +
625 + // Tack it on
626 + $uri .= $sep . implode("&", $q);
627 + endif;
628 + endif;
629 +
630 + return $uri;
329 631 } /* SyndicatedLink::uri () */
330 632
331 - function homepage () {
332 - return (isset($this->settings['feed/link']) ? $this->settings['feed/link'] : NULL);
633 + function property_cascade ($fromFeed, $link_field, $setting, $simplepie_method) {
634 + $value = NULL;
635 + if ($fromFeed) :
636 + if (isset($this->settings[$setting])) :
637 + $value = $this->settings[$setting];
638 + elseif (is_object($this->simplepie)
639 + and method_exists($this->simplepie, $simplepie_method)) :
640 + $value = $this->simplepie->{$simplepie_method}();
641 + endif;
642 + else :
643 + $value = $this->link->{$link_field};
644 + endif;
645 + return $value;
646 + } /* SyndicatedLink::property_cascade () */
647 +
648 + function homepage ($fromFeed = true) {
649 + return $this->property_cascade($fromFeed, 'link_url', 'feed/link', 'get_link');
333 650 } /* SyndicatedLink::homepage () */
334 651
335 - function ttl () {
652 + function name ($fromFeed = true) {
653 + return $this->property_cascade($fromFeed, 'link_name', 'feed/title', 'get_title');
654 + } /* SyndicatedLink::name () */
655 +
656 + function guid () {
657 + $ret = $this->setting('feed/id', NULL, $this->uri());
658 +
659 + // If we can get it live from the feed, do so.
660 + if (is_object($this->simplepie)) :
661 + $search = array(
662 + array(SIMPLEPIE_NAMESPACE_ATOM_10, 'id'),
663 + array(SIMPLEPIE_NAMESPACE_ATOM_03, 'id'),
664 + array(SIMPLEPIE_NAMESPACE_RSS_20, 'guid'),
665 + array(SIMPLEPIE_NAMESPACE_DC_11, 'identifier'),
666 + array(SIMPLEPIE_NAMESPACE_DC_10, 'identifier'),
667 + );
668 +
669 + foreach ($search as $pair) :
670 + if ($id_tags = $this->simplepie->get_feed_tags($pair[0], $pair[1])) :
671 + $ret = $id_tags[0]['data'];
672 + break;
673 + elseif ($id_tags = $this->simplepie->get_channel_tags($pair[0], $pair[1])) :
674 + $ret = $id_tags[0]['data'];
675 + break;
676 + endif;
677 + endforeach;
678 + endif;
679 + return $ret;
680 + }
681 +
682 + function ttl ($return_element = false) {
336 683 if (is_object($this->magpie)) :
337 684 $channel = $this->magpie->channel;
338 685 else :
339 686 $channel = array();
@@ -343,8 +690,9 @@
343 690 // "ttl stands for time to live. It's a number of
344 691 // minutes that indicates how long a channel can be
345 692 // cached before refreshing from the source."
346 693 // <http://blogs.law.harvard.edu/tech/rss#ltttlgtSubelementOfLtchannelgt>
694 + $xml = 'rss:ttl';
347 695 $ret = $channel['ttl'];
348 696 elseif (isset($channel['sy']['updatefrequency']) or isset($channel['sy']['updateperiod'])) :
349 697 $period_minutes = array (
350 698 'hourly' => 60, /* minutes in an hour */
@@ -370,15 +718,38 @@
370 718 if (isset($channel['sy']['updatefrequency'])) : $freq = (int) $channel['sy']['updatefrequency'];
371 719 else : $freq = 1;
372 720 endif;
373 721
722 + $xml = 'sy:updateFrequency';
374 723 $ret = (int) ($period_minutes[$period] / $freq);
375 724 else :
725 + $xml = NULL;
376 726 $ret = NULL;
377 727 endif;
378 - return $ret;
728 +
729 + if ('yes'==$this->setting('update/minimum', 'update_minimum', 'no')) :
730 + $min = (int) $this->setting('update/window', 'update_window', DEFAULT_UPDATE_PERIOD);
731 +
732 + if ($min > $ret) :
733 + $ret = NULL;
734 + endif;
735 + endif;
736 + return ($return_element ? array($ret, $xml) : $ret);
379 737 } /* SyndicatedLink::ttl() */
380 738
739 + function automatic_ttl () {
740 + // spread out over a time interval for staggered updates
741 + $updateWindow = $this->setting('update/window', 'update_window', DEFAULT_UPDATE_PERIOD);
742 + if (!is_numeric($updateWindow) or ($updateWindow < 1)) :
743 + $updateWindow = DEFAULT_UPDATE_PERIOD;
744 + endif;
745 +
746 + // We get a fudge of 1/3 of window from elsewhere. We'll do some more
747 + // fudging here.
748 + $fudgedInterval = $updateWindow+rand(-($updateWindow/6), 5*($updateWindow/12));
749 + return apply_filters('syndicated_feed_automatic_ttl', $fudgedInterval, $this);
750 + } /* SyndicatedLink::automatic_ttl () */
751 +
381 752 // SyndicatedLink::flatten_array (): flatten an array. Useful for
382 753 // hierarchical and namespaced elements.
383 754 //
384 755 // Given an array which may contain array or object elements in it,
@@ -416,17 +787,31 @@
416 787 endif;
417 788 return $ret;
418 789 } /* SyndicatedLink::hardcode () */
419 790
420 - function syndicated_status ($what, $default) {
791 + function syndicated_status ($what, $default, $fallback = true) {
421 792 global $wpdb;
422 793
423 - $ret = get_option("feedwordpress_syndicated_{$what}_status");
794 + // Use local setting if we have it
424 795 if ( isset($this->settings["$what status"]) ) :
425 796 $ret = $this->settings["$what status"];
426 - elseif (!$ret) :
797 +
798 + // Or fall back to global default if we can
799 + elseif ($fallback) :
800 + $ret = FeedWordPress::syndicated_status($what, $default);
801 +
802 + // Or use default value if we can't.
803 + else :
427 804 $ret = $default;
805 +
428 806 endif;
807 +
429 808 return $wpdb->escape(trim(strtolower($ret)));
430 809 } /* SyndicatedLink:syndicated_status () */
810 +
811 + function taxonomies () {
812 + $post_type = $this->setting('syndicated post type', 'syndicated_post_type', 'post');
813 + return get_object_taxonomies(array('object_type' => $post_type), 'names');
814 + } /* SyndicatedLink::taxonomies () */
815 +
431 816 } // class SyndicatedLink
432 817