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