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