[ 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  
  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  }


Generated: Tue Dec 10 01:01:39 2019 Cross-referenced by PHPXref 0.7.1