| @@ -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; |
| @@ -123,9 +126,9 @@ | ||
| 123 | 126 | endif; |
| 124 | 127 | } /* SyndicatedLink::SyndicatedLink () */ |
| 125 | 128 | |
| 126 | 129 | function found () { |
| 127 | - return is_object($this->link); | |
| 130 | + return is_object($this->link) and !is_wp_error($this->link); | |
| 128 | 131 | } /* SyndicatedLink::found () */ |
| 129 | 132 | |
| 130 | 133 | function stale () { |
| 131 | 134 | $stale = true; |
| @@ -145,9 +148,23 @@ | ||
| 145 | 148 | |
| 146 | 149 | function poll ($crash_ts = NULL) { |
| 147 | 150 | global $wpdb; |
| 148 | 151 | |
| 149 | - $this->magpie = fetch_rss($this->link->link_rss); | |
| 152 | + FeedWordPress::diagnostic('updated_feeds', 'Polling feed <'.$this->link->link_rss.'>'); | |
| 153 | + | |
| 154 | + $this->simplepie = apply_filters( | |
| 155 | + 'syndicated_feed', | |
| 156 | + FeedWordPress::fetch($this->link->link_rss), | |
| 157 | + $this | |
| 158 | + ); | |
| 159 | + | |
| 160 | + // Filter compatibility mode | |
| 161 | + if (is_wp_error($this->simplepie)) : | |
| 162 | + $this->magpie = $this->simplepie; | |
| 163 | + else : | |
| 164 | + $this->magpie = new MagpieFromSimplePie($this->simplepie); | |
| 165 | + endif; | |
| 166 | + | |
| 150 | 167 | $new_count = NULL; |
| 151 | 168 | |
| 152 | 169 | $resume = FeedWordPress::affirmative($this->settings, 'update/unfinished'); |
| 153 | 170 | if ($resume) : |
| @@ -157,9 +174,11 @@ | ||
| 157 | 174 | // begin at the beginning |
| 158 | 175 | $processed = array(); |
| 159 | 176 | endif; |
| 160 | 177 | |
| 161 | - if (is_object($this->magpie)) : | |
| 178 | + if (is_wp_error($this->simplepie)) : | |
| 179 | + $new_count = $this->simplepie; | |
| 180 | + elseif (is_object($this->simplepie)) : | |
| 162 | 181 | $new_count = array('new' => 0, 'updated' => 0); |
| 163 | 182 | |
| 164 | 183 | # -- Update Link metadata live from feed |
| 165 | 184 | $channel = $this->magpie->channel; |
| @@ -192,14 +211,13 @@ | ||
| 192 | 211 | $this->settings['update/ttl'] = $ttl; |
| 193 | 212 | $this->settings['update/timed'] = 'feed'; |
| 194 | 213 | else : |
| 195 | 214 | // 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 | - | |
| 215 | + $updateWindow = $this->setting( | |
| 216 | + 'update/window', | |
| 217 | + 'update_window', | |
| 218 | + DEFAULT_UPDATE_PERIOD | |
| 219 | + ); | |
| 202 | 220 | if (!is_numeric($updateWindow) or ($updateWindow < 1)) : |
| 203 | 221 | $updateWindow = DEFAULT_UPDATE_PERIOD; |
| 204 | 222 | endif; |
| 205 | 223 | |
| @@ -224,15 +242,26 @@ | ||
| 224 | 242 | UPDATE $wpdb->links |
| 225 | 243 | SET $update_set |
| 226 | 244 | WHERE link_id='$this->id' |
| 227 | 245 | "); |
| 246 | + do_action('update_syndicated_feed', $this->id, $this); | |
| 228 | 247 | |
| 229 | 248 | # -- Add new posts from feed and update any updated posts |
| 230 | 249 | $crashed = false; |
| 231 | 250 | |
| 232 | - if (is_array($this->magpie->items)) : | |
| 233 | - foreach ($this->magpie->items as $item) : | |
| 234 | - $post =& new SyndicatedPost($item, $this); | |
| 251 | + $posts = apply_filters( | |
| 252 | + 'syndicated_feed_items', | |
| 253 | + $this->magpie->originals, | |
| 254 | + $this | |
| 255 | + ); | |
| 256 | + if (is_array($posts)) : | |
| 257 | + foreach ($posts as $key => $original) : | |
| 258 | + $item = $this->magpie->items[$key]; | |
| 259 | + $post = new SyndicatedPost(array( | |
| 260 | + 'simplepie' => $original, | |
| 261 | + 'magpie' => $item, | |
| 262 | + ), $this); | |
| 263 | + | |
| 235 | 264 | if (!$resume or !in_array(trim($post->guid()), $processed)) : |
| 236 | 265 | $processed[] = $post->guid(); |
| 237 | 266 | if (!$post->filtered()) : |
| 238 | 267 | $new = $post->store(); |
| @@ -243,11 +272,15 @@ | ||
| 243 | 272 | $crashed = true; |
| 244 | 273 | break; |
| 245 | 274 | endif; |
| 246 | 275 | endif; |
| 276 | + unset($post); | |
| 247 | 277 | endforeach; |
| 248 | 278 | endif; |
| 249 | - | |
| 279 | + $suffix = ($crashed ? 'crashed' : 'completed'); | |
| 280 | + do_action('update_syndicated_feed_items', $this->id, $this); | |
| 281 | + do_action("update_syndicated_feed_items_${suffix}", $this->id, $this); | |
| 282 | + | |
| 250 | 283 | // Copy back any changes to feed settings made in the course of updating (e.g. new author rules) |
| 251 | 284 | $to_notes = $this->settings; |
| 252 | 285 | |
| 253 | 286 | $this->settings['update/processed'] = $processed; |
| @@ -262,8 +295,10 @@ | ||
| 262 | 295 | UPDATE $wpdb->links |
| 263 | 296 | SET $update_set |
| 264 | 297 | WHERE link_id='$this->id' |
| 265 | 298 | "); |
| 299 | + | |
| 300 | + do_action("update_syndicated_feed_completed", $this->id, $this); | |
| 266 | 301 | endif; |
| 267 | 302 | |
| 268 | 303 | return $new_count; |
| 269 | 304 | } /* SyndicatedLink::poll() */ |
| @@ -364,11 +399,19 @@ | ||
| 364 | 399 | |
| 365 | 400 | function save_settings ($reload = false) { |
| 366 | 401 | global $wpdb; |
| 367 | 402 | |
| 368 | - $update_set = "link_notes = '".$wpdb->escape($this->settings_to_notes())."'"; | |
| 369 | - | |
| 370 | - // Update the properties of the link from the feed information | |
| 403 | + // Save channel-level meta-data | |
| 404 | + foreach (array('link_name', 'link_description', 'link_url') as $what) : | |
| 405 | + $alter[] = "{$what} = '".$wpdb->escape($this->link->{$what})."'"; | |
| 406 | + endforeach; | |
| 407 | + | |
| 408 | + // Save settings to the notes field | |
| 409 | + $alter[] = "link_notes = '".$wpdb->escape($this->settings_to_notes())."'"; | |
| 410 | + | |
| 411 | + // Update the properties of the link from settings changes, etc. | |
| 412 | + $update_set = implode(", ", $alter); | |
| 413 | + | |
| 371 | 414 | $result = $wpdb->query(" |
| 372 | 415 | UPDATE $wpdb->links |
| 373 | 416 | SET $update_set |
| 374 | 417 | WHERE link_id='$this->id' |
| @@ -374,14 +417,49 @@ | ||
| 374 | 417 | WHERE link_id='$this->id' |
| 375 | 418 | "); |
| 376 | 419 | |
| 377 | 420 | if ($reload) : |
| 378 | - // reload link information from DB | |
| 421 | + // force reload of link information from DB | |
| 379 | 422 | if (function_exists('clean_bookmark_cache')) : |
| 380 | 423 | clean_bookmark_cache($this->id); |
| 381 | 424 | endif; |
| 382 | 425 | endif; |
| 383 | 426 | } /* SyndicatedLink::save_settings () */ |
| 427 | + | |
| 428 | + /** | |
| 429 | + * Retrieves the value of a setting, allowing for a global setting to be | |
| 430 | + * used as a fallback, or a constant value, or both. | |
| 431 | + * | |
| 432 | + * @param string $name The link setting key | |
| 433 | + * @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. | |
| 434 | + * @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. | |
| 435 | + * @return bool TRUE on success, FALSE on failure. | |
| 436 | + */ | |
| 437 | + function setting ($name, $fallback_global = NULL, $fallback_value = NULL) { | |
| 438 | + $ret = NULL; | |
| 439 | + if (isset($this->settings[$name])) : | |
| 440 | + $ret = $this->settings[$name]; | |
| 441 | + endif; | |
| 442 | + | |
| 443 | + $no_value = ( | |
| 444 | + is_null($ret) | |
| 445 | + or (is_string($ret) and strtolower($ret)=='default') | |
| 446 | + ); | |
| 447 | + | |
| 448 | + if ($no_value and !is_null($fallback_global)) : | |
| 449 | + $ret = get_option('feedwordpress_'.$fallback_global, /*default=*/ NULL); | |
| 450 | + endif; | |
| 451 | + | |
| 452 | + $no_value = ( | |
| 453 | + is_null($ret) | |
| 454 | + or (is_string($ret) and strtolower($ret)=='default') | |
| 455 | + ); | |
| 456 | + | |
| 457 | + if ($no_value and !is_null($fallback_value)) : | |
| 458 | + $ret = $fallback_value; | |
| 459 | + endif; | |
| 460 | + return $ret; | |
| 461 | + } /* SyndicatedLink::setting () */ | |
| 384 | 462 | |
| 385 | 463 | function uri () { |
| 386 | 464 | return (is_object($this->link) ? $this->link->link_rss : NULL); |
| 387 | 465 | } /* SyndicatedLink::uri () */ |