Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
Complex classes like Jetpack_Display_Posts_Widget often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use Jetpack_Display_Posts_Widget, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 122 | class Jetpack_Display_Posts_Widget extends WP_Widget { |
||
| 123 | |||
| 124 | /** |
||
| 125 | * @var string Remote service API URL prefix. |
||
| 126 | */ |
||
| 127 | public $service_url = 'https://public-api.wordpress.com/rest/v1.1/'; |
||
| 128 | |||
| 129 | /** |
||
| 130 | * @var string Widget options key prefix. |
||
| 131 | */ |
||
| 132 | public $widget_options_key_prefix = 'display_posts_site_data_'; |
||
| 133 | |||
| 134 | /** |
||
| 135 | * @var string The name of the cron that will update widget data. |
||
| 136 | */ |
||
| 137 | public static $cron_name = 'jetpack_display_posts_widget_cron_update'; |
||
| 138 | |||
| 139 | |||
| 140 | public function __construct() { |
||
| 141 | parent::__construct( |
||
| 142 | // internal id |
||
| 143 | 'jetpack_display_posts_widget', |
||
| 144 | /** This filter is documented in modules/widgets/facebook-likebox.php */ |
||
| 145 | apply_filters( 'jetpack_widget_name', __( 'Display WordPress Posts', 'jetpack' ) ), |
||
| 146 | array( |
||
| 147 | 'description' => __( 'Displays a list of recent posts from another WordPress.com or Jetpack-enabled blog.', 'jetpack' ), |
||
| 148 | ) |
||
| 149 | ); |
||
| 150 | } |
||
| 151 | |||
| 152 | /** |
||
| 153 | * Expiring transients have a name length maximum of 45 characters, |
||
| 154 | * so this function returns an abbreviated MD5 hash to use instead of |
||
| 155 | * the full URI. |
||
| 156 | * |
||
| 157 | * @param string $site Site to get the hash for. |
||
| 158 | * |
||
| 159 | * @return string |
||
| 160 | */ |
||
| 161 | public function get_site_hash( $site ) { |
||
| 164 | |||
| 165 | /** |
||
| 166 | * Fetch a remote service endpoint and parse it. |
||
| 167 | * |
||
| 168 | * Timeout is set to 15 seconds right now, because sometimes the WordPress API |
||
| 169 | * takes more than 5 seconds to fully respond. |
||
| 170 | * |
||
| 171 | * Caching is used here so we can avoid re-downloading the same endpoint |
||
| 172 | * in a single request. |
||
| 173 | * |
||
| 174 | * @param string $endpoint Parametrized endpoint to call. |
||
| 175 | * |
||
| 176 | * @param int $timeout How much time to wait for the API to respond before failing. |
||
| 177 | * |
||
| 178 | * @return array|WP_Error |
||
| 179 | */ |
||
| 180 | public function fetch_service_endpoint( $endpoint, $timeout = 15 ) { |
||
| 194 | |||
| 195 | /** |
||
| 196 | * Parse data from service response. |
||
| 197 | * Do basic error handling for general service and data errors |
||
| 198 | * |
||
| 199 | * @param array $service_response Response from the service. |
||
| 200 | * |
||
| 201 | * @return array|WP_Error |
||
| 202 | */ |
||
| 203 | public function parse_service_response( $service_response ) { |
||
| 278 | |||
| 279 | /** |
||
| 280 | * Fetch site information from the WordPress public API |
||
| 281 | * |
||
| 282 | * @param string $site URL of the site to fetch the information for. |
||
| 283 | * |
||
| 284 | * @return array|WP_Error |
||
| 285 | */ |
||
| 286 | public function fetch_site_info( $site ) { |
||
| 292 | |||
| 293 | /** |
||
| 294 | * Parse external API response from the site info call and handle errors if they occur. |
||
| 295 | * |
||
| 296 | * @param array|WP_Error $service_response The raw response to be parsed. |
||
| 297 | * |
||
| 298 | * @return array|WP_Error |
||
| 299 | */ |
||
| 300 | View Code Duplication | public function parse_site_info_response( $service_response ) { |
|
| 322 | |||
| 323 | /** |
||
| 324 | * Fetch list of posts from the WordPress public API. |
||
| 325 | * |
||
| 326 | * @param int $site_id The site to fetch the posts for. |
||
| 327 | * |
||
| 328 | * @return array|WP_Error |
||
| 329 | */ |
||
| 330 | public function fetch_posts_for_site( $site_id ) { |
||
| 353 | |||
| 354 | /** |
||
| 355 | * Parse external API response from the posts list request and handle errors if any occur. |
||
| 356 | * |
||
| 357 | * @param object|WP_Error $service_response The raw response to be parsed. |
||
| 358 | * |
||
| 359 | * @return array|WP_Error |
||
| 360 | */ |
||
| 361 | View Code Duplication | public function parse_posts_response( $service_response ) { |
|
| 387 | |||
| 388 | /** |
||
| 389 | * Format the posts for better storage. Drop all the data that is not used. |
||
| 390 | * |
||
| 391 | * @param object $parsed_data Array of posts returned by the APIs. |
||
| 392 | * |
||
| 393 | * @return array Formatted posts or an empty array if no posts were found. |
||
| 394 | */ |
||
| 395 | public function format_posts_for_storage( $parsed_data ) { |
||
| 425 | |||
| 426 | /** |
||
| 427 | * Fetch site information and posts list for a site. |
||
| 428 | * |
||
| 429 | * @param string $site Site to fetch the data for. |
||
| 430 | * @param array $original_data Optional original data to updated. |
||
| 431 | * |
||
| 432 | * @param bool $site_data_only Fetch only site information, skip posts list. |
||
| 433 | * |
||
| 434 | * @return array Updated or new data. |
||
| 435 | */ |
||
| 436 | public function fetch_blog_data( $site, $original_data = array(), $site_data_only = false ) { |
||
| 531 | |||
| 532 | /** |
||
| 533 | * Gets blog data from the cache. |
||
| 534 | * |
||
| 535 | * @param string $site |
||
| 536 | * |
||
| 537 | * @return array|WP_Error |
||
| 538 | */ |
||
| 539 | public function get_blog_data( $site ) { |
||
| 558 | |||
| 559 | /** |
||
| 560 | * Activates widget update cron task. |
||
| 561 | */ |
||
| 562 | public static function activate_cron() { |
||
| 567 | |||
| 568 | /** |
||
| 569 | * Deactivates widget update cron task. |
||
| 570 | * |
||
| 571 | * This is a wrapper over the static method as it provides some syntactic sugar. |
||
| 572 | */ |
||
| 573 | public function deactivate_cron() { |
||
| 576 | |||
| 577 | /** |
||
| 578 | * Deactivates widget update cron task. |
||
| 579 | */ |
||
| 580 | public static function deactivate_cron_static() { |
||
| 584 | |||
| 585 | /** |
||
| 586 | * Checks if the update cron should be running and returns appropriate result. |
||
| 587 | * |
||
| 588 | * @return bool If the cron should be running or not. |
||
| 589 | */ |
||
| 590 | public function should_cron_be_running() { |
||
| 591 | /** |
||
| 592 | * The cron doesn't need to run empty loops. |
||
| 593 | */ |
||
| 594 | $widget_instances = $this->get_instances_sites(); |
||
| 595 | |||
| 596 | if ( empty( $widget_instances ) || ! is_array( $widget_instances ) ) { |
||
| 597 | return false; |
||
| 598 | } |
||
| 599 | |||
| 600 | if ( ! defined( 'IS_WPCOM' ) || ! IS_WPCOM ) { |
||
| 601 | /** |
||
| 602 | * If Jetpack is not active or in development mode, we don't want to update widget data. |
||
| 603 | */ |
||
| 604 | if ( ! Jetpack::is_active() && ! Jetpack::is_development_mode() ) { |
||
| 605 | return false; |
||
| 606 | } |
||
| 607 | |||
| 608 | /** |
||
| 609 | * If Extra Sidebar Widgets module is not active, we don't need to update widget data. |
||
| 610 | */ |
||
| 611 | if ( ! Jetpack::is_module_active( 'widgets' ) ) { |
||
| 612 | return false; |
||
| 613 | } |
||
| 614 | } |
||
| 615 | |||
| 616 | /** |
||
| 617 | * If none of the above checks failed, then we definitely want to update widget data. |
||
| 618 | */ |
||
| 619 | return true; |
||
| 620 | } |
||
| 621 | |||
| 622 | /** |
||
| 623 | * Main cron code. Updates all instances of the widget. |
||
| 624 | * |
||
| 625 | * @return bool |
||
| 626 | */ |
||
| 627 | public function cron_task() { |
||
| 628 | |||
| 629 | /** |
||
| 630 | * If the cron should not be running, disable it. |
||
| 631 | */ |
||
| 632 | if ( false === $this->should_cron_be_running() ) { |
||
| 633 | return true; |
||
| 634 | } |
||
| 635 | |||
| 636 | $instances_to_update = $this->get_instances_sites(); |
||
| 637 | |||
| 638 | /** |
||
| 639 | * If no instances are found to be updated - stop. |
||
| 640 | */ |
||
| 641 | if ( empty( $instances_to_update ) || ! is_array( $instances_to_update ) ) { |
||
| 642 | return true; |
||
| 643 | } |
||
| 644 | |||
| 645 | foreach ( $instances_to_update as $site_url ) { |
||
| 646 | $this->update_instance( $site_url ); |
||
| 647 | } |
||
| 648 | |||
| 649 | return true; |
||
| 650 | } |
||
| 651 | |||
| 652 | /** |
||
| 653 | * Get a list of unique sites from all instances of the widget. |
||
| 654 | * |
||
| 655 | * @return array|bool |
||
| 656 | */ |
||
| 657 | public function get_instances_sites() { |
||
| 658 | |||
| 659 | $widget_settings = $this->wp_get_option( 'widget_jetpack_display_posts_widget' ); |
||
| 660 | |||
| 661 | /** |
||
| 662 | * If the widget still hasn't been added anywhere, the config will not be present. |
||
| 663 | * |
||
| 664 | * In such case we don't want to continue execution. |
||
| 665 | */ |
||
| 666 | if ( false === $widget_settings || ! is_array( $widget_settings ) ) { |
||
| 667 | return false; |
||
| 668 | } |
||
| 669 | |||
| 670 | $urls = array(); |
||
| 671 | |||
| 672 | foreach ( $widget_settings as $widget_instance_data ) { |
||
| 673 | if ( isset( $widget_instance_data['url'] ) && ! empty( $widget_instance_data['url'] ) ) { |
||
| 674 | $urls[] = $widget_instance_data['url']; |
||
| 675 | } |
||
| 676 | } |
||
| 677 | |||
| 678 | /** |
||
| 679 | * Make sure only unique URLs are returned. |
||
| 680 | */ |
||
| 681 | $urls = array_unique( $urls ); |
||
| 682 | |||
| 683 | return $urls; |
||
| 684 | |||
| 685 | } |
||
| 686 | |||
| 687 | /** |
||
| 688 | * Update a widget instance. |
||
| 689 | * |
||
| 690 | * @param string $site The site to fetch the latest data for. |
||
| 691 | */ |
||
| 692 | public function update_instance( $site ) { |
||
| 693 | |||
| 694 | /** |
||
| 695 | * Fetch current information for a site. |
||
| 696 | */ |
||
| 697 | $site_hash = $this->get_site_hash( $site ); |
||
| 698 | |||
| 699 | $option_key = $this->widget_options_key_prefix . $site_hash; |
||
| 700 | |||
| 701 | $instance_data = $this->wp_get_option( $option_key ); |
||
| 702 | |||
| 703 | /** |
||
| 704 | * Fetch blog data and save it in $instance_data. |
||
| 705 | */ |
||
| 706 | $new_data = $this->fetch_blog_data( $site, $instance_data ); |
||
| 707 | |||
| 708 | /** |
||
| 709 | * If the option doesn't exist yet - create a new option |
||
| 710 | */ |
||
| 711 | if ( false === $instance_data ) { |
||
| 712 | $this->wp_add_option( $option_key, $new_data ); |
||
| 713 | } |
||
| 714 | else { |
||
| 715 | $this->wp_update_option( $option_key, $new_data ); |
||
| 716 | } |
||
| 717 | } |
||
| 718 | |||
| 719 | /** |
||
| 720 | * Set up the widget display on the front end. |
||
| 721 | * |
||
| 722 | * @param array $args |
||
| 723 | * @param array $instance |
||
| 724 | */ |
||
| 725 | public function widget( $args, $instance ) { |
||
| 726 | |||
| 727 | /** This filter is documented in core/src/wp-includes/default-widgets.php */ |
||
| 728 | $title = apply_filters( 'widget_title', $instance['title'] ); |
||
| 729 | |||
| 730 | wp_enqueue_style( 'jetpack_display_posts_widget', plugins_url( 'wordpress-post-widget/style.css', __FILE__ ) ); |
||
| 731 | |||
| 732 | echo $args['before_widget']; |
||
| 733 | |||
| 734 | $data = $this->get_blog_data( $instance['url'] ); |
||
| 735 | |||
| 736 | // check for errors |
||
| 737 | if ( is_wp_error( $data ) || empty( $data['site_info']['data'] ) ) { |
||
| 738 | echo '<p>' . __( 'Cannot load blog information at this time.', 'jetpack' ) . '</p>'; |
||
| 739 | echo $args['after_widget']; |
||
| 740 | |||
| 741 | return; |
||
| 742 | } |
||
| 743 | |||
| 744 | $site_info = $data['site_info']['data']; |
||
| 745 | |||
| 746 | if ( ! empty( $title ) ) { |
||
| 747 | echo $args['before_title'] . esc_html( $title . ': ' . $site_info->name ) . $args['after_title']; |
||
| 748 | } |
||
| 749 | else { |
||
| 750 | echo $args['before_title'] . esc_html( $site_info->name ) . $args['after_title']; |
||
| 751 | } |
||
| 752 | |||
| 753 | echo '<div class="jetpack-display-remote-posts">'; |
||
| 754 | |||
| 755 | if ( is_wp_error( $data['posts']['data'] ) || empty( $data['posts']['data'] ) ) { |
||
| 756 | echo '<p>' . __( 'Cannot load blog posts at this time.', 'jetpack' ) . '</p>'; |
||
| 757 | echo '</div><!-- .jetpack-display-remote-posts -->'; |
||
| 758 | echo $args['after_widget']; |
||
| 759 | |||
| 760 | return; |
||
| 761 | } |
||
| 762 | |||
| 763 | $posts_list = $data['posts']['data']; |
||
| 764 | |||
| 765 | /** |
||
| 766 | * Show only as much posts as we need. If we have less than configured amount, |
||
| 767 | * we must show only that much posts. |
||
| 768 | */ |
||
| 769 | $number_of_posts = min( $instance['number_of_posts'], count( $posts_list ) ); |
||
| 770 | |||
| 771 | for ( $i = 0; $i < $number_of_posts; $i ++ ) { |
||
| 772 | $single_post = $posts_list[ $i ]; |
||
| 773 | $post_title = ( $single_post['title'] ) ? $single_post['title'] : '( No Title )'; |
||
| 774 | |||
| 775 | $target = ''; |
||
| 776 | if ( isset( $instance['open_in_new_window'] ) && $instance['open_in_new_window'] == true ) { |
||
| 777 | $target = ' target="_blank"'; |
||
| 778 | } |
||
| 779 | echo '<h4><a href="' . esc_url( $single_post['url'] ) . '"' . $target . '>' . esc_html( $post_title ) . '</a></h4>' . "\n"; |
||
| 780 | if ( ( $instance['featured_image'] == true ) && ( ! empty ( $single_post['featured_image'] ) ) ) { |
||
| 781 | $featured_image = $single_post['featured_image']; |
||
| 782 | /** |
||
| 783 | * Allows setting up custom Photon parameters to manipulate the image output in the Display Posts widget. |
||
| 784 | * |
||
| 785 | * @see https://developer.wordpress.com/docs/photon/ |
||
| 786 | * |
||
| 787 | * @module widgets |
||
| 788 | * |
||
| 789 | * @since 3.6.0 |
||
| 790 | * |
||
| 791 | * @param array $args Array of Photon Parameters. |
||
| 792 | */ |
||
| 793 | $image_params = apply_filters( 'jetpack_display_posts_widget_image_params', array() ); |
||
| 794 | echo '<a title="' . esc_attr( $post_title ) . '" href="' . esc_url( $single_post['url'] ) . '"' . $target . '><img src="' . jetpack_photon_url( $featured_image, $image_params ) . '" alt="' . esc_attr( $post_title ) . '"/></a>'; |
||
| 795 | } |
||
| 796 | |||
| 797 | if ( $instance['show_excerpts'] == true ) { |
||
| 798 | echo $single_post['excerpt']; |
||
| 799 | } |
||
| 800 | } |
||
| 801 | |||
| 802 | echo '</div><!-- .jetpack-display-remote-posts -->'; |
||
| 803 | echo $args['after_widget']; |
||
| 804 | } |
||
| 805 | |||
| 806 | /** |
||
| 807 | * Scan and extract first error from blog data array. |
||
| 808 | * |
||
| 809 | * @param array|WP_Error $blog_data Blog data to scan for errors. |
||
| 810 | * |
||
| 811 | * @return string First error message found |
||
| 812 | */ |
||
| 813 | public function extract_errors_from_blog_data( $blog_data ) { |
||
| 814 | |||
| 815 | $errors = array( |
||
| 816 | 'message' => '', |
||
| 817 | 'debug' => '', |
||
| 818 | 'where' => '', |
||
| 819 | ); |
||
| 820 | |||
| 821 | |||
| 822 | /** |
||
| 823 | * When the cache result is an error. Usually when the cache is empty. |
||
| 824 | * This is not an error case for now. |
||
| 825 | */ |
||
| 826 | if ( is_wp_error( $blog_data ) ) { |
||
| 827 | return $errors; |
||
| 828 | } |
||
| 829 | |||
| 830 | /** |
||
| 831 | * Loop through `site_info` and `posts` keys of $blog_data. |
||
| 832 | */ |
||
| 833 | foreach ( array( 'site_info', 'posts' ) as $info_key ) { |
||
| 834 | |||
| 835 | /** |
||
| 836 | * Contains information on which stage the error ocurred. |
||
| 837 | */ |
||
| 838 | $errors['where'] = $info_key; |
||
| 839 | |||
| 840 | /** |
||
| 841 | * If an error is set, we want to check it for usable messages. |
||
| 842 | */ |
||
| 843 | if ( isset( $blog_data[ $info_key ]['error'] ) && ! empty( $blog_data[ $info_key ]['error'] ) ) { |
||
| 844 | |||
| 845 | /** |
||
| 846 | * Extract error message from the error, if possible. |
||
| 847 | */ |
||
| 848 | if ( is_wp_error( $blog_data[ $info_key ]['error'] ) ) { |
||
| 849 | /** |
||
| 850 | * In the case of WP_Error we want to have the error message |
||
| 851 | * and the debug information available. |
||
| 852 | */ |
||
| 853 | $error_messages = $blog_data[ $info_key ]['error']->get_error_messages(); |
||
| 854 | $errors['message'] = reset( $error_messages ); |
||
| 855 | |||
| 856 | $extra_data = $blog_data[ $info_key ]['error']->get_error_data(); |
||
| 857 | if ( is_array( $extra_data ) ) { |
||
| 858 | $errors['debug'] = implode( '; ', $extra_data ); |
||
| 859 | } |
||
| 860 | else { |
||
| 861 | $errors['debug'] = $extra_data; |
||
| 862 | } |
||
| 863 | |||
| 864 | break; |
||
| 865 | } |
||
| 866 | elseif ( is_array( $blog_data[ $info_key ]['error'] ) ) { |
||
| 867 | /** |
||
| 868 | * In this case we don't have debug information, because |
||
| 869 | * we have no way to know the format. The widget works with |
||
| 870 | * WP_Error objects only. |
||
| 871 | */ |
||
| 872 | $errors['message'] = reset( $blog_data[ $info_key ]['error'] ); |
||
| 873 | break; |
||
| 874 | } |
||
| 875 | |||
| 876 | /** |
||
| 877 | * We do nothing if no usable error is found. |
||
| 878 | */ |
||
| 879 | } |
||
| 880 | } |
||
| 881 | |||
| 882 | return $errors; |
||
| 883 | } |
||
| 884 | |||
| 885 | /** |
||
| 886 | * Display the widget administration form. |
||
| 887 | * |
||
| 888 | * @param array $instance Widget instance configuration. |
||
| 889 | * |
||
| 890 | * @return string|void |
||
| 891 | */ |
||
| 892 | public function form( $instance ) { |
||
| 893 | |||
| 894 | /** |
||
| 895 | * Initialize widget configuration variables. |
||
| 896 | */ |
||
| 897 | $title = ( isset( $instance['title'] ) ) ? $instance['title'] : __( 'Recent Posts', 'jetpack' ); |
||
| 898 | $url = ( isset( $instance['url'] ) ) ? $instance['url'] : ''; |
||
| 899 | $number_of_posts = ( isset( $instance['number_of_posts'] ) ) ? $instance['number_of_posts'] : 5; |
||
| 900 | $open_in_new_window = ( isset( $instance['open_in_new_window'] ) ) ? $instance['open_in_new_window'] : false; |
||
| 901 | $featured_image = ( isset( $instance['featured_image'] ) ) ? $instance['featured_image'] : false; |
||
| 902 | $show_excerpts = ( isset( $instance['show_excerpts'] ) ) ? $instance['show_excerpts'] : false; |
||
| 903 | |||
| 904 | |||
| 905 | /** |
||
| 906 | * Check if the widget instance has errors available. |
||
| 907 | * |
||
| 908 | * Only do so if a URL is set. |
||
| 909 | */ |
||
| 910 | $update_errors = array(); |
||
| 911 | |||
| 912 | if ( ! empty( $url ) ) { |
||
| 913 | $data = $this->get_blog_data( $url ); |
||
| 914 | $update_errors = $this->extract_errors_from_blog_data( $data ); |
||
| 915 | } |
||
| 916 | |||
| 917 | ?> |
||
| 918 | <p> |
||
| 919 | <label for="<?php echo $this->get_field_id( 'title' ); ?>"><?php _e( 'Title:', 'jetpack' ); ?></label> |
||
| 920 | <input class="widefat" id="<?php echo $this->get_field_id( 'title' ); ?>" name="<?php echo $this->get_field_name( 'title' ); ?>" type="text" value="<?php echo esc_attr( $title ); ?>" /> |
||
| 921 | </p> |
||
| 922 | |||
| 923 | <p> |
||
| 924 | <label for="<?php echo $this->get_field_id( 'url' ); ?>"><?php _e( 'Blog URL:', 'jetpack' ); ?></label> |
||
| 925 | <input class="widefat" id="<?php echo $this->get_field_id( 'url' ); ?>" name="<?php echo $this->get_field_name( 'url' ); ?>" type="text" value="<?php echo esc_attr( $url ); ?>" /> |
||
| 926 | <i> |
||
| 927 | <?php _e( "Enter a WordPress.com or Jetpack WordPress site URL.", 'jetpack' ); ?> |
||
| 928 | </i> |
||
| 929 | <?php |
||
| 930 | /** |
||
| 931 | * Show an error if the URL field was left empty. |
||
| 932 | * |
||
| 933 | * The error is shown only when the widget was already saved. |
||
| 934 | */ |
||
| 935 | if ( empty( $url ) && ! preg_match( '/__i__|%i%/', $this->id ) ) { |
||
| 936 | ?> |
||
| 937 | <br /> |
||
| 938 | <i class="error-message"><?php echo __( 'You must specify a valid blog URL!', 'jetpack' ); ?></i> |
||
| 939 | <?php |
||
| 940 | } |
||
| 941 | ?> |
||
| 942 | </p> |
||
| 943 | <p> |
||
| 944 | <label for="<?php echo $this->get_field_id( 'number_of_posts' ); ?>"><?php _e( 'Number of Posts to Display:', 'jetpack' ); ?></label> |
||
| 945 | <select name="<?php echo $this->get_field_name( 'number_of_posts' ); ?>"> |
||
| 946 | <?php |
||
| 947 | for ( $i = 1; $i <= 10; $i ++ ) { |
||
| 948 | echo '<option value="' . $i . '" ' . selected( $number_of_posts, $i ) . '>' . $i . '</option>'; |
||
| 949 | } |
||
| 950 | ?> |
||
| 951 | </select> |
||
| 952 | </p> |
||
| 953 | <p> |
||
| 954 | <label for="<?php echo $this->get_field_id( 'open_in_new_window' ); ?>"><?php _e( 'Open links in new window/tab:', 'jetpack' ); ?></label> |
||
| 955 | <input type="checkbox" name="<?php echo $this->get_field_name( 'open_in_new_window' ); ?>" <?php checked( $open_in_new_window, 1 ); ?> /> |
||
| 956 | </p> |
||
| 957 | <p> |
||
| 958 | <label for="<?php echo $this->get_field_id( 'featured_image' ); ?>"><?php _e( 'Show Featured Image:', 'jetpack' ); ?></label> |
||
| 959 | <input type="checkbox" name="<?php echo $this->get_field_name( 'featured_image' ); ?>" <?php checked( $featured_image, 1 ); ?> /> |
||
| 960 | </p> |
||
| 961 | <p> |
||
| 962 | <label for="<?php echo $this->get_field_id( 'show_excerpts' ); ?>"><?php _e( 'Show Excerpts:', 'jetpack' ); ?></label> |
||
| 963 | <input type="checkbox" name="<?php echo $this->get_field_name( 'show_excerpts' ); ?>" <?php checked( $show_excerpts, 1 ); ?> /> |
||
| 964 | </p> |
||
| 965 | |||
| 966 | <?php |
||
| 967 | |||
| 968 | /** |
||
| 969 | * Show error messages. |
||
| 970 | */ |
||
| 971 | if ( ! empty( $update_errors['message'] ) ) { |
||
| 972 | |||
| 973 | /** |
||
| 974 | * Prepare the error messages. |
||
| 975 | */ |
||
| 976 | |||
| 977 | $where_message = ''; |
||
| 978 | switch ( $update_errors['where'] ) { |
||
| 979 | case 'posts': |
||
| 980 | $where_message .= __( 'An error occurred while downloading blog posts list', 'jetpack' ); |
||
| 981 | break; |
||
| 982 | |||
| 983 | /** |
||
| 984 | * If something else, beside `posts` and `site_info` broke, |
||
| 985 | * don't handle it and default to blog `information`, |
||
| 986 | * as it is generic enough. |
||
| 987 | */ |
||
| 988 | case 'site_info': |
||
| 989 | default: |
||
| 990 | $where_message .= __( 'An error occurred while downloading blog information', 'jetpack' ); |
||
| 991 | break; |
||
| 992 | } |
||
| 993 | |||
| 994 | ?> |
||
| 995 | <p class="error-message"> |
||
| 996 | <?php echo esc_html( $where_message ); ?>: |
||
| 997 | <br /> |
||
| 998 | <i> |
||
| 999 | <?php echo esc_html( $update_errors['message'] ); ?> |
||
| 1000 | <?php |
||
| 1001 | /** |
||
| 1002 | * If there is any debug - show it here. |
||
| 1003 | */ |
||
| 1004 | if ( ! empty( $update_errors['debug'] ) ) { |
||
| 1005 | ?> |
||
| 1006 | <br /> |
||
| 1007 | <br /> |
||
| 1008 | <?php esc_html_e( 'Detailed information', 'jetpack' ); ?>: |
||
| 1009 | <br /> |
||
| 1010 | <?php echo esc_html( $update_errors['debug'] ); ?> |
||
| 1011 | <?php |
||
| 1012 | } |
||
| 1013 | ?> |
||
| 1014 | </i> |
||
| 1015 | </p> |
||
| 1016 | |||
| 1017 | <?php |
||
| 1018 | } |
||
| 1019 | } |
||
| 1020 | |||
| 1021 | public function update( $new_instance, $old_instance ) { |
||
| 1071 | |||
| 1072 | /** |
||
| 1073 | * This is just to make method mocks in the unit tests easier. |
||
| 1074 | * |
||
| 1075 | * @param string $param Option key to get |
||
| 1076 | * |
||
| 1077 | * @return mixed |
||
| 1078 | * |
||
| 1079 | * @codeCoverageIgnore |
||
| 1080 | */ |
||
| 1081 | public function wp_get_option( $param ) { |
||
| 1084 | |||
| 1085 | /** |
||
| 1086 | * This is just to make method mocks in the unit tests easier. |
||
| 1087 | * |
||
| 1088 | * @param string $option_name Option name to be added |
||
| 1089 | * @param mixed $option_value Option value |
||
| 1090 | * |
||
| 1091 | * @return mixed |
||
| 1092 | * |
||
| 1093 | * @codeCoverageIgnore |
||
| 1094 | */ |
||
| 1095 | public function wp_add_option( $option_name, $option_value ) { |
||
| 1098 | |||
| 1099 | /** |
||
| 1100 | * This is just to make method mocks in the unit tests easier. |
||
| 1101 | * |
||
| 1102 | * @param string $option_name Option name to be updated |
||
| 1103 | * @param mixed $option_value Option value |
||
| 1104 | * |
||
| 1105 | * @return mixed |
||
| 1106 | * |
||
| 1107 | * @codeCoverageIgnore |
||
| 1108 | */ |
||
| 1109 | public function wp_update_option( $option_name, $option_value ) { |
||
| 1112 | |||
| 1113 | |||
| 1114 | /** |
||
| 1115 | * This is just to make method mocks in the unit tests easier. |
||
| 1116 | * |
||
| 1117 | * @param string $url The URL to fetch |
||
| 1118 | * @param array $args Optional. Request arguments. |
||
| 1119 | * |
||
| 1120 | * @return array|WP_Error |
||
| 1121 | * |
||
| 1122 | * @codeCoverageIgnore |
||
| 1123 | */ |
||
| 1124 | public function wp_wp_remote_get( $url, $args = array() ) { |
||
| 1127 | } |
||
| 1128 |
Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.