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