[ Index ]

PHP Cross Reference of BuddyPress

title

Body

[close]

/src/bp-activity/classes/ -> class-bp-activity-feed.php (source)

   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  }


Generated: Sun Oct 24 01:00:54 2021 Cross-referenced by PHPXref 0.7.1