BP_Activity_Feed

Create a RSS feed using the activity component.

Defined (1)

The class is defined in the following location(s).

/bp-activity/classes/class-bp-activity-feed.php  
  1. class BP_Activity_Feed { 
  2.  
  3. /** 
  4. * Holds our custom class properties. 
  5. * These variables are stored in a protected array that is magically 
  6. * updated using PHP 5.2+ methods. 
  7. * @see BP_Feed::__construct() This is where $data is added. 
  8. * @since 1.8.0 
  9. * @var array 
  10. */ 
  11. protected $data; 
  12.  
  13. /** 
  14. * Magic method for checking the existence of a certain data variable. 
  15. * @since 1.8.0 
  16. * @param string $key Property to check. 
  17. * @return bool Whether or not data variable exists. 
  18. */ 
  19. public function __isset( $key ) { return isset( $this->data[$key] ); } 
  20.  
  21. /** 
  22. * Magic method for getting a certain data variable. 
  23. * @since 1.8.0 
  24. * @param string $key Property to get. 
  25. * @return mixed Data in variable if available or null. 
  26. */ 
  27. public function __get( $key ) { return isset( $this->data[$key] ) ? $this->data[$key] : null; } 
  28.  
  29. /** 
  30. * Magic method for setting a certain data variable. 
  31. * @since 2.4.0 
  32. * @param string $key The property to set. 
  33. * @param mixed $value The value to set. 
  34. */ 
  35. public function __set( $key, $value ) { $this->data[$key] = $value; } 
  36.  
  37. /** 
  38. * Constructor. 
  39. * @since 1.8.0 
  40. * @param array $args Optional. 
  41. */ 
  42. public function __construct( $args = array() ) { 
  43.  
  44. /** 
  45. * Filters if BuddyPress should consider feeds enabled. If disabled, it will return early. 
  46. * @since 1.8.0 
  47. * @param bool true Default true aka feeds are enabled. 
  48. */ 
  49. if ( false === (bool) apply_filters( 'bp_activity_enable_feeds', true ) ) { 
  50. global $wp_query; 
  51.  
  52. // Set feed flag to false. 
  53. $wp_query->is_feed = false; 
  54.  
  55. return false; 
  56.  
  57. // Setup data. 
  58. $this->data = wp_parse_args( $args, array( 
  59. // Internal identifier for the RSS feed - should be alphanumeric only. 
  60. 'id' => '',  
  61.  
  62. // RSS title - should be plain-text. 
  63. 'title' => '',  
  64.  
  65. // Relevant link for the RSS feed. 
  66. 'link' => '',  
  67.  
  68. // RSS description - should be plain-text. 
  69. 'description' => '',  
  70.  
  71. // Time-to-live - number of minutes to cache the data before an aggregator 
  72. // requests it again. This is only acknowledged if the RSS client supports it 
  73. // 
  74. // See: http://www.rssboard.org/rss-profile#element-channel-ttl. 
  75. // See: http://www.kbcafe.com/rss/rssfeedstate.html#ttl. 
  76. 'ttl' => '30',  
  77.  
  78. // Syndication module - similar to ttl, but not really supported by RSS 
  79. // clients 
  80. // 
  81. // See: http://web.resource.org/rss/1.0/modules/syndication/#description. 
  82. // See: http://www.kbcafe.com/rss/rssfeedstate.html#syndicationmodule. 
  83. 'update_period' => 'hourly',  
  84. 'update_frequency' => 2,  
  85.  
  86. // Number of items to display. 
  87. 'max' => 50,  
  88.  
  89. // Activity arguments passed to bp_has_activities(). 
  90. 'activity_args' => array() 
  91. ) ); 
  92.  
  93. /** 
  94. * Fires before the feed is setup so plugins can modify. 
  95. * @since 1.8.0 
  96. * @param BP_Activity_Feed $this Current instance of activity feed. Passed by reference. 
  97. */ 
  98. do_action_ref_array( 'bp_activity_feed_prefetch', array( &$this ) ); 
  99.  
  100. // Setup class properties. 
  101. $this->setup_properties(); 
  102.  
  103. // Check if id is valid. 
  104. if ( empty( $this->id ) ) { 
  105. _doing_it_wrong( 'BP_Activity_Feed', __( "RSS feed 'id' must be defined", 'buddypress' ), 'BP 1.8' ); 
  106. return false; 
  107.  
  108. /** 
  109. * Fires after the feed is setup so plugins can modify. 
  110. * @since 1.8.0 
  111. * @param BP_Activity_Feed $this Current instance of activity feed. Passed by reference. 
  112. */ 
  113. do_action_ref_array( 'bp_activity_feed_postfetch', array( &$this ) ); 
  114.  
  115. // Setup feed hooks. 
  116. $this->setup_hooks(); 
  117.  
  118. // Output the feed. 
  119. $this->output(); 
  120.  
  121. // Kill the rest of the output. 
  122. die(); 
  123.  
  124. /** SETUP ****************************************************************/ 
  125.  
  126. /** 
  127. * Setup and validate the class properties. 
  128. * @since 1.8.0 
  129. */ 
  130. protected function setup_properties() { 
  131. $this->id = sanitize_title( $this->id ); 
  132. $this->title = strip_tags( $this->title ); 
  133. $this->link = esc_url_raw( $this->link ); 
  134. $this->description = strip_tags( $this->description ); 
  135. $this->ttl = (int) $this->ttl; 
  136. $this->update_period = strip_tags( $this->update_period ); 
  137. $this->update_frequency = (int) $this->update_frequency; 
  138.  
  139. $this->activity_args = wp_parse_args( $this->activity_args, array( 
  140. 'max' => $this->max,  
  141. 'per_page' => $this->max,  
  142. 'display_comments' => 'stream' 
  143. ) ); 
  144.  
  145.  
  146. /** 
  147. * Setup some hooks that are used in the feed. 
  148. * Currently, these hooks are used to maintain backwards compatibility with 
  149. * the RSS feeds previous to BP 1.8. 
  150. * @since 1.8.0 
  151. */ 
  152. protected function setup_hooks() { 
  153. add_action( 'bp_activity_feed_rss_attributes', array( $this, 'backpat_rss_attributes' ) ); 
  154. add_action( 'bp_activity_feed_channel_elements', array( $this, 'backpat_channel_elements' ) ); 
  155. add_action( 'bp_activity_feed_item_elements', array( $this, 'backpat_item_elements' ) ); 
  156.  
  157. /** BACKPAT HOOKS ********************************************************/ 
  158.  
  159. /** 
  160. * Fire a hook to ensure backward compatibility for RSS attributes. 
  161. * @since 1.8.0 
  162. */ 
  163. public function backpat_rss_attributes() { 
  164.  
  165. /** 
  166. * Fires inside backpat_rss_attributes method for backwards compatibility related to RSS attributes. 
  167. * This hook was originally separated out for individual components but has since been abstracted into the BP_Activity_Feed class. 
  168. * @since 1.0.0 
  169. */ 
  170. do_action( 'bp_activity_' . $this->id . '_feed' ); 
  171.  
  172. /** 
  173. * Fire a hook to ensure backward compatibility for channel elements. 
  174. * @since 1.8.0 
  175. */ 
  176. public function backpat_channel_elements() { 
  177.  
  178. /** 
  179. * Fires inside backpat_channel_elements method for backwards compatibility related to RSS channel elements. 
  180. * This hook was originally separated out for individual components but has since been abstracted into the BP_Activity_Feed class. 
  181. * @since 1.0.0 
  182. */ 
  183. do_action( 'bp_activity_' . $this->id . '_feed_head' ); 
  184.  
  185. /** 
  186. * Fire a hook to ensure backward compatibility for item elements. 
  187. * @since 1.8.0 
  188. */ 
  189. public function backpat_item_elements() { 
  190. switch ( $this->id ) { 
  191.  
  192. // Sitewide and friends feeds use the 'personal' hook. 
  193. case 'sitewide' : 
  194. case 'friends' : 
  195. $id = 'personal'; 
  196.  
  197. break; 
  198.  
  199. default : 
  200. $id = $this->id; 
  201.  
  202. break; 
  203.  
  204. /** 
  205. * Fires inside backpat_item_elements method for backwards compatibility related to RSS item elements. 
  206. * This hook was originally separated out for individual components but has since been abstracted into the BP_Activity_Feed class. 
  207. * @since 1.0.0 
  208. */ 
  209. do_action( 'bp_activity_' . $id . '_feed_item' ); 
  210.  
  211. /** HELPERS **************************************************************/ 
  212.  
  213. /** 
  214. * Output the feed's item content. 
  215. * @since 1.8.0 
  216. */ 
  217. protected function feed_content() { 
  218. bp_activity_content_body(); 
  219.  
  220. switch ( $this->id ) { 
  221.  
  222. // Also output parent activity item if we're on a specific feed. 
  223. case 'favorites' : 
  224. case 'friends' : 
  225. case 'mentions' : 
  226. case 'personal' : 
  227.  
  228. if ( 'activity_comment' == bp_get_activity_action_name() ) : 
  229. ?> 
  230. <strong><?php _e( 'In reply to', 'buddypress' ) ?></strong> - 
  231. <?php bp_activity_parent_content() ?> 
  232. <?php 
  233. endif; 
  234.  
  235. break; 
  236.  
  237. /** 
  238. * Sets various HTTP headers related to Content-Type and browser caching. 
  239. * Most of this class method is derived from {@link WP::send_headers()}. 
  240. * @since 1.9.0 
  241. */ 
  242. protected function http_headers() { 
  243. // Set up some additional headers if not on a directory page 
  244. // this is done b/c BP uses pseudo-pages. 
  245. if ( ! bp_is_directory() ) { 
  246. global $wp_query; 
  247.  
  248. $wp_query->is_404 = false; 
  249. status_header( 200 ); 
  250.  
  251. // Set content-type. 
  252. @header( 'Content-Type: text/xml; charset=' . get_option( 'blog_charset' ), true ); 
  253. send_nosniff_header(); 
  254.  
  255. // Cache-related variables. 
  256. $last_modified = mysql2date( 'D, d M Y H:i:s O', bp_activity_get_last_updated(), false ); 
  257. $modified_timestamp = strtotime( $last_modified ); 
  258. $etag = md5( $last_modified ); 
  259.  
  260. // Set cache-related headers. 
  261. @header( 'Last-Modified: ' . $last_modified ); 
  262. @header( 'Pragma: no-cache' ); 
  263. @header( 'ETag: ' . '"' . $etag . '"' ); 
  264.  
  265. // First commit of BuddyPress! (Easter egg). 
  266. @header( 'Expires: Tue, 25 Mar 2008 17:13:55 GMT'); 
  267.  
  268. // Get ETag from supported user agents. 
  269. if ( isset( $_SERVER['HTTP_IF_NONE_MATCH'] ) ) { 
  270. $client_etag = wp_unslash( $_SERVER['HTTP_IF_NONE_MATCH'] ); 
  271.  
  272. // Remove quotes from ETag. 
  273. $client_etag = trim( $client_etag, '"' ); 
  274.  
  275. // Strip suffixes from ETag if they exist (eg. "-gzip"). 
  276. $etag_suffix_pos = strpos( $client_etag, '-' ); 
  277. if ( ! empty( $etag_suffix_pos ) ) { 
  278. $client_etag = substr( $client_etag, 0, $etag_suffix_pos ); 
  279.  
  280. // No ETag found. 
  281. } else { 
  282. $client_etag = false; 
  283.  
  284. // Get client last modified timestamp from supported user agents. 
  285. $client_last_modified = empty( $_SERVER['HTTP_IF_MODIFIED_SINCE'] ) ? '' : trim( $_SERVER['HTTP_IF_MODIFIED_SINCE'] ); 
  286. $client_modified_timestamp = $client_last_modified ? strtotime( $client_last_modified ) : 0; 
  287.  
  288. // Set 304 status if feed hasn't been updated since last fetch. 
  289. if ( ( $client_last_modified && $client_etag ) ? 
  290. ( ( $client_modified_timestamp >= $modified_timestamp ) && ( $client_etag == $etag ) ) : 
  291. ( ( $client_modified_timestamp >= $modified_timestamp ) || ( $client_etag == $etag ) ) ) { 
  292. $status = 304; 
  293. } else { 
  294. $status = false; 
  295.  
  296. // If feed hasn't changed as reported by the user agent, set 304 status header. 
  297. if ( ! empty( $status ) ) { 
  298. status_header( $status ); 
  299.  
  300. // Cached response, so stop now! 
  301. if ( $status == 304 ) { 
  302. exit(); 
  303.  
  304. /** OUTPUT ***************************************************************/ 
  305.  
  306. /** 
  307. * Output the RSS feed. 
  308. * @since 1.8.0 
  309. */ 
  310. protected function output() { 
  311. $this->http_headers(); 
  312. echo '<?xml version="1.0" encoding="' . get_option( 'blog_charset' ) . '"?'.'>'; 
  313. ?> 
  314.  
  315. <rss version="2.0" 
  316. xmlns:content="http://purl.org/rss/1.0/modules/content/" 
  317. xmlns:atom="http://www.w3.org/2005/Atom" 
  318. xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" 
  319. xmlns:slash="http://purl.org/rss/1.0/modules/slash/" 
  320. <?php 
  321.  
  322. /** 
  323. * Fires at the end of the opening RSS tag for feed output so plugins can add extra attributes. 
  324. * @since 1.8.0 
  325. */ 
  326. do_action( 'bp_activity_feed_rss_attributes' ); ?> 
  327.  
  328. <channel> 
  329. <title><?php echo $this->title; ?></title> 
  330. <link><?php echo $this->link; ?></link> 
  331. <atom:link href="<?php self_link(); ?>" rel="self" type="application/rss+xml" /> 
  332. <description><?php echo $this->description ?></description> 
  333. <lastBuildDate><?php echo mysql2date( 'D, d M Y H:i:s O', bp_activity_get_last_updated(), false ); ?></lastBuildDate> 
  334. <generator>https://buddypress.org/?v=<?php bp_version(); ?></generator> 
  335. <language><?php bloginfo_rss( 'language' ); ?></language> 
  336. <ttl><?php echo $this->ttl; ?></ttl> 
  337. <sy:updatePeriod><?php echo $this->update_period; ?></sy:updatePeriod> 
  338. <sy:updateFrequency><?php echo $this->update_frequency; ?></sy:updateFrequency> 
  339. <?php 
  340.  
  341. /** 
  342. * Fires at the end of channel elements list in RSS feed so plugins can add extra channel elements. 
  343. * @since 1.8.0 
  344. */ 
  345. do_action( 'bp_activity_feed_channel_elements' ); ?> 
  346.  
  347. <?php if ( bp_has_activities( $this->activity_args ) ) : ?> 
  348. <?php while ( bp_activities() ) : bp_the_activity(); ?> 
  349. <item> 
  350. <guid isPermaLink="false"><?php bp_activity_feed_item_guid(); ?></guid> 
  351. <title><?php echo stripslashes( bp_get_activity_feed_item_title() ); ?></title> 
  352. <link><?php bp_activity_thread_permalink() ?></link> 
  353. <pubDate><?php echo mysql2date( 'D, d M Y H:i:s O', bp_get_activity_feed_item_date(), false ); ?></pubDate> 
  354.  
  355. <?php if ( bp_get_activity_feed_item_description() ) : ?> 
  356. <content:encoded><![CDATA[<?php $this->feed_content(); ?>]]></content:encoded> 
  357. <?php endif; ?> 
  358.  
  359. <?php if ( bp_activity_can_comment() ) : ?> 
  360. <slash:comments><?php bp_activity_comment_count(); ?></slash:comments> 
  361. <?php endif; ?> 
  362.  
  363. <?php 
  364.  
  365. /** 
  366. * Fires at the end of the individual RSS Item list in RSS feed so plugins can add extra item elements. 
  367. * @since 1.8.0 
  368. */ 
  369. do_action( 'bp_activity_feed_item_elements' ); ?> 
  370. </item> 
  371. <?php endwhile; ?> 
  372.  
  373. <?php endif; ?> 
  374. </channel> 
  375. </rss><?php