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