PluginProbe
FeedWordPress / trunk
FeedWordPress vtrunk
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
feedwordpress / feedwordpresssyndicationpage.class.php

feedwordpresssyndicationpage.class.php in FeedWordPress trunk, at feedwordpresssyndicationpage.class.php

1,459 lines 53.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * feedwordpresssyndicationpage.class.php
4 * feedwordpress
5 *
6 * @author radgeek
7 */
8 require_once dirname(__FILE__) . '/admin-ui.php';
9 require_once dirname(__FILE__) . '/feedfinder.class.php';
10
11 ################################################################################
12 ## ADMIN MENU ADD-ONS: implement Dashboard management pages ####################
13 ################################################################################
14
15 define( 'FWP_PROJECT_WEBSITE_URL', 'https://fwpplugin.com/' );
16
17 define( 'FWP_UPDATE_CHECKED', 'Update Checked' );
18 define( 'FWP_UNSUB_CHECKED', 'Unsubscribe' );
19 define( 'FWP_DELETE_CHECKED', 'Delete' );
20 define( 'FWP_RESUB_CHECKED', 'Re-subscribe' );
21 define( 'FWP_SYNDICATE_NEW', 'Add →' );
22 define( 'FWP_UNSUB_FULL', 'Unsubscribe from selected feeds →' );
23 define( 'FWP_CANCEL_BUTTON', '× Cancel' );
24 define( 'FWP_CHECK_FOR_UPDATES', 'Update' );
25
26 /**
27 * Tab for the admin page where syndication is dealt with.
28 *
29 * @extends FeedWordPressAdminPage
30 *
31 * @uses MyPHP
32 * @uses FeedFinder
33 * @uses FeedWordPress
34 * @uses FeedWordPressCompatibility
35 * @uses FeedWordPressDiagnostic
36 */
37 class FeedWordPressSyndicationPage extends FeedWordPressAdminPage
38 {
39 public function __construct( $filename = NULL )
40 {
41 parent::__construct( 'feedwordpresssyndication', /*link=*/ NULL );
42
43 // No over-arching form element
44 $this->dispatch = NULL;
45 if ( is_null( $filename ) ) :
46 $this->filename = __FILE__;
47 else :
48 $this->filename = $filename;
49 endif;
50 } /* FeedWordPressSyndicationPage constructor */
51
52 /**
53 * Stub function to comply with parent class.
54 *
55 * @return bool Always returns FALSE in this class.
56 */
57 function has_link()
58 {
59 return false;
60 } /* FeedWordPressSyndicationPage::has_link() */
61
62 /** @var array|null List of sources which gets initialised by $this->sources('Y') if it's still NULL */
63 var $_sources = NULL;
64
65 /**
66 * Builds _sources (list of visible or invisible links to sources of syndicated links)
67 * or returns existing _sources if it's already built.
68 *
69 * @param string $visibility Unknown flag which toggles source visibility
70 *
71 * @return array Constructed list of visible/invisible sources
72 *
73 * @uses FeedWordPress::syndicated_links()
74 *
75 */
76 function sources( $visibility = 'Y' )
77 {
78 if ( is_null( $this->_sources) ) :
79 $links = FeedWordPress::syndicated_links( array( "hide_invisible" => false ) );
80 $this->_sources = array( "Y" => array(), "N" => array() );
81 foreach ( $links as $link ) :
82 $this->_sources[$link->link_visible][] = $link;
83 endforeach;
84 endif;
85 $ret = (
86 array_key_exists( $visibility, $this->_sources )
87 ? $this->_sources[$visibility]
88 : $this->_sources
89 );
90 return $ret;
91 } /* FeedWordPressSyndicationPage::sources() */
92
93 /**
94 * Toggles source visibility, using the side-effect of pseudo-getter $this->sources(...) method-
95 *
96 * @return string
97 *
98 * @uses FeedWordPress::param()
99 */
100 function visibility_toggle()
101 {
102 $sources = $this->sources( '*' ); // return value unnecessary, it seems the code is just using the side-effect of initialising $this->_sources if it's uninitialised. (gwyneth 20230916)
103
104 $defaultVisibility = 'Y';
105 if ( ( count( $this->sources( 'N' ) ) > 0 )
106 and ( count( $this->sources( 'Y' ) ) == 0 ) ) :
107 $defaultVisibility = 'N';
108 endif;
109
110 // this may be output into HTML, and it should really only ever be Y or N...
111 $sVisibility = FeedWordPress::param( 'visibility', 'REQUEST', $defaultVisibility );
112
113 // Ensure $sVisibility is treated as a string
114 $sVisibility = (string) $sVisibility;
115
116 // Apply preg_replace to remove unwanted characters
117 $visibility = preg_replace('/[^YyNn]+/', '', $sVisibility);
118
119 // If preg_replace fails or returns null, ensure $visibility is an empty string
120 $visibility = $visibility !== null ? $visibility : '';
121
122 return ( strlen( $visibility ) > 0 ? $visibility : $defaultVisibility );
123 } /* FeedWordPressSyndicationPage::visibility_toggle() */
124
125 /**
126 * Shows source feeds that are currently not visible.
127 *
128 * @return string
129 */
130 function show_inactive()
131 {
132 return ( 'N' == $this->visibility_toggle() );
133 }
134
135 /**
136 * sanitize_ids: Protect id numbers from untrusted sources (POST array etc.)
137 * from possibility of SQLi attacks. Runs everything through an intval filter
138 * and then for good measure through esc_sql()
139 *
140 * @param array $link_ids An array of one or more putative link IDs
141 * @return array
142 */
143 public function sanitize_ids_sql( $link_ids ) {
144 $link_ids = array_map(
145 'esc_sql',
146 array_map(
147 'intval',
148 $link_ids
149 )
150 );
151 return $link_ids;
152 } /* FeedWordPressSyndicationPage::sanitize_ids_sql () */
153
154 /**
155 * requested_link_ids_sql()
156 *
157 * @return string An SQL list literal containing the link IDs, sanitized
158 * and escaped for direct use in MySQL queries.
159 *
160 * @uses sanitize_ids_sql()
161 * @uses sanitize_text_field()
162 * @uses MyPHP::post()
163 * @uses MyPHP::request()
164 * @uses FeedWordPress::post()
165 */
166 public function requested_link_ids_sql()
167 {
168 // Multiple link IDs passed in link_ids[]=...
169
170 $link_ids = array_map(
171 'sanitize_text_field',
172 (array) MyPHP::request( 'link_ids', array() )
173 );
174
175 // Or single in link_id=...
176 if ( ! is_null( MyPHP::request( 'link_id' ) ) ) :
177 array_push( $link_ids, sanitize_text_field( MyPHP::request( 'link_id' ) ) );
178 endif;
179
180 // Now use method to sanitize for safe use in MySQL queries.
181 $link_ids = $this->sanitize_ids_sql( $link_ids );
182
183 // Convert to MySQL list literal.
184 return "('" . implode( "', '", $link_ids ) . "')";
185 } /* FeedWordPressSyndicationPage::requested_link_ids_sql () */
186
187 /**
188 * Returns the list of requested updates.
189 *
190 * @return array List of requested updates
191 *
192 * @uses MyPHP::post()
193 * @uses MyPHP::request()
194 * @uses FeedWordPress::post()
195 * @uses FeedWordPressDiagnostic::critical_bug()
196 */
197 function updates_requested()
198 {
199 global $wpdb;
200
201 if ( FeedWordPress::post( 'update' ) || FeedWordPress::post( 'action' ) || FeedWordPress::post( 'update_uri' ) ) :
202 // Only do things with side-effects for HTTP POST or command line
203 $fwp_update_invoke = 'post';
204 else :
205 $fwp_update_invoke = 'get';
206 endif;
207
208 $update_set = array();
209 if ( $fwp_update_invoke != 'get' ) :
210 if ( is_array( MyPHP::post( 'link_ids' ) )
211 and ( MyPHP::post( 'action' ) == FWP_UPDATE_CHECKED ) ) :
212 // Get single link ID or multiple link IDs from REQUEST parameters
213 // if available. Sanitize values for MySQL.
214 $link_list = $this->requested_link_ids_sql();
215
216 // $link_list has previously been sanitized for html by self::requested_link_ids_sql
217 $targets = $wpdb->get_results("
218 SELECT * FROM $wpdb->links
219 WHERE link_id IN {$link_list}
220 ");
221 if ( is_array( $targets ) ) :
222 foreach ($targets as $target) :
223 $update_set[] = $target->link_rss;
224 endforeach;
225 else : // This should never happen
226 FeedWordPressDiagnostic::critical_bug( 'fwp_syndication_manage_page::targets', $targets, __LINE__, __FILE__ );
227 endif;
228 elseif ( !is_null( FeedWordPress::post( 'update_uri' ) ) ) :
229 $targets = FeedWordPress::post( 'update_uri' );
230 if ( !is_array( $targets ) ) :
231 $targets = array( $targets );
232 endif;
233
234 $targets_keys = array_keys( $targets );
235 $first_key = reset( $targets_keys );
236 if ( !is_numeric( $first_key) ) : // URLs in keys
237 $targets = $targets_keys;
238 endif;
239 $update_set = $targets;
240 endif;
241 endif;
242 return $update_set;
243 }
244
245 /**
246 * Cancels the request.
247 *
248 * @return bool Success
249 *
250 * @uses FeedWordPress::post()
251 */
252 public function cancel_requested()
253 {
254 $cancel = FeedWordPress::post( 'cancel' );
255 return ( $cancel === __( FWP_CANCEL_BUTTON ) );
256 }
257
258 /**
259 * Adds multiple requests.
260 *
261 * @return bool Success
262 *
263 * @uses FeedWordPress::post()
264 */
265 public function multiadd_requested()
266 {
267 $multiadd = FeedWordPress::post( 'multiadd' );
268 return ( $multiadd === FWP_SYNDICATE_NEW );
269 }
270
271 /**
272 * Confirms that multiple requests were added.
273 *
274 * @return bool Success
275 *
276 * @uses FeedWordPress::post()
277 */
278 public function multiadd_confirm_requested()
279 {
280 $confirm = FeedWordPress::post( 'confirm' );
281 return ( $confirm === 'multiadd' );
282 }
283
284 /**
285 * Accepts multiple requests that were added.
286 *
287 * @return bool Always true
288 *
289 * @uses FeedWordPress::post()
290 * @uses FeedWordPress::syndicate_link()
291 * @uses FeedWordPressCompatibility::validate_http_request()
292 */
293 function accept_multiadd()
294 {
295 if ( $this->cancel_requested() ) :
296 return true; // Continue ....
297 endif;
298
299 // If this is a POST, validate source and user credentials
300 FeedWordPressCompatibility::validate_http_request(/*action=*/ 'feedwordpress_feeds', /*capability=*/ 'manage_links');
301
302 $in = FeedWordPress::post( 'multilookup', '' )
303 . FeedWordPress::post( 'opml_lookup', '' );
304 if ( $this->multiadd_confirm_requested() ) :
305 $chex = FeedWordPress::post( 'multilookup' );
306 $added = array(); $errors = array();
307 foreach ( $chex as $feed ) :
308 if ( isset( $feed['add'] ) and $feed['add'] == 'yes' ) :
309 // Then, add in the URL.
310 $link_id = FeedWordPress::syndicate_link(
311 $feed['title'],
312 $feed['link'],
313 $feed['url']
314 );
315 if ( !empty( $link_id ) and !is_wp_error( $link_id ) ):
316 $added[] = $link_id;
317 else :
318 $errors[] = array( $feed['url'], $link_id );
319 endif;
320 endif;
321 endforeach;
322
323 print "<div class='updated'>\n";
324 print "<p>Added " . count( $added ) . " new syndicated sources.</p>";
325 if ( count( $errors ) > 0 ) :
326 print "<p>FeedWordPress encountered errors trying to add the following sources:</p>
327 <ul>\n";
328 foreach ($errors as $err) :
329 $url = $err[0];
330 $short = feedwordpress_display_url($url);
331
332 printf(
333 '<li><a href="%s">%s</a>',
334 esc_url( $url ),
335 esc_html( $short )
336 );
337
338 if ( is_wp_error( $err[1] ) ) :
339 $error = $err[1];
340 printf( ' (<code>%s</code>)', esc_html( $error->get_error_messages() ) );
341 endif;
342
343 print "</li>\n";
344
345 endforeach;
346 print "</ul>\n";
347 endif;
348 print "</div>\n";
349
350 elseif ( is_array( $in ) or strlen( $in ) > 0 ) :
351 add_meta_box(
352 /*id=*/ 'feedwordpress_multiadd_box',
353 /*title=*/ __( 'Add Feeds' ),
354 /*callback=*/ array( $this, 'multiadd_box' ),
355 /*page=*/ $this->meta_box_context(),
356 /*context =*/ $this->meta_box_context()
357 );
358 endif;
359 return true; // Continue...
360 }
361
362 /**
363 * Emits HTML for multiple added lines.
364 *
365 * @param array $line Line item to be displayed.
366 */
367 function display_multiadd_line( $line )
368 {
369 $short_feed = feedwordpress_display_url( $line['feed'] );
370 $feed = $line['feed'];
371 $link = $line['link'];
372 $title = $line['title'];
373 $i = $line['i'];
374
375 print "<li><label><input type='checkbox' name='multilookup[" . esc_attr( $i ) . "][add]' value='yes'";
376 if ( strlen( $line['checked'] ) > 0 ) :
377 print ' checked="checked" ';
378 endif;
379 print "/> " . esc_html( $title ) . "</label> &middot; <a href='"
380 . esc_url($feed) . "'>" . esc_html( $short_feed ) . "</a>";
381
382 if ( isset( $line['extra']) ) :
383 print " &middot; " . esc_html( $line['extra'] );
384 endif;
385
386 print
387 "<input type='hidden' name='multilookup[" . esc_attr( $i ) . "][url]' value='" . esc_attr( $feed ) . "' />
388 <input type='hidden' name='multilookup[" . esc_attr( $i ) . "][link]' value='" . esc_attr( $link ) . "' />
389 <input type='hidden' name='multilookup[" . esc_attr( $i ) . "][title]' value='" . esc_attr( $title ) . "' />
390 </li>\n";
391
392 flush();
393 }
394
395 /**
396 * Emits HTML for the box that allows adding multiple sources.
397 *
398 * @param int $page Unknown and unused.
399 * @param string|null $box Unknown and unused.
400 *
401 * @return bool Always true
402 *
403 * @uses file_get_contents()
404 * @uses FeedFinder
405 * @uses FeedWordPress::fetch()
406 * @uses FeedWordPress::post()
407 * @uses FeedWordPressCompatibility::stamp_nonce()
408 */
409 function multiadd_box($page, $box = NULL)
410 {
411 $localData = NULL;
412
413 if ( isset( $_FILES['opml_upload']['name'] )
414 and ( strlen( $_FILES['opml_upload']['name'] ) > 0 ) ) :
415 $in = 'tag:localhost';
416
417 /*FIXME: check whether $_FILES['opml_upload']['error'] === UPLOAD_ERR_OK or not...*/
418 $localData = file_get_contents( $_FILES['opml_upload']['tmp_name'] );
419 $merge_all = true;
420 elseif ( ! is_null( FeedWordPress::post( 'multilookup' ) ) ) :
421 $in = FeedWordPress::post( 'multilookup' );
422 $merge_all = false;
423 elseif ( ! is_null( FeedWordPress::post( 'opml_lookup' ) ) ) :
424 $in = FeedWordPress::post( 'opml_lookup' );
425 $merge_all = true;
426 else :
427 $in = '';
428 $merge_all = false;
429 endif;
430
431 if ( strlen( $in ) > 0 ) :
432 $lines = preg_split(
433 "/\s+/",
434 $in,
435 /*no limit soldier*/ -1,
436 PREG_SPLIT_NO_EMPTY
437 );
438
439 $i = 0;
440 ?>
441 <!-- Page: <? echo $page; ?> Box: <? echo $box ?: '(empty)'; ?> -->
442 <form id="multiadd-form" action="<?php print esc_attr( $this->form_action() ); ?>" method="post">
443 <div><?php FeedWordPressCompatibility::stamp_nonce( 'feedwordpress_feeds' ); ?>
444 <input type="hidden" name="multiadd" value="<?php print esc_attr( FWP_SYNDICATE_NEW ); ?>" />
445 <input type="hidden" name="confirm" value="multiadd" />
446
447 <input type="hidden" name="multiadd" value="<?php print esc_attr( FWP_SYNDICATE_NEW ); ?>" />
448 <input type="hidden" name="confirm" value="multiadd" /></div>
449
450 <div id="multiadd-status">
451 <p><img src="<?php print esc_url( admin_url( 'images/wpspin_light.gif' ) ); ?>" alt="" />
452 <?php esc_html_e( 'Looking up feed information...' ); ?></p>
453 </div>
454
455 <div id="multiadd-buttons">
456 <input type="submit" class="button" name="cancel" value="<?php esc_html_e( FWP_CANCEL_BUTTON ); ?>" />
457 <input type="submit" class="button-primary" value="<?php esc_html_e( 'Subscribe to selected sources →' ); ?>" />
458 </div>
459
460 <p><?php esc_html_e( 'Here are the feeds that FeedWordPress has discovered from the addresses that you provided. To opt out of a subscription, unmark the checkbox next to the feed.' ); ?></p>
461
462 <?php
463 print "<ul id=\"multiadd-list\">\n"; flush();
464 foreach ( $lines as $line ) :
465 $url = trim( $line );
466 if ( strlen( $url ) > 0) :
467 // First, use FeedFinder to check the URL.
468 if ( is_null( $localData ) ) :
469 $finder = new FeedFinder( $url, /*verify=*/ false, /*fallbacks=*/ 1 );
470 else :
471 $finder = new FeedFinder( 'tag:localhost', /*verify=*/ false, /*fallbacks=*/ 1 );
472 $finder->upload_data( $localData );
473 endif;
474
475 $feeds = array_values(
476 array_unique(
477 $finder->find()
478 )
479 );
480
481 $found = false;
482 if ( count( $feeds ) > 0 ) :
483 foreach ( $feeds as $feed ) :
484 $pie = FeedWordPress::fetch( $feed );
485 if ( !is_wp_error( $pie ) ) :
486 $found = true;
487
488 $this->display_multiadd_line(array(
489 'feed' => $feed,
490 'title' => $pie->get_title(),
491 'link' => $pie->get_link(),
492 'checked' => ' checked="checked"',
493 'i' => $i,
494 ));
495
496 $i++; // Increment field counter
497
498 if ( ! $merge_all ) : // Break out after first find
499 break;
500 endif;
501 endif;
502 endforeach;
503 endif;
504
505 if ( ! $found ) :
506 $this->display_multiadd_line( array(
507 'feed' => $url,
508 'title' => feedwordpress_display_url( $url ),
509 'extra' => __(" [FeedWordPress couldn't detect any feeds for this URL.]" ),
510 'link' => NULL,
511 'checked' => '',
512 'i' => $i,
513 ) );
514 $i++; // Increment field counter
515 endif;
516 endif;
517 endforeach;
518 print "</ul>\n";
519 ?>
520 </form>
521
522 <script type="text/javascript">
523 jQuery( document ).ready( function () {
524 // Hide it now that we're done.
525 jQuery( '#multiadd-status' ).fadeOut( 500 /*ms*/ );
526 } );
527 </script>
528 <?php
529 endif;
530
531 $this->_sources = NULL; // Force reload of sources list
532 return true; // Continue
533 }
534
535 /**
536 * Displays the main syndication page.
537 *
538 * @uses FeedWordPress::needs_upgrade()
539 * @uses FeedWordPress::param()
540 */
541 function display()
542 {
543 if ( FeedWordPress::needs_upgrade() ) :
544 fwp_upgrade_page();
545 return;
546 endif;
547
548 $cont = true;
549 $dispatcher = array(
550 "feedfinder" => 'feedfinder_page',
551 FWP_SYNDICATE_NEW => 'feedfinder_page',
552 "switchfeed" => 'switchfeed_page',
553 FWP_UNSUB_CHECKED => 'multidelete_page',
554 FWP_DELETE_CHECKED => 'multidelete_page',
555 'Unsubscribe' => 'multidelete_page',
556 FWP_RESUB_CHECKED => 'multiundelete_page',
557 );
558
559 $act = FeedWordPress::param( 'action' );
560 if ( isset( $dispatcher[ $act ] ) ) :
561 $method = $dispatcher[ $act ];
562 if ( method_exists( $this, $method ) ) :
563 $cont = $this->{$method}();
564 else :
565 $cont = call_user_func( $method );
566 endif;
567 elseif ( $this->multiadd_requested() ) :
568 $cont = $this->accept_multiadd();
569 endif;
570
571 if ( $cont ) :
572 $links = $this->sources( 'Y' ); // side-effect of getting _sources instantiated... (gwyneth 20230916)
573 $potential_updates = ( ! $this->show_inactive() and ( count( $this->sources( 'Y' ) ) > 0 ) );
574
575 $this->open_sheet( 'Syndicated Sites' );
576 ?>
577 <div id="post-body">
578 <?php
579 if ( $potential_updates
580 or ( count( $this->updates_requested() ) > 0 ) ) :
581 add_meta_box(
582 /*id=*/ 'feedwordpress_update_box',
583 /*title=*/ __( 'Update feeds now' ),
584 /*callback=*/ 'fwp_syndication_manage_page_update_box',
585 /*page=*/ $this->meta_box_context(),
586 /*context =*/ $this->meta_box_context()
587 );
588 endif;
589 add_meta_box(
590 /*id=*/ 'feedwordpress_feeds_box',
591 /*title=*/ __( 'Syndicated sources' ),
592 /*callback=*/ array( $this, 'syndicated_sources_box' ),
593 /*page=*/ $this->meta_box_context(),
594 /*context =*/ $this->meta_box_context()
595 );
596
597 do_action( 'feedwordpress_admin_page_syndication_meta_boxes', $this );
598 ?>
599 <div class="metabox-holder">
600 <?php
601 do_meta_boxes( $this->meta_box_context(), $this->meta_box_context(), $this );
602 ?>
603 </div> <!-- class="metabox-holder" -->
604 </div> <!-- id="post-body" -->
605
606 <?php $this->close_sheet( /*dispatch=*/ NULL ); ?>
607
608 <div style="display: none">
609 <div id="tags-input"></div> <!-- avoid JS error from WP 2.5 bug -->
610 </div>
611 <?php
612 endif;
613 } /* FeedWordPressSyndicationPage::display () */
614
615 /**
616 * Displays the dashboard box.
617 *
618 * @param int $page Unknown usage.
619 * @param array|null $box Unknown usage.
620 */
621 function dashboard_box($page, $box = NULL)
622 {
623 $links = FeedWordPress::syndicated_links( array( "hide_invisible" => false ) ); // what is $links for? (gwyneth 20230916)
624 $sources = $this->sources( '*' ); // uses side-effects to initialise _sources (gwyneth 20230916)
625
626 /** @var string what is this used for? (gwyneth 20230915) */
627 $visibility = 'Y';
628 $hrefPrefix = $this->form_action();
629 $activeHref = $hrefPrefix . '&visibility=' . $visibility;
630 $inactiveHref = $hrefPrefix . '&visibility=N';
631
632 $lastUpdate = get_option( 'feedwordpress_last_update_all', NULL );
633 $automatic_updates = get_option( 'feedwordpress_automatic_updates', NULL );
634
635 /** @var string default value set here, to avoid having a else clause, but also to init the variable in the right scope. (gwyneth 20230915) */
636 $update_setting = __( 'using a cron job or manual check-ins' );
637 if ( 'init' == $automatic_updates ) :
638 $update_setting = __( 'automatically before page loads' );
639 elseif ( 'shutdown' == $automatic_updates ) :
640 $update_setting = __( 'automatically after page loads' );
641 endif;
642 // Hey ho, let's go...
643 ?>
644 <div style="float: left; background: /* #F5F5F5 */ white; padding-top: 5px; padding-right: 5px;"><a href="<?php print esc_url( $this->form_action() ); ?>"><img src="<?php print esc_url( plugins_url( /* "feedwordpress.png" */ "assets/images/icon.svg", __FILE__ ) ); ?>" width="36px" height="36px" alt="FeedWordPress Logo" /></a></div>
645 <p class="info" style="margin-bottom: 0px; border-bottom: 1px dotted black;"><?php esc_html_e( 'Managed by' ); ?><a href="<?php print esc_url( FWP_PROJECT_WEBSITE_URL ); ?>">FeedWordPress</a>
646 <?php print esc_html( FEEDWORDPRESS_VERSION ); ?>.</p>
647 <?php if ( FEEDWORDPRESS_BLEG ) : ?>
648 <p class="info" style="margin-top: 0px; font-style: italic; font-size: 75%; color: #666;"><?php esc_html_e( 'If you find this tool useful for your daily work, you can
649 contribute to ongoing support and development with '); ?>
650 <a href="<?php print esc_url( FWP_PROJECT_WEBSITE_URL ); ?>donate/"><?php esc_html_e('a modest donation'); ?></a>.</p>
651 <br style="clear: left;" />
652 <?php endif; ?>
653
654 <div class="feedwordpress-actions">
655 <h4>Updates</h4>
656 <ul class="options">
657 <li><strong><?php esc_html_e( 'Scheduled:' ); ?></strong> <?php print esc_html($update_setting); ?>
658 (<a href="<?php print esc_url($this->form_action('feeds-page.php')); ?>"><?php esc_html_e( 'change setting' ); ?></a>)</li>
659
660 <li><?php if ( !is_null($lastUpdate)) : ?>
661 <strong><?php esc_html_e( 'Last checked:' );?></strong> <?php print esc_html(fwp_time_elapsed($lastUpdate)); ?>
662 <?php else : ?>
663 <strong><?php esc_html_e( 'Last checked:' );?>&nbsp;</strong><?php esc_html_e( 'none yet' ); ?>
664 <?php endif; ?> </li>
665
666 </ul>
667 </div>
668
669 <div class="feedwordpress-stats">
670 <h4><?php esc_html_e( 'Subscriptions' ); ?></h4>
671 <table>
672 <tbody>
673 <tr class="first">
674 <td class="first b b-active"><a href="<?php print esc_url($activeHref); ?>"><?php print esc_html(count($sources['Y'])); ?></a></td>
675 <td class="t active"><a href="<?php print esc_url($activeHref); ?>"><?php esc_html_e( 'Active' ); ?></a></td>
676 </tr>
677
678 <tr>
679 <td class="b b-inactive"><a href="<?php print esc_url($inactiveHref); ?>"><?php print esc_html(count($sources['N'])); ?></a></td>
680 <td class="t inactive"><a href="<?php print esc_url($inactiveHref); ?>"><?php esc_html_e( 'Inactive' ); ?></a></td>
681 </tr>
682 </table>
683 </div>
684
685 <div id="add-single-uri">
686 <?php if (count($sources['Y']) > 0) : ?>
687 <form id="check-for-updates" action="<?php print esc_url( $this->form_action() ); ?>" method="POST">
688 <div class="container"><input type="submit" class="button-primary" name"update" value="<?php print esc_attr(FWP_CHECK_FOR_UPDATES); ?>" />
689 <?php FeedWordPressCompatibility::stamp_nonce('feedwordpress_feeds'); ?>
690 <input type="hidden" name="update_uri" value="*" /></div>
691 </form>
692 <?php endif; ?>
693
694 <form id="syndicated-links" action="<?php print esc_url( $this->form_action() ); // TODO: needs to be checked, because it doesn't seem to be defined properly (gwyneth 20230915) ?>" method="post">
695 <div class="container"><?php FeedWordPressCompatibility::stamp_nonce('feedwordpress_feeds'); ?>
696 <label for="add-uri">Add:
697 <input type="text" name="lookup" id="add-uri" placeholder="Source URL"
698 value="Source URL" style="width: 55%;" /></label>
699
700 <?php FeedWordPressSettingsUI::magic_input_tip_js('add-uri'); ?>
701 <input type="hidden" name="action" value="<?php print esc_attr( FWP_SYNDICATE_NEW ); ?>" />
702 <input style="vertical-align: middle;" type="image" src="<?php print esc_url(plugins_url('plus.png', __FILE__)); ?>" alt="<?php print esc_html(FWP_SYNDICATE_NEW); ?>" /></div>
703 </form>
704 </div> <!-- id="add-single-uri" -->
705
706 <br style="clear: both;" />
707
708 <?php
709 } /* FeedWordPressSyndicationPage::dashboard_box () */
710
711 /**
712 * One of the status boxes for the FWP dashboard.
713 *
714 * @param mixed $page Unused
715 * @param mixed|null $box Unused
716 * *
717 * @uses FeedWordPress::syndicated_links()
718 * @uses FeedWordPressCompatibility::stamp_nonce()
719 * @uses FeedWordPressSettingsUI::magic_input_tip_js()
720 */
721 function syndicated_sources_box ($page, $box = NULL) {
722
723 $links = FeedWordPress::syndicated_links(array("hide_invisible" => false)); // what is $links for? (gwyneth 20230916)
724 $sources = $this->sources('*');
725
726 $visibility = $this->visibility_toggle();
727 $showInactive = $this->show_inactive();
728
729 $hrefPrefix = $this->form_action();
730 $formHref = sprintf( '%s&amp;visibility=%s', $hrefPrefix, urlencode($visibility) );
731 ?>
732 <div><?php FeedWordPressCompatibility::stamp_nonce('feedwordpress_feeds'); ?></div>
733 <div class="tablenav">
734
735 <div id="add-multiple-uri" class="hide-if-js">
736 <form action="<?php print esc_url( $formHref ); ?>" method="post">
737 <div><?php FeedWordPressCompatibility::stamp_nonce('feedwordpress_feeds'); ?></div>
738 <h4><?php esc_html_e( 'Add Multiple Sources' ); ?></h4>
739 <div><?php esc_html_e( 'Enter one feed or website URL per line. If a URL links to a website which provides multiple feeds, FeedWordPress will use the first one listed.' ); ?></div>
740 <div><textarea name="multilookup" rows="8" cols="60"
741 style="vertical-align: top"></textarea></div>
742 <div style="border-top: 1px dotted black; padding-top: 10px">
743 <div class="alignright"><input type="submit" class="button-primary" name="multiadd" value="<?php print esc_attr(FWP_SYNDICATE_NEW); ?>" /></div>
744 <div class="alignleft"><input type="button" class="button-secondary" name="action" value="<?php print esc_attr(FWP_CANCEL_BUTTON); ?>" id="turn-off-multiple-sources" /></div>
745 </div>
746 </form>
747 </div> <!-- id="add-multiple-uri" -->
748
749 <div id="upload-opml" style="float: right" class="hide-if-js">
750 <h4><?php esc_html_e( 'Import source list' ); ?></h4>
751 <p><?php esc_html_e( 'You can import a list of sources in OPML format, either by providing
752 a URL for the OPML document, or by uploading a copy from your
753 computer.' ); ?></p>
754
755 <form enctype="multipart/form-data" action="<?php print esc_url( $formHref ); ?>" method="post">
756 <div><?php FeedWordPressCompatibility::stamp_nonce('feedwordpress_feeds'); ?><input type="hidden" name="MAX_FILE_SIZE" value="100000" /></div>
757 <div style="clear: both"><label for="opml-lookup" style="float: left; width: 8.0em; margin-top: 5px;"><?php esc_html_e( 'From URL:' ); ?></label> <input type="text" id="opml-lookup" name="opml_lookup" value="OPML document" /></div>
758 <div style="clear: both"><label for="opml-upload" style="float: left; width: 8.0em; margin-top: 5px;"><?php esc_html_e( 'From file:' ); ?></label> <input type="file" id="opml-upload" name="opml_upload" /></div>
759
760 <div style="border-top: 1px dotted black; padding-top: 10px">
761 <div class="alignright"><input type="submit" class="button-primary" name="action" value="<?php print esc_html(FWP_SYNDICATE_NEW); ?>" /></div>
762 <div class="alignleft"><input type="button" class="button-secondary" name="action" value="<?php print esc_html(FWP_CANCEL_BUTTON); ?>" id="turn-off-opml-upload" /></div>
763 </div>
764 </form>
765 </div> <!-- id="upload-opml" -->
766
767 <div id="add-single-uri" class="alignright">
768 <form id="syndicated-links" action="<?php print esc_url( $formHref ); ?>" method="post">
769 <div><?php FeedWordPressCompatibility::stamp_nonce('feedwordpress_feeds'); ?></div>
770 <ul class="subsubsub">
771 <li><label for="add-uri"><?php esc_html_e( 'New source:' ); ?></label>
772 <input type="text" name="lookup" id="add-uri" value="Website or feed URI" />
773
774 <?php FeedWordPressSettingsUI::magic_input_tip_js('add-uri'); FeedWordPressSettingsUI::magic_input_tip_js('opml-lookup'); ?>
775
776 <input type="hidden" name="action" value="feedfinder" />
777 <input type="submit" class="button-secondary" name="action" value="<?php print esc_html( FWP_SYNDICATE_NEW ); ?>" />
778 <div style="text-align: right; margin-right: 2.0em">
779 <!-- Using WP Dashicon plus and down-arrow symbols below (gwyneth 20210717) -->
780 <a id="turn-on-multiple-sources" href="#add-multiple-uri"><span class="dashicons feedwordpress-dashicons dashicons-list-view"></span>&nbsp;<?php esc_html_e( 'add multiple' ); ?></a>
781 <span class="screen-reader-text"> or </span>
782 <a id="turn-on-opml-upload" href="#upload-opml"><span class="dashicons feedwordpress-dashicons dashicons-upload"></span>&nbsp;<?php esc_html_e( 'import source list' ); ?></a>
783 </div>
784 </li>
785 </ul>
786 </form>
787 </div> <!-- class="alignright" -->
788
789 <div class="alignleft">
790 <?php
791 if (count($sources[$visibility]) > 0) :
792 $this->manage_page_links_subsubsub($sources, $showInactive);
793 endif;
794 ?>
795 </div> <!-- class="alignleft" -->
796
797 </div> <!-- class="tablenav" -->
798
799 <form id="syndicated-links" action="<?php print esc_url( $formHref ); ?>" method="post">
800 <div><?php FeedWordPressCompatibility::stamp_nonce('feedwordpress_feeds'); ?></div>
801
802 <?php if ($showInactive) : ?>
803 <div style="clear: right" class="alignright">
804 <p style="font-size: smaller; font-style: italic"><?php esc_html_e( 'FeedWordPress used to syndicate
805 posts from these sources, but you have unsubscribed from them.' ); ?></p>
806 </div>
807 <?php
808 endif;
809 ?>
810
811 <?php
812 if (count($sources[$visibility]) > 0) :
813 $this->display_button_bar($showInactive);
814 else :
815 $this->manage_page_links_subsubsub($sources, $showInactive);
816 endif;
817
818 fwp_syndication_manage_page_links_table_rows($sources[$visibility], $this, $visibility);
819 $this->display_button_bar($showInactive);
820 ?>
821 </form>
822 <?php
823 } /* FeedWordPressSyndicationPage::syndicated_sources_box() */
824
825 /**
826 * Handles subpages on syndication dashboard (showing active/inactive feeds).
827 *
828 * @param array $sources List of feed URLs (active or inactive).
829 * @param bool $showInactive True if we're showing the inactive feeds.
830 *
831 */
832 function manage_page_links_subsubsub( $sources, $showInactive ) {
833 $hrefPrefix = $this->admin_page_href( "syndication.php" );
834 $hrefY = sprintf( "%s&amp;visibility=%s", $hrefPrefix, "Y" );
835 $hrefN = sprintf( "%s&amp;visibility=%s", $hrefPrefix, "N" );
836 ?>
837 <ul class="subsubsub">
838 <li><a <?php if ( ! $showInactive ) : ?>class="current" <?php endif; ?>href="<?php print esc_url( $hrefY ); ?>"><?php esc_html_e( 'Subscribed' ); ?>
839 <span class="count">(<?php print count( $sources['Y'] ); ?>)</span></a></li>
840 <?php if ( $showInactive or ( count( $sources['N'] ) > 0 ) ) : ?>
841 <li><a <?php if ( $showInactive ) : ?>class="current" <?php endif; ?>href="<?php print esc_url( $hrefN ); ?>"><?php esc_html_e( 'Inactive' ); ?></a>
842 <span class="count">(<?php print count( $sources['N'] ); ?>)</span></a></li>
843 <?php endif; ?>
844
845 </ul> <!-- class="subsubsub" -->
846 <?php
847 } /* FeedWordPressSyndicationPage::manage_page_links_subsubsub() */
848
849 /**
850 * Displays the button bar showing options per feed.
851 *
852 * @param bool $showInactive True if we're showing inactive feeds.
853 */
854 function display_button_bar( $showInactive ) {
855 ?>
856 <div style="clear: left" class="alignleft">
857 <?php if ( $showInactive ) : ?>
858 <input class="button-secondary" type="submit" name="action" value="<?php print esc_attr( FWP_RESUB_CHECKED ); ?>" />
859 <input class="button-secondary" type="submit" name="action" value="<?php print esc_attr( FWP_DELETE_CHECKED ); ?>" />
860 <?php else : ?>
861 <input class="button-secondary" type="submit" name="action" value="<?php print esc_attr( FWP_UPDATE_CHECKED ); ?>" />
862 <input class="button-secondary delete" type="submit" name="action" value="<?php print esc_attr( FWP_UNSUB_CHECKED ); ?>" />
863 <?php endif ; ?>
864 </div> <!-- class="alignleft" -->
865
866 <br class="clear" />
867 <?php
868 }
869
870 /**
871 * Displays page to thank user for donation.
872 *
873 * @param mixed $page Unused.
874 * @param mixed|null $box Unused.
875 */
876 function bleg_thanks( $page, $box = NULL ) {
877 ?>
878 <div class="donation-thanks">
879 <h4><?php esc_html_e( 'Thank you!' ); ?></h4>
880 <p><strong><?php esc_html_e( 'Thank you' ); ?></strong> <?php esc_html_e( ' for your contribution to '); ?>
881 <a href="<?php print esc_url( FWP_PROJECT_WEBSITE_URL ); ?>"><?php esc_html_e( 'FeedWordPress development' ); ?></a>.
882 <?php esc_html_e( 'Your generous gifts make ongoing support and development for
883 FeedWordPress possible.' ); ?></p>
884 <p><?php esc_html_e( 'If you have any questions about FeedWordPress, or if there
885 is anything I can do to help make FeedWordPress more useful for
886 you, please '); ?><a href="<?php print esc_url( FWP_PROJECT_WEBSITE_URL ); ?>contact"><?php esc_html_e( 'contact me' ); ?></a>
887 <?php esc_html_e(' and let me know what you&rsquo;re thinking about.' ); ?></p>
888 <p class="signature">&mdash;<a href="<?php print esc_url( FWP_PROJECT_WEBSITE_URL ); ?>">Charles Johnson</a>, <?php esc_html_e(' Developer' ); ?>, <a href="<?php print esc_url( FWP_PROJECT_WEBSITE_URL ); ?>">FeedWordPress</a>.</p>
889 </div>
890 <?php
891 } /* FeedWordPressSyndicationPage::bleg_thanks () */
892
893 /**
894 * Displays a donation form.
895 *
896 * @note Flattr unfortunately changed their business model :-(
897 * (gwyneth 20230917)
898 *
899 * @param mixed $page Unused.
900 * @param mixed|null $box Unused.
901 */
902 function bleg_box ($page, $box = NULL) {
903 ?>
904 <div class="donation-form">
905 <h4><?php esc_html_e( 'Consider a Donation to FeedWordPress' ); ?></h4>
906 <form action="https://www.paypal.com/cgi-bin/webscr" accept-charset="UTF-8" method="post"><div>
907 <p><a href="<?php print esc_url( FWP_PROJECT_WEBSITE_URL ); ?>">FeedWordPress</a> <?php esc_html_e( 'makes syndication
908 simple and empowers you to stream content from all over the web into your
909 WordPress hub. If you&rsquo;re finding FWP useful, ' ); ?>
910 <a href="<?php print esc_url( FWP_PROJECT_WEBSITE_URL ); ?>donate/"><?php esc_html_e( 'a modest gift' ); ?></a>
911 <?php esc_html_e( ' is the best way to support steady progress on development, enhancements,
912 support, and documentation.' ); ?></p>
913
914 <div class="donate" style="vertical-align: middle">
915
916 <div id="flattr-paypal">
917
918 <div class="hovered-component" style="display: inline-block; vertical-align: bottom">
919 <a href="bitcoin:<?php print esc_attr( FEEDWORDPRESS_BLEG_BTC ); ?>"><img src="<?php print esc_url( plugins_url('/'.FeedWordPress::path('assets/images/btc-qr-128px.png') ) ); ?>" alt="<?php esc_html_e( 'Donate' ); ?>" /></a>
920 <div><a href="bitcoin:<?php print esc_attr( FEEDWORDPRESS_BLEG_BTC ); ?>"><?php esc_html_e( 'via' ); ?> bitcoin<span class="hover-on pop-over" style="background-color: #ddffdd; padding: 5px; color: black; border-radius: 5px;">bitcoin:<?php print esc_html( FEEDWORDPRESS_BLEG_BTC ); ?></span></a></div>
921 </div>
922
923 <div style="display: inline-block; vertical-align: bottom">
924 <input type="image" name="submit" src="<?php print esc_url( plugins_url( '/' . FeedWordPress::path('assets/images/paypal-donation-64px.png' ) ) ); ?>" style="width: 128px; height: 128px;" alt="<?php esc_html_e( 'Donate via PayPal' ); ?>" />
925 <input type="hidden" name="business" value="<?php print esc_attr( FEEDWORDPRESS_BLEG_PAYPAL ); ?>" />
926 <input type="hidden" name="cmd" value="_xclick" />
927 <input type="hidden" name="item_name" value="<?php esc_html_e( 'FeedWordPress donation' ); ?>" />
928 <input type="hidden" name="no_shipping" value="1" />
929 <input type="hidden" name="return" value="<?php print esc_attr( $this->admin_page_href( basename( $this->filename ), array( 'paid' => 'yes' ) ) ); ?>" />
930 <input type="hidden" name="currency_code" value="USD" />
931 <input type="hidden" name="notify_url" value="<?php print esc_url( FWP_PROJECT_WEBSITE_URL ); ?>/ipn/donation" />
932 <input type="hidden" name="custom" value="1" />
933 <div><?php esc_html_e( 'via PayPal' ); ?></div>
934 </div> <!-- style="display: inline-block" -->
935
936 </div> <!-- id="flattr-paypal" -->
937 </div> <!-- class="donate" -->
938
939 </div> <!-- class="donation-form" -->
940 </form>
941
942 <p><?php esc_html_e( 'You can make a gift online (or ' ); ?><a href="<?php print esc_url( FWP_PROJECT_WEBSITE_URL ) ;?>donation"><?php esc_html_e( 'set up an automatic
943 regular donation' ); ?></a><?php esc_html_e( ' using an existing PayPal account or any major credit card.' ); ?></p>
944
945 <div class="sod-off">
946 <form style="text-align: center" action="<?php print esc_url( $this->form_action() ); ?>" method="POST"><div>
947 <input class="button" type="submit" name="maybe_later" value="<?php esc_attr_e( 'Maybe Later' ); ?>"/>
948 <input class="button" type="submit" name="go_away" value="<?php esc_attr_e( 'Dismiss' ); ?>"/>
949 </div></form>
950 </div>
951 </div> <!-- class="donation-form" -->
952 <?php
953 } /* FeedWordPressSyndicationPage::bleg_box() */
954
955 /**
956 * Override the default display of a save-settings button and replace
957 * it with nothing.
958 */
959 function interstitial() {
960 /* NOOP */
961 } /* FeedWordPressSyndicationPage::interstitial() */
962
963 function multidelete_page() {
964 global $wpdb;
965
966 // If this is a POST, validate source and user credentials
967 FeedWordPressCompatibility::validate_http_request( /*action=*/ 'feedwordpress_feeds', /*capability=*/ 'manage_links' );
968
969 if ( MyPHP::post( 'submit' ) == FWP_CANCEL_BUTTON ) :
970 return true; // Continue without further ado.
971 endif;
972
973 // Get single link ID or multiple link IDs from REQUEST parameters
974 // if available. Sanitize values for MySQL.
975 $link_list = $this->requested_link_ids_sql();
976
977 if (MyPHP::post('confirm')=='Delete'):
978 $actions = array(); // avoids "else" complaint _and_ guarantees that we don't have any scoping issues (gwyneth 20230916)
979 if ( is_array(MyPHP::post('link_action')) ) :
980 $actions = MyPHP::post('link_action');
981 endif;
982
983 $do_it = array(
984 'hide' => array(),
985 'nuke' => array(),
986 'delete' => array(),
987 );
988
989 foreach ($actions as $link_id => $what) :
990 $do_it[$what][] = $link_id;
991 endforeach;
992
993 $alter = array();
994 if (count($do_it['hide']) > 0) :
995 $hidem = "(".implode(', ', $do_it['hide']).")";
996 $alter[] = "
997 UPDATE $wpdb->links
998 SET link_visible = 'N'
999 WHERE link_id IN {$hidem}
1000 ";
1001 endif;
1002
1003 if (count($do_it['nuke']) > 0) :
1004 $nukem = "(".implode(', ', $do_it['nuke']).")";
1005
1006 // Make a list of the items syndicated from this feed...
1007 $post_ids = $wpdb->get_col("
1008 SELECT post_id FROM $wpdb->postmeta
1009 WHERE meta_key = 'syndication_feed_id'
1010 AND meta_value IN {$nukem}
1011 ");
1012
1013 // ... and kill them all
1014 if (count($post_ids) > 0) :
1015 foreach ($post_ids as $post_id) :
1016 // Force scrubbing of deleted post
1017 // rather than sending to Trashcan
1018 wp_delete_post(
1019 /*postid=*/ $post_id,
1020 /*force_delete=*/ true
1021 );
1022 endforeach;
1023 endif;
1024
1025 $alter[] = "
1026 DELETE FROM $wpdb->links
1027 WHERE link_id IN {$nukem}
1028 ";
1029 endif;
1030
1031 if (count($do_it['delete']) > 0) :
1032 $deletem = "(".implode(', ', $do_it['delete']).")";
1033
1034 // Make the items syndicated from this feed appear to be locally-authored
1035 $alter[] = "
1036 DELETE FROM $wpdb->postmeta
1037 WHERE meta_key = 'syndication_feed_id'
1038 AND meta_value IN {$deletem}
1039 ";
1040
1041 // ... and delete the links themselves.
1042 $alter[] = "
1043 DELETE FROM $wpdb->links
1044 WHERE link_id IN {$deletem}
1045 ";
1046 endif;
1047
1048 $errs = array();
1049 foreach ($alter as $sql) :
1050 $result = $wpdb->query($sql);
1051 if ( ! $result):
1052 $errs[] = $wpdb->last_error;
1053 endif;
1054 endforeach;
1055
1056 if (count($alter) > 0) :
1057 echo "<div class=\"updated\">\n";
1058 if (count($errs) > 0) :
1059 echo "There were some problems processing your unsubscribe request. [SQL: ";
1060 $sep = '';
1061 foreach ( $errs as $err ) :
1062 print esc_html($sep);
1063 print esc_html($err);
1064 $sep = '; ';
1065 endforeach;
1066 echo "]";
1067 else :
1068 echo "Your unsubscribe request(s) have been processed.";
1069 endif;
1070 echo "</div>\n";
1071 endif;
1072
1073 return true; // Continue on to Syndicated Sites listing
1074 else :
1075 // $link_list has previously been sanitized for html by self::requested_link_ids_sql
1076 $targets = $wpdb->get_results("
1077 SELECT * FROM $wpdb->links
1078 WHERE link_id IN {$link_list}
1079 ");
1080 ?>
1081 <form action="<?php print esc_url( $this->form_action() ); ?>" method="post">
1082 <div class="wrap">
1083 <?php FeedWordPressCompatibility::stamp_nonce('feedwordpress_feeds'); ?>
1084 <input type="hidden" name="action" value="Unsubscribe" />
1085 <input type="hidden" name="confirm" value="Delete" />
1086
1087 <h2><?php esc_html_e( 'Unsubscribe from Syndicated Links:' ); ?></h2>
1088 <?php foreach ($targets as $link) :
1089 $subscribed = ('Y' == strtoupper($link->link_visible));
1090 ?>
1091 <fieldset>
1092 <legend><?php echo esc_html($link->link_name); ?></legend>
1093 <table class="editform" width="100%" cellspacing="2" cellpadding="5">
1094 <tr><th scope="row" width="20%"><?php esc_html_e( 'Feed URI:' ) ?></th>
1095 <td width="80%"><a href="<?php echo esc_url($link->link_rss); ?>"><?php echo esc_html( $link->link_rss ); ?></a></td></tr>
1096 <tr><th scope="row" width="20%"><?php esc_html_e( 'Short description:' ) ?></th>
1097 <td width="80%"><?php echo esc_html( $link->link_description ); ?></span></td></tr>
1098 <tr><th width="20%" scope="row"><?php esc_html_e( 'Homepage:' ) ?></th>
1099 <td width="80%"><a href="<?php echo esc_url($link->link_url); ?>"><?php echo esc_html( $link->link_url ); ?></a></td></tr>
1100 <tr style="vertical-align:top"><th width="20%" scope="row"><?php esc_html_e( 'Subscription ' ); ?><?php esc_html_e( 'Options' ); ?>:</th>
1101 <td width="80%"><ul style="margin:0; padding: 0; list-style: none">
1102 <?php if ($subscribed) : ?>
1103 <li><input type="radio" id="hide-<?php echo esc_attr($link->link_id); ?>"
1104 name="link_action[<?php echo esc_attr($link->link_id); ?>]" value="hide" checked="checked" />
1105 <label for="hide-<?php echo esc_attr($link->link_id); ?>"><?php esc_html_e( 'Turn off the subscription for this
1106 syndicated link<br/><span style="font-size:smaller">(Keep the feed information
1107 and all the posts from this feed in the database, but don&rsquo;t syndicate any
1108 new posts from the feed.)' ); ?></span></label></li>
1109 <?php endif; ?>
1110 <li><input type="radio" id="nuke-<?php echo esc_attr($link->link_id); ?>"<?php if ( ! $subscribed) : ?> checked="checked"<?php endif; ?>
1111 name="link_action[<?php echo esc_attr($link->link_id); ?>]" value="nuke" />
1112 <label for="nuke-<?php echo esc_attr($link->link_id); ?>"><?php esc_html_e( 'Delete this syndicated link and all the
1113 posts that were syndicated from it' ); ?></label></li>
1114 <li><input type="radio" id="delete-<?php echo esc_attr($link->link_id); ?>"
1115 name="link_action[<?php echo esc_attr($link->link_id); ?>]" value="delete" />
1116 <label for="delete-<?php echo esc_attr($link->link_id); ?>"><?php esc_html_e( 'Delete this syndicated link, but
1117 <em>keep</em> posts that were syndicated from it (as if they were authored
1118 locally).' ); ?></label></li>
1119 <li><input type="radio" id="nothing-<?php echo esc_attr( $link->link_id ); ?>"
1120 name="link_action[<?php echo esc_attr( $link->link_id ); ?>]" value="nothing" />
1121 <label for="nothing-<?php echo esc_attr( $link->link_id ); ?>"><?php esc_html_e( 'Keep this feed as it is. I changed
1122 my mind.' ); ?></label></li>
1123 </ul>
1124 </table>
1125 </fieldset>
1126 <?php endforeach; ?>
1127
1128 <div class="submit">
1129 <input type="submit" name="submit" value="<?php esc_html_e( FWP_CANCEL_BUTTON ); ?>" />
1130 <input class="delete" type="submit" name="submit" value="<?php esc_html_e( FWP_UNSUB_FULL ) ?>" />
1131 </div>
1132 </div>
1133 <?php
1134 return false; // Don't continue on to Syndicated Sites listing
1135 endif;
1136 } /* FeedWordPressSyndicationPage::multidelete_page() */
1137
1138 function multiundelete_page () {
1139 global $wpdb;
1140
1141 // If this is a POST, validate source and user credentials
1142 FeedWordPressCompatibility::validate_http_request(/*action=*/ 'feedwordpress_feeds', /*capability=*/ 'manage_links');
1143
1144 // Get single link ID or multiple link IDs from REQUEST parameters
1145 // if available. Sanitize values for MySQL.
1146 $link_list = $this->requested_link_ids_sql();
1147
1148 if (MyPHP::post('confirm')=='Undelete'):
1149 if ( is_array(MyPHP::post('link_action')) ) :
1150 $actions = MyPHP::post('link_action');
1151 else :
1152 $actions = array();
1153 endif;
1154
1155 $do_it = array(
1156 'unhide' => array(),
1157 );
1158
1159 foreach ($actions as $link_id => $what) :
1160 $do_it[$what][] = $link_id;
1161 endforeach;
1162
1163 $alter = array();
1164 if (count($do_it['unhide']) > 0) :
1165 $unhiddem = "(".implode(', ', $do_it['unhide']).")";
1166 $alter[] = "
1167 UPDATE $wpdb->links
1168 SET link_visible = 'Y'
1169 WHERE link_id IN {$unhiddem}
1170 ";
1171 endif;
1172
1173 $errs = array();
1174 foreach ($alter as $sql) :
1175 $result = $wpdb->query($sql);
1176 if ( ! $result):
1177 $errs[] = $wpdb->last_error;
1178 endif;
1179 endforeach;
1180
1181 if (count($alter) > 0) :
1182 echo "<div class=\"updated\">\n";
1183 if (count($errs) > 0) :
1184 esc_html_e( 'There were some problems processing your re-subscribe request. ' );
1185 echo esc_html( "[SQL: ".implode('; ', $errs)."]" );
1186 else :
1187 esc_html_e( 'Your re-subscribe request(s) have been processed.' );
1188 endif;
1189 echo "</div>\n";
1190 endif;
1191
1192 return true; // Continue on to Syndicated Sites listing
1193 else :
1194 // $link_list has previously been sanitized for html by self::requested_link_ids_sql
1195 $targets = $wpdb->get_results("
1196 SELECT * FROM $wpdb->links
1197 WHERE link_id IN {$link_list}
1198 ");
1199 ?>
1200 <form action="<?php print esc_url( $this->form_action() ); ?>" method="post">
1201 <div class="wrap">
1202 <?php FeedWordPressCompatibility::stamp_nonce('feedwordpress_feeds'); ?>
1203 <input type="hidden" name="action" value="<?php print esc_attr( FWP_RESUB_CHECKED ); ?>" />
1204 <input type="hidden" name="confirm" value="Undelete" />
1205
1206 <h2><?php esc_html_e( 'Re-subscribe to Syndicated Links:' ); ?></h2>
1207 <?php
1208 foreach ($targets as $link) :
1209 $subscribed = ( 'Y' == strtoupper( $link->link_visible ) );
1210 if ( ! $subscribed ) :
1211 ?>
1212 <fieldset>
1213 <legend><?php echo esc_html( $link->link_name ); ?></legend>
1214 <table class="editform" width="100%" cellspacing="2" cellpadding="5">
1215 <tr><th scope="row" width="20%"><?php esc_html_e( 'Feed URI:' ) ?></th>
1216 <td width="80%"><a href="<?php echo esc_url( $link->link_rss ); ?>"><?php echo esc_html( $link->link_rss ); ?></a></td></tr>
1217 <tr><th scope="row" width="20%"><?php esc_html_e( 'Short description:' ) ?></th>
1218 <td width="80%"><?php echo esc_html($link->link_description); ?></span></td></tr>
1219 <tr><th width="20%" scope="row"><?php esc_html_e( 'Homepage:' ) ?></th>
1220 <td width="80%"><a href="<?php echo esc_url($link->link_url); ?>"><?php echo esc_html($link->link_url); ?></a></td></tr>
1221 <tr style="vertical-align:top"><th width="20%" scope="row"><?php esc_html_e( 'Subscription' ); ?> <?php esc_html_e( 'Options' ); ?>:</th>
1222 <td width="80%"><ul style="margin:0; padding: 0; list-style: none">
1223 <li><input type="radio" id="unhide-<?php echo esc_attr($link->link_id); ?>"
1224 name="link_action[<?php echo esc_attr($link->link_id); ?>]" value="unhide" checked="checked" />
1225 <label for="unhide-<?php echo esc_attr($link->link_id); ?>"><?php esc_html_e( 'Turn back on the subscription
1226 for this syndication source.' ); ?></label></li>
1227 <li><input type="radio" id="nothing-<?php echo esc_attr($link->link_id); ?>"
1228 name="link_action[<?php echo esc_attr($link->link_id); ?>]" value="nothing" />
1229 <label for="nothing-<?php echo esc_attr($link->link_id); ?>"><?php esc_html_e( 'Leave this feed as it is.
1230 I changed my mind.' ); ?></label></li>
1231 </ul>
1232 </table>
1233 </fieldset>
1234 <?php
1235 endif;
1236 endforeach;
1237 ?>
1238
1239 <div class="submit">
1240 <input class="button-primary delete" type="submit" name="submit" value="<?php esc_html_e( 'Re-subscribe to selected feeds &raquo;' ) ?>" />
1241 </div>
1242 </div>
1243 <?php
1244 return false; // Don't continue on to Syndicated Sites listing
1245 endif;
1246 } /* FeedWordPressSyndicationPage::multiundelete_page() */
1247
1248 public function switchfeed_page () {
1249 global $wpdb;
1250
1251 // If this is a POST, validate source and user credentials
1252 FeedWordPressCompatibility::validate_http_request(/*action=*/ 'feedwordpress_switchfeed', /*capability=*/ 'manage_links');
1253
1254 $changed = false;
1255 if ( is_null( FeedWordPress::post( 'Cancel' ) ) ):
1256 $save_link_id = FeedWordPress::post( 'save_link_id' );
1257
1258 if ( $save_link_id == '*' ) :
1259 $changed = true;
1260
1261 $feed_title = FeedWordPress::post( 'feed_title' );
1262 $feed_link = FeedWordPress::post( 'feed_link' );
1263 $feed = FeedWordPress::post( 'feed' );
1264
1265 $link_id = FeedWordPress::syndicate_link( $feed_title, $feed_link, $feed );
1266 if ($link_id):
1267 $existingLink = new SyndicatedLink($link_id);
1268 $adminPageHref = $this->admin_page_href( 'feeds-page.php', array( "link_id" => $link_id ) );
1269 ?>
1270 <div class="updated"><p><a href="<?php print esc_url($feed_link); ?>"><?php print esc_html($feed_title); ?></a>
1271 <?php esc_html_e( 'has been added as a contributing site, using the feed at' ); ?>
1272 &lt;<a href="<?php print esc_url( $feed ); ?>"><?php print esc_html( $feed ); ?></a>&gt;.
1273 | <a href="<?php print esc_url( $adminPageHref ); ?>"><?php esc_html_e( 'Configure settings' ); ?></a>.</p></div>
1274 <?php
1275 else:
1276 ?>
1277 <div class="updated"><p><?php esc_html_e( 'There was a problem adding the feed.' ); ?> [SQL: <?php echo esc_html($wpdb->last_error); ?>]</p></div>
1278 <?php
1279 endif;
1280 elseif ( ! is_null( $save_link_id ) ):
1281 $feed = FeedWordPress::post( 'feed' );
1282 $existingLink = new SyndicatedLink( $save_link_id );
1283
1284 $changed = $existingLink->set_uri($feed);
1285
1286 if ($changed):
1287 $home = $existingLink->homepage(/*from feed=*/ false);
1288 $name = $existingLink->name(/*from feed=*/ false);
1289 ?>
1290 <div class="updated"><p><?php esc_html_e( 'Feed for ' ); ?><a href="<?php echo esc_html($home); ?>"><?php echo esc_html($name); ?></a>
1291 <?php esc_html_e( 'updated to ' ); ?>&lt;<a href="<?php echo esc_html( $feed ); ?>"><?php echo esc_html( $feed ); ?></a>&gt;.</p></div>
1292 <?php
1293 endif;
1294 endif;
1295 endif;
1296
1297 if (isset($existingLink)) :
1298 $auth = FeedWordPress::post('link_rss_auth_method');
1299 if ( !is_null($auth) and (strlen($auth) > 0) and ($auth != '-')) :
1300 $existingLink->update_setting('http auth method', $auth);
1301 $existingLink->update_setting('http username',
1302 FeedWordPress::post('link_rss_username')
1303 );
1304 $existingLink->update_setting('http password',
1305 FeedWordPress::post('link_rss_password')
1306 );
1307 else :
1308 $existingLink->update_setting('http auth method', NULL);
1309 $existingLink->update_setting('http username', NULL);
1310 $existingLink->update_setting('http password', NULL);
1311 endif;
1312 do_action('feedwordpress_admin_switchfeed', FeedWordPress::post( 'feed' ), $existingLink);
1313 $existingLink->save_settings(/*reload=*/ true);
1314 endif;
1315
1316 if ( ! $changed) :
1317 ?>
1318 <div class="updated"><p><?php esc_html_e( 'Nothing was changed.' ); ?></p></div>
1319 <?php
1320 endif;
1321 return true; // Continue.
1322 }
1323
1324 function feedfinder_page () {
1325 global $post_source;
1326
1327 if ( FeedWordPress::post( 'opml_lookup' ) or isset( $_FILES['opml_upload'] ) ) :
1328 $this->accept_multiadd();
1329 return true;
1330 else :
1331 $post_source = 'feedwordpress_feeds';
1332
1333 // With action=feedfinder, this goes directly to the feedfinder page
1334 include_once(dirname(__FILE__) . '/feeds-page.php');
1335 return false;
1336 endif;
1337 } /* function feedfinder_page () */
1338
1339 } /* class FeedWordPressSyndicationPage */
1340
1341 function fwp_dashboard_update_if_requested ($object) {
1342 global $crash_dt;
1343
1344 $update_set = $object->updates_requested();
1345
1346 if (count($update_set) > 0) :
1347 shuffle($update_set); // randomize order for load balancing purposes...
1348
1349 $feedwordpress = new FeedWordPress;
1350 add_action('feedwordpress_check_feed', 'update_feeds_mention');
1351 add_action('feedwordpress_check_feed_complete', 'update_feeds_finish', 10, 3);
1352
1353 $crash_ts = $feedwordpress->crash_ts();
1354
1355 echo "<div class=\"update-results\">\n";
1356 echo "<ul>\n";
1357 $tdelta = NULL;
1358 foreach ($update_set as $uri) :
1359 if ( !is_null($crash_ts) and (time() > $crash_ts)) :
1360 echo "<li><p><strong>" . esc_html__( "Further updates postponed:" ) . "</strong> "
1361 . esc_html__( "update time limit of " ) . esc_html( $crash_dt ) . esc_html__( " second"
1362 . ( ( 1 == $crash_dt ) ? "" : "s" ) ) . esc_html__( " exceeded." ) . "</p></li>";
1363 break;
1364 endif;
1365
1366 if ($uri == '*') : $uri = NULL; endif;
1367 $delta = $feedwordpress->update($uri, $crash_ts);
1368 if ( !is_null($delta)) :
1369 if (is_null($tdelta)) :
1370 $tdelta = $delta;
1371 else :
1372 $tdelta['new'] += $delta['new'];
1373 $tdelta['updated'] += $delta['updated'];
1374 endif;
1375 else :
1376 $display_uri = esc_html(feedwordpress_display_url($uri));
1377 $uri = esc_html($uri);
1378 echo '<li><p><strong>' . esc_html__( "Error:" ) . "</strong> ". esc_html__( 'There was a problem updating ' )
1379 . '<code><a href="' . esc_url( $uri ) . '">' . esc_html( $display_uri ) . '</a></code></p></li>' . "\n";
1380 endif;
1381 endforeach;
1382 echo "</ul>\n";
1383
1384 if ( !is_null($tdelta)) :
1385 echo '<p><strong>'; esc_html_e( 'Update complete.' ); echo '</strong>'; print esc_html( fwp_update_set_results_message($delta) ); print '</p>';
1386 echo "\n"; flush();
1387 endif;
1388 echo "</div> <!-- class=\"updated\" -->\n";
1389 endif;
1390 }
1391
1392 define('FEEDWORDPRESS_BLEG_MAYBE_LATER_OFFSET', (60 /*sec/min*/ * 60 /*min/hour*/ * 24 /*hour/day*/ * 31 /*days*/));
1393 define('FEEDWORDPRESS_BLEG_ALREADY_PAID_OFFSET', (60 /*sec/min*/ * 60 /*min/hour*/ * 24 /*hour/day*/ * 183 /*days*/));
1394 function fwp_syndication_manage_page_update_box ($object = NULL, $box = NULL) {
1395 $bleg_box_hidden = null;
1396
1397 if ( FeedWordPress::post( 'maybe_later' ) ) :
1398 $bleg_box_hidden = time() + FEEDWORDPRESS_BLEG_MAYBE_LATER_OFFSET;
1399 elseif ( FeedWordPress::post( 'paid' ) ) :
1400 $bleg_box_hidden = time() + FEEDWORDPRESS_BLEG_ALREADY_PAID_OFFSET;
1401 elseif ( FeedWordPress::post( 'go_away' ) ) :
1402 $bleg_box_hidden = 'permanent';
1403 endif;
1404
1405 if ( !is_null($bleg_box_hidden)) :
1406 update_option('feedwordpress_bleg_box_hidden', $bleg_box_hidden);
1407 else :
1408 $bleg_box_hidden = get_option('feedwordpress_bleg_box_hidden');
1409 endif;
1410 ?>
1411 <?php
1412 $bleg_box_ready = (FEEDWORDPRESS_BLEG and (
1413 ! $bleg_box_hidden
1414 or (is_numeric($bleg_box_hidden) and $bleg_box_hidden < time())
1415 ));
1416
1417 $bleg_box_ready = apply_filters( 'feedwordpress_bleg_box_ready', $bleg_box_ready );
1418 if ( FeedWordPress::post( 'paid' ) || ( FeedWordPress::param( 'test' ) == 'thanks' ) ) :
1419 $object->bleg_thanks($object, $box);
1420 elseif ($bleg_box_ready || ( FeedWordPress::param( 'test' ) == 'bleg' ) ) :
1421 $object->bleg_box($object, $box);
1422 endif;
1423 ?>
1424
1425 <form
1426 action="<?php print esc_url( $object->form_action() ); ?>"
1427 method="POST"
1428 class="update-form<?php if ($bleg_box_ready) : ?> with-donation<?php endif; ?>"
1429 >
1430 <div><?php FeedWordPressCompatibility::stamp_nonce('feedwordpress_feeds'); ?></div>
1431 <p><?php esc_html_e( 'Check currently scheduled feeds for new and updated posts.' ); ?></p>
1432
1433 <?php
1434 fwp_dashboard_update_if_requested($object);
1435
1436 if ( !get_option('feedwordpress_automatic_updates')) :
1437 ?>
1438 <p class="heads-up"><strong><?php esc_html_e( 'Note:' ); ?></strong> <?php esc_html_e( 'Automatic updates are currently turned
1439 <strong>off</strong>. New posts from your feeds will not be syndicated
1440 until you manually check for them here. You can turn on automatic
1441 updates under' ); ?> <a href="<?php print esc_url( $object->admin_page_href('feeds-page.php') ); ?>"><?php esc_html_e( 'Feed &amp; Update Settings' ); ?></a>.</p>
1442 <?php
1443 endif;
1444 ?>
1445
1446 <div class="submit"><?php if ($object->show_inactive()) : ?>
1447 <?php foreach ($object->updates_requested() as $req) : ?>
1448 <input type="hidden" name="update_uri[]" value="<?php print esc_html($req); ?>" />
1449 <?php endforeach; ?>
1450 <?php else : ?>
1451 <input type="hidden" name="update_uri" value="*" />
1452 <?php endif; ?>
1453 <input class="button-primary" type="submit" name="update" value="<?php esc_html_e( FWP_CHECK_FOR_UPDATES ); ?>" /></div>
1454
1455 <br style="clear: both" />
1456 </form>
1457 <?php
1458 } /* function fwp_syndication_manage_page_update_box () */
1459