Changeset 612743
- Timestamp:
- 10/15/2012 02:09:57 PM (13 years ago)
- Location:
- globalfeed/trunk
- Files:
-
- 9 edited
-
admin/pages/style.css (modified) (1 diff)
-
event_scheduler_interfaces/wp-schedule-interface.php (modified) (1 diff)
-
feeds/mb_facebook/mb_facebook.php (modified) (6 diffs)
-
feeds/mb_facebook/pages/setup.php (modified) (2 diffs)
-
feeds/mb_twitter/mb_twitter.php (modified) (7 diffs)
-
feeds/mb_twitter/pages/js/mb_twitter.js (modified) (1 diff)
-
feeds/mb_twitter/pages/setup.php (modified) (9 diffs)
-
feeds/mbgf_rss/mbgf_rss.php (modified) (2 diffs)
-
mb_globalfeed.php (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
globalfeed/trunk/admin/pages/style.css
r593074 r612743 137 137 margin: 0px 20px 20px 0px; 138 138 padding: 5px 10px 10px; 139 position:relative; 140 } 141 142 .optgrp .bottom-button { 143 position: absolute; 144 bottom: 10px; 145 left: 0px; 146 width: 100%; 139 147 } 140 148 -
globalfeed/trunk/event_scheduler_interfaces/wp-schedule-interface.php
r593074 r612743 81 81 } else { 82 82 $inner = array_shift(array_values($event[$this->hook_name])); 83 if ( $event[$this->hook_name]['args']['caller'] != $caller &&84 $event[$this->hook_name]['args']['action'] != $action )83 if ( !isset($event[$this->hook_name]['args']) || ($event[$this->hook_name]['args']['caller'] != $caller && 84 $event[$this->hook_name]['args']['action'] != $action) ) 85 85 $new_schedule[$timestamp] = $event; 86 86 } -
globalfeed/trunk/feeds/mb_facebook/mb_facebook.php
r591186 r612743 167 167 $this->setup_filters(); 168 168 169 // Check for our query vars that tell the feed to take control. (IE communications received from Facebook.) 170 // if ( isset( $_GET['reset_since'] ) ) 171 // $this->feed_options['last_feed_update'] = 0; 172 173 // if ( isset( $_GET[ 'setup_fb' ] ) && $feed_options != false) 174 // $this->get_authorization(); 175 176 // If were in the admin, we need to be using sessions 169 // If we're in the admin, we need to be using sessions 177 170 if ( is_admin() ) { 178 171 if (!isset($_SESSION['state'])) … … 195 188 $this->handle_subscription_call(); 196 189 197 // If we're set to automatically interupt application flow, then exit so WordPress doesn't do its thing.198 // if ( (isset( $_GET['feed_queryvar']) || isset( $_POST['feed_queryvar'])) && $this->auto_interupt_flow && false)199 // exit;200 190 } 201 191 … … 371 361 wp_verify_nonce( 'facebook-connect-settings_main' ); 372 362 373 if (!empty($this->feed_options['oauth_user_token']) || (isset($_SERVER['mbgf_ app_is_authed']) && $_SERVER['mbgf_app_is_authed']) || get_transient('mbgf_app_is_authed')) {374 unset( $_SERVER['mbgf_ app_is_authed'] );363 if (!empty($this->feed_options['oauth_user_token']) || (isset($_SERVER['mbgf_facebook_authed']) && $_SERVER['mbgf_facebook_authed']) || get_transient('mbgf_facebook_authed')) { 364 unset( $_SERVER['mbgf_facebook_authed'] ); 375 365 die( json_encode(true) ); 376 366 } else { … … 378 368 while ( $c <= 2 ) { 379 369 sleep(2); 380 if ( (isset($_SERVER['mbgf_ app_is_authed']) && $_SERVER['mbgf_app_is_authed']) || get_transient('mbgf_app_is_authed') ) {381 unset( $_SERVER['mbgf_ app_is_authed'] );370 if ( (isset($_SERVER['mbgf_facebook_authed']) && $_SERVER['mbgf_facebook_authed']) || get_transient('mbgf_facebook_authed') ) { 371 unset( $_SERVER['mbgf_facebook_authed'] ); 382 372 die(json_encode(true)); 383 373 } … … 518 508 return new WP_Error ('MB_Facebook_Feed_Activation_Failed', 'Feed registration failed for an unknown reason.'); 519 509 520 // Get Facebook Authorization.521 //if ( !$this->get_authorization())522 // return new WP_Error ('MB_Facebook_Feed_Authorization_Failed', 'Feed authentication with Facebook failed.');523 510 524 511 } … … 1058 1045 $this->register_feed( true ); 1059 1046 1060 $_SERVER['mbgf_ app_is_authed'] = true;1061 set_transient('mbgf_ app_is_authed', true, 3600);1047 $_SERVER['mbgf_facebook_authed'] = true; 1048 set_transient('mbgf_facebook_authed', true, 3600); 1062 1049 1063 1050 if ($this->feed_type == 'callback') -
globalfeed/trunk/feeds/mb_facebook/pages/setup.php
r582062 r612743 31 31 <th><?php _e('Facebook App ID:',$mb_globalfeed_facebook_connect->get_slug()) ?></th> 32 32 <td><input type="text" name="app_id" class="auth-form-input" id="app_id" value="<?php echo $feed_options['app_id']; ?>"/></td> 33 </tr> 33 </tr> 34 34 <tr> 35 35 <th><?php _e('Facebook App Secret:',$mb_globalfeed_facebook_connect->get_slug()) ?></th> 36 36 <td><input type="text" name="app_secret" class="auth-form-input" id="app_secret" value="<?php echo $feed_options['app_secret']; ?>" /></td> 37 </tr> 37 </tr> 38 38 <tr> 39 39 <th></th> … … 102 102 jQuery('#authorize_button').attr("disabled", true); 103 103 104 // In order to get pas sedpopup blockers, we open the AuthWindow now. In the future, this should pop up a temporary loading page, however we aren't that fancy yet.104 // In order to get past popup blockers, we open the AuthWindow now. In the future, this should pop up a temporary loading page, however we aren't that fancy yet. 105 105 authWindow = window.open('',"fb_activation_window","location=0,status=0,scrollbars=0, width=750,height=500"); 106 106 107 107 // Post the app_id and secret to the server for use in the auth process. 108 108 jQuery.post(ajaxurl, {action:'mbgf_facebook_connect_set_app_info',app_id:app_id,app_secret:app_secret,_wpnonce:jQuery('#_wpnonce').val()}, function(response){ 109 //authWindow = window.open(jQuery('#activation_url').val() + '&client_id=' + jQuery('#app_id').val(), );110 109 authWindow.location.href = jQuery('#activation_url').val() + '&client_id=' + jQuery('#app_id').val(); 111 110 setAuthWindowChecker( '#step-1', function(){jQuery('#authorize_button').attr("disabled", false)}, jQuery('#activation_redirection_url').val() ); -
globalfeed/trunk/feeds/mb_twitter/mb_twitter.php
r593074 r612743 89 89 private $_apiurl = 'http://api.twitter.com/1/'; 90 90 91 private $tw_endpoints = array( 92 // OAuth endpoints 93 'oauth_request_token' => 'https://api.twitter.com/oauth/request_token', 94 'oauth_authorize' => 'https://api.twitter.com/oauth/authorize', 95 'oauth_access_token' => 'https://api.twitter.com/oauth/access_token', 96 97 // Content endpoints 98 'get_status' => 'http://api.twitter.com/1/statuses/user_timeline.json', 99 'get_retweet'=> 'http://api.twitter.com/1/statuses/retweeted_by_user.json', 100 ); //['oauth_request_token'] 101 91 102 /** 92 103 * Gets the Twitter REST API url … … 124 135 'show_welcome_message' => false, 125 136 'geotagging_enabled' => true, 137 'allow_showing_statuses' => true, 126 138 'allow_showing_retweets' => false, 127 139 'override_post_time_on_timezone_discrepency' => false, 140 'alerts' => array(), 128 141 ); 129 142 … … 158 171 return; 159 172 } 173 174 // If we're in the admin, we need to be using sessions 175 if ( is_admin() ) { 176 if (!isset($_SESSION['state'])) 177 $_SESSION['state'] = md5(uniqid(rand(), TRUE)); //CSRF protection for admin. 178 } 179 160 180 161 181 $this->feed_slug = !empty($feed_options['feed_slug']) ? $feed_options['feed_slug'] : $this->feed_slug; … … 193 213 // Setup feed filters 194 214 $this->setup_filters(); 215 216 // Check for url parameters indicating an OAuth orization 217 if ( $this->feed_options['tw_auth_status'] == 'authorizing' && isset($_GET['oauth_token']) && isset($_GET['oauth_verifier']) ) 218 $this->complete_oauth_authentication(); 195 219 } 196 220 … … 220 244 // These action are related to the setup while were in admin... 221 245 if (is_admin()) { 222 add_action( 'wp_ajax_mbgf_twitter_connect_set_tw_obj_id', array( &$this, 'set_tw_obj_id' ) ); 246 // Authorization hooks 247 add_action( 'wp_ajax_mbgf_twitter_connect_set_app_info', array( &$this, 'set_app_info' )); 248 add_action( 'wp_ajax_mbgf_twitter_connect_is_authed', array( &$this, 'ajax_app_is_authed' )); 249 add_action( 'wp_ajax_mbgf_twitter_connect_set_tw_obj_id', array( &$this, 'ajax_set_tw_obj_id' )); 250 251 // Ajax hooks 252 add_action( 'wp_ajax_mbgf_twitter_connect_set_tw_obj_id', array( &$this, 'ajax_set_tw_obj_id' ) ); 253 add_action( 'wp_ajax_mbgf_twitter_connect_get_tw_obj_id', array( &$this, 'ajax_get_tw_obj_id' ) ); 223 254 add_action( 'wp_ajax_mbgf_twitter_connect_redo_initial_setup', array( &$this, 'redo_initial_setup' ) ); 224 255 add_action( 'wp_ajax_mbgf_twitter_connect_reset_feed_defaults', array( &$this, 'reset_feed_defaults' ) ); 225 256 add_action( 'wp_ajax_mbgf_twitter_connect_manual_feed_update', array( &$this, 'ajax_do_update' ) ); 257 258 // General Hooks 259 add_action( 'admin_notices', array( &$this, 'show_alerts' ) ); 260 261 // Unregister feed hook 226 262 add_action( 'mbgf_unregister_feed-' . $this->get_slug(), array( &$this, 'unregister_feed') ); 227 263 } … … 410 446 die(json_encode(array('status' => 'failure', 'error' => $res))); 411 447 } 448 449 /** 450 * When the user attempts to authorize the twitter app with API parameters, 451 * this function is called to set an app_id and app_secret. 452 * 453 */ 454 public function set_app_info() { 455 check_admin_referer( 'twitter-connect-admin' ); 456 wp_verify_nonce( 'twitter-connect-admin' ); 457 458 $consumer_key = $_POST['consumer_key']; 459 $consumer_secret = $_POST['consumer_secret']; 460 461 // Validate the values we've received 462 if (preg_match('/^[a-zA-Z0-9]+$/', $consumer_secret) == 0 || preg_match('/^[a-zA-Z0-9]+$/', $consumer_key) == 0 ) 463 die('Invalid'); 464 465 // Save these values and mark us as unauthorized 466 $this->feed_options['tw_auth_status'] = 'authorizing'; 467 $this->feed_options['consumer_key'] = $consumer_key; 468 $this->feed_options['consumer_secret'] = $consumer_secret; 469 470 // Clear any previous tokens 471 $this->feed_options['oauth_token'] = ''; 472 $this->feed_options['oauth_token_secret'] = ''; 473 $this->feed_options['oauth_access_token'] = ''; 474 $this->feed_options['oauth_access_token_secret'] = ''; 475 476 $this->globalfeed->print_debug_info("OAuth Key Generation"); 477 $this->get_oauth_key_request(); // will call register_feed 478 479 $this->register_feed(true); 480 481 // This should return the Twitter URL to direct the user to so that the confirm authorization for the app 482 die(json_encode( 483 array( 484 'consumer_key' => $this->feed_options['consumer_key'], 485 'consumer_secret' => $this->feed_options['consumer_secret'], 486 'oauth_url' => $this->tw_endpoints['oauth_authorize'] . "?oauth_token={$this->feed_options['oauth_token']}&force_login=true" , 487 'callback_url' => get_bloginfo('wpurl').'/', 488 ))); 489 490 } 491 492 /** 493 * When the user attempts to authorize the twitter app with API parameters, 494 * this function is called to see if the feed now has an app_id and app_secret 495 * 496 */ 497 public function ajax_app_is_authed() { 498 check_admin_referer( 'twitter-connect-admin' ); 499 wp_verify_nonce( 'twitter-connect-admin' ); 500 501 if (!empty($this->feed_options['oauth_user_token']) || (isset($_SERVER['mbgf_twitter_authed']) && $_SERVER['mbgf_twitter_authed']) || get_transient('mbgf_twitter_authed')) { 502 unset( $_SERVER['mbgf_twitter_authed'] ); 503 die( json_encode(true) ); 504 } else { 505 $c = 1; 506 while ( $c <= 2 ) { 507 sleep(2); 508 if ( (isset($_SERVER['mbgf_twitter_authed']) && $_SERVER['mbgf_twitter_authed']) || get_transient('mbgf_twitter_authed') ) { 509 unset( $_SERVER['mbgf_twitter_authed'] ); 510 die(json_encode(true)); 511 } 512 513 $c++; 514 } 515 516 die( json_encode(false) ); 517 } 518 } 519 520 public function ajax_get_tw_obj_id() { 521 check_admin_referer( 'twitter-connect-admin' ); 522 wp_verify_nonce( 'twitter-connect-admin' ); 523 524 die(json_encode(array('object' => $this->feed_options['object_to_subscribe']))); 525 } 526 527 /** 528 * When the user attempts to authorize the facebook app, this function is called to 529 * see if the feed now has an app_id and app_secret 530 * 531 */ 532 public function ajax_set_tw_obj_id() { 533 check_admin_referer( 'twitter-connect-admin' ); 534 wp_verify_nonce( 'twitter-connect-admin' ); 535 536 $obj_id = $_POST['tw_object_id'] ; 537 538 // Validate the values we've received 539 if (preg_match('/^[0-9]+$/', $obj_id) == 0){ 540 die(json_encode('Input arguments are not of the right format')); 541 } 542 543 // If we're receveing a new ID, kill the last update time 544 foreach ($this->feed_options['last_feed_update'] as $key => $value) 545 $this->feed_options['last_feed_update'][$key] = 0; 546 547 // The object ID appears valid. Save. 548 $this->feed_options['object_to_subscribe'] = $obj_id; 549 550 // If this var is set, then mark the initial setup complete. 551 if (isset($_POST['mb_twitter_finish_setup']) && ((bool) $_POST['mb_twitter_finish_setup']) == true ) { 552 $this->feed_options['initial_setup_done'] = true; 553 $this->feed_options['show_welcome_message'] = true; 554 } 555 556 // Unset any auth info if we arent authorized 557 if ($this->feed_options['tw_auth_status'] != 'authorized') 558 $this->feed_options['tw_auth_status'] = 'not_initiated'; 559 560 $result = $this->update_feed(null); 561 562 if ( $result === false ) { 563 $this->feed_options['object_to_subscribe'] = $this->feed_defaults['object_to_subscribe']; 564 $this->feed_options['initial_setup_done'] = false; 565 $this->feed_options['show_welcome_message'] = false; 566 567 // Save changes 568 $this->register_feed(true); 569 570 die(json_encode('Error: A network error occured while requesting data from twitter.')); 571 } 572 573 // Update and return the feed items retrieved. 574 die(json_encode( 575 array( 'num_feed_items_retrieved' => $result ) 576 )); 577 } 578 579 private function get_oauth_key_request() { 580 if ( empty($this->feed_options['consumer_key']) || empty($this->feed_options['consumer_secret']) ) 581 return new WP_Error ('not_setup', "You must set a Twitter consumer Key and Secret to get a request token"); 582 583 // Do the request 584 $request = $this->do_twitter_remote_post( $this->tw_endpoints['oauth_request_token'] ); 585 586 // Check if a request error occured 587 if ( is_wp_error($request) ) 588 return $request; 589 590 // Check if the twitter endpoint didn't say everythings alright 591 if ( $request['response']['code'] !== 200 ) { 592 $this->globalfeed->print_debug_info("req error: "); 593 $this->globalfeed->print_debug_info($request); 594 return new WP_Error('bad_response', "The response code from the Twitter API while requesting an authorization token was: {$request['response']['code']}", $request['response']['code']); 595 } 596 597 // Parse the OAuth token and secret from the response string 598 $vals = array(); 599 parse_str($request['body'], $vals); 600 601 // Store the settings 602 $this->feed_options['oauth_token'] = $vals['oauth_token']; 603 $this->feed_options['oauth_token_secret'] = $vals['oauth_token_secret']; 604 605 $this->register_feed(); 606 return true; 607 } 608 609 /** 610 * Called when the application is still authorizing with Twitter, and the user arrives 611 * at the callback url. 612 */ 613 private function complete_oauth_authentication() { 614 $this->globalfeed->print_debug_info("Completeing Oauth..."); 615 $oauth_token = $_GET['oauth_token']; 616 $oauth_verifier = $_GET['oauth_verifier']; 617 618 // Check that the approved OAuth token matches the one we're attempting to verify. 619 if ( $oauth_token !== $this->feed_options['oauth_token'] ) { 620 $this->globalfeed->print_debug_info("Oauth failed..."); 621 $this->feed_options['tw_auth_status'] = 'failed'; 622 return; 623 } 624 625 // Get the actual access token for the application 626 $request = $this->do_twitter_remote_post($this->tw_endpoints['oauth_access_token'], array('oauth_verifier' => $oauth_verifier, 'oauth_token' => $oauth_token)); 627 628 // Check for errors... 629 if (is_wp_error($request) ) { 630 $this->globalfeed->print_debug_info("OAuth failed..."); 631 $this->globalfeed->print_debug_info($request); 632 $this->feed_options['tw_auth_status'] = 'failed'; 633 return; 634 } 635 636 // Check that the request succeeded 637 if ( $request['response']['code'] !== 200 ){ 638 $this->globalfeed->print_debug_info("Error completeing oauth authentication"); 639 $this->globalfeed->print_debug_info($request); 640 $this->feed_options['tw_auth_status'] = 'failed'; 641 return; 642 } 643 644 // Load values from the response 645 $vals = array(); 646 parse_str($request['body'], $vals); 647 648 // Set markers 649 $_SERVER['mbgf_twitter_authed'] = true; 650 set_transient('mbgf_twitter_authed', true); 651 652 // Set values in feed options 653 $this->feed_options['object_to_subscribe'] = $vals['screen_name']; 654 $this->feed_options['oauth_access_token'] = $vals['oauth_token']; 655 $this->feed_options['oauth_access_token_secret'] = $vals['oauth_token_secret']; 656 657 // Save changes 658 $this->register_feed(true); 659 $this->globalfeed->print_debug_info("Oauth complete..."); 660 } 661 662 /** 663 * Generates a Titter request string (including signature) for the given URL 664 * with the given parameters. This function should only be used when the user 665 * has chosen to use the App-Authenticated approach to connecting to the API, 666 * if the user has not supplied app info, the return request string will fail. 667 * 668 * @uses $this->generate_twitter_request_signature() 669 * 670 * @param str $endpoint 671 * @param array $parameters 672 * @param str $method 673 * 674 * @return array|WP_Error The result from executing wp_remote_post on the generated request 675 */ 676 private function do_twitter_remote_post( $endpoint, $parameters = array(), $method = 'POST' ) { 677 $default_parameters = array( 678 'oauth_consumer_key' => $this->feed_options['consumer_key'], 679 'oauth_nonce' => $_SESSION['state'], 680 'oauth_signature_method' => 'HMAC-SHA1', 681 'oauth_timestamp' => time(), 682 'oauth_version' => '1.0', 683 'oauth_callback' => get_bloginfo('wpurl').'/', 684 'x_auth_access_type' => 'read' 685 ); 686 687 if ( !empty($this->feed_options['oauth_access_token']) ) 688 $default_parameters['oauth_access_token'] = $this->feed_options['oauth_access_token']; 689 690 // Parse the default parameters 691 $parameters = wp_parse_args($parameters, $default_parameters); 692 693 // Get the signature for the request 694 $parameters['oauth_signature'] = $this->generate_twitter_request_signature($endpoint, $method, $parameters); 695 696 // The below code is what is SUPPOSED to be done -- but it didn't want to work :( 697 // // Build the Authorization header string 698 // $header_str = 'OAuth '; 699 // foreach ( $parameters as $key => $value ) 700 // $header_str .= rawurlencode($key) . '="' . rawurlencode($value) . '", '; 701 // 702 // // Remove trailing ", " from string 703 // $header_str = substr($header_str, 0, -2); 704 705 $endpoint .= '?'; 706 foreach ( $parameters as $key => $value ) 707 $endpoint .= $key . '=' . rawurlencode($value) . '&'; 708 709 $endpoint = substr($endpoint, 0, -1); 710 711 // Execute the request, and return whatever results 712 return wp_remote_post($endpoint, array( 'method' => strtoupper($method), ) ); 713 } 714 715 /** 716 * Generates a request signature for the given request. 717 * 718 * @param str $endpoint 719 * @param str $method 720 * @param array $parameters 721 * @return str 722 */ 723 private function generate_twitter_request_signature( $endpoint, $method, $parameters ) { 724 // Sort the parameters alphabetically 725 ksort($parameters); 726 727 // Percent encode parameters and build the parameter string 728 $param_str = ''; 729 foreach ($parameters as $key => $value) 730 $param_str .= rawurlencode($key) . '=' . rawurlencode($value) . '&'; 731 732 // Remove the trailing & from the string... 733 $param_str = substr($param_str, 0, -1); 734 735 // The base string is the parameter string appendd to the base string (as per oauth spec) 736 $base_str = strtoupper($method) . '&' . rawurlencode($endpoint) . '&' . rawurlencode($param_str); 737 738 // Build the signing key 739 $signing_key = rawurlencode($this->feed_options['consumer_secret']) . '&'; 740 741 // If we have a user request token, that needs to be a part of the signing key 742 if ( !empty($this->feed_options['oauth_access_token_secret']) ) 743 $signing_key .= rawurlencode($this->feed_options['oauth_token_secret']); 744 745 // Create and return the signature 746 return base64_encode(hash_hmac('sha1', $base_str, $signing_key, true)); 747 } 748 749 /** 750 * Adds a Twitter alert that should be displayed to the user 751 * 752 * If an alert with the same $alert_code already exists, it will be overwritten. 753 * 754 * @param str $alert_code A slug-style code for the alert 755 * @param str $alert_text The alert text 756 * @param bool $sitewide (optional, defaults to false) Whether the alert should be shown sitewide, or just within GlobalFeed. 757 */ 758 759 /** 760 * Adds a Twitter alert that should be displayed to the user 761 * 762 * If an alert with the same $alert_code already exists, it will be overwritten. 763 * 764 * @global type $current_user 765 * 766 * @param str $alert_code A slug-style code for the alert 767 * @param str $alert_text The alert text 768 * @param type $important Whether the alert should be shown as a notice or an error 769 * @param bool $sitewide (optional, defaults to false) Whether the alert should be shown sitewide, or just within GlobalFeed. 770 * @param type $require_priv What privilege the alert requires to be seen. '' if none. 771 * @param type $dismissable Whether the alert should be dismissable by the user 772 */ 773 function add_alert( $alert_code, $alert_text, $important = false, $sitewide = false, $require_priv = 'manage_options', $dismissable = true ) { 774 global $current_user; 775 776 $this->feed_options['alerts'][$alert_code] = array( 777 'alert_code' => $alert_code, 778 'alert_text' => $alert_text, 779 'sitewide' => $sitewide, 780 'hidden' => false, 781 'remind' => 0, 782 'important' => $important, 783 'require_priv' => $require_priv, 784 'never_show' => (isset($this->feed_options['alerts'][$alert_code]) ? $this->feed_options['alerts'][$alert_code]['never_show'] : false), 785 'dismissable'=> $dismissable, 786 ); 787 788 $this->globalfeed->print_debug_info("Feed options"); 789 $this->globalfeed->print_debug_info($this->feed_options['alerts']); 790 791 $this->register_feed(true); 792 793 delete_user_meta($current_user->ID, "mbgf_twitter_connect_hide_alert_" . $alert_code); 794 795 $this->globalfeed->print_debug_info("Added alert: $alert_code"); 796 } 797 798 /** 799 * When an alert no longer applies, hide it from the user. 800 * 801 * @param type $alert_code 802 */ 803 function hide_alert( $alert_code ) { 804 if ( isset($this->feed_options['alerts'][$alert_code]) ) 805 $this->feed_options['alerts'][$alert_code]['hidden'] = true; 806 807 $this->register_feed(true); 808 } 809 810 /** 811 * Shows any queued alerts. Also detects if the user hides an alert 812 * 813 * Called by WordPress Action 'admin_notices' 814 * 815 */ 816 function show_alerts() { 817 global $current_user; 818 819 // Check if there are alerts 820 if ( !count($this->feed_options['alerts']) ) 821 return; 822 823 $hide_text = __('Hide', 'mb_twitter'); 824 $never_show_text = __('Never show again', 'mb_twitter'); 825 826 // Used for show/hide urls 827 $server_args = array(); 828 parse_str($_SERVER['QUERY_STRING'], $server_args); 829 830 // Loop through alerts 831 foreach ($this->feed_options['alerts'] as $alert_code => $alert) { 832 // Check if this alert should be hidden from the user 833 $hide_alert = "mbgf_twitter_connect_hide_alert_" . $alert['alert_code']; 834 $never_show_alert = "mbgf_twitter_connect_never_show_alert_" . $alert['alert_code']; 835 836 // Check if alert is disabled -- but make sure we catch anything telling us to hide the alert (but make sure the user has permission) 837 if ( !isset($_GET[$hide_alert]) && !isset($_GET[$never_show_alert]) && !( $alert['require_priv'] !== '' && current_user_can($require_priv) ) && ( 838 // Is this alert disabled? 839 $alert['hidden'] || $alert['never_show'] 840 841 // Check if the alert should be shown accross WP-Admin 842 || ( $this->globalfeed->in_admin() === false && !$alert['sitewide'] ) 843 844 // Check if the user has previously hidden this alert 845 || get_user_meta($current_user->ID, $hide_alert, true) === true ) ) 846 continue; 847 848 // Check if alert show status changed 849 if ( isset($_GET[$hide_alert]) ) { 850 add_user_meta($current_user->ID, $hide_alert, true); 851 continue; 852 } 853 854 if ( isset($_GET[$never_show_alert]) ) { 855 $this->feed_options['alerts'][$alert_code]['never_show'] = true; 856 $this->register_feed(true); 857 continue; 858 } 859 860 // This alert should be shown to the user 861 echo "<div class='{$alert['alert_code']} " . ($alert['important'] ? 'error' : 'updated') . "'><p>{$alert['alert_text']}</p>"; 862 863 if ( $alert['dismissable'] ) { 864 $hide_addr = http_build_query(array_merge($server_args, array($hide_alert=>1))); 865 $never_addr= http_build_query(array_merge($server_args, array($never_show_alert=>1))); 866 echo "<div class='align_right'><a href='?$hide_addr' title='$hide_text'>$hide_text</a> | <a href='?$never_addr' title='$never_show_text'>$never_show_text</a></div></div>"; 867 } else 868 echo '</div>'; 869 } 870 } 412 871 413 872 /** … … 416 875 * mode. 417 876 * 877 * @todo Alert the user if the endpoints are being rate limited. 418 878 * @todo Give the user the option whether to show the user screen name, or name as the title. 419 879 * @param type $args 420 880 */ 421 881 function update_feed() { 882 883 // Don't try and update if authorization is in progress 884 if ( $this->feed_options['tw_auth_status'] !== 'authorized' && $this->feed_options['tw_auth_status'] !== 'not_initiated' ) 885 return; 886 422 887 $globalfeed = &$this->globalfeed; 423 888 $feed_options = &$this->feed_options; 424 $globalfeed->print_debug_info('Update Twitter Feed Called.', 'mb_twitter'); 425 $globalfeed->print_debug_info($feed_options, 'mb_twitter'); 426 427 $endpoints = array( 428 "status" => "http://api.twitter.com/1/statuses/user_timeline.json?user_id={$feed_options['object_to_subscribe']}&count={$feed_options['max_feed_items']}" . ($feed_options['last_feed_update']['status'] ? "&since_id={$feed_options['last_feed_update']['status']}" : '') 429 ); 430 431 if ( $feed_options['allow_showing_retweets'] ) 432 $endpoints["retweet"] = "http://api.twitter.com/1/statuses/retweeted_by_user.json?user_id={$feed_options['object_to_subscribe']}&count={$feed_options['max_feed_items']}" . ($feed_options['last_feed_update']['retweet'] ? "&since_id={$feed_options['last_feed_update']['retweet']}" : ''); 433 889 890 // Check if we should be making authenticated requests 891 if ( !empty($this->feed_options['oauth_access_token']) ) { 892 $endpoints = array(); 893 894 // Add statuses to list if enabled 895 if ( $feed_options['allow_showing_statuses'] ) 896 $endpoints["status"] = array( 897 'endpoint_url' => $this->tw_endpoints['get_status'], 898 'parameters' => array( 899 'user_id' => $feed_options['object_to_subscribe'], 900 'count' => $feed_options['max_feed_items'] 901 ) 902 ); 903 904 // Add retweets to the list if enabled 905 if ( $feed_options['allow_showing_retweets'] ) 906 $endpoints['retweet'] = array( 907 'endpoint_url' => $this->tw_endpoints['get_retweet'], 908 'parameters' => array( 909 'user_id' => $feed_options['object_to_subscribe'], 910 'count' => $feed_options['max_feed_items'] 911 ) 912 ); 913 914 // If this isn't the first update, get the last update 915 foreach ( $endpoints as $key => $value ) { 916 if ( $feed_options['last_feed_update'][$key] ) 917 $endpoints[$key]['parameters']['since'] = $feed_options['last_feed_update'][$key]; 918 } 919 } else { 920 $endpoints = array(); 921 if ( $feed_options['allow_showing_statuses'] ) 922 $endpoints["status"] = $this->tw_endpoints['get_status'] . "?user_id={$feed_options['object_to_subscribe']}&count={$feed_options['max_feed_items']}" . ($feed_options['last_feed_update']['status'] ? "&since_id={$feed_options['last_feed_update']['status']}" : ''); 923 924 if ( $feed_options['allow_showing_retweets'] ) 925 $endpoints["retweet"] = $this->tw_endpoints['get_retweet'] . "?user_id={$feed_options['object_to_subscribe']}&count={$feed_options['max_feed_items']}" . ($feed_options['last_feed_update']['retweet'] ? "&since_id={$feed_options['last_feed_update']['retweet']}" : ''); 926 } 927 928 // Get time info 434 929 $feed_items = array(); 435 930 $gmt_timezone = new DateTimeZone('GMT'); 436 931 $time_offset = get_option( 'gmt_offset' ) * 3600; 437 932 933 // Loop through endpoints and grab content 438 934 foreach ( $endpoints as $endpoint_id => $endpoint ) { 439 $request = wp_remote_get( $endpoint ); 440 935 if ( is_array($endpoint) ) 936 $request = $this->do_twitter_remote_post( $endpoint['endpoint_url'], $endpoint['parameters'], 'GET' ); 937 else 938 $request = wp_remote_get( $endpoint ); 939 940 $this->globalfeed->print_debug_info($endpoint); 941 942 // Check for a WP Error 441 943 if ( is_wp_error($request) ) 442 944 return $request; 443 945 946 // Check the response code 947 $request['response']['code'] = (int) $request['response']['code']; 948 if ( $request['response']['code'] !== 200 ) { 949 if ( $request['response']['code'] === 302 ) { 950 $this->globalfeed->print_debug_info('Rate limiting error', 'mb_twitter'); 951 952 // We are being rate limited 953 if ( !empty($this->feed_options['oauth_access_token'])) { 954 // Authentication is enabled 955 $this->add_alert( 'rate_limiting', "GlobalFeed Twitter Connect is currently being rate limited by Twitter and is unable to fetch new content. Because you setup Twitter Connect with authentication, please ensure that any other apps using your Applications' consumer key and secret are not generating too many requests.", true, true ); 956 } else { 957 $this->add_alert( 'rate_limiting', "GlobalFeed Twitter Connect is currently being rate limited by Twitter and is unable to fetch new content. You may want to consider setting up Twitter Connect using a Twitter Application, especially if you are on shared hosting. For more information, visit Twitter Connect within the GlobalFeed settings.", true, true ); 958 } 959 960 return new WP_Error('rate_limiting', "Twitter connect is being rate limited by Twitter, Status Code 302"); 961 } else { 962 $this->globalfeed->print_debug_info('Request error.', 'mb_twitter'); 963 $this->add_alert('error_connecting', "Problems were experienced communicating with Twitter. Received response code {$request['response']['code']} on endpoint {$endpoint_id}"); 964 return new WP_Error('request_error', "Twitter connect experienced a comms error fetching new content from Twitter.", $request['response']['code']); 965 } 966 } 967 968 // Hide any previous alerts 969 $this->hide_alert('request_error'); 970 $this->hide_alert('rate_limiting'); 971 444 972 // Use the regex to replace numerical values to strings for older versions of php 445 973 $updates = json_decode( preg_replace('/("\w+"):(\d+)/', '\\1:"\\2"', $request['body']), true ); 446 974 447 if ( $updates == NULL || empty($updates) ) 975 // Check that we actually have content 976 if ( $updates == NULL || empty($updates) || !is_array($updates) || !count($updates) ) 448 977 continue; 449 978 450 979 // Mark the last feed update item 451 $feed_options['last_feed_update'][$endpoint_id] = $updates[0]['id']; 980 $feed_options['last_feed_update'][$endpoint_id] = $updates[0]['id']; 452 981 453 982 foreach ($updates as $update) { -
globalfeed/trunk/feeds/mb_twitter/pages/js/mb_twitter.js
r563348 r612743 64 64 }); 65 65 } 66 67 /* ----------------------------------------------- TW Authorization Interface */ 68 var authWindowChecker = null; 69 var authWindow = null; 70 function setAuthWindowChecker( statusdiv, fail, redir_url ) { 71 authWindowChecker = setTimeout(function(){ 72 checkAuthWindow( statusdiv, fail, redir_url ); 73 }, 1000); 74 //authWindowChecker = setTimeout('checkAuthWindow("' + statusdiv + ',' + fail + ',' + '")', 1000); 75 return; 76 } 77 function checkAuthWindow( statusdiv, fail, redir_url ) { 78 clearTimeout(authWindowChecker); 79 try { 80 // If this is true, then the user is most likely authenticating with Twitter, or we have checked before the opened window was redirected to TWitter. 81 if (typeof(authWindow) == undefined || Object.keys(authWindow).length == 0) { 82 setAuthWindowChecker( statusdiv, fail, redir_url ); 83 return; 84 } 85 } catch(exc) { 86 // If an error has occured, we've most likely run into a problem accessing the authWindow object because Twitter is on the login page. We need to wait for the user to 87 // authenticate. 88 if ( error_count < 40 ) { 89 error_count++; 90 setAuthWindowChecker( statusdiv, fail, redir_url ); 91 return; 92 } else { 93 // We've restarted the script too many times. Assume the user closed the window. 94 hideAjaxIndicator( statusdiv ); 95 eval(fail); 96 showMessage('The authorization either took too long, or the window was closed before authentication was completed.\n\nPlease try again.','authWindowError', true, 10000); 97 authWindow.close(); 98 error_count = 0; 99 return; 100 } 101 } 102 103 if (authWindow.closed == true) { 104 // The window was closed by the user before auth was completed... 105 showMessage('The authorization window was closed before the authorization process was completed.\n\nPlease try again.', 'authWindowClosed', true, 10000); 106 hideAjaxIndicator( statusdiv ); 107 eval(fail); 108 return; 109 } 110 111 childWinLocation = authWindow.location.href; 112 if (childWinLocation.indexOf( redir_url ) != -1) { 113 // The user has been redirected back to the site... 114 jQuery(authWindow.document).ready(function () { 115 authWindow.close(); 116 if (childWinLocation.indexOf('error') != -1){ 117 // Auth failed. Likely the user denied access. 118 showMessage('The authorization failed. Most likely you did not allow app access.\n\nPlease try again.', 'authNotApproved', true, 10000); 119 hideAjaxIndicator( statusdiv ); 120 fail(); 121 return; 122 } 123 124 // Check with the server to see if we now have an access token 125 jQuery.post(ajaxurl, {action:'mbgf_twitter_connect_is_authed',_wpnonce:jQuery('#_wpnonce').val()}, function(response){ 126 if (jQuery.parseJSON(response) == true){ 127 // Get the object that was subscribed to 128 jQuery.post(ajaxurl, {action:'mbgf_twitter_connect_get_tw_obj_id',_wpnonce:jQuery('#_wpnonce').val()}, function(response){ 129 response = jQuery.parseJSON(response); 130 if (in_wizard == true) { 131 if ( typeof tw_obj_id !== 'undefined' ) { 132 tw_obj_id = response.object; 133 console.log(response); 134 } 135 136 nextStep(); 137 } else { 138 hideAjaxIndicator( statusdiv ); 139 showMessage('Authorization was successful. The access codes have been received.', 'authSuccessful', false, 10000); 140 } 141 }); 142 } else { 143 hideAjaxIndicator( statusdiv ); 144 fail(); 145 } 146 }); 147 }); 148 } else { 149 setAuthWindowChecker( statusdiv, fail, redir_url ); 150 return; 151 } 152 } -
globalfeed/trunk/feeds/mb_twitter/pages/setup.php
r582062 r612743 23 23 <div id="notices"></div> 24 24 <div id="step-1"> 25 <p><h2>How would you like to connect to Twitter?</h2></p> 26 <div class="optgrp bottom-button" style="min-height:270px;"> 27 <p class="center"><h2>Without a Twitter App</h2></p> 28 <p> 29 Setting up Twitter Connect without an App is the quickest and easiest way to get started with Twitter Connect. 30 </p> 31 <p> 32 When you setup without using a Twitter App, Twitter Connect will not authenticate with Twitter 33 (although all of your data is still communicated over SSL.) The caveat to this approach 34 is that if your site is located on shared hosting Twitter Connect may become rate limited by Twitter 35 and may not be able to consistently fetch content. 36 </p> 37 <p> 38 If you encounter issues with not receiving new content while using Twitter Connect without a Twitter App 39 you can always supply App information to switch to Authenticated mode at a later time. 40 </p> 41 <p class="center"><input type="button" id="setup_without_app" value="Without a Twitter App" class="button-primary" /></p> 42 </div> 43 <div class="optgrp" style="min-height:270px;"> 44 <p class="center"><h2>With a Twitter App</h2></p> 45 <p> 46 This approach requires you to have a Twitter Application with a Consumer Key and Secret. If you 47 do not have an application already, you can <a href="https://dev.twitter.com/apps/new" title="Generate application on Twitter" target="_blank">generate one</a> with Twitter. 48 </p> 49 <p> 50 This method is less susceptible to rate limiting, especially on shared servers. 51 </p> 52 <p class="center bottom-button"><input type="button" id="setup_with_app" value="With a Twitter App" class="button-primary" /></p> 53 </div> 54 </div> 55 <div id="step-3" class="hidden-step"> 25 56 <p>Welcome to the initial setup for Twitter Connect. We need a bit of information before you get started:</p> 26 57 <p>All we need to know is the Twitter object whose updates you would like to appear in Globalfeed.</p> … … 32 63 </tr> 33 64 <tr id="validate_button_container"> 34 <t h></th>65 <td><input type="button" class="button-secondary last_step_button" value="Back" /></td> 35 66 <td><input type="button" class="button-primary" id="validate_button" value="Validate" /><img alt="" class="ajax-loading-icon" src="<?php bloginfo('wpurl') ?>/wp-admin/images/wpspin_light.gif" /></td> 36 67 </tr> … … 44 75 </div> 45 76 </div> 77 <p><small>If your username contains only numbers, prefix it with an @ or a question mark (?)</small></p> 46 78 </div> 47 <p><small>If your username contains only numbers, prefix it with a question mark (?)</small></p> 79 <div id="step-2" class="hidden-step"> 80 <p>Welcome to the initial setup for Twitter Connect. We need a bit of information before you get started:</p> 81 <p>First, you'll need to setup a Twitter app, and get its consumer key and secret. If you have not done so already, you can <a href="https://dev.twitter.com/apps/new" title="Generate application on Twitter" target="_blank">create an app here</a></p> 82 <table class="form-table"> 83 <tr> 84 <th><?php _e('Twitter Consumer Key:',$mb_globalfeed_twitter_connect->get_slug()) ?></th> 85 <td><input type="text" name="consumer_key" class="auth-form-input" id="consumer_key" value="<?php echo $feed_options['consumer_key']; ?>"/></td> 86 </tr> 87 <tr> 88 <th><?php _e('Twitter Consumer Secret:',$mb_globalfeed_twitter_connect->get_slug()) ?></th> 89 <td><input type="text" name="consumer_secret" class="auth-form-input" id="consumer_secret" value="<?php echo $feed_options['consumer_secret']; ?>" /></td> 90 </tr> 91 <tr> 92 <td><input type="button" class="button-secondary last_step_button" value="Back" /></td> 93 <td><input type="button" class="button-primary" id="authorize_button" value="Authorize" /><img alt="" class="ajax-loading-icon" src="<?php bloginfo('wpurl') ?>/wp-admin/images/wpspin_light.gif" /></td> 94 </tr> 95 </table> 96 </div> 48 97 </form> 49 98 <script type="text/javascript"> … … 51 100 var tw_obj_id = null; 52 101 var tw_obj_type = null; 102 var setup_with_app = false; 53 103 54 104 jQuery(document).ready(function(){ … … 58 108 }); 59 109 110 function authorize(){ 111 // Begin authorization 112 var consumer_key = jQuery('#consumer_key').val(); 113 var consumer_secret = jQuery('#consumer_secret').val(); 114 var consumer_match = new RegExp(/^[a-zA-Z0-9]+$/); 115 if (consumer_match.exec( consumer_key ) == null){ 116 showMessage('You must provide a valid consumer key (can be numbers and letters)', 'consumer_key', true); 117 setMsgRemove( 'consumer_key', 'consumer_key' ); 118 return false; 119 } else if (consumer_match.exec( consumer_secret ) == null){ 120 showMessage('You must provide a valid consumer secret (can be numbers and letters)', 'consumer_secret', true); 121 setMsgRemove( 'consumer_secret', 'consumer_secret' ); 122 return false; 123 } else { 124 hideMessage( 'consumer_key' ); 125 hideMessage( 'consumer_secret' ); 126 } 127 128 // Disable the button and begin auth 129 toggleAjaxIndicator( '#step-1' ); 130 hideAllMessages(); 131 jQuery('#authorize_button').attr("disabled", true); 132 133 // In order to get past popup blockers, we open the AuthWindow now. In the future, this should pop up a temporary loading page, however we aren't that fancy yet. 134 authWindow = window.open('',"tw_activation_window","location=0,status=0,scrollbars=0, width=750,height=500"); 135 136 // Post the consumer_key and secret to the server for use in the auth process. 137 jQuery.post(ajaxurl, {action:'mbgf_twitter_connect_set_app_info',consumer_key:consumer_key,consumer_secret:consumer_secret,_wpnonce:jQuery('#_wpnonce').val()}, function(response){ 138 response = jQuery.parseJSON(response); 139 authWindow.location.href = response.oauth_url; 140 setAuthWindowChecker( '#step-1', function(){ 141 // Re-enable the auth button 142 jQuery('#authorize_button').attr("disabled", false); 143 }, response.callback_url ); 144 }); 145 } 146 60 147 function setupStep( step ) { 148 var stepClass = "#step-" + step; 61 149 switch( step ){ 62 150 case 1: 63 if ( !jQuery('#step-1').hasClass('setup') ) { 151 if ( !jQuery(stepClass).hasClass('setup') ) { 152 // Step 2 is for auth with an app 153 jQuery('#setup_with_app').click(nextStep); 154 155 // Steps 3+ are for auth without an app 156 jQuery('#setup_without_app').click(function () { 157 loadStep(3); 158 }); 159 160 jQuery(stepClass).addClass('setup'); 161 } 162 163 break; // End of step 1 164 case 2: 165 setup_with_app = true; 166 jQuery('#authorize_button').attr("disabled", false).click(authorize); 167 if ( !jQuery(stepClass).hasClass('setup') ) { 168 jQuery(stepClass + ' .last_step_button').click(lastStep); 169 jQuery(stepClass).addClass('setup'); 170 } 171 172 break; 173 case 3: 174 setup_with_app = false; 175 176 if ( jQuery('#tw_object_id').val() === '' && tw_obj_id !== '' ) 177 jQuery('#tw_object_id').val(tw_obj_id); 178 179 jQuery('#validate_button, #confirm_id_yes').attr("disabled", false); 180 181 if ( !jQuery(stepClass).hasClass('setup') ) { 182 // Setup the last step button 183 console.log(jQuery(stepClass + ' .last_step_button')); 184 jQuery(stepClass + ' .last_step_button').click(function(){ 185 loadStep( 1 + setup_with_app ); 186 }); 64 187 jQuery('#validate_button').attr("disabled", false); 65 188 jQuery('#confirm_id_no').click(function(){ … … 67 190 jQuery(this).addClass('hidden-step'); 68 191 showMessage('Please try again.', 'tryagain', false, 10000); 69 jQuery('#validate_button ').attr("disabled", false);192 jQuery('#validate_button, #confirm_id_yes').attr("disabled", false); 70 193 }); 71 jQuery( '#step-1>table').show().fadeIn('fast');194 jQuery(stepClass + '>table').show().fadeIn('fast'); 72 195 }); 73 196 jQuery('#confirm_id_yes').click(function(){ 74 jQuery(this).attr('disabled', '');197 jQuery(this).attr('disabled', true); 75 198 toggleAjaxIndicator( '#confirm_buttons' ); 76 199 … … 101 224 req = get_tw_object( jQuery('#tw_object_id').val(), '#confirm_tw_obj_id') 102 225 req.success(function () { 103 jQuery( '#step-1>table').hide('fast', function () {jQuery(this).hide()});226 jQuery(stepClass + '>table').hide('fast', function () {jQuery(this).hide()}); 104 227 jQuery( '#tw_obj_confirm' ).removeClass('hidden-step').show( 'fast' ); 105 228 }); … … 107 230 showMessage( 'Error: The given Twitter ID or Screen Name was not found or failure connecting to Twitter. Please try again.', 'tw_obj_not_found', true); 108 231 setMsgRemove( 'tw_object_id','tw_obj_not_found' ); 109 toggleAjaxIndicator( '#step-1');110 jQuery( '#step-1>table').show('fast');232 toggleAjaxIndicator( stepClass ); 233 jQuery(stepClass + '>table').show('fast'); 111 234 jQuery('#validate_button').attr("disabled", false); 112 235 }) … … 116 239 jQuery('#validate_button').click(validate); 117 240 jQuery('#setup-form').submit(validate); 118 jQuery('#step-1').addClass('setup'); 119 120 241 jQuery(stepClass).addClass('setup'); 121 242 } 122 243 break; // End of step 2 -
globalfeed/trunk/feeds/mbgf_rss/mbgf_rss.php
r608776 r612743 550 550 551 551 // Check that a guid is not empty 552 $post_args['guid'] = str_replace(" ", "_", substr($post_args['meta']['source'], 0, 50) . $post_args['title'] . $post_args['post_date']); 553 552 $post_args['guid'] = str_replace(" ", "_", substr($post_args['meta']['source'], 0, 50) . $post_args['post_title'] . $post_args['post_date']); 554 553 555 554 // Process the post date … … 560 559 561 560 // Check if this item is already stored in the DB, and update if so... 562 $posts = $wpdb->get_results($wpdb->prepare( "SELECT posts.ID FROM $wpdb->posts posts WHERE posts.guid = %s AND posts.post_type = '{$this->globalfeed->post_type_namespace()}{$this->feed_slug}' LIMIT 1", (string) trim($ update->link)));561 $posts = $wpdb->get_results($wpdb->prepare( "SELECT posts.ID FROM $wpdb->posts posts WHERE posts.guid = %s AND posts.post_type = '{$this->globalfeed->post_type_namespace()}{$this->feed_slug}' LIMIT 1", (string) trim($post_args['guid']))); 563 562 if ( count($posts) >= 1 ) 564 563 $post_args['ID'] = $post_args['import_id'] = $posts[0]->ID; -
globalfeed/trunk/mb_globalfeed.php
r593083 r612743 82 82 /** 83 83 * Returns the current instance of the GlobalFeed admin class. 84 * 85 * admin_instance will be false if not in the GlobalFeed admin, or if 86 * show_admin_page has not yet been called. 87 * 84 88 * @return type 85 89 */ 86 90 public function admin_instance() { 87 91 return $this->_admin_instance; 92 } 93 94 /** 95 * Returns whether or not we are current in the GlobalFeed admin. 96 * 97 * @global str $pagenow 98 * @return bool 99 */ 100 public function in_admin() { 101 global $pagenow; 102 103 return ( $pagenow === 'admin.php' && $_REQUEST['page'] === 'globalfeed' ); 88 104 } 89 105 … … 1633 1649 * anonymous functions for PHP < 5.3 1634 1650 * 1635 * @param type $matches 1651 * Replaces newlines within the link, as WordPress breaks the hell out of them. 1652 * 1653 * @param array $matches 1636 1654 */ 1637 1655 private function _replace_link_callback ( $matches ) { 1638 return '<a href="' .$matches[0]. '"' . ($this->settings['autodetect_link_open_new_window'] ? ' target="_blank">' : '>') . $matches[0] . '</a>'; 1656 $no_newline = preg_replace("/(\n(\r)*)+/", '', $matches[0]); 1657 return '<a href="' .$no_newline. '"' . ($this->settings['autodetect_link_open_new_window'] ? ' target="_blank">' : '>') . $no_newline . '</a>'; 1639 1658 } 1640 1659
Note: See TracChangeset
for help on using the changeset viewer.