BP_Activity_oEmbed_Extension

OEmbed handler to respond and render single activity items.

Defined (1)

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

/bp-activity/classes/class-bp-activity-oembed-extension.php  
  1. class BP_Activity_oEmbed_Extension extends BP_Core_oEmbed_Extension { 
  2. /** 
  3. * Custom oEmbed slug endpoint. 
  4. * @since 2.6.0 
  5. * @var string 
  6. */ 
  7. public $slug_endpoint = 'activity'; 
  8.  
  9. /** 
  10. * Custom hooks. 
  11. * @since 2.6.0 
  12. */ 
  13. protected function custom_hooks() { 
  14. add_action( 'oembed_dataparse', array( $this, 'use_custom_iframe_sandbox_attribute' ), 20, 3 ); 
  15. add_action( 'embed_content_meta', array( $this, 'embed_comments_button' ), 5 ); 
  16. add_action( 'get_template_part_assets/embeds/header', array( $this, 'on_activity_header' ), 10, 2 ); 
  17.  
  18. add_filter( 'bp_activity_embed_html', array( $this, 'modify_iframe' ) ); 
  19.  
  20. /** 
  21. * Add custom endpoint arguments. 
  22. * Currently, includes 'hide_media'. 
  23. * @since 2.6.0 
  24. * @return array 
  25. */ 
  26. protected function set_route_args() { 
  27. return array( 
  28. 'hide_media' => array( 
  29. 'default' => false,  
  30. 'sanitize_callback' => 'wp_validate_boolean' 
  31. ); 
  32.  
  33. /** 
  34. * Output our custom embed template part. 
  35. * @since 2.6.0 
  36. */ 
  37. protected function content() { 
  38. bp_get_asset_template_part( 'embeds/activity' ); 
  39.  
  40. /** 
  41. * Check if we're on our single activity page. 
  42. * @since 2.6.0 
  43. * @return bool 
  44. */ 
  45. protected function is_page() { 
  46. return bp_is_single_activity(); 
  47.  
  48. /** 
  49. * Validates the URL to determine if the activity item is valid. 
  50. * @since 2.6.0 
  51. * @param string $url The URL to check. 
  52. * @return int|bool Activity ID on success; boolean false on failure. 
  53. */ 
  54. protected function validate_url_to_item_id( $url ) { 
  55. if ( bp_core_enable_root_profiles() ) { 
  56. $domain = bp_get_root_domain(); 
  57. } else { 
  58. $domain = bp_get_members_directory_permalink(); 
  59.  
  60. // Check the URL to see if this is a single activity URL. 
  61. if ( 0 !== strpos( $url, $domain ) ) { 
  62. return false; 
  63.  
  64. // Check for activity slug. 
  65. if ( false === strpos( $url, '/' . bp_get_activity_slug() . '/' ) ) { 
  66. return false; 
  67.  
  68. // Do more checks. 
  69. $url = trim( untrailingslashit( $url ) ); 
  70.  
  71. // Grab the activity ID. 
  72. $activity_id = (int) substr( 
  73. $url,  
  74. strrpos( $url, '/' ) + 1 
  75. ); 
  76.  
  77. if ( ! empty( $activity_id ) ) { 
  78. // Check if activity item still exists. 
  79. $activity = new BP_Activity_Activity( $activity_id ); 
  80.  
  81. // Okay, we're good to go! 
  82. if ( ! empty( $activity->component ) && 0 === (int) $activity->is_spam ) { 
  83. return $activity_id; 
  84.  
  85. return false; 
  86.  
  87. /** 
  88. * Sets the oEmbed response data for our activity item. 
  89. * @since 2.6.0 
  90. * @param int $item_id The activity ID. 
  91. * @return array 
  92. */ 
  93. protected function set_oembed_response_data( $item_id ) { 
  94. $activity = new BP_Activity_Activity( $item_id ); 
  95.  
  96. return array( 
  97. 'content' => $activity->content,  
  98. 'title' => __( 'Activity', 'buddypress' ),  
  99. 'author_name' => bp_core_get_user_displayname( $activity->user_id ),  
  100. 'author_url' => bp_core_get_user_domain( $activity->user_id ),  
  101.  
  102. // Custom identifier. 
  103. 'x_buddypress' => 'activity' 
  104. ); 
  105.  
  106. /** 
  107. * Sets a custom <blockquote> for our oEmbed fallback HTML. 
  108. * @since 2.6.0 
  109. * @param int $item_id The activity ID. 
  110. * @return string 
  111. */ 
  112. protected function set_fallback_html( $item_id ) { 
  113. $activity = new BP_Activity_Activity( $item_id ); 
  114. $mentionname = bp_activity_do_mentions() ? ' (@' . bp_activity_get_user_mentionname( $activity->user_id ) . ')' : ''; 
  115. $date = date_i18n( get_option( 'date_format' ), strtotime( $activity->date_recorded ) ); 
  116.  
  117. // Make sure we can use some activity functions that depend on the loop. 
  118. $GLOBALS['activities_template'] = new stdClass; 
  119. $GLOBALS['activities_template']->activity = $activity; 
  120.  
  121. // 'wp-embedded-content' CSS class is necessary due to how the embed JS works. 
  122. $blockquote = sprintf( '<blockquote class="wp-embedded-content bp-activity-item">%1$s%2$s %3$s</blockquote>',  
  123. bp_activity_get_embed_excerpt( $activity->content ),  
  124. '- ' . bp_core_get_user_displayname( $activity->user_id ) . $mentionname,  
  125. '<a href="' . esc_url( bp_activity_get_permalink( $item_id ) ) . '">' . $date . '</a>' 
  126. ); 
  127.  
  128. // Clean up. 
  129. unset( $GLOBALS['activities_template'] ); 
  130.  
  131. /** 
  132. * Filters the fallback HTML used when embedding a BP activity item. 
  133. * @since 2.6.0 
  134. * @param string $blockquote Current fallback HTML 
  135. * @param BP_Activity_Activity $activity Activity object 
  136. */ 
  137. return apply_filters( 'bp_activity_embed_fallback_html', $blockquote, $activity ); 
  138.  
  139. /** 
  140. * Sets a custom <iframe> title for our oEmbed item. 
  141. * @since 2.6.0 
  142. * @param int $item_id The activity ID 
  143. * @return string 
  144. */ 
  145. protected function set_iframe_title( $item_id ) { 
  146. return __( 'Embedded Activity Item', 'buddypress' ); 
  147.  
  148. /** 
  149. * Use our custom <iframe> sandbox attribute in our oEmbed response. 
  150. * WordPress sets the <iframe> sandbox attribute to 'allow-scripts' regardless 
  151. * of whatever the oEmbed response is in {@link wp_filter_oembed_result()}. We 
  152. * need to add back our custom sandbox value so links will work. 
  153. * @since 2.6.0 
  154. * @see BP_Activity_Component::modify_iframe() where our custom sandbox value is set. 
  155. * @param string $result The oEmbed HTML result. 
  156. * @param object $data A data object result from an oEmbed provider. 
  157. * @param string $url The URL of the content to be embedded. 
  158. * @return string 
  159. */ 
  160. public function use_custom_iframe_sandbox_attribute( $result, $data, $url ) { 
  161. // Make sure we are on a BuddyPress activity oEmbed request. 
  162. if ( false === isset( $data->x_buddypress ) || 'activity' !== $data->x_buddypress ) { 
  163. return $result; 
  164.  
  165. // Get unfiltered sandbox attribute from our own oEmbed response. 
  166. $sandbox_pos = strpos( $data->html, 'sandbox=' ) + 9; 
  167. $sandbox = substr( $data->html, $sandbox_pos, strpos( $data->html, '"', $sandbox_pos ) - $sandbox_pos ); 
  168.  
  169. // Replace only if our sandbox attribute contains 'allow-top-navigation'. 
  170. if ( false !== strpos( $sandbox, 'allow-top-navigation' ) ) { 
  171. $result = str_replace( ' sandbox="allow-scripts"', " sandbox=\"{$sandbox}\"", $result ); 
  172.  
  173. // Also remove 'security' attribute; this is only used for IE < 10. 
  174. $result = str_replace( 'security="restricted"', "", $result ); 
  175.  
  176. return $result; 
  177.  
  178. /** 
  179. * Modify various IFRAME-related items if embeds are allowed. 
  180. * HTML modified: 
  181. * - Add sandbox="allow-top-navigation" attribute. This allows links to work 
  182. * within the iframe sandbox attribute. 
  183. * JS modified: 
  184. * - Remove IFRAME height restriction of 1000px. Fixes long embed items being 
  185. * truncated. 
  186. * @since 2.6.0 
  187. * @param string $retval Current embed HTML. 
  188. * @return string 
  189. */ 
  190. public function modify_iframe( $retval ) { 
  191. // Add 'allow-top-navigation' to allow links to be clicked. 
  192. $retval = str_replace( 'sandbox="', 'sandbox="allow-top-navigation ', $retval ); 
  193.  
  194. // See /wp-includes/js/wp-embed.js. 
  195. if ( SCRIPT_DEBUG ) { 
  196. // Removes WP's hardcoded IFRAME height restriction. 
  197. $retval = str_replace( 'height = 1000;', 'height = height;', $retval ); 
  198.  
  199. // This is for the WP build minified version. 
  200. } else { 
  201. $retval = str_replace( 'g=1e3', 'g=g', $retval ); 
  202.  
  203. return $retval; 
  204.  
  205. /** 
  206. * Do stuff when our oEmbed activity header template part is loading. 
  207. * Currently, removes wpautop() from the bp_activity_action() function. 
  208. * @since 2.6.0 
  209. * @param string $slug Template part slug requested. 
  210. * @param string $name Template part name requested. 
  211. */ 
  212. public function on_activity_header( $slug, $name ) { 
  213. if ( false === $this->is_page() || 'activity' !== $name ) { 
  214. return; 
  215.  
  216. remove_filter( 'bp_get_activity_action', 'wpautop' ); 
  217.  
  218. /** 
  219. * Prints the markup for the activity embed comments button. 
  220. * Basically a copy of {@link print_embed_comments_button()}, but modified for 
  221. * the BP activity component. 
  222. * @since 2.6.0 
  223. */ 
  224. public function embed_comments_button() { 
  225. if ( ! did_action( 'bp_embed_content' ) || ! bp_is_single_activity() ) { 
  226. return; 
  227.  
  228. // Make sure our custom permalink shows up in the 'WordPress Embed' block. 
  229. add_filter( 'the_permalink', array( $this, 'filter_embed_url' ) ); 
  230.  
  231. // Only show comment bubble if we have some activity comments. 
  232. $count = bp_activity_get_comment_count(); 
  233. if ( empty( $count ) ) { 
  234. return; 
  235. ?> 
  236.  
  237. <div class="wp-embed-comments"> 
  238. <a href="<?php bp_activity_thread_permalink(); ?>"> 
  239. <span class="dashicons dashicons-admin-comments"></span> 
  240. <?php 
  241. printf( 
  242. _n( 
  243. /** translators: accessibility text */ 
  244. '%s <span class="screen-reader-text">Comment</span>',  
  245. /** translators: accessibility text */ 
  246. '%s <span class="screen-reader-text">Comments</span>',  
  247. $count,  
  248. 'buddypress' 
  249. ),  
  250. number_format_i18n( $count ) 
  251. ); 
  252. ?> 
  253. </a> 
  254. </div> 
  255.  
  256. <?php