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 +374 -69 2009.11112011.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,31 +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 - // spread out over a time interval for staggered updates
196 - if (isset($this->settings['update/window'])) :
197 - $updateWindow = $this->settings['update/window'];
198 - else :
199 - $updateWindow = get_option('feedwordpress_update_window');
200 - endif;
201 -
202 - if (!is_numeric($updateWindow) or ($updateWindow < 1)) :
203 - $updateWindow = DEFAULT_UPDATE_PERIOD;
204 - endif;
205 -
206 - $fudgedInterval = $updateWindow+rand(0, 2*($updateWindow/3));
207 - $this->settings['update/ttl'] = apply_filters('syndicated_feed_automatic_ttl', $fudgedInterval, $this);
296 + $ttl = $this->automatic_ttl();
297 + $this->settings['update/ttl'] = $ttl;
298 + $this->settings['update/xml'] = NULL;
208 299 $this->settings['update/timed'] = 'automatically';
209 300 endif;
210 - $this->settings['update/ttl'] = apply_filters('syndicated_feed_ttl', $this->settings['update/ttl'], $this);
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);
211 303
212 - if (!isset($this->settings['update/hold']) or $this->settings['update/hold']!='ping') :
304 + if (!$this->setting('update/hold') != 'ping') :
213 305 $this->settings['update/hold'] = 'scheduled';
214 306 endif;
215 307
216 308 $this->settings['update/unfinished'] = 'yes';
@@ -224,15 +316,25 @@
224 316 UPDATE $wpdb->links
225 317 SET $update_set
226 318 WHERE link_id='$this->id'
227 319 ");
320 + do_action('update_syndicated_feed', $this->id, $this);
228 321
229 322 # -- Add new posts from feed and update any updated posts
230 323 $crashed = false;
231 324
232 - if (is_array($this->magpie->items)) :
233 - foreach ($this->magpie->items as $item) :
234 - $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 +
235 337 if (!$resume or !in_array(trim($post->guid()), $processed)) :
236 338 $processed[] = $post->guid();
237 339 if (!$post->filtered()) :
238 340 $new = $post->store();
@@ -243,11 +345,15 @@
243 345 $crashed = true;
244 346 break;
245 347 endif;
246 348 endif;
349 + unset($post);
247 350 endforeach;
248 351 endif;
249 -
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 +
250 356 // Copy back any changes to feed settings made in the course of updating (e.g. new author rules)
251 357 $to_notes = $this->settings;
252 358
253 359 $this->settings['update/processed'] = $processed;
@@ -262,10 +368,22 @@
262 368 UPDATE $wpdb->links
263 369 SET $update_set
264 370 WHERE link_id='$this->id'
265 371 ");
372 +
373 + do_action("update_syndicated_feed_completed", $this->id, $this);
266 374 endif;
267 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 +
268 386 return $new_count;
269 387 } /* SyndicatedLink::poll() */
270 388
271 389 /**
@@ -292,24 +410,61 @@
292 410 endif;
293 411 return $ret;
294 412 } /* SyndicatedLink::set_uri () */
295 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 +
296 462 function map_name_to_new_user ($name, $newuser_name) {
297 463 global $wpdb;
298 464
299 465 if (strlen($newuser_name) > 0) :
300 - $userdata = array();
301 - $userdata['ID'] = NULL;
302 -
303 - $userdata['user_login'] = sanitize_user($newuser_name);
304 - $userdata['user_login'] = apply_filters('pre_user_login', $userdata['user_login']);
305 -
306 - $userdata['user_nicename'] = sanitize_title($newuser_name);
307 - $userdata['user_nicename'] = apply_filters('pre_user_nicename', $userdata['user_nicename']);
308 -
309 - $userdata['display_name'] = $wpdb->escape($newuser_name);
310 -
311 - $newuser_id = wp_insert_user($userdata);
466 + $newuser_id = fwp_insert_new_user($newuser_name);
312 467 if (is_numeric($newuser_id)) :
313 468 if (is_null($name)) : // Unfamiliar author
314 469 $this->settings['unfamiliar author'] = $newuser_id;
315 470 else :
@@ -322,8 +477,11 @@
322 477 // TODO: Add some error reporting
323 478 endif;
324 479 } /* SyndicatedLink::map_name_to_new_user () */
325 480
481 + function imploded_settings () {
482 + return array('cats', 'tags', 'match/cats', 'match/tags', 'match/filter');
483 + }
326 484 function settings_to_notes () {
327 485 $to_notes = $this->settings;
328 486
329 487 unset($to_notes['link/id']); // Magic setting; don't save
@@ -336,15 +494,22 @@
336 494 if (isset($to_notes['update/processed']) and (is_array($to_notes['update/processed']))) :
337 495 $to_notes['update/processed'] = implode("\n", $to_notes['update/processed']);
338 496 endif;
339 497
340 - if (isset($to_notes['cats']) and is_array($to_notes['cats'])) :
341 - $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']);
342 510 endif;
343 - if (isset($to_notes['tags']) and is_array($to_notes['tags'])) :
344 - $to_notes['tags'] = implode(FEEDWORDPRESS_CAT_SEPARATOR, $to_notes['tags']);
345 - endif;
346 -
511 +
347 512 // Collapse the author mapping rule structure back into a flat string
348 513 if (isset($to_notes['map authors'])) :
349 514 $ma = array();
350 515 foreach ($to_notes['map authors'] as $rule_type => $author_rules) :
@@ -364,11 +529,19 @@
364 529
365 530 function save_settings ($reload = false) {
366 531 global $wpdb;
367 532
368 - $update_set = "link_notes = '".$wpdb->escape($this->settings_to_notes())."'";
369 -
370 - // Update the properties of the link from the feed information
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 +
371 544 $result = $wpdb->query("
372 545 UPDATE $wpdb->links
373 546 SET $update_set
374 547 WHERE link_id='$this->id'
@@ -374,9 +547,9 @@
374 547 WHERE link_id='$this->id'
375 548 ");
376 549
377 550 if ($reload) :
378 - // reload link information from DB
551 + // force reload of link information from DB
379 552 if (function_exists('clean_bookmark_cache')) :
380 553 clean_bookmark_cache($this->id);
381 554 endif;
382 555 endif;
@@ -381,31 +554,133 @@
381 554 endif;
382 555 endif;
383 556 } /* SyndicatedLink::save_settings () */
384 557
385 - function uri () {
386 - return (is_object($this->link) ? $this->link->link_rss : NULL);
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;
387 631 } /* SyndicatedLink::uri () */
388 632
389 - function homepage ($fromFeed = true) {
633 + function property_cascade ($fromFeed, $link_field, $setting, $simplepie_method) {
634 + $value = NULL;
390 635 if ($fromFeed) :
391 - $url = (isset($this->settings['feed/link']) ? $this->settings['feed/link'] : NULL);
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;
392 642 else :
393 - $url = $this->link->link_url;
643 + $value = $this->link->{$link_field};
394 644 endif;
395 - return $url;
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');
396 650 } /* SyndicatedLink::homepage () */
397 651
398 652 function name ($fromFeed = true) {
399 - if ($fromFeed) :
400 - $name = (isset($this->settings['feed/title']) ? $this->settings['feed/title'] : NULL);
401 - else :
402 - $name = $this->link->link_name;
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;
403 678 endif;
404 - return $name;
405 - } /* SyndicatedLink::name () */
679 + return $ret;
680 + }
406 681
407 - function ttl () {
682 + function ttl ($return_element = false) {
408 683 if (is_object($this->magpie)) :
409 684 $channel = $this->magpie->channel;
410 685 else :
411 686 $channel = array();
@@ -415,8 +690,9 @@
415 690 // "ttl stands for time to live. It's a number of
416 691 // minutes that indicates how long a channel can be
417 692 // cached before refreshing from the source."
418 693 // <http://blogs.law.harvard.edu/tech/rss#ltttlgtSubelementOfLtchannelgt>
694 + $xml = 'rss:ttl';
419 695 $ret = $channel['ttl'];
420 696 elseif (isset($channel['sy']['updatefrequency']) or isset($channel['sy']['updateperiod'])) :
421 697 $period_minutes = array (
422 698 'hourly' => 60, /* minutes in an hour */
@@ -442,15 +718,38 @@
442 718 if (isset($channel['sy']['updatefrequency'])) : $freq = (int) $channel['sy']['updatefrequency'];
443 719 else : $freq = 1;
444 720 endif;
445 721
722 + $xml = 'sy:updateFrequency';
446 723 $ret = (int) ($period_minutes[$period] / $freq);
447 724 else :
725 + $xml = NULL;
448 726 $ret = NULL;
449 727 endif;
450 - 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);
451 737 } /* SyndicatedLink::ttl() */
452 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 +
453 752 // SyndicatedLink::flatten_array (): flatten an array. Useful for
454 753 // hierarchical and namespaced elements.
455 754 //
456 755 // Given an array which may contain array or object elements in it,
@@ -507,6 +806,12 @@
507 806 endif;
508 807
509 808 return $wpdb->escape(trim(strtolower($ret)));
510 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 +
511 816 } // class SyndicatedLink
512 817