/modules/widgets/wordpress-post-widget.php

  1. <?php 
  2. /** 
  3. * Plugin Name: Display Recent WordPress Posts Widget 
  4. * Description: Displays recent posts from a WordPress.com or Jetpack-enabled self-hosted WordPress site. 
  5. * Version: 1.0 
  6. * Author: Brad Angelcyk, Kathryn Presner, Justin Shreve, Carolyn Sonnek 
  7. * Author URI: http://automattic.com 
  8. * License: GPL2 
  9. */ 
  10. add_action( 'widgets_init', 'jetpack_display_posts_widget' ); 
  11. function jetpack_display_posts_widget() { 
  12. register_widget( 'Jetpack_Display_Posts_Widget' ); 
  13.  
  14. /** 
  15. * Display a list of recent posts from a WordPress.com or Jetpack-enabled blog. 
  16. */ 
  17. class Jetpack_Display_Posts_Widget extends WP_Widget { 
  18.  
  19. public function __construct() { 
  20. parent::__construct( 
  21. // internal id 
  22. 'jetpack_display_posts_widget',  
  23. /** This filter is documented in modules/widgets/facebook-likebox.php */ 
  24. apply_filters( 'jetpack_widget_name', __( 'Display WordPress Posts', 'jetpack' ) ),  
  25. array( 
  26. 'description' => __( 'Displays a list of recent posts from another WordPress.com or Jetpack-enabled blog.', 'jetpack' ),  
  27. ); 
  28.  
  29. /** 
  30. * Expiring transients have a name length maximum of 45 characters,  
  31. * so this function returns an abbreviated MD5 hash to use instead of 
  32. * the full URI. 
  33. */ 
  34. public function get_site_hash( $site ) { 
  35. return substr( md5( $site ), 0, 21 ); 
  36.  
  37. public function get_site_info( $site ) { 
  38. $site_hash = $this->get_site_hash( $site ); 
  39. $data_from_cache = get_transient( 'display_posts_site_info_' . $site_hash ); 
  40. if ( false === $data_from_cache ) { 
  41. $response = wp_remote_get( sprintf( 'https://public-api.wordpress.com/rest/v1.1/sites/%s', urlencode( $site ) ) ); 
  42. set_transient( 'display_posts_site_info_' . $site_hash, $response, 10 * MINUTE_IN_SECONDS ); 
  43. } else { 
  44. $response = $data_from_cache; 
  45.  
  46. if ( is_wp_error( $response ) ) { 
  47. return false; 
  48.  
  49. $site_info = json_decode( $response ['body'] ); 
  50. if ( ! isset( $site_info->ID ) ) { 
  51. return false; 
  52.  
  53. return $site_info; 
  54.  
  55. /** 
  56. * Set up the widget display on the front end 
  57. */ 
  58. public function widget( $args, $instance ) { 
  59. /** This filter is documented in core/src/wp-includes/default-widgets.php */ 
  60. $title = apply_filters( 'widget_title', $instance['title'] ); 
  61.  
  62. wp_enqueue_style( 'jetpack_display_posts_widget', plugins_url( 'wordpress-post-widget/style.css', __FILE__ ) ); 
  63.  
  64. $site_info = $this->get_site_info( $instance['url'] ); 
  65.  
  66. echo $args['before_widget']; 
  67.  
  68. if ( false === $site_info ) { 
  69. echo '<p>' . __( 'We cannot load blog data at this time.', 'jetpack' ) . '</p>'; 
  70. echo $args['after_widget']; 
  71. return; 
  72.  
  73. if ( ! empty( $title ) ) { 
  74. echo $args['before_title'] . esc_html( $title . ': ' . $site_info->name ) . $args['after_title']; 
  75. } else { 
  76. echo $args['before_title'] . esc_html( $site_info->name ) . $args['after_title']; 
  77.  
  78. $site_hash = $this->get_site_hash( $instance['url'] ); 
  79. $data_from_cache = get_transient( 'display_posts_post_info_' . $site_hash ); 
  80. if ( false === $data_from_cache ) { 
  81. $response = wp_remote_get( 
  82. sprintf( 
  83. 'https://public-api.wordpress.com/rest/v1.1/sites/%1$d/posts/%2$s',  
  84. $site_info->ID,  
  85. /** 
  86. * Filters the parameters used to fetch for posts in the Display Posts Widget. 
  87. * 
  88. * @see https://developer.wordpress.com/docs/api/1.1/get/sites/%24site/posts/ 
  89. * 
  90. * @module widgets 
  91. * 
  92. * @since 3.6.0 
  93. * 
  94. * @param string $args Extra parameters to filter posts returned from the WordPress.com REST API. 
  95. */ 
  96. apply_filters( 'jetpack_display_posts_widget_posts_params', '' ) 
  97. ); 
  98. set_transient( 'display_posts_post_info_' . $site_hash, $response, 10 * MINUTE_IN_SECONDS ); 
  99. } else { 
  100. $response = $data_from_cache; 
  101.  
  102. if ( is_wp_error( $response ) ) { 
  103. echo '<p>' . __( 'We cannot load blog data at this time.', 'jetpack' ) . '</p>'; 
  104. echo $args['after_widget']; 
  105. return; 
  106.  
  107. $posts_info = json_decode( $response['body'] ); 
  108.  
  109. echo '<div class="jetpack-display-remote-posts">'; 
  110.  
  111. if ( isset( $posts_info->error ) && 'jetpack_error' == $posts_info->error ) { 
  112. echo '<p>' . __( 'We cannot display posts for this blog.', 'jetpack' ) . '</p>'; 
  113. echo '</div><!-- .jetpack-display-remote-posts -->'; 
  114. echo $args['after_widget']; 
  115. return; 
  116.  
  117. $number_of_posts = min( $instance['number_of_posts'], count( $posts_info->posts ) ); 
  118.  
  119. for ( $i = 0; $i < $number_of_posts; $i++ ) { 
  120. $single_post = $posts_info->posts[$i]; 
  121. $post_title = ( $single_post->title ) ? $single_post->title : '( No Title )'; 
  122.  
  123. $target = ''; 
  124. if ( isset( $instance['open_in_new_window'] ) && $instance['open_in_new_window'] == true ) { 
  125. $target = ' target="_blank"'; 
  126. echo '<h4><a href="' . esc_url( $single_post->URL ) . '"' . $target . '>' . esc_html( $post_title ) . '</a></h4>' . "\n"; 
  127. if ( ( $instance['featured_image'] == true ) && ( ! empty ( $single_post->featured_image) ) ) { 
  128. $featured_image = ( $single_post->featured_image ) ? $single_post->featured_image : ''; 
  129. /** 
  130. * Allows setting up custom Photon parameters to manipulate the image output in the Display Posts widget. 
  131. * 
  132. * @see https://developer.wordpress.com/docs/photon/ 
  133. * 
  134. * @module widgets 
  135. * 
  136. * @since 3.6.0 
  137. * 
  138. * @param array $args Array of Photon Parameters. 
  139. */ 
  140. $image_params = apply_filters( 'jetpack_display_posts_widget_image_params', array() ); 
  141. echo '<a title="' . esc_attr( $post_title ) . '" href="' . esc_url( $single_post->URL ) . '"><img src="' . jetpack_photon_url( $featured_image, $image_params ) . '" alt="' . esc_attr( $post_title ) . '"/></a>'; 
  142.  
  143. if ( $instance['show_excerpts'] == true ) { 
  144. $post_excerpt = ( $single_post->excerpt ) ? $single_post->excerpt : ''; 
  145. echo $post_excerpt; 
  146.  
  147. echo '</div><!-- .jetpack-display-remote-posts -->'; 
  148. echo $args['after_widget']; 
  149.  
  150. public function form( $instance ) { 
  151. if ( isset( $instance['title'] ) ) { 
  152. $title = $instance['title']; 
  153. } else { 
  154. $title = __( 'Recent Posts', 'jetpack' ); 
  155.  
  156. if ( isset( $instance['url'] ) ) { 
  157. $url = $instance['url']; 
  158. } else { 
  159. $url = ''; 
  160.  
  161. if ( isset( $instance['number_of_posts'] ) ) { 
  162. $number_of_posts = $instance['number_of_posts']; 
  163. } else { 
  164. $number_of_posts = 5; 
  165.  
  166. $open_in_new_window = false; 
  167. if ( isset( $instance['open_in_new_window'] ) ) { 
  168. $open_in_new_window = $instance['open_in_new_window']; 
  169.  
  170. if ( isset( $instance['featured_image'] ) ) { 
  171. $featured_image = $instance['featured_image']; 
  172. } else { 
  173. $featured_image = false; 
  174.  
  175. if ( isset( $instance['show_excerpts'] ) ) { 
  176. $show_excerpts = $instance['show_excerpts']; 
  177. } else { 
  178. $show_excerpts = false; 
  179.  
  180. ?> 
  181. <p> 
  182. <label for="<?php echo $this->get_field_id( 'title' ); ?>"><?php _e( 'Title:', 'jetpack' ); ?></label> 
  183. <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 ); ?>" /> 
  184. </p> 
  185.  
  186. <p> 
  187. <label for="<?php echo $this->get_field_id( 'url' ); ?>"><?php _e( 'Blog URL:', 'jetpack' ); ?></label> 
  188. <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 ); ?>" /> 
  189. <p> 
  190. <?php _e( "Enter a WordPress.com or Jetpack WordPress site URL.", 'jetpack' ); ?> 
  191. </p> 
  192. </p> 
  193. <p> 
  194. <label for="<?php echo $this->get_field_id( 'number_of_posts' ); ?>"><?php _e( 'Number of Posts to Display:', 'jetpack' ); ?></label> 
  195. <select name="<?php echo $this->get_field_name( 'number_of_posts' ); ?>"> 
  196. <?php 
  197. for ($i = 1; $i <= 10; $i++) { 
  198. echo '<option value="' . $i . '" '.selected( $number_of_posts, $i ).'>' . $i . '</option>'; 
  199. ?> 
  200. </select> 
  201. </p> 
  202. <label for="<?php echo $this->get_field_id( 'open_in_new_window' ); ?>"><?php _e( 'Open links in new window/tab:', 'jetpack' ); ?></label> 
  203. <input type="checkbox" name="<?php echo $this->get_field_name( 'open_in_new_window' ); ?>" <?php checked( $open_in_new_window, 1 ); ?> /> 
  204. </p> 
  205. <p> 
  206. <label for="<?php echo $this->get_field_id( 'featured_image' ); ?>"><?php _e( 'Show Featured Image:', 'jetpack' ); ?></label> 
  207. <input type="checkbox" name="<?php echo $this->get_field_name( 'featured_image' ); ?>" <?php checked( $featured_image, 1 ); ?> /> 
  208. </p> 
  209. <p> 
  210. <label for="<?php echo $this->get_field_id( 'show_excerpts' ); ?>"><?php _e( 'Show Excerpts:', 'jetpack' ); ?></label> 
  211. <input type="checkbox" name="<?php echo $this->get_field_name( 'show_excerpts' ); ?>" <?php checked( $show_excerpts, 1 ); ?> /> 
  212. </p> 
  213.  
  214. <?php 
  215.  
  216. public function update( $new_instance, $old_instance ) { 
  217. $instance = array(); 
  218. $instance['title'] = ( ! empty( $new_instance['title'] ) ) ? strip_tags( $new_instance['title'] ) : ''; 
  219. $instance['url'] = ( ! empty( $new_instance['url'] ) ) ? strip_tags( $new_instance['url'] ) : ''; 
  220. $instance['url'] = str_replace( "http://", "", $instance['url'] ); 
  221. $instance['url'] = untrailingslashit( $instance['url'] ); 
  222.  
  223. // Normalize www. 
  224. $site_info = $this->get_site_info( $instance['url'] ); 
  225. if ( ! $site_info && 'www.' === substr( $instance['url'], 0, 4 ) ) { 
  226. $site_info = $this->get_site_info( substr( $instance['url'], 4 ) ); 
  227. if ( $site_info ) { 
  228. $instance['url'] = substr( $instance['url'], 4 ); 
  229.  
  230. $instance['number_of_posts'] = ( ! empty( $new_instance['number_of_posts'] ) ) ? intval( $new_instance['number_of_posts'] ) : ''; 
  231. $instance['open_in_new_window'] = ( ! empty( $new_instance['open_in_new_window'] ) ) ? true : ''; 
  232. $instance['featured_image'] = ( ! empty( $new_instance['featured_image'] ) ) ? true : ''; 
  233. $instance['show_excerpts'] = ( ! empty( $new_instance['show_excerpts'] ) ) ? true : ''; 
  234. return $instance; 
.