PluginProbe
FeedWordPress / 2016.1213
FeedWordPress v2016.1213
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 | feeds-page.php +860 -388 2009.11112016.1213 View file →
@@ -1,8 +1,9 @@
1 1 <?php
2 2 require_once(dirname(__FILE__) . '/admin-ui.php');
3 3 require_once(dirname(__FILE__) . '/magpiemocklink.class.php');
4 4 require_once(dirname(__FILE__) . '/feedfinder.class.php');
5 +require_once(dirname(__FILE__) . '/updatedpostscontrol.class.php');
5 6
6 7 class FeedWordPressFeedsPage extends FeedWordPressAdminPage {
7 8 var $HTTPStatusMessages = array (
8 9 200 => 'OK. FeedWordPress had no problems retrieving the content at this URL but the content does not seem to be a feed, and does not seem to include links to any feeds.',
@@ -43,166 +44,148 @@
43 44 503 => 'Service Unavailable. The server is currently unable to handle the request due to a temporary overloading or maintenance of the server that hosts this URL. This is probably a temporary condition and you should try again later to see if the issue has been resolved.',
44 45 504 => 'Gateway Timeout',
45 46 505 => 'HTTP Version Not Supported',
46 47 );
48 + var $updatedPosts = NULL;
47 49
48 - /**
49 - * Constructs the Feeds page object
50 - *
51 - * @param mixed $link An object of class {@link SyndicatedLink} if created for one feed's settings, NULL if created for global default settings
52 - */
53 - function FeedWordPressFeedsPage ($link = -1) {
54 - if (is_numeric($link) and -1 == $link) :
55 - $link = FeedWordPressAdminPage::submitted_link();
56 - endif;
57 -
58 - FeedWordPressAdminPage::FeedWordPressAdminPage('feedwordpressfeeds', $link);
59 -
60 - $this->dispatch = get_class($this);
61 - $this->filename = __FILE__;
62 - } /* FeedWordPressFeedsPage constructor */
63 -
64 50 var $special_settings = array ( /* Regular expression syntax is OK here */
65 51 'cats',
66 52 'cat_split',
53 + 'fetch timeout',
54 + 'freeze updates',
67 55 'hardcode name',
68 56 'hardcode url',
69 57 'hardcode description',
70 58 'hardcode categories', /* Deprecated */
71 - 'post status',
72 59 'comment status',
60 + 'terms',
61 + 'map authors',
62 + 'munge permalink',
73 63 'ping status',
64 + 'post status',
65 + 'postmeta',
66 + 'query parameters',
67 + 'resolve relative',
68 + 'syndicated post type',
69 + 'tags',
74 70 'unfamiliar author',
75 71 'unfamliar categories', /* Deprecated */
76 72 'unfamiliar category',
77 - 'map authors',
78 - 'tags',
79 - 'postmeta',
73 + 'unfamiliar post_tag',
74 + 'add/.*',
80 75 'update/.*',
81 76 'feed/.*',
82 77 'link/.*',
78 + 'match/.*',
83 79 );
84 80
81 + /**
82 + * Constructs the Feeds page object
83 + *
84 + * @param mixed $link An object of class {@link SyndicatedLink} if created for one feed's settings, NULL if created for global default settings
85 + */
86 + public function __construct( $link = -1 ) {
87 + if (is_numeric($link) and -1 == $link) :
88 + $link = $this->submitted_link();
89 + endif;
90 +
91 + parent::__construct('feedwordpressfeeds', $link);
92 +
93 + $this->dispatch = 'feedwordpress_admin_page_feeds';
94 + $this->pagenames = array(
95 + 'default' => 'Feeds',
96 + 'settings-update' => 'Syndicated feed',
97 + 'open-sheet' => 'Feed and Update',
98 + );
99 + $this->filename = __FILE__;
100 + $this->updatedPosts = new UpdatedPostsControl($this);
101 +
102 + $this->special_settings = apply_filters('syndicated_feed_special_settings', $this->special_settings, $this);
103 + } /* FeedWordPressFeedsPage constructor */
104 +
85 105 function display () {
86 - global $wpdb;
87 106 global $fwp_post;
88 107 global $post_source;
89 -
90 - if (FeedWordPress::needs_upgrade()) :
91 - fwp_upgrade_page();
92 - return;
93 - endif;
94 108
109 + $this->boxes_by_methods = array(
110 + 'feed_information_box' => __('Feed Information'),
111 + 'global_feeds_box' => __('Update Scheduling'),
112 + 'updated_posts_box' => __('Updated Posts'),
113 + 'custom_settings_box' => __('Custom Feed Settings (for use in templates)'),
114 + 'advanced_settings_box' => __('Advanced Settings'),
115 + );
116 + if ($this->for_default_settings()) :
117 + unset($this->boxes_by_methods['custom_settings_box']);
118 + endif;
119 +
95 120 // Allow overriding of normal source for FeedFinder, which may
96 121 // be called from multiple points.
97 122 if (isset($post_source) and !is_null($post_source)) :
98 123 $source = $post_source;
99 124 else :
100 - $source = get_class($this);
125 + $source = $this->dispatch;
101 126 endif;
102 127
103 - // If this is a POST, validate source and user credentials
104 - FeedWordPressCompatibility::validate_http_request(/*action=*/ $source, /*capability=*/ 'manage_links');
105 -
106 128 if (isset($_REQUEST['feedfinder'])
107 129 or (isset($_REQUEST['action']) and $_REQUEST['action']=='feedfinder')
108 130 or (isset($_REQUEST['action']) and $_REQUEST['action']==FWP_SYNDICATE_NEW)) :
131 + // If this is a POST, validate source and user credentials
132 + FeedWordPressCompatibility::validate_http_request(/*action=*/ $source, /*capability=*/ 'manage_links');
133 +
109 134 return $this->display_feedfinder(); // re-route to Feed Finder page
110 - else :
111 - if (strtoupper($_SERVER['REQUEST_METHOD'])=='POST') :
112 - $this->accept_POST($fwp_post);
113 - do_action('feedwordpress_admin_page_feeds_save', $GLOBALS['fwp_post'], $this);
114 - endif;
115 -
116 - ////////////////////////////////////////////////
117 - // Prepare settings page ///////////////////////
118 - ////////////////////////////////////////////////
119 -
120 - $this->ajax_interface_js();
121 - $this->display_update_notice_if_updated('Syndicated feed');
122 - $this->open_sheet('Feed and Update');
123 - ?>
124 - <div id="post-body">
125 - <?php
126 - ////////////////////////////////////////////////
127 - // Display settings boxes //////////////////////
128 - ////////////////////////////////////////////////
129 -
130 - $boxes_by_methods = array(
131 - 'feed_information_box' => __('Feed Information'),
132 - 'global_feeds_box' => __('Update Scheduling'),
133 - 'posts_box' => __('Syndicated Posts, Links, Comments & Pings'),
134 - 'authors_box' => __('Syndicated Authors'),
135 - 'categories_box' => __('Categories'.FEEDWORDPRESS_AND_TAGS),
136 - 'custom_settings_box' => __('Custom Feed Settings (for use in templates)'),
137 - );
138 - if ($this->for_default_settings()) :
139 - unset($boxes_by_methods['custom_settings_box']);
140 - endif;
141 -
142 - foreach ($boxes_by_methods as $method => $row) :
143 - if (is_array($row)) :
144 - $id = $row['id'];
145 - $title = $row['title'];
146 - else :
147 - $id = 'feedwordpress_'.$method;
148 - $title = $row;
149 - endif;
150 -
151 - fwp_add_meta_box(
152 - /*id=*/ $id,
153 - /*title=*/ $title,
154 - /*callback=*/ array(get_class($this), $method),
155 - /*page=*/ $this->meta_box_context(),
156 - /*context=*/ $this->meta_box_context()
157 - );
158 - endforeach;
159 - do_action('feedwordpress_admin_page_feeds_meta_boxes', $this);
160 - ?>
161 - <div class="metabox-holder">
162 - <?php
163 - fwp_do_meta_boxes($this->meta_box_context(), $this->meta_box_context(), $this);
164 - ?>
165 - </div> <!-- class="metabox-holder" -->
166 - </div> <!-- id="post-body" -->
167 - <?php $this->close_sheet(); ?>
135 + endif;
168 136
169 - <script type="text/javascript">
170 - var els = ['name', 'description', 'url'];
171 - for (var i = 0; i < els.length; i++) {
172 - contextual_appearance(
173 - /*item=*/ 'basics-hardcode-'+els[i],
174 - /*appear=*/ 'basics-'+els[i]+'-view',
175 - /*disappear=*/ 'basics-'+els[i]+'-edit',
176 - /*value=*/ 'no',
177 - /*visibleStyle=*/ 'block',
178 - /*checkbox=*/ true
179 - );
180 - } /* for */
181 - </script>
182 - <?php
183 - endif;
137 + parent::display();
184 138 return false; // Don't continue
185 139 } /* FeedWordPressFeedsPage::display() */
186 140
187 - /*static*/ function global_feeds_box ($page, $box = NULL) {
188 - global $wpdb;
141 + function ajax_interface_js () {
142 + parent::ajax_interface_js();
143 + ?>
189 144
190 - $defaultUpdateWindow = get_option('feedwordpress_update_window');
191 - if (!is_numeric($defaultUpdateWindow)) :
192 - $defaultUpdateWindow = DEFAULT_UPDATE_PERIOD;
193 - else :
194 - $defaultUpdateWindow = (int) $defaultUpdateWindow;
195 - endif;
145 + jQuery(document).ready( function () {
146 + contextual_appearance('automatic-updates-selector', 'cron-job-explanation', null, 'no');
147 + contextual_appearance('time-limit', 'time-limit-box', null, 'yes');
148 + contextual_appearance('use-default-update-window-no', 'update-scheduling-note', null, null, 'block', true);
149 + jQuery('#use-default-update-window-yes, #use-default-update-window-no').click( function () {
150 + contextual_appearance('use-default-update-window-no', 'update-scheduling-note', null, null, 'block', true);
151 + } );
152 +
153 + var els = ['name', 'description', 'url'];
154 + for (var i = 0; i < els.length; i++) {
155 + contextual_appearance(
156 + /*item=*/ 'basics-hardcode-'+els[i],
157 + /*appear=*/ 'basics-'+els[i]+'-view',
158 + /*disappear=*/ 'basics-'+els[i]+'-edit',
159 + /*value=*/ 'no',
160 + /*visibleStyle=*/ 'block',
161 + /*checkbox=*/ true
162 + );
163 + } /* for */
164 + } );
165 +
166 + <?php
167 + }
168 +
169 + /*static*/ function updated_posts_box ($page, $box = NULL) {
196 170 ?>
197 -
198 171 <table class="edit-form">
172 + <?php $page->updatedPosts->display(); ?>
173 + </table>
199 174 <?php
200 - if ($page->for_default_settings()) :
201 - $automatic_updates = get_option('feedwordpress_automatic_updates');
202 - $update_time_limit = (int) get_option('feedwordpress_update_time_limit');
175 + } /* FeedWordPressFeedsPage::updated_posts_box() */
176 +
177 + /*static*/ function global_feeds_box ($page, $box = NULL) {
178 + global $feedwordpress;
179 + $automatic_updates = $feedwordpress->automatic_update_hook(array('setting only' => true));
180 + $update_time_limit = (int) get_option('feedwordpress_update_time_limit');
181 +
182 + // Hey, ho, let's go...
203 183 ?>
204 184
185 + <table class="edit-form">
186 + <?php if ($page->for_default_settings()) : ?>
187 +
205 188 <tr>
206 189 <th scope="row">Updates:</th>
207 190 <td><select id="automatic-updates-selector" name="automatic_updates" size="1" onchange="contextual_appearance('automatic-updates-selector', 'cron-job-explanation', null, 'no');">
208 191 <option value="shutdown"<?php echo ($automatic_updates=='shutdown')?' selected="selected"':''; ?>>automatically check for updates after pages load</option>
@@ -209,13 +192,26 @@
209 192 <option value="init"<?php echo ($automatic_updates=='init')?' selected="selected"':''; ?>>automatically check for updates before pages load</option>
210 193 <option value="no"<?php echo (!$automatic_updates)?' selected="selected"':''; ?>>cron job or manual updates</option>
211 194 </select>
212 195 <div id="cron-job-explanation" class="setting-description">
213 - <p>If you want to use a cron job,
196 + <p><?php
197 + $path = `which curl`; $opts = '--silent %s';
198 + if (is_null($path) or strlen(trim($path))==0) :
199 + $path = `which wget`; $opts = '-q -O - %s';
200 + if (is_null($path) or strlen(trim($path))==0) :
201 + $path = '/usr/bin/curl'; $opts = '--silent %s';
202 + endif;
203 + endif;
204 + $path = preg_replace('/\n+$/', '', $path);
205 + $crontab = `crontab -l`;
206 +
207 + $cmdline = $path . ' ' . sprintf($opts, get_bloginfo('url').'?update_feedwordpress=1');
208 +
209 + ?>If you want to use a cron job,
214 210 you can perform scheduled updates by sending regularly-scheduled
215 - requests to <a href="<?php bloginfo('home'); ?>?update_feedwordpress=1"><code><?php bloginfo('home') ?>?update_feedwordpress=1</code></a>
211 + requests to <a href="<?php bloginfo('url'); ?>?update_feedwordpress=1"><code><?php bloginfo('url') ?>?update_feedwordpress=1</code></a>
216 212 For example, inserting the following line in your crontab:</p>
217 - <pre style="font-size: 0.80em"><code>*/10 * * * * /usr/bin/curl --silent <?php bloginfo('home'); ?>?update_feedwordpress=1</code></pre>
213 + <pre style="font-size: 0.80em"><code>*/10 * * * * <?php print esc_html($cmdline); ?></code></pre>
218 214 <p class="setting-description">will check in every 10 minutes
219 215 and check for updates on any feeds that are ready to be polled for updates.</p>
220 216 </div>
221 217 </td>
@@ -220,39 +216,10 @@
220 216 </div>
221 217 </td>
222 218 </tr>
223 219
224 - <tr>
225 - <th scope="row"><?php print __('Update scheduling:') ?></th>
226 - <td><p style="margin-top:0px">How long should FeedWordPress wait between updates before it considers a feed ready to be polled for updates again?</p>
227 - <p style="font-style: italic; margin-left: 2.0em"><label>Wait <input type="text" name="update_window" value="<?php print $defaultUpdateWindow; ?>" size="4" /> minutes between polling.</label></p>
228 - <div class="setting-description">
229 - <p<?php if ($defaultUpdateWindow<50) : ?> style="color: white; background-color: #703030; padding: 1.0em;"<?php endif; ?>><strong>Recommendation.</strong> Unless you are positive that you have the webmaster's permission, you generally should not set FeedWordPress to poll feeds more frequently than once every 60 minutes. Many webmasters consider more frequent automated polling to be abusive, and may complain to your web host, or ban your IP address, as retaliation for hammering their servers too hard.</p>
230 - <p><strong>Note.</strong> This is a default setting that FeedWordPress uses to schedule updates when the feed does not provide any scheduling requests. If a feed does provide update scheduling information (through elements such as <code>&lt;rss:ttl&gt;</code> or <code>&lt;sy:updateFrequency&gt;</code>), FeedWordPress will respect the feed's request.</p>
231 - </div></td>
232 - </tr>
233 -
234 - <tr>
235 - <th scope="row"><?php print __('Time limit on updates'); ?>:</th>
236 - <td><select id="time-limit" name="update_time_limit" size="1" onchange="contextual_appearance('time-limit', 'time-limit-box', null, 'yes');">
237 - <option value="no"<?php echo ($update_time_limit>0)?'':' selected="selected"'; ?>>no time limit on updates</option>
238 - <option value="yes"<?php echo ($update_time_limit>0)?' selected="selected"':''; ?>>limit updates to no more than...</option>
239 - </select>
240 - <span id="time-limit-box"><label><input type="text" name="time_limit_seconds" value="<?php print $update_time_limit; ?>" size="5" /> seconds</label></span>
241 - </tr>
220 + <?php else : /* Feed-specific settings */ ?>
242 221
243 - <?php else :
244 - $useDefaultUpdateWindow = !(isset($page->link->settings['update/window']));
245 -
246 - $updateWindow = (isset($page->link->settings['update/window']) ? $page->link->settings['update/window'] : null);
247 - if (!is_numeric($updateWindow)) :
248 - $updateWindow = 60;
249 - else :
250 - $updateWindow = (int) $updateWindow;
251 - endif;
252 -
253 - ?>
254 -
255 222 <tr>
256 223 <th scope="row"><?php _e('Last update') ?>:</th>
257 224 <td><?php
258 225 if (isset($page->link->settings['update/last'])) :
@@ -287,39 +254,240 @@
287 254 ?></option>
288 255 <option value="next"<?php echo ($holdem=='next')?' selected="selected"':''; ?>>update ASAP</option>
289 256 <option value="ping"<?php echo ($holdem=='ping')?' selected="selected"':''; ?>>update only when pinged</option>
290 257 </select></td></tr>
291 -
258 +
259 + <?php endif; ?>
260 +
292 261 <tr>
293 262 <th scope="row"><?php print __('Update scheduling:') ?></th>
294 263 <td><p style="margin-top:0px">How long should FeedWordPress wait between updates before it considers this feed ready to be polled for updates again?</p>
295 - <ul>
296 - <li><label><input type="radio" name="use_default_update_window" value="Yes" <?php if ($useDefaultUpdateWindow) : ?>checked="checked"<?php endif; ?> /> Use site-wide setting (currently <?php print $defaultUpdateWindow; ?> minutes)</li>
297 - <li><label><input type="radio" name="use_default_update_window" value="No" <?php if (!$useDefaultUpdateWindow) : ?>checked="checked"<?php endif; ?> /> Wait <input type="text" name="update_window" value="<?php print $updateWindow; ?>" size="4" /> minutes between polling.</label></li>
298 - </ul>
264 + <?php
265 +
266 + $this->setting_radio_control(
267 + 'update/window', 'update_window',
268 + array($this, 'update_window_edit_box'),
269 + array(
270 + 'global-setting-default' => DEFAULT_UPDATE_PERIOD,
271 + 'default-input-name' => 'use_default_update_window',
272 + 'default-input-id' => 'use-default-update-window-yes',
273 + 'default-input-id-no' => 'use-default-update-window-no',
274 + 'labels' => array($this, 'update_window_currently'),
275 + )
276 + );
277 + ?></td>
278 + </tr>
279 +
280 + <tr>
281 + <th scope="row"><?php print __('Minimum Interval:'); ?></th>
282 + <td><p style="margin-top:0px">Some feeds include standard elements that
283 + request a specific update schedule. If the interval requested by the
284 + feed provider is <em>longer</em> than FeedWordPress's normal scheduling,
285 + FeedWordPress will always respect their request to slow down. But what
286 + should it do if the update interval is <em>shorter</em> than the schedule set above?</p>
287 + <?php
288 + $this->setting_radio_control(
289 + 'update/minimum', 'update_minimum',
290 + /*options=*/ array(
291 + 'no' => 'Speed up and accept the interval from the feed provider',
292 + 'yes' => 'Keep pace and use the longer scheduling from FeedWordPress',
293 + ),
294 + /*params=*/ array(
295 + 'setting-default' => NULL,
296 + 'global-setting-default' => 'no',
297 + 'default-input-value' => 'default',
298 + )
299 + );
300 + ?>
301 + </td>
302 + </tr>
299 303
300 - <div class="setting-description">
304 + <?php if ($this->for_default_settings()) : ?>
305 +
306 + <tr>
307 + <th scope="row"><?php print __('Time limit on updates'); ?>:</th>
308 + <td><select id="time-limit" name="update_time_limit" size="1" onchange="contextual_appearance('time-limit', 'time-limit-box', null, 'yes');">
309 + <option value="no"<?php echo ($update_time_limit>0)?'':' selected="selected"'; ?>>no time limit on updates</option>
310 + <option value="yes"<?php echo ($update_time_limit>0)?' selected="selected"':''; ?>>limit updates to no more than...</option>
311 + </select>
312 + <span id="time-limit-box"><label><input type="text" name="time_limit_seconds" value="<?php print $update_time_limit; ?>" size="5" /> seconds</label></span>
313 + </tr>
314 +
315 + <?php endif; ?>
316 +
317 + </table>
318 +
319 + <?php
320 + } /* FeedWordPressFeedsPage::global_feeds_box() */
321 +
322 + function update_window_edit_box ($updateWindow, $defaulted, $params) {
323 + if (!is_numeric($updateWindow)) :
324 + $updateWindow = DEFAULT_UPDATE_PERIOD;
325 + endif;
326 + ?>
327 + <p>Wait <input type="text" name="update_window" value="<?php print $updateWindow; ?>" size="4" /> minutes between polling.</p>
328 + <div class="setting-description" id="update-scheduling-note">
301 329 <p<?php if ($updateWindow<50) : ?> style="color: white; background-color: #703030; padding: 1.0em;"<?php endif; ?>><strong>Recommendation.</strong> Unless you are positive that you have the webmaster's permission, you generally should not set FeedWordPress to poll feeds more frequently than once every 60 minutes. Many webmasters consider more frequent automated polling to be abusive, and may complain to your web host, or ban your IP address, as retaliation for hammering their servers too hard.</p>
302 330 <p><strong>Note.</strong> This is a default setting that FeedWordPress uses to schedule updates when the feed does not provide any scheduling requests. If this feed does provide update scheduling information (through elements such as <code>&lt;rss:ttl&gt;</code> or <code>&lt;sy:updateFrequency&gt;</code>), FeedWordPress will respect the feed's request.</p>
303 - </div></td>
331 + </div>
332 + <?php
333 + } /* FeedWordPressFeedsPage::update_window_edit_box () */
334 +
335 + function update_window_currently ($updateWindow, $defaulted, $params) {
336 + $updateWindow = (int) $updateWindow;
337 + if (1==$updateWindow) :
338 + $caption = 'wait %d minute between polling';
339 + else :
340 + $caption = 'wait %d minutes between polling';
341 + endif;
342 + return sprintf(__($caption), $updateWindow);
343 + } /* FeedWordPressFeedsPage::update_window_currently () */
344 +
345 + function fetch_timeout_setting ($setting, $defaulted, $params) {
346 + $timeout = intval($this->setting('fetch timeout', FEEDWORDPRESS_FETCH_TIMEOUT_DEFAULT));
347 +
348 + if ($this->for_feed_settings()) :
349 + $article = 'this';
350 + else :
351 + $article = 'a';
352 + endif;
353 + ?>
354 + <p>Wait no more than
355 + than <input name="fetch_timeout" type="number" min="0" size="3" value="<?php print $timeout; ?>" />
356 + second(s) when trying to fetch <?php print $article; ?> feed to check for updates.</p>
357 + <p>If <?php print $article; ?> source's web server does not respond before time runs
358 + out, FeedWordPress will skip over the source and try again during
359 + the next update cycle.</p>
360 + <?php
361 + }
362 + function fetch_timeout_setting_value ($setting, $defaulted, $params) {
363 + print number_format(intval($setting)) . " " . (($setting==1) ? "second" : "seconds");
364 + }
365 +
366 + function advanced_settings_box ($page, $box = NULL) {
367 + ?>
368 + <table class="edit-form">
369 + <tr>
370 + <th>Fetch Timeout:</th>
371 + <td>
372 + <?php
373 + $this->setting_radio_control(
374 + 'fetch timeout', 'fetch_timeout',
375 + array($this, 'fetch_timeout_setting'),
376 + array(
377 + 'global-setting-default' => FEEDWORDPRESS_FETCH_TIMEOUT_DEFAULT,
378 + 'input-name' => 'fetch_timeout',
379 + 'default-input-name' => 'fetch_timeout_default',
380 + 'labels' => array($this, 'fetch_timeout_setting_value'),
381 + )
382 + );
383 + ?>
384 + </td>
304 385 </tr>
305 - <?php endif; ?>
386 + <tr>
387 + <th>Feed Update Type:</th>
388 + <td><?php
389 + $this->setting_radio_control('update_incremental', 'update_incremental',
390 + /*options=*/ array(
391 + 'incremental' => '<strong>Incremental.</strong> When items no longer appear on the feed, keep them in the WordPress posts table.',
392 + 'complete' => '<strong>Complete.</strong> When items no longer appear on the feed, they are obsolete; retire them from the WordPress posts table.',
393 + ),
394 + /*params=*/ array(
395 + 'setting-default' => NULL,
396 + 'global-setting-default' => 'incremental',
397 + 'default-input-value' => 'default',
398 + )
399 + ); ?></td>
400 + </tr>
401 + <tr>
402 + <th>Allow Feeds to Delete Posts:</th>
403 + <td><?php
404 + $this->setting_radio_control('tombstones', 'tombstones',
405 + /*options=*/ array(
406 + 'yes' => 'Yes. If a feed indicates that one of its posts has been deleted, delete the local copy syndicated to this website.',
407 + 'no' => 'No. Even if a feed indicates that one of its posts has been deleted, retain the local copy on this website.',
408 + ),
409 + /*params=*/ array(
410 + 'setting-default' => NULL,
411 + 'global-setting-default' => 'yes',
412 + 'default-input-value' => 'default',
413 + )
414 + ); ?></td>
415 + </tr>
416 + </table>
417 + <?php
418 + } /* FeedWordPressFeedsPage::advanced_settings_box () */
419 +
420 + function display_authentication_credentials_box ($params = array()) {
421 + static $count = 0;
306 422
423 + $params = wp_parse_args($params, array(
424 + 'username' => NULL,
425 + 'password' => NULL,
426 + 'method' => '-',
427 + ));
428 +
429 + // Equivalents
430 + if (is_null($params['method'])) : $params['method'] = '-'; endif;
431 +
432 + $count++;
433 + $slug = ($count > 1 ? '-'.$count : '');
434 +
435 + global $feedwordpress;
436 + $authMethods = apply_filters(
437 + 'feedwordpress_http_auth_methods',
438 + $feedwordpress->httpauth->methods_available()
439 + );
307 440
308 -</table>
309 -<script type="text/javascript">
310 -contextual_appearance('automatic-updates-selector', 'cron-job-explanation', null, 'no');
311 -contextual_appearance('time-limit', 'time-limit-box', null, 'yes');
312 -</script>
313 -<?php
314 - } /* FeedWordPressFeedsPage::global_feeds_box() */
315 -
441 + if (count($authMethods) > 1) : /* More than '-' */
442 + ?>
443 + <div class="link-rss-authentication" id="link-rss-authentication<?php print $slug; ?>">
444 + <table>
445 + <tbody>
446 + <tr class="link-rss-authentication-credentials" id="link-rss-authentication-credentials<?php print $slug; ?>">
447 + <td><label>user: <input type="text" name="link_rss_username"
448 + value="<?php print esc_attr($params['username']); ?>" size="16"
449 + placeholder="username to access this feed" /></label></td>
450 + <td><label>pass: <input type="text" name="link_rss_password"
451 + value="<?php print esc_attr($params['password']); ?>" size="16"
452 + placeholder="password to access this feed" /></label></td>
453 + <td class="link-rss-authentication-method" id="link-rss-authentication-method<?php print $slug; ?>"><label>method: <select class="link-rss-auth-method" id="link-rss-auth-method" name="link_rss_auth_method" size="1">
454 +<?php foreach ($authMethods as $value => $label) : ?>
455 + <option value="<?php print esc_attr($value); ?>"<?php
456 + if ($value == $params['method']) : ?> selected="selected"<?php
457 + endif; ?>><?php print esc_html($label); ?></option>
458 +<?php endforeach; ?>
459 + </select></label></td>
460 + </tr>
461 + </tbody>
462 + </table>
463 + </div>
464 +
465 + <script type="text/javascript">
466 + jQuery('<td><a class="add-remove remove-it" id="link-rss-userpass-remove<?php print $slug; ?>" href="#"><span class="x">(X)</span> Remove</a></td>')
467 + .appendTo('#link-rss-authentication-credentials<?php print $slug; ?>')
468 + .click( feedAuthenticationMethodUnPress );
469 + jQuery('#link-rss-auth-method<?php print $slug; ?>').change( feedAuthenticationMethod );
470 + feedAuthenticationMethod({
471 + init: true,
472 + node: jQuery('#link-rss-authentication<?php print $slug; ?>') });
473 + </script>
474 +
475 + <?php
476 + endif;
477 + }
478 +
316 479 function feed_information_box ($page, $box = NULL) {
317 480 global $wpdb;
481 + $link_rss_params = maybe_unserialize($page->setting('query parameters', ''));
482 + if (!is_array($link_rss_params)) :
483 + $link_rss_params = array();
484 + endif;
485 +
318 486 if ($page->for_feed_settings()) :
319 - $info['name'] = wp_specialchars($page->link->link->link_name, 1);
320 - $info['description'] = wp_specialchars($page->link->link->link_description, 'both');
321 - $info['url'] = wp_specialchars($page->link->link->link_url, 1);
487 + $info['name'] = esc_html($page->link->link->link_name);
488 + $info['description'] = esc_html($page->link->link->link_description);
489 + $info['url'] = esc_html($page->link->link->link_url);
322 490 $rss_url = $page->link->link->link_rss;
323 491
324 492 $hardcode['name'] = $page->link->hardcode('name');
325 493 $hardcode['description'] = $page->link->hardcode('description');
@@ -325,26 +493,29 @@
325 493 $hardcode['description'] = $page->link->hardcode('description');
326 494 $hardcode['url'] = $page->link->hardcode('url');
327 495 else :
328 496 $cat_id = FeedWordPress::link_category_id();
329 - if (FeedWordPressCompatibility::test_version(FWP_SCHEMA_21)) :
330 - $results = get_categories(array(
331 - "type" => 'link',
332 - "hide_empty" => false,
333 - ));
497 +
498 + $params = array();
499 + if (FeedWordPressCompatibility::test_version(FWP_SCHEMA_USES_ARGS_TAXONOMY)) :
500 + $params['taxonomy'] = 'link_category';
501 + else :
502 + $params['type'] = 'link';
503 + endif;
504 + $params['hide_empty'] = false;
505 + $results = get_categories($params);
334 506
335 - // Guarantee that the Contributors category will be in the drop-down chooser, even if it is empty.
336 - $found_link_category_id = false;
337 - foreach ($results as $row) :
338 - // Normalize case
339 - if (!isset($row->cat_id)) : $row->cat_id = $row->cat_ID; endif;
507 + // Guarantee that the Contributors category will be in the drop-down chooser, even if it is empty.
508 + $found_link_category_id = false;
509 + foreach ($results as $row) :
510 + // Normalize case
511 + if (!isset($row->cat_id)) : $row->cat_id = $row->cat_ID; endif;
340 512
341 - if ($row->cat_id == $cat_id) : $found_link_category_id = true; endif;
342 - endforeach;
343 -
344 - if (!$found_link_category_id) : $results[] = get_category($cat_id); endif;
345 - else :
346 - $results = $wpdb->get_results("SELECT cat_id, cat_name, auto_toggle FROM $wpdb->linkcategories ORDER BY cat_id");
513 + if ($row->cat_id == $cat_id) : $found_link_category_id = true; endif;
514 + endforeach;
515 +
516 + if (!$found_link_category_id) :
517 + $results[] = get_category($cat_id);
347 518 endif;
348 519
349 520 $info = array();
350 521 $rss_url = null;
@@ -353,17 +524,34 @@
353 524 $hardcode['description'] = get_option('feedwordpress_hardcode_description');
354 525 $hardcode['url'] = get_option('feedwordpress_hardcode_url');
355 526 endif;
356 527
528 + $hideAuth = false;
529 +
530 + $username = $this->setting('http username', NULL);
531 +
532 + if (is_null($username)) :
533 + $username = '';
534 + $hideAuth = true;
535 + endif;
536 +
537 + $password = $this->setting('http password', NULL);
538 + if (is_null($password)) :
539 + $password = '';
540 + endif;
541 +
542 + $auth = $this->setting('http auth method', NULL);
543 +
544 + global $feedwordpress;
545 +
546 + if (is_null($auth) or (strlen($auth)==0)) :
547 + $auth = '-';
548 + $hideAuth = true;
549 + endif;
550 +
357 551 // Hey ho, let's go
552 +
358 553 ?>
359 - <style type="text/css">
360 - table.edit-form { width: 100%; }
361 - table.edit-form th { width: 25%; vertical-align: top; text-align: right; padding: 0.5em; }
362 - table.edit-form td { width: 75%; vertical-align: top; padding: 0.5em; }
363 - table.edit-form td ul.options { margin: 0; padding: 0; list-style: none; }
364 - </style>
365 -
366 554 <table class="edit-form">
367 555
368 556 <?php if ($page->for_feed_settings()) : ?>
369 557
@@ -368,14 +556,82 @@
368 556 <?php if ($page->for_feed_settings()) : ?>
369 557
370 558 <tr>
371 559 <th scope="row"><?php _e('Feed URL:') ?></th>
372 - <td><a href="<?php echo wp_specialchars($rss_url, 'both'); ?>"><?php echo wp_specialchars($rss_url, 'both'); ?></a>
560 + <td><a href="<?php echo esc_html($rss_url); ?>"><?php echo esc_html($rss_url); ?></a>
373 561 (<a href="<?php echo FEEDVALIDATOR_URI; ?>?url=<?php echo urlencode($rss_url); ?>"
374 - title="Check feed &lt;<?php echo wp_specialchars($rss_url, 'both'); ?>&gt; for validity">validate</a>)
375 - <input type="submit" name="feedfinder" value="switch &rarr;" style="font-size:smaller" /></td>
562 + title="Check feed &lt;<?php echo esc_html($rss_url); ?>&gt; for validity">validate</a>)
563 + <input type="submit" name="feedfinder" value="switch &rarr;" style="font-size:smaller" />
564 +
565 + <?php $this->display_authentication_credentials_box(array(
566 + 'username' => $username,
567 + 'password' => $password,
568 + 'method' => $auth,
569 + )); ?>
570 +
571 + <table id="link-rss-params">
572 + <tbody>
573 + <?php
574 + $link_rss_params['new'] = array('', '');
575 + $i = 0;
576 + foreach ($link_rss_params as $index => $pair) :
577 + ?>
578 + <tr class="link-rss-params-row" id="link-rss-params-<?php print $index; ?>">
579 + <td><label>Parameter: <input type="text" class="link_params_key"
580 + name="link_rss_params_key[<?php print $index; ?>]" value="<?php print esc_html($pair[0]); ?>"
581 + size="5" style="width: 5em" placeholder="name" /></label></td>
582 + <td class="link-rss-params-value-cell"><label class="link_params_value_label">= <input type="text" class="link_params_value"
583 + name="link_rss_params_value[<?php print $index; ?>]" value="<?php print esc_html($pair[1]); ?>"
584 + size="8" placeholder="value" /></label></td>
376 585 </tr>
586 + <?php
587 + $i++;
588 + endforeach;
589 + ?>
590 + </tbody>
591 + </table>
592 +
593 + <div><input type="hidden" id="link-rss-params-num" name="link_rss_params_num" value="<?php print $i; ?>" /></div>
594 +
595 + <script type="text/javascript">
596 + function linkParamsRowRemove (element) {
597 + jQuery(element).closest('tr').fadeOut('slow', function () {
598 + jQuery(this).remove();
599 + } );
600 + }
377 601
602 + jQuery('<td><a href="#" class="add-remove link-rss-params-remove"><span class="x">(X)</span> Remove</a></td>').insertAfter('.link-rss-params-value-cell');
603 +
604 + jQuery('#link-rss-params-new').hide();
605 + jQuery('<a class="add-remove" id="link-rss-params-add" href="#">+ Add a query parameter</a>').insertAfter('#link-rss-params');
606 + jQuery('#link-rss-params-add').click( function () {
607 + var next = jQuery('#link-rss-params-num').val();
608 + var newRow = jQuery('#link-rss-params-new').clone().attr('id', 'link-rss-params-'+next);
609 + newRow.find('.link_params_key').attr('name', 'link_rss_params_key['+next+']');
610 + newRow.find('.link_params_value').attr('name', 'link_rss_params_value['+next+']');
611 +
612 + newRow.find('.link-rss-params-remove').click( function () {
613 + linkParamsRowRemove(this);
614 + return false;
615 + } );
616 +
617 + newRow.appendTo('#link-rss-params');
618 + newRow.show();
619 +
620 + // Update counter for next row.
621 + next++;
622 + jQuery('#link-rss-params-num').val(next);
623 +
624 + return false;
625 + } );
626 + jQuery('.link-rss-params-remove').click( function () {
627 + linkParamsRowRemove(this);
628 + return false;
629 + } );
630 + </script>
631 + </td>
632 + </tr>
633 +
378 634 <?php
379 635 $rows = array(
380 636 "name" => __('Link Name'),
381 637 "description" => __('Short Description'),
@@ -423,9 +679,9 @@
423 679 echo "\n\t<option value=\"$row->cat_id\"";
424 680 if ($row->cat_id == $cat_id) :
425 681 echo " selected='selected'";
426 682 endif;
427 - echo ">$row->cat_id: ".wp_specialchars($row->cat_name);
683 + echo ">$row->cat_id: ".esc_html($row->cat_name);
428 684 echo "</option>\n";
429 685 endforeach;
430 686 ?></select></p>
431 687 <p class="setting-description">FeedWordPress will syndicate the
@@ -453,26 +709,15 @@
453 709 </table>
454 710 <?php
455 711 } /* FeedWordPressFeedsPage::feed_information_box() */
456 712
457 - function posts_box ($page, $box = NULL) {
458 - FeedWordPressSettingsUI::instead_of_posts_box($page->link->id);
459 - } /* FeedWordPressFeedsPage::posts_box() */
460 -
461 - function authors_box ($page, $box = NULL) {
462 - FeedWordPressSettingsUI::instead_of_authors_box($page->link->id);
463 - } /* FeedWordPressFeedsPage::authors_box() */
464 -
465 - function categories_box ($page, $box = NULL) {
466 - FeedWordPressSettingsUI::instead_of_categories_box($page->link->id);
467 - } /* FeedWordPressFeedsPage::categories_box() */
468 -
469 713 function custom_settings_box ($page, $box = NULL) {
714 + $postsSettings = $this->admin_page_href('posts-page.php', array(), $page->link);
470 715 ?>
471 716 <p class="setting-description">These custom settings are special fields for the <strong>feed</strong> you are
472 717 syndicating, to be retrieved in templates using the <code>get_feed_meta()</code> function. They do not create
473 718 custom fields on syndicated <strong>posts</strong>. If you want to create custom fields that are applied to each
474 - individual post from this feed, set up the settings in <a href="admin.php?page=<?php print $GLOBALS['fwp_path'] ?>/posts-page.php&amp;link_id=<?php print $page->link->id; ?>">Syndicated Posts</a>.</p>
719 + individual post from this feed, set up the settings in <a href="<?php print $postsSettings; ?>">Syndicated Posts</a>.</p>
475 720
476 721 <div id="postcustomstuff">
477 722 <table id="meta-list" cellpadding="3">
478 723 <tr>
@@ -486,11 +731,11 @@
486 731 foreach ($page->link->settings as $key => $value) :
487 732 if (!preg_match("\007^((".implode(')|(', $page->special_settings)."))$\007i", $key)) :
488 733 ?>
489 734 <tr style="vertical-align:top">
490 - <th width="30%" scope="row"><input type="hidden" name="notes[<?php echo $i; ?>][key0]" value="<?php echo wp_specialchars($key, 'both'); ?>" />
491 - <input id="notes-<?php echo $i; ?>-key" name="notes[<?php echo $i; ?>][key1]" value="<?php echo wp_specialchars($key, 'both'); ?>" /></th>
492 - <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>
735 + <th width="30%" scope="row"><input type="hidden" name="notes[<?php echo $i; ?>][key0]" value="<?php echo esc_html($key); ?>" />
736 + <input id="notes-<?php echo $i; ?>-key" name="notes[<?php echo $i; ?>][key1]" value="<?php echo esc_html($key); ?>" /></th>
737 + <td width="60%"><textarea rows="2" cols="40" id="notes-<?php echo $i; ?>-value" name="notes[<?php echo $i; ?>][value]"><?php echo esc_html($value); ?></textarea></td>
493 738 <td width="10%"><select name="notes[<?php echo $i; ?>][action]">
494 739 <option value="update">save changes</option>
495 740 <option value="delete">delete this setting</option>
496 741 </select></td>
@@ -509,71 +754,171 @@
509 754 </div> <!-- id="postcustomstuff" -->
510 755 <?php
511 756 }
512 757
758 + function url_for_401 ($err) {
759 + $ret = NULL;
760 + if (is_wp_error($err)) :
761 + if ($err->get_error_code()=='http_request_failed') :
762 + $data = $err->get_error_data('http_request_failed');
763 +
764 + if (is_array($data) and isset($data['status'])) :
765 + if (401==$data['status']) :
766 + $ret = $data['uri'];
767 + endif;
768 + endif;
769 + endif;
770 + endif;
771 + return $ret;
772 + }
773 +
513 774 function display_feedfinder () {
514 775 global $wpdb;
515 776
516 777 $lookup = (isset($_REQUEST['lookup']) ? $_REQUEST['lookup'] : NULL);
778 +
779 + $auth = MyPHP::request('link_rss_auth_method');
780 + $username = MyPHP::request('link_rss_username');
781 + $password = MyPHP::request('link_rss_password');
782 + $credentials = array(
783 + "authentication" => $auth,
784 + "username" => $username,
785 + "password" => $password,
786 + );
517 787
788 + $feeds = array(); $feedSwitch = false; $current = null;
518 789 if ($this->for_feed_settings()) : // Existing feed?
519 - if (is_null($lookup)) : $lookup = $this->link->link->link_url; endif;
520 - $name = wp_specialchars($this->link->link->link_name, 'both');
790 + $feedSwitch = true;
791 + if (is_null($lookup)) :
792 + // Switch Feed without a specific feed yet suggested
793 + // Go to the human-readable homepage to look for
794 + // auto-detection links
795 +
796 + $lookup = $this->link->link->link_url;
797 + $auth = $this->link->setting('http auth method');
798 + $username = $this->link->setting('http username');
799 + $password = $this->link->setting('http password');
800 +
801 + // Guarantee that you at least have the option to
802 + // stick with what works.
803 + $current = $this->link->link->link_rss;
804 + $feeds[] = $current;
805 + endif;
806 + $name = esc_html($this->link->link->link_name);
521 807 else: // Or a new subscription to add?
522 - $name = "Subscribe to <code>".wp_specialchars(feedwordpress_display_url($lookup))."</code>";
808 + $name = "Subscribe to <code>".esc_html(feedwordpress_display_url($lookup))."</code>";
523 809 endif;
524 810 ?>
525 - <style type="text/css">
526 - form.fieldset {
527 - clear: both;
528 - }
529 - .feed-sample {
530 - float: right;
531 - background-color: #D0D0D0;
532 - color: black;
533 - width: 45%;
534 - font-size: 70%;
535 - border-left: 1px dotted #A0A0A0;
536 - margin-left: 1.0em;
537 - }
538 - .feed-sample p, .feed-sample h3 {
539 - padding-left: 0.5em;
540 - padding-right: 0.5em;
541 - }
542 - .feed-sample .feed-problem {
543 - background-color: #ffd0d0;
544 - border-bottom: 1px dotted black;
545 - padding-bottom: 0.5em;
546 - margin-bottom: 0.5em;
547 - }
548 - </style>
549 -
550 - <div class="wrap">
811 + <div class="wrap" id="feed-finder">
551 812 <h2>Feed Finder: <?php echo $name; ?></h2>
552 813
553 814 <?php
554 - $f =& new FeedFinder($lookup);
555 - $feeds = $f->find();
815 + if ($feedSwitch) :
816 + $this->display_alt_feed_box($lookup);
817 + endif;
818 +
819 + $finder = array();
820 + if (!is_null($current)) :
821 + $finder[$current] = new FeedFinder($current);
822 + endif;
823 + $finder[$lookup] = new FeedFinder($lookup);
824 +
825 + foreach ($finder as $url => $ff) :
826 + $feeds = array_merge($feeds, $ff->find(
827 + /*url=*/ NULL,
828 + /*params=*/ $credentials));
829 + endforeach;
830 +
831 + $feeds = array_values( // Renumber from 0..(N-1)
832 + $feeds
833 + );
834 +
835 + // Allow for some simple FeedFinder results filtering
836 + $feeds = apply_filters(
837 + 'feedwordpress_feedfinder_results',
838 + $feeds,
839 + array(
840 + "url" => $lookup,
841 + "auth" => $auth,
842 + "username" => $username,
843 + "password" => $password,
844 + "finder" => $finder,
845 + ),
846 + $this
847 + );
848 +
556 849 if (count($feeds) > 0):
850 + if ($feedSwitch) :
851 + ?>
852 + <h3>Feeds Found</h3>
853 + <?php
854 + endif;
855 +
856 + if (count($feeds) > 1) :
857 + $option_template = 'Option %d: ';
858 + $form_class = ' class="multi"';
859 + ?>
860 + <p><strong>This web page provides at least <?php print count($feeds); ?> different feeds.</strong> These feeds may provide the same information
861 + in different formats, or may track different items. (You can check the Feed Information and the
862 + Sample Item for each feed to get an idea of what the feed provides.) Please select the feed that you'd like to subscribe to.</p>
863 + <?php
864 + else :
865 + $option_template = '';
866 + $form_class = '';
867 + endif;
868 +
869 + global $fwp_credentials;
870 +
557 871 foreach ($feeds as $key => $f):
558 - $rss = @fetch_rss($f);
559 - if ($rss):
560 - $feed_title = isset($rss->channel['title'])?$rss->channel['title']:$rss->channel['link'];
561 - $feed_link = isset($rss->channel['link'])?$rss->channel['link']:'';
872 + $ofc = $fwp_credentials;
873 + $fwp_credentials = $credentials; // Set
874 + $pie = FeedWordPress::fetch($f, array("cache" => false));
875 + $fwp_credentials = $ofc; // Re-Set
876 +
877 + $rss = (is_wp_error($pie) ? $pie : new MagpieFromSimplePie($pie));
878 +
879 + if ($this->url_for_401($pie)) :
880 + $this->display_alt_feed_box($lookup, array(
881 + "err" => $pie,
882 + "auth" => $auth,
883 + "username" => $username,
884 + "password" => $password
885 + ));
886 + continue;
887 + endif;
888 +
889 + if ($rss and !is_wp_error($rss)):
890 + $feed_link = (isset($rss->channel['link'])?$rss->channel['link']:'');
891 + $feed_title = (isset($rss->channel['title'])?$rss->channel['title']:$feed_link);
562 892 $feed_type = ($rss->feed_type ? $rss->feed_type : 'Unknown');
893 + $feed_version_template = '%.1f';
894 + $feed_version = $rss->feed_version;
563 895 else :
564 896 // Give us some sucky defaults
565 897 $feed_title = feedwordpress_display_url($lookup);
566 898 $feed_link = $lookup;
567 899 $feed_type = 'Unknown';
900 + $feed_version_template = '';
901 + $feed_version = '';
568 902 endif;
569 903 ?>
570 - <form action="admin.php?page=<?php print $GLOBALS['fwp_path'] ?>/syndication.php" method="post">
571 - <div><?php FeedWordPressCompatibility::stamp_nonce('feedwordpress_switchfeed'); ?></div>
572 - <fieldset>
573 - <legend><?php echo $feed_type; ?> <?php echo $rss->feed_version; ?> feed</legend>
904 + <form<?php print $form_class; ?> action="<?php print $this->form_action('syndication.php'); ?>" method="post">
905 + <div class="inside"><?php FeedWordPressCompatibility::stamp_nonce('feedwordpress_switchfeed'); ?>
574 906
575 907 <?php
908 + $classes = array('feed-found'); $currentFeed = '';
909 + if (!is_null($current) and $current==$f) :
910 + $classes[] = 'current';
911 + $currentFeed = ' (currently subscribed)';
912 + endif;
913 + if ($key%2) :
914 + $classes[] = 'alt';
915 + endif;
916 + ?>
917 + <fieldset class="<?php print implode(" ", $classes); ?>">
918 + <legend><?php printf($option_template, ($key+1)); print $feed_type." "; printf($feed_version_template, $feed_version); ?> feed<?php print $currentFeed; ?></legend>
919 +
920 + <?php
576 921 $this->stamp_link_id();
577 922
578 923 // No feed specified = add new feed; we
579 924 // need to pass along a starting title
@@ -579,25 +924,26 @@
579 924 // need to pass along a starting title
580 925 // and homepage URL for the new Link.
581 926 if (!$this->for_feed_settings()):
582 927 ?>
583 - <input type="hidden" name="feed_title" value="<?php echo wp_specialchars($feed_title, 'both'); ?>" />
584 - <input type="hidden" name="feed_link" value="<?php echo wp_specialchars($feed_link, 'both'); ?>" />
928 + <input type="hidden" name="feed_title" value="<?php echo esc_html($feed_title); ?>" />
929 + <input type="hidden" name="feed_link" value="<?php echo esc_html($feed_link); ?>" />
585 930 <?php
586 931 endif;
587 932 ?>
588 933
589 - <input type="hidden" name="feed" value="<?php echo wp_specialchars($f, 'both'); ?>" />
934 + <input type="hidden" name="feed" value="<?php echo esc_html($f); ?>" />
590 935 <input type="hidden" name="action" value="switchfeed" />
591 936
592 937 <div>
593 938 <div class="feed-sample">
594 -
595 939 <?php
596 - if (count($rss->items) > 0):
940 + $link = NULL;
941 + $post = NULL;
942 + if (!is_wp_error($rss) and count($rss->items) > 0):
597 943 // Prepare to display Sample Item
598 - $link =& new MagpieMockLink($rss, $f);
599 - $post =& new SyndicatedPost($rss->items[0], $link);
944 + $link = new MagpieMockLink(array('simplepie' => $pie, 'magpie' => $rss), $f);
945 + $post = new SyndicatedPost(array('simplepie' => $rss->originals[0], 'magpie' => $rss->items[0]), $link);
600 946 ?>
601 947 <h3>Sample Item</h3>
602 948 <ul>
603 949 <li><strong>Title:</strong> <a href="<?php echo $post->post['meta']['syndication_permalink']; ?>"><?php echo $post->post['post_title']; ?></a></li>
@@ -606,15 +952,16 @@
606 952 <div class="entry">
607 953 <?php print $post->post['post_content']; ?>
608 954 </div>
609 955 <?php
956 + do_action('feedwordpress_feed_finder_sample_item', $f, $post, $link);
610 957 else:
611 - if (magpie_error()) :
958 + if (is_wp_error($rss)) :
612 959 print '<div class="feed-problem">';
613 960 print "<h3>Problem:</h3>\n";
614 961 print "<p>FeedWordPress encountered the following error
615 962 when trying to retrieve this feed:</p>";
616 - print '<p style="margin: 1.0em 3.0em"><code>'.magpie_error().'</code></p>';
963 + print '<p style="margin: 1.0em 3.0em"><code>'.$rss->get_error_message().'</code></p>';
617 964 print "<p>If you think this is a temporary problem, you can still force FeedWordPress to add the subscription. FeedWordPress will not be able to find any syndicated posts until this problem is resolved.</p>";
618 965 print "</div>";
619 966 endif;
620 967 ?>
@@ -628,171 +975,296 @@
628 975 <div>
629 976 <h3>Feed Information</h3>
630 977 <ul>
631 978 <li><strong>Homepage:</strong> <a href="<?php echo $feed_link; ?>"><?php echo is_null($feed_title)?'<em>Unknown</em>':$feed_title; ?></a></li>
632 - <li><strong>Feed URL:</strong> <a href="<?php echo wp_specialchars($f, 'both'); ?>"><?php echo wp_specialchars($f, 'both'); ?></a> (<a title="Check feed &lt;<?php echo wp_specialchars($f, 'both'); ?>&gt; for validity" href="http://feedvalidator.org/check.cgi?url=<?php echo urlencode($f); ?>">validate</a>)</li>
633 - <li><strong>Encoding:</strong> <?php echo isset($rss->encoding)?wp_specialchars($rss->encoding, 'both'):"<em>Unknown</em>"; ?></li>
634 - <li><strong>Description:</strong> <?php echo isset($rss->channel['description'])?wp_specialchars($rss->channel['description'], 'both'):"<em>Unknown</em>"; ?></li>
979 + <li><strong>Feed URL:</strong> <a title="<?php echo esc_html($f); ?>" href="<?php echo esc_html($f); ?>"><?php echo esc_html(feedwordpress_display_url($f, 40, 10)); ?></a> (<a title="Check feed &lt;<?php echo esc_html($f); ?>&gt; for validity" href="http://feedvalidator.org/check.cgi?url=<?php echo urlencode($f); ?>">validate</a>)</li>
980 + <li><strong>Encoding:</strong> <?php echo isset($rss->encoding)?esc_html($rss->encoding):"<em>Unknown</em>"; ?></li>
981 + <li><strong>Description:</strong> <?php echo isset($rss->channel['description'])?esc_html($rss->channel['description']):"<em>Unknown</em>"; ?></li>
635 982 </ul>
636 - <div class="submit"><input type="submit" name="Use" value="&laquo; Use this feed" /></div>
637 - <div class="submit"><input type="submit" name="Cancel" value="&laquo; Cancel" /></div>
983 + <?php $this->display_authentication_credentials_box(array(
984 + 'username' => $username,
985 + 'password' => $password,
986 + 'method' => $auth,
987 + )); ?>
988 + <?php do_action('feedwordpress_feedfinder_form', $f, $post, $link, $this->for_feed_settings()); ?>
989 + <div class="submit"><input type="submit" class="button-primary" name="Use" value="&laquo; Use this feed" />
990 + <input type="submit" class="button" name="Cancel" value="× Cancel" /></div>
638 991 </div>
639 992 </div>
640 993 </fieldset>
994 + </div> <!-- class="inside" -->
641 995 </form>
642 996 <?php
997 + unset($link);
998 + unset($post);
643 999 endforeach;
644 1000 else:
645 - print "<p><strong>".__('Error').":</strong> ".__("FeedWordPress couldn't find any feeds at").' <code><a href="'.htmlspecialchars($lookup).'">'.htmlspecialchars($lookup).'</a></code>';
646 - print ". ".__('Try another URL').".</p>";
1001 + foreach ($finder as $url => $ff) :
1002 + $url = esc_html($url);
1003 + print "<h3>Searched for feeds at ${url}</h3>\n";
1004 + print "<p><strong>".__('Error').":</strong> ".__("FeedWordPress couldn't find any feeds at").' <code><a href="'.htmlspecialchars($lookup).'">'.htmlspecialchars($lookup).'</a></code>';
1005 + print ". ".__('Try another URL').".</p>";
647 1006
648 - // Diagnostics
649 - print "<div class=\"updated\" style=\"margin-left: 3.0em; margin-right: 3.0em;\">\n";
650 - print "<h3>".__('Diagnostic information')."</h3>\n";
651 - if (!is_null($f->error()) and strlen($f->error()) > 0) :
652 - print "<h4>".__('HTTP request failure')."</h4>\n";
653 - print "<p>".$f->error()."</p>\n";
654 - else :
655 - print "<h4>".__('HTTP request completed')."</h4>\n";
656 - print "<p><strong>Status ".$f->status().":</strong> ".$this->HTTPStatusMessages[(int) $f->status()]."</p>\n";
657 - endif;
1007 + // Diagnostics
1008 + print "<div class=\"updated\" style=\"margin-left: 3.0em; margin-right: 3.0em;\">\n";
1009 + print "<h3>".__('Diagnostic information')."</h3>\n";
1010 + if (!is_null($ff->error()) and strlen($ff->error()) > 0) :
1011 + print "<h4>".__('HTTP request failure')."</h4>\n";
1012 + print "<p>".$ff->error()."</p>\n";
1013 + else :
1014 + print "<h4>".__('HTTP request completed')."</h4>\n";
1015 + print "<p><strong>Status ".$ff->status().":</strong> ".$this->HTTPStatusMessages[(int) $ff->status()]."</p>\n";
1016 + endif;
658 1017
659 - // Do some more diagnostics if the API for it is available.
660 - if (function_exists('_wp_http_get_object')) :
661 - $httpObject = _wp_http_get_object();
662 - $transports = $httpObject->_getTransport();
1018 + // Do some more diagnostics if the API for it is available.
1019 + if (function_exists('_wp_http_get_object')) :
1020 + $httpObject = _wp_http_get_object();
1021 +
1022 + if (is_callable(array($httpObject, '_getTransport'))) :
1023 + $transports = $httpObject->_getTransport();
1024 +
1025 + print "<h4>".__('HTTP Transports available').":</h4>\n";
1026 + print "<ol>\n";
1027 + print "<li>".implode("</li>\n<li>", array_map('get_class', $transports))."</li>\n";
1028 + print "</ol>\n";
1029 + elseif (is_callable(array($httpObject, '_get_first_available_transport'))) :
1030 + $transport = $httpObject->_get_first_available_transport(
1031 + array(),
1032 + $url
1033 + );
1034 +
1035 + print "<h4>".__("HTTP Transport").":</h4>\n";
1036 + print "<ol>\n";
1037 + print "<li>".MyPHP::val($transport)."</li>\n";
1038 + print "</ol>\n";
1039 + endif;
1040 +
1041 + print "</div>\n";
1042 + endif;
1043 + endforeach;
1044 + endif;
1045 +
1046 + if (!$feedSwitch) :
1047 + $this->display_alt_feed_box($lookup, /*alt=*/ true);
1048 + endif;
1049 + ?>
1050 + </div> <!-- class="wrap" -->
1051 + <?php
1052 + return false; // Don't continue
1053 + } /* FeedWordPressFeedsPage::display_feedfinder() */
663 1054
664 - print "<h4>".__('HTTP Transports available').":</h4>\n";
665 - print "<ol>\n";
666 - print "<li>".implode("</li>\n<li>", array_map('get_class', $transports))."</li>\n";
667 - print "</ol>\n";
668 - print "</div>\n";
1055 + function display_alt_feed_box ($lookup, $params = false) {
1056 + global $fwp_post;
1057 +
1058 + if (is_bool($params)) :
1059 + $params = array("alt" => $params);
1060 + endif;
1061 +
1062 + $params = wp_parse_args($params, array( // Defaults
1063 + "alt" => false,
1064 + "err" => NULL,
1065 + "auth" => NULL,
1066 + "password" => NULL,
1067 + "username" => NULL,
1068 + ));
1069 + $alt = $params['alt'];
1070 +
1071 + ?>
1072 + <form action="<?php print $this->form_action('syndication.php'); ?>" method="post">
1073 + <div class="inside"><?php
1074 + FeedWordPressCompatibility::stamp_nonce('feedwordpress_feeds');
1075 + ?>
1076 + <fieldset class="alt"
1077 + <?php if (!$alt): ?>style="margin: 1.0em 3.0em; font-size: smaller;"<?php endif; ?>>
1078 + <legend><?php if ($alt) : ?>Alternative feeds<?php else: ?>Find feeds<?php endif; ?></legend>
1079 + <?php if ($alt) : ?><h3>Use a different feed</h3><?php endif; ?>
1080 + <?php if (is_wp_error($params['err'])) :
1081 + ?>
1082 + <p><em><strong>401 Not Authorized.</strong> This URL may require
1083 + a username and password to access it.</em> You may want to add login
1084 + credentials below and check it again.</p>
1085 + <?php
669 1086 endif;
1087 + ?>
1088 + <div><label>Address:
1089 + <input type="text" name="lookup" id="use-another-feed"
1090 + placeholder="URL"
1091 + <?php if (is_null($lookup)) : ?>
1092 + value="URL"
1093 + <?php else : ?>
1094 + value="<?php print esc_html($lookup); ?>"
1095 + <?php endif; ?>
1096 + size="64" style="max-width: 80%" /></label>
1097 + <?php if (is_null($lookup)) : ?>
1098 + <?php FeedWordPressSettingsUI::magic_input_tip_js('use-another-feed'); ?>
1099 + <?php endif; ?>
670 1100
671 - endif;
672 - ?>
673 - </div>
674 -
675 - <form action="admin.php?page=<?php print $GLOBALS['fwp_path'] ?>/<?php echo basename(__FILE__); ?>" method="post">
676 - <div><?php
677 - FeedWordPressCompatibility::stamp_nonce(get_class($this));
678 - ?></div>
679 - <div class="wrap">
680 - <h2>Use another feed</h2>
681 - <div><label>Feed:</label>
682 - <input type="text" name="lookup" id="use-another-feed" value="URI" />
683 - <?php FeedWordPressSettingsUI::magic_input_tip_js('use-another-feed'); ?>
684 1101 <?php $this->stamp_link_id('link_id'); ?>
685 - <input type="hidden" name="action" value="feedfinder" /></div>
686 - <div class="submit"><input type="submit" value="Use this feed &raquo;" /></div>
687 - </div>
688 - </form>
1102 + <input type="hidden" name="action" value="feedfinder" />
1103 + <input type="submit" class="button<?php if ($alt): ?>-primary<?php endif; ?>" value="Check &raquo;" /></div>
1104 +
1105 + <?php $this->display_authentication_credentials_box(array(
1106 + 'username' => $params['username'],
1107 + 'password' => $params['password'],
1108 + 'method' => $params['auth'],
1109 + )); ?>
1110 +
1111 + <p>This can be the address of a feed, or of a website. FeedWordPress
1112 + will try to automatically detect any feeds associated with a
1113 + website.</p>
1114 + </div> <!-- class="inside" -->
1115 + </fieldset></form>
1116 +
689 1117 <?php
690 - return false; // Don't continue
691 - } /* WordPressFeedsPage::display_feedfinder() */
692 -
693 - function accept_POST ($post) {
694 - global $wpdb;
1118 + } /* FeedWordPressFeedsPage::display_alt_feed_box() */
1119 +
1120 + function save_settings ($post) {
1121 + if ($this->for_feed_settings()) :
695 1122
696 - // User mashed a Save Changes button
697 - if (isset($post['save']) or isset($post['submit'])) :
698 - if ($this->for_feed_settings()) :
699 - $alter = array ();
700 -
701 - // custom feed settings first
702 - foreach ($post['notes'] as $mn) :
703 - $mn['key0'] = trim($mn['key0']);
704 - $mn['key1'] = trim($mn['key1']);
705 - if (preg_match("\007^(("
706 - .implode(')|(',$this->special_settings)
707 - ."))$\007i",
708 - $mn['key1'])) :
709 - $mn['key1'] = 'user/'.$mn['key1'];
1123 + if (isset($post['link_rss_params_key'])) :
1124 + $qp = array();
1125 + foreach ($post['link_rss_params_key'] as $index => $key) :
1126 + if (strlen($key) > 0) :
1127 + if (isset($post['link_rss_params_value'][$index])
1128 + and strlen($post['link_rss_params_value'][$index])) :
1129 + $value = $post['link_rss_params_value'][$index];
1130 + $qp[] = array($key, $value);
1131 + endif;
710 1132 endif;
711 -
712 - if (strlen($mn['key0']) > 0) :
713 - unset($this->link->settings[$mn['key0']]); // out with the old
714 - endif;
715 -
716 - if (($mn['action']=='update') and (strlen($mn['key1']) > 0)) :
717 - $this->link->settings[$mn['key1']] = $mn['value']; // in with the new
718 - endif;
719 1133 endforeach;
720 -
721 - // now stuff through the web form
722 - // hardcoded feed info
723 -
724 - foreach (array('name', 'description', 'url') as $what) :
725 - // We have a checkbox for "No," so if it's unchecked, mark as "Yes."
726 - $this->link->settings["hardcode {$what}"] = (isset($post["hardcode_{$what}"]) ? $post["hardcode_{$what}"] : 'yes');
727 - if (FeedWordPress::affirmative($this->link->settings, "hardcode {$what}")) :
728 - $alter[] = "link_{$what} = '".$wpdb->escape($post['link'.$what])."'";
729 - endif;
730 - endforeach;
731 -
732 - // Update scheduling
733 - if (isset($post['update_schedule'])) :
734 - $this->link->settings['update/hold'] = $post['update_schedule'];
1134 + $this->update_setting('query parameters', serialize($qp));
1135 + endif;
1136 +
1137 + // custom feed settings first
1138 + foreach ($post['notes'] as $mn) :
1139 + $mn['key0'] = (isset($mn['key0']) ? trim($mn['key0']) : NULL);
1140 + $mn['key1'] = trim($mn['key1']);
1141 + if (preg_match("\007^(("
1142 + .implode(')|(',$this->special_settings)
1143 + ."))$\007i",
1144 + $mn['key1'])) :
1145 + $mn['key1'] = 'user/'.$mn['key1'];
735 1146 endif;
736 1147
737 - if (isset($post['use_default_update_window']) and strtolower($post['use_default_update_window'])=='yes') :
738 - unset($this->link->settings['update/window']);
739 - elseif (isset($post['update_window'])):
740 - if ((int) $post['update_window'] > 0) :
741 - $this->link->settings['update/window'] = (int) $post['update_window'];
742 - endif;
1148 + if (strlen($mn['key0']) > 0) :
1149 + unset($this->link->settings[$mn['key0']]); // out with the old
743 1150 endif;
744 1151
745 - $alter[] = "link_notes = '".$wpdb->escape($this->link->settings_to_notes())."'";
1152 + if (($mn['action']=='update') and (strlen($mn['key1']) > 0)) :
1153 + $this->link->settings[$mn['key1']] = $mn['value']; // in with the new
1154 + endif;
1155 + endforeach;
1156 +
1157 + // now stuff through the web form
1158 + // hardcoded feed info
1159 +
1160 + foreach (array('name', 'description', 'url') as $what) :
1161 + // We have a checkbox for "No," so if it's unchecked, mark as "Yes."
1162 + $this->link->settings["hardcode {$what}"] = (isset($post["hardcode_{$what}"]) ? $post["hardcode_{$what}"] : 'yes');
1163 + if (FeedWordPress::affirmative($this->link->settings, "hardcode {$what}")) :
1164 + $this->link->link->{'link_'.$what} = $post['link'.$what];
1165 + endif;
1166 + endforeach;
1167 +
1168 + // Update scheduling
1169 + if (isset($post['update_schedule'])) :
1170 + $this->link->settings['update/hold'] = $post['update_schedule'];
1171 + endif;
746 1172
747 - $alter_set = implode(", ", $alter);
748 -
749 - // issue update query
750 - $result = $wpdb->query("
751 - UPDATE $wpdb->links
752 - SET $alter_set
753 - WHERE link_id='{$this->link->id}'
754 - ");
755 - $this->updated = true;
756 -
757 - // reload link information from DB
758 - if (function_exists('clean_bookmark_cache')) :
759 - clean_bookmark_cache($this->link->id);
1173 + if (isset($post['use_default_update_window']) and strtolower($post['use_default_update_window'])=='yes') :
1174 + unset($this->link->settings['update/window']);
1175 + elseif (isset($post['update_window'])):
1176 + if ((int) $post['update_window'] > 0) :
1177 + $this->link->settings['update/window'] = (int) $post['update_window'];
760 1178 endif;
761 - $this->link = new SyndicatedLink($this->link->id);
1179 + endif;
1180 +
1181 + else :
1182 + // Global
1183 + update_option('feedwordpress_cat_id', $post['syndication_category']);
1184 +
1185 + if (!isset($post['automatic_updates']) or !in_array($post['automatic_updates'], array('init', 'shutdown'))) :
1186 + $automatic_updates = NULL;
762 1187 else :
763 - // Global
764 - update_option('feedwordpress_cat_id', $post['syndication_category']);
765 -
766 - if (!isset($post['automatic_updates']) or !in_array($post['automatic_updates'], array('init', 'shutdown'))) :
767 - $automatic_updates = false;
768 - else :
769 - $automatic_updates = $post['automatic_updates'];
1188 + $automatic_updates = $post['automatic_updates'];
1189 + endif;
1190 + update_option('feedwordpress_automatic_updates', $automatic_updates);
1191 +
1192 + if (isset($post['update_window'])):
1193 + if ((int) $post['update_window'] > 0) :
1194 + update_option('feedwordpress_update_window', (int) $post['update_window']);
770 1195 endif;
771 - update_option('feedwordpress_automatic_updates', $automatic_updates);
1196 + endif;
772 1197
773 - if (isset($post['update_window'])):
774 - if ((int) $post['update_window'] > 0) :
775 - update_option('feedwordpress_update_window', (int) $post['update_window']);
776 - endif;
777 - endif;
1198 + update_option('feedwordpress_update_time_limit', ($post['update_time_limit']=='yes')?(int) $post['time_limit_seconds']:0);
778 1199
779 - update_option('feedwordpress_update_time_limit', ($post['update_time_limit']=='yes')?(int) $post['time_limit_seconds']:0);
1200 + foreach (array('name', 'description', 'url') as $what) :
1201 + // We have a checkbox for "No," so if it's unchecked, mark as "Yes."
1202 + $hardcode = (isset($post["hardcode_{$what}"]) ? $post["hardcode_{$what}"] : 'yes');
1203 + update_option("feedwordpress_hardcode_{$what}", $hardcode);
1204 + endforeach;
1205 +
1206 + endif;
1207 +
1208 + if (isset($post['fetch_timeout'])) :
1209 + if (isset($post['fetch_timeout_default']) and $post['fetch_timeout_default']=='yes') :
1210 + $timeout = NULL;
1211 + else :
1212 + $timeout = $post['fetch_timeout'];
1213 + endif;
780 1214
781 - foreach (array('name', 'description', 'url') as $what) :
782 - // We have a checkbox for "No," so if it's unchecked, mark as "Yes."
783 - $hardcode = (isset($post["hardcode_{$what}"]) ? $post["hardcode_{$what}"] : 'yes');
784 - update_option("feedwordpress_hardcode_{$what}", $hardcode);
785 - endforeach;
786 -
787 - $this->updated = true;
1215 + if (is_int($timeout)) :
1216 + $timeout = intval($timeout);
788 1217 endif;
1218 + $this->update_setting('fetch timeout', $timeout);
1219 + endif;
1220 +
1221 + if (isset($post['update_incremental'])) :
1222 + $this->update_setting('update_incremental', $post['update_incremental']);
1223 + endif;
789 1224
790 - // Probably a "Go" button for the drop-down
1225 + if (isset($post['tombstones'])) :
1226 + $this->update_setting('tombstones', $post['tombstones']);
1227 + endif;
1228 +
1229 + if (isset($post['update_minimum'])) :
1230 + $this->update_setting('update/minimum', $post['update_minimum']);
1231 + endif;
1232 +
1233 + if (
1234 + isset($post['link_rss_auth_method'])
1235 + and $post['link_rss_auth_method']
1236 + and ('-' != $post['link_rss_auth_method'])
1237 + ) :
1238 + $this->update_setting('http auth method', $post['link_rss_auth_method']);
791 1239 else :
792 - $this->updated = false;
1240 + $this->update_setting('http auth method', NULL);
793 1241 endif;
794 - } /* WordPressFeedsPage::accept_POST() */
1242 +
1243 + if (
1244 + isset($post['link_rss_username'])
1245 + and (strlen($post['link_rss_username']) > 0)
1246 + and ('-' != $post['link_rss_auth_method'])
1247 + ) :
1248 + $this->update_setting('http username', $post['link_rss_username']);
1249 + else :
1250 + $this->update_setting('http username', NULL);
1251 + endif;
1252 +
1253 + if (
1254 + isset($post['link_rss_password'])
1255 + and (strlen($post['link_rss_password']) > 0)
1256 + and ('-' != $post['link_rss_auth_method'])
1257 + ) :
1258 + $this->update_setting('http password', $post['link_rss_password']);
1259 + else :
1260 + $this->update_setting('http password', NULL);
1261 + endif;
1262 +
1263 + $this->updatedPosts->accept_POST($post);
1264 +
1265 + parent::save_settings($post);
1266 + } /* FeedWordPressFeedsPage::save_settings() */
795 1267
796 1268 } /* class FeedWordPressFeedsPage */
797 1269
798 1270 $feedsPage = new FeedWordPressFeedsPage;