Ticket #6772: 6772.03.patch
File 6772.03.patch, 30.4 KB (added by , 9 years ago) |
---|
-
src/bp-activity/bp-activity-actions.php
diff --git src/bp-activity/bp-activity-actions.php src/bp-activity/bp-activity-actions.php index f648b41..18ee4c1 100644
function bp_activity_setup_akismet() { 744 744 $bp->activity->akismet = new BP_Akismet(); 745 745 } 746 746 747 748 /** 749 * Loads our activity oEmbed component. 750 * 751 * @since 2.5.0 752 */ 753 function bp_activity_setup_oembed() { 754 if ( bp_get_major_wp_version() >= 4.4 && bp_is_active( 'activity', 'embeds' ) ) { 755 buddypress()->activity->oembed = new BP_Activity_oEmbed_Component; 756 } 757 } 758 747 759 /** 748 760 * AJAX endpoint for Suggestions API lookups. 749 761 * -
src/bp-activity/bp-activity-loader.php
diff --git src/bp-activity/bp-activity-loader.php src/bp-activity/bp-activity-loader.php index dfdf325..ff8dd0f 100644
class BP_Activity_Component extends BP_Component { 31 31 array( 32 32 'adminbar_myaccount_order' => 10, 33 33 'search_query_arg' => 'activity_search', 34 'features' => array( 'embeds' ) 34 35 ) 35 36 ); 36 37 } … … class BP_Activity_Component extends BP_Component { 67 68 $includes[] = 'akismet'; 68 69 } 69 70 71 // Embeds - only applicable for WP 4.4+ 72 if ( bp_get_major_wp_version() >= 4.4 && bp_is_active( $this->id, 'embeds' ) ) { 73 $includes[] = 'classes/class-bp-activity-oembed-component'; 74 } 75 70 76 if ( is_admin() ) { 71 77 $includes[] = 'admin'; 72 78 } … … class BP_Activity_Component extends BP_Component { 365 371 // Spam prevention. 366 372 add_action( 'bp_include', 'bp_activity_setup_akismet' ); 367 373 374 // oEmbed handler. 375 add_action( 'bp_loaded', 'bp_activity_setup_oembed' ); 376 368 377 parent::setup_actions(); 369 378 } 370 379 -
new file src/bp-activity/classes/class-bp-activity-oembed-component.php
diff --git src/bp-activity/classes/class-bp-activity-oembed-component.php src/bp-activity/classes/class-bp-activity-oembed-component.php new file mode 100644 index 0000000..95d174d
- + 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 require_once( buddypress()->plugin_dir . '/bp-core/classes/class-bp-oembed-component.php' ); 13 14 /** 15 * oEmbed handler to respond and render single activity items. 16 * 17 * @since 2.5.0 18 */ 19 class BP_Activity_oEmbed_Component extends BP_oEmbed_Component { 20 /** 21 * Custom oEmbed slug endpoint. 22 * 23 * @since 2.5.0 24 * 25 * @var string 26 */ 27 public $slug_endpoint = 'activity'; 28 29 /** 30 * Conditional function to determine if we're on our activity page. 31 * 32 * @since 2.5.0 33 * 34 * @var string 35 */ 36 protected $page_conditional_fn = 'bp_is_single_activity'; 37 38 /** 39 * Custom hooks. 40 * 41 * @since 2.5.0 42 */ 43 protected function custom_hooks() { 44 add_action( 'embed_content_meta', array( $this, 'embed_comments_button' ), 5 ); 45 } 46 47 /** 48 * Output our custom embed template part. 49 * 50 * @since 2.5.0 51 */ 52 protected function content() { 53 bp_get_template_part( 'embeds/activity' ); 54 } 55 56 /** 57 * Validates the URL to determine if the activity item is valid. 58 * 59 * @since 2.5.0 60 * 61 * @param string $url The URL to check. 62 * @return int|bool Activity ID on success; boolean false on failure. 63 */ 64 protected function validate_url_to_item_id( $url ) { 65 if ( bp_core_enable_root_profiles() ) { 66 $domain = bp_get_root_domain(); 67 } else { 68 $domain = bp_get_members_directory_permalink(); 69 } 70 71 // Check the URL to see if this is a single activity URL. 72 if ( 0 !== strpos( $url, $domain ) ) { 73 return false; 74 } 75 76 // Check for activity slug. 77 if ( false === strpos( $url, '/' . bp_get_activity_slug() . '/' ) ) { 78 return false; 79 } 80 81 // Do more checks. 82 $url = trim( untrailingslashit( $url ) ); 83 84 // Grab the activity ID. 85 $activity_id = (int) substr( 86 $url, 87 strrpos( $url, '/' ) + 1 88 ); 89 90 if ( ! empty( $activity_id ) ) { 91 // Check if activity item still exists. 92 $activity = new BP_Activity_Activity( $activity_id ); 93 94 // Okay, we're good to go! 95 if ( ! empty( $activity->component ) && 0 === (int) $activity->is_spam ) { 96 return $activity_id; 97 } 98 } 99 100 return false; 101 } 102 103 /** 104 * Sets the oEmbed response data for our activity item. 105 * 106 * @since 2.5.0 107 * 108 * @param int $item_id The activity ID. 109 * @return array 110 */ 111 protected function set_oembed_response_data( $item_id ) { 112 $activity = new BP_Activity_Activity( $item_id ); 113 114 return array( 115 'user_id' => $activity->user_id, 116 'content' => $activity->content, 117 'title' => __( 'Activity', 'buddypress' ), 118 'author_url' => bp_core_get_user_domain( $activity->user_id ) 119 ); 120 } 121 122 /** 123 * Sets a custom <blockquote> for our oEmbed fallback HTML. 124 * 125 * @since 2.5.0 126 * 127 * @param int $item_id The activity ID. 128 * @return string 129 */ 130 protected function set_fallback_html( $item_id ) { 131 $activity = new BP_Activity_Activity( $item_id ); 132 $mentionname = bp_activity_do_mentions() ? ' (@' . bp_activity_get_user_mentionname( $activity->user_id ) . ')' : ''; 133 $date = date_i18n( get_option( 'date_format' ), strtotime( $activity->date_recorded ) ); 134 135 // 'wp-embedded-content' CSS class is necessary due to how the embed JS works. 136 $blockquote = sprintf( '<blockquote class="wp-embedded-content bp-activity-item">%1$s%2$s %3$s</blockquote>', 137 apply_filters( 'bp_get_activity_content_body', $activity->content ), 138 '- ' . bp_core_get_user_displayname( $activity->user_id ) . $mentionname, 139 '<a href="' . esc_url( bp_activity_get_permalink( $item_id ) ) . '">' . $date . '</a>' 140 ); 141 142 /** 143 * Filters the fallback HTML used when embedding a BP activity item. 144 * 145 * @since 2.5.0 146 * 147 * @param string $blockquote Current fallback HTML 148 * @param BP_Activity_Activity $activity Activity object 149 */ 150 return apply_filters( 'bp_activity_embed_fallback_html', $blockquote, $activity ); 151 } 152 153 /** 154 * Sets a custom <iframe> title for our oEmbed item. 155 * 156 * @since 2.5.0 157 * 158 * @param int $item_id The activity ID 159 * @return string 160 */ 161 protected function set_iframe_title( $item_id ) { 162 return __( 'Embedded Activity Item', 'buddypress' ); 163 } 164 165 /** 166 * Prints the markup for the activity embed comments button. 167 * 168 * @since 2.5.0 169 */ 170 public function embed_comments_button() { 171 if ( ! bp_is_single_activity() ) { 172 return; 173 } 174 175 // Make sure our custom permalink shows up in the 'WordPress Embed' block. 176 add_filter( 'the_permalink', array( $this, 'filter_embed_url' ) ); 177 178 // Only show comment bubble if we have some activity comments. 179 $count = bp_activity_get_comment_count(); 180 if ( empty( $count ) ) { 181 return; 182 } 183 ?> 184 185 <div class="wp-embed-comments"> 186 <a href="<?php bp_activity_thread_permalink(); ?>"> 187 <span class="dashicons dashicons-admin-comments"></span> 188 <?php 189 printf( 190 _n( 191 '%s <span class="screen-reader-text">Comment</span>', 192 '%s <span class="screen-reader-text">Comments</span>', 193 $count 194 ), 195 number_format_i18n( $count ) 196 ); 197 ?> 198 </a> 199 </div> 200 201 <?php 202 } 203 } -
src/bp-core/bp-core-functions.php
diff --git src/bp-core/bp-core-functions.php src/bp-core/bp-core-functions.php index f865d7c..8bb63e5 100644
function bp_use_embed_in_private_messages() { 1666 1666 return apply_filters( 'bp_use_embed_in_private_messages', !defined( 'BP_EMBED_DISABLE_PRIVATE_MESSAGES' ) || !BP_EMBED_DISABLE_PRIVATE_MESSAGES ); 1667 1667 } 1668 1668 1669 /** 1670 * Checks a given content to see if a certain media type exists. 1671 * 1672 * @since 2.5.0 1673 * 1674 * @param string $content The content to check. 1675 * @param string $type The type to check. See the class constants in the BP_Media_Extractor class. 1676 * @return bool 1677 */ 1678 function bp_core_check_content_for_media_type( $content = '', $type = 'all' ) { 1679 $retval = false; 1680 1681 $class = new ReflectionClass( 'BP_Media_Extractor' ); 1682 $bitmask = $class->getConstant( strtoupper( $type ) ); 1683 1684 // Type isn't valid, so bail. 1685 if ( empty( $bitmask ) ) { 1686 return false; 1687 } 1688 1689 $x = new BP_Media_Extractor; 1690 $media = $x->extract( $content, $bitmask ); 1691 1692 if ( 'all' === $type ) { 1693 unset( $media['has'] ); 1694 $media = array_filter( $media ); 1695 if ( ! empty( $media ) ) { 1696 $retval = true; 1697 } 1698 } 1699 1700 if ( ! empty( $media[ $type ] ) ) { 1701 $retval = true; 1702 } 1703 1704 return $retval; 1705 } 1706 1669 1707 /** Admin *********************************************************************/ 1670 1708 1671 1709 /** -
src/bp-core/bp-core-theme-compatibility.php
diff --git src/bp-core/bp-core-theme-compatibility.php src/bp-core/bp-core-theme-compatibility.php index da54dce..0de2895 100644
function bp_register_theme_package( $theme = array(), $override = true ) { 650 650 } 651 651 652 652 /** 653 * Create a dummy WP_Post object. 654 * 655 * @since 2.5.0 656 * 657 * @param array $args Array of optional arguments. Arguments parallel the properties 658 * of {@link WP_Post}; see that class for more details. 659 * @return WP_Post 660 */ 661 function bp_theme_compat_create_dummy_post( $args = array() ) { 662 $args = wp_parse_args( $args, array( 663 'ID' => -9999, 664 'post_status' => 'public', 665 'post_author' => 0, 666 'post_parent' => 0, 667 'post_type' => 'page', 668 'post_date' => 0, 669 'post_date_gmt' => 0, 670 'post_modified' => 0, 671 'post_modified_gmt' => 0, 672 'post_content' => '', 673 'post_title' => '', 674 'post_excerpt' => '', 675 'post_content_filtered' => '', 676 'post_mime_type' => '', 677 'post_password' => '', 678 'post_name' => '', 679 'guid' => '', 680 'menu_order' => 0, 681 'pinged' => '', 682 'to_ping' => '', 683 'ping_status' => '', 684 'comment_status' => 'closed', 685 'comment_count' => 0, 686 'filter' => 'raw', 687 688 'is_404' => false, 689 'is_page' => false, 690 'is_single' => false, 691 'is_archive' => false, 692 'is_tax' => false, 693 ) ); 694 695 // Create the dummy post. 696 $post = new WP_Post( (object) $args ); 697 698 return $post; 699 } 700 701 /** 653 702 * Populate various WordPress globals with dummy data to prevent errors. 654 703 * 655 704 * This dummy data is necessary because theme compatibility essentially fakes … … function bp_theme_compat_reset_post( $args = array() ) { 670 719 671 720 // Switch defaults if post is set. 672 721 if ( isset( $wp_query->post ) ) { 673 $ dummy= wp_parse_args( $args, array(722 $args = wp_parse_args( $args, array( 674 723 'ID' => $wp_query->post->ID, 675 724 'post_status' => $wp_query->post->post_status, 676 725 'post_author' => $wp_query->post->post_author, … … function bp_theme_compat_reset_post( $args = array() ) { 695 744 'comment_status' => $wp_query->post->comment_status, 696 745 'comment_count' => $wp_query->post->comment_count, 697 746 'filter' => $wp_query->post->filter, 698 699 'is_404' => false,700 'is_page' => false,701 'is_single' => false,702 'is_archive' => false,703 'is_tax' => false,704 ) );705 } else {706 $dummy = wp_parse_args( $args, array(707 'ID' => -9999,708 'post_status' => 'public',709 'post_author' => 0,710 'post_parent' => 0,711 'post_type' => 'page',712 'post_date' => 0,713 'post_date_gmt' => 0,714 'post_modified' => 0,715 'post_modified_gmt' => 0,716 'post_content' => '',717 'post_title' => '',718 'post_excerpt' => '',719 'post_content_filtered' => '',720 'post_mime_type' => '',721 'post_password' => '',722 'post_name' => '',723 'guid' => '',724 'menu_order' => 0,725 'pinged' => '',726 'to_ping' => '',727 'ping_status' => '',728 'comment_status' => 'closed',729 'comment_count' => 0,730 'filter' => 'raw',731 732 'is_404' => false,733 'is_page' => false,734 'is_single' => false,735 'is_archive' => false,736 'is_tax' => false,737 747 ) ); 738 748 } 739 749 740 750 // Bail if dummy post is empty. 741 if ( empty( $ dummy) ) {751 if ( empty( $args ) ) { 742 752 return; 743 753 } 744 754 745 755 // Set the $post global. 746 $post = new WP_Post( (object) $dummy);756 $post = bp_theme_compat_create_dummy_post( $args ); 747 757 748 758 // Copy the new post global into the main $wp_query. 749 759 $wp_query->post = $post; … … function bp_theme_compat_reset_post( $args = array() ) { 751 761 752 762 // Prevent comments form from appearing. 753 763 $wp_query->post_count = 1; 754 $wp_query->is_404 = $dummy['is_404']; 755 $wp_query->is_page = $dummy['is_page']; 756 $wp_query->is_single = $dummy['is_single']; 757 $wp_query->is_archive = $dummy['is_archive']; 758 $wp_query->is_tax = $dummy['is_tax']; 759 760 // Clean up the dummy post. 761 unset( $dummy ); 764 $wp_query->is_404 = $post->is_404; 765 $wp_query->is_page = $post->is_page; 766 $wp_query->is_single = $post->is_single; 767 $wp_query->is_archive = $post->is_archive; 768 $wp_query->is_tax = $post->is_tax; 762 769 763 770 /** 764 771 * Force the header back to 200 status if not a deliberate 404 -
new file src/bp-core/classes/class-bp-oembed-component.php
diff --git src/bp-core/classes/class-bp-oembed-component.php src/bp-core/classes/class-bp-oembed-component.php new file mode 100644 index 0000000..52dd9c5
- + 1 <?php 2 /** 3 * Core component classes. 4 * 5 * @package BuddyPress 6 * @subpackage Core 7 */ 8 9 // Exit if accessed directly. 10 defined( 'ABSPATH' ) || exit; 11 12 /** 13 * API for responding and returning a custom oEmbed request. 14 * 15 * @since 2.5.0 16 */ 17 abstract class BP_oEmbed_Component { 18 19 /** START PROPERTIES ****************************************************/ 20 21 /** 22 * (required) The slug endpoint. 23 * 24 * Should be your component id. 25 * 26 * @var string 27 */ 28 public $slug_endpoint = ''; 29 30 /** 31 * (required) Callback to determine if you're on the page requiring oEmbed. 32 * 33 * eg. bp_is_single_activity() without the brackets - 'bp_is_single_activity'. 34 * 35 * @var string 36 */ 37 protected $page_conditional_fn = ''; 38 39 /** 40 * (optional) Embed template hierarchy. 41 * 42 * Define the template hierarchy for your oEmbed rendering. 43 * 44 * @var array 45 */ 46 protected $template_hierarchy = array(); 47 48 /** END PROPERTIES ******************************************************/ 49 50 /** 51 * Constructor. 52 */ 53 final public function __construct() { 54 $this->setup_properties(); 55 56 // Some rudimentary logic checking. 57 if ( empty( $this->slug_endpoint ) ) { 58 $class = get_class( $this ); 59 throw new \LogicException( $class . ' class must define $slug_endpoint property' ); 60 } elseif ( empty( $this->page_conditional_fn ) || false === is_callable( $this->page_conditional_fn ) ) { 61 $child = get_class( $this ); 62 throw new \LogicException( $class . ' class must define $page_conditional_fn property or must be callable' ); 63 } 64 65 $this->setup_hooks(); 66 $this->custom_hooks(); 67 } 68 69 /** REQUIRED METHODS ****************************************************/ 70 71 /** 72 * Add content for your oEmbed response here. 73 * 74 * @since 2.5.0 75 */ 76 abstract protected function content(); 77 78 /** 79 * Validate the URL to see if it matches your item ID. 80 * 81 * @since 2.5.0 82 * 83 * @return int Your item ID 84 */ 85 abstract protected function validate_url_to_item_id( $url ); 86 87 /** 88 * Set the oEmbed response data. 89 * 90 * @since 2.5.0 91 * 92 * @param int $item_id Your item ID to do checks against. 93 * @return array Should contain 'user_id', 'content', 'title', 'author_url' as array keys. 94 * 'author_url' is optional; the rest are required. 95 */ 96 abstract protected function set_oembed_response_data( $item_id ); 97 98 /** 99 * Sets the fallback HTML for the oEmbed response. 100 * 101 * In a WordPress oEmbed item, the fallback HTML is a <blockquote>. This is 102 * usually hidden after the <iframe> is loaded. 103 * 104 * @since 2.5.0 105 * 106 * @param int $item_id Your item ID to do checks against. 107 * @return string Fallback HTML you want to output. 108 */ 109 abstract protected function set_fallback_html( $item_id ); 110 111 /** OPTIONAL METHODS ****************************************************/ 112 113 /** 114 * Set permalink for oEmbed link discovery. 115 * 116 * This method will be called on the page we want to oEmbed. Override in your 117 * extended class method if needed. 118 * 119 * @since 2.5.0 120 */ 121 protected function set_permalink() { 122 return bp_get_requested_url(); 123 } 124 125 /** 126 * Set the iframe title. 127 * 128 * If not set, this will fallback to WP's 'Embedded WordPress Post'. 129 * 130 * @param int $item_id The item ID to do checks for. 131 * @return string 132 */ 133 protected function set_iframe_title( $item_id ) {} 134 135 /** 136 * Do what you need to do here to initialize any custom hooks. 137 * 138 * @since 2.5.0 139 */ 140 protected function custom_hooks() {} 141 142 /** SET UP **************************************************************/ 143 144 /** 145 * Set up properties. 146 * 147 * @since 2.5.0 148 */ 149 protected function setup_properties() { 150 $this->slug_endpoint = sanitize_title( $this->slug_endpoint ); 151 } 152 153 /** 154 * Hooks! We do the dirty work here, so you don't have to! :) 155 * 156 * @since 2.5.0 157 */ 158 protected function setup_hooks() { 159 add_action( 'rest_api_init', array( $this, 'register_route' ) ); 160 add_action( 'embed_content', array( $this, 'inject_content' ) ); 161 162 add_filter( 'embed_template', array( $this, 'filter_template' ) ); 163 add_filter( 'post_embed_url', array( $this, 'filter_embed_url' ) ); 164 add_filter( 'embed_html', array( $this, 'filter_embed_html' ) ); 165 add_filter( 'oembed_discovery_links', array( $this, 'add_oembed_discovery_links' ) ); 166 } 167 168 /** HOOKS ***************************************************************/ 169 170 /** 171 * Register the oEmbed REST API route. 172 * 173 * @since 2.5.0 174 */ 175 public function register_route() { 176 /** This filter is documented in wp-includes/class-wp-oembed-controller.php */ 177 $maxwidth = apply_filters( 'oembed_default_width', 600 ); 178 179 register_rest_route( 'oembed/1.0', "/embed/{$this->slug_endpoint}", array( 180 array( 181 'methods' => WP_REST_Server::READABLE, 182 'callback' => array( $this, 'get_item' ), 183 'args' => array( 184 'url' => array( 185 'required' => true, 186 'sanitize_callback' => 'esc_url_raw', 187 ), 188 'format' => array( 189 'default' => 'json', 190 'sanitize_callback' => 'wp_oembed_ensure_format', 191 ), 192 'maxwidth' => array( 193 'default' => $maxwidth, 194 'sanitize_callback' => 'absint', 195 ), 196 ), 197 ), 198 ) ); 199 } 200 201 /** 202 * Filters the embed template. 203 * 204 * Override if needed. 205 * 206 * @since 2.5.0 207 * 208 * @param string $template File path to current embed template. 209 * @return string 210 */ 211 public function filter_template( $template ) { 212 $conditional = $this->page_conditional_fn; 213 214 if ( ! $conditional() || is_404() ) { 215 return $template; 216 } 217 218 // Embed template hierarchy! 219 return bp_locate_template( array( 220 'embeds/template.php' 221 ) ); 222 } 223 224 /** 225 * Adds oEmbed discovery links on single activity pages. 226 * 227 * @since 2.5.0 228 * 229 * @param string $retval Current discovery links. 230 * @return string 231 */ 232 public function add_oembed_discovery_links( $retval ) { 233 $conditional = $this->page_conditional_fn; 234 if ( ! $conditional() ) { 235 return $retval; 236 } 237 238 $permalink = $this->set_permalink(); 239 if ( empty( $permalink ) ) { 240 return $retval; 241 } 242 243 add_filter( 'rest_url' , array( $this, 'filter_rest_url' ) ); 244 245 $retval = '<link rel="alternate" type="application/json+oembed" href="' . esc_url( get_oembed_endpoint_url( $permalink ) ) . '" />' . "\n"; 246 247 if ( class_exists( 'SimpleXMLElement' ) ) { 248 $retval .= '<link rel="alternate" type="text/xml+oembed" href="' . esc_url( get_oembed_endpoint_url( $permalink, 'xml' ) ) . '" />' . "\n"; 249 } 250 251 remove_filter( 'rest_url' , array( $this, 'filter_rest_url' ) ); 252 253 return $retval; 254 } 255 256 /** 257 * Callback for the API endpoint. 258 * 259 * Returns the JSON object for the item. 260 * 261 * @since 2.5.0 262 * 263 * @param WP_REST_Request $request Full data about the request. 264 * @return WP_Error|array oEmbed response data or WP_Error on failure. 265 */ 266 public function get_item( $request ) { 267 $url = $request['url']; 268 269 $data = false; 270 271 $item_id = (int) $this->validate_url_to_item_id( $url ); 272 273 if ( ! empty( $item_id ) ) { 274 $item = $this->set_oembed_response_data( $item_id ); 275 276 // Create dummy post to piggyback off of get_oembed_response_data() 277 $post = bp_theme_compat_create_dummy_post( array( 278 'post_author' => $item['user_id'], 279 'post_title' => $item['title'], 280 'post_content' => $item['content'], 281 282 // This passes the get_oembed_response_data() check. 283 'post_status' => 'publish' 284 ) ); 285 286 // Add markers to tell that we're embedding a single activity. 287 // This is needed for various oEmbed response data filtering. 288 if ( empty( buddypress()->{$this->slug_endpoint} ) ) { 289 buddypress()->$this->slug_endpoint = new stdClass; 290 } 291 buddypress()->{$this->slug_endpoint}->embedurl_in_progress = $url; 292 buddypress()->{$this->slug_endpoint}->embedid_in_progress = $item_id; 293 294 // Use WP's oEmbed response data function. 295 $data = get_oembed_response_data( $post, $request['maxwidth'] ); 296 297 // Set custom 'author_url' if we have one. 298 if ( ! empty( $item['author_url'] ) ) { 299 $data['author_url'] = $item['author_url']; 300 } 301 } 302 303 if ( ! $data ) { 304 return new WP_Error( 'oembed_invalid_url', get_status_header_desc( 404 ), array( 'status' => 404 ) ); 305 } 306 307 return $data; 308 } 309 310 /** 311 * Pass our BuddyPress activity permalink for embedding. 312 * 313 * @since 2.5.0 314 * 315 * @see bp_activity_embed_rest_route_callback() 316 * 317 * @param string $retval Current embed URL 318 * @return string 319 */ 320 public function filter_embed_url( $retval ) { 321 $conditional = $this->page_conditional_fn; 322 if ( false === isset( buddypress()->{$this->slug_endpoint}->embedurl_in_progress ) && ! $conditional() ) { 323 return $retval; 324 } 325 326 $url = $conditional() ? $this->set_permalink() : buddypress()->{$this->slug_endpoint}->embedurl_in_progress; 327 $url = trailingslashit( $url ); 328 329 // This is for the 'WordPress Embed' block 330 // @see bp_activity_embed_comments_button() 331 if ( 'the_permalink' !== current_filter() ) { 332 $url = add_query_arg( 'embed', 'true', trailingslashit( $url ) ); 333 } 334 335 return $url; 336 } 337 338 /** 339 * Filters the embed HTML for the default oEmbed fallback HTML. 340 * 341 * @since 2.5.0 342 * 343 * @param string $retval Current embed HTML 344 * @return string 345 */ 346 public function filter_embed_html( $retval ) { 347 $conditional = $this->page_conditional_fn; 348 if ( false === isset( buddypress()->{$this->slug_endpoint}->embedurl_in_progress ) && ! $conditional() ) { 349 return $retval; 350 } 351 352 // Remove querystring from URL 353 $url = substr( bp_get_requested_url(), 0, strpos( bp_get_requested_url(), '?' ) ); 354 355 $item_id = $conditional() ? $this->validate_url_to_item_id( $url ) : buddypress()->{$this->slug_endpoint}->embedid_in_progress; 356 357 // Change 'Embedded WordPress Post' to custom title. 358 $custom_title = $this->set_iframe_title( $item_id ); 359 if ( ! empty( $custom_title ) ) { 360 $retval = str_replace( __( 'Embedded WordPress Post' ), esc_attr( $custom_title ), $retval ); 361 } 362 363 // Remove default <blockquote> 364 $retval = substr( $retval, strpos( $retval, '</blockquote>' ) + 13 ); 365 366 // Set up new fallback HTML 367 // @todo Maybe use KSES? 368 $fallback_html = $this->set_fallback_html( $item_id ); 369 370 // Add our custom <blockquote> 371 return $fallback_html . $retval; 372 } 373 374 /** 375 * Append our custom slug endpoint to oEmbed endpoint URL. 376 * 377 * Meant to be used as a filter on 'rest_url' before any call to 378 * {@link get_oembed_endpoint_url()} is used. 379 * 380 * @since 2.5.0 381 * 382 * @see add_oembed_discovery_links() 383 * 384 * @param string $retval Current oEmbed endpoint URL 385 * @return string 386 */ 387 function filter_rest_url( $retval = '' ) { 388 return $retval . "/{$this->slug_endpoint}"; 389 } 390 391 /** 392 * Inject activity content into the embed template. 393 * 394 * @since 2.5.0 395 */ 396 public function inject_content() { 397 $conditional = $this->page_conditional_fn; 398 if ( ! $conditional() ) { 399 return; 400 } 401 402 $this->content(); 403 } 404 } 405 No newline at end of file -
new file src/bp-templates/bp-legacy/buddypress/embeds/activity.php
diff --git src/bp-templates/bp-legacy/buddypress/embeds/activity.php src/bp-templates/bp-legacy/buddypress/embeds/activity.php new file mode 100644 index 0000000..589fad2
- + 1 2 <?php if ( bp_has_activities( 'display_comments=threaded&show_hidden=true&include=' . bp_current_action() ) ) : ?> 3 4 <?php while ( bp_activities() ) : bp_the_activity(); ?> 5 <div class="wp-embed-excerpt"><?php bp_activity_content_body(); ?></div> 6 7 <p><a href="<?php bp_activity_thread_permalink(); ?>"><?php echo date_i18n( get_option( 'time_format' ) . ' - ' . get_option( 'date_format' ), strtotime( bp_get_activity_date_recorded() ) ); ?></a></p> 8 9 <?php 10 // Add inline JS for responsive IFRAMES if an embed is detected. 11 if ( bp_core_check_content_for_media_type( $GLOBALS['activities_template']->activity->content, 'embeds' ) ) { 12 ?> 13 14 <script> 15 /*! fluidvids.js v1.2.0 | (c) 2013 @toddmotto | https://github.com/toddmotto/fluidvids */ 16 window.fluidvids=function(a,b){"use strict";var c=function(a){this.elem=a};c.prototype={init:function(){var a=100*(this.elem.height/this.elem.width);this.elem.style.position="absolute",this.elem.style.top="0",this.elem.style.left="0",this.elem.width="100%",this.elem.height="100%";var c=b.createElement("div");c.className="fluidvids",c.style.width="100%",c.style.position="relative",c.style.paddingTop=a+"%";var d=this.elem.parentNode;d.insertBefore(c,this.elem),c.appendChild(this.elem)}};for(var d=b.getElementsByTagName("iframe"),e=0;e<d.length;e++){d[e].src&&new c(d[e]).init()}}(window,document); 17 </script> 18 19 <?php 20 } 21 ?> 22 23 <?php endwhile; ?> 24 25 <?php endif; ?> 26 -
new file src/bp-templates/bp-legacy/buddypress/embeds/css.php
diff --git src/bp-templates/bp-legacy/buddypress/embeds/css.php src/bp-templates/bp-legacy/buddypress/embeds/css.php new file mode 100644 index 0000000..129c877
- + 1 <style type="text/css"> 2 #wp-embed-header:after { 3 clear: both; 4 content: ""; 5 display: table; 6 margin-bottom: 1em; 7 } 8 9 .wp-embed-avatar { 10 float: left; 11 margin: 0 .75em 0 0; 12 } 13 14 p.wp-embed-heading { 15 font-size: 16px; 16 margin-bottom: 0; 17 } 18 19 .wp-embed-excerpt { 20 margin-bottom: .5em; 21 } 22 23 .wp-embed-footer { 24 margin-top: 20px; 25 } 26 </style> 27 No newline at end of file -
new file src/bp-templates/bp-legacy/buddypress/embeds/footer.php
diff --git src/bp-templates/bp-legacy/buddypress/embeds/footer.php src/bp-templates/bp-legacy/buddypress/embeds/footer.php new file mode 100644 index 0000000..22de696
- + 1 <div class="wp-embed-footer"> 2 <div class="wp-embed-site-title"> 3 <?php 4 $site_title = sprintf( 5 '<a href="%s"><img src="%s" srcset="%s 2x" width="32" height="32" alt="" class="wp-embed-site-icon"/><span>%s</span></a>', 6 esc_url( home_url() ), 7 esc_url( get_site_icon_url( 32, admin_url( 'images/w-logo-blue.png' ) ) ), 8 esc_url( get_site_icon_url( 64, admin_url( 'images/w-logo-blue.png' ) ) ), 9 esc_html( get_bloginfo( 'name' ) ) 10 ); 11 12 /** 13 * Filter the site title HTML in the embed footer. 14 * 15 * @since 4.4.0 16 * 17 * @param string $site_title The site title HTML. 18 */ 19 echo apply_filters( 'embed_site_title_html', $site_title ); 20 ?> 21 </div> 22 23 <div class="wp-embed-meta"> 24 <?php 25 /** 26 * Print additional meta content in the embed template. 27 * 28 * @since 4.4.0 29 */ 30 do_action( 'embed_content_meta'); 31 ?> 32 </div> 33 </div> 34 No newline at end of file -
new file src/bp-templates/bp-legacy/buddypress/embeds/header.php
diff --git src/bp-templates/bp-legacy/buddypress/embeds/header.php src/bp-templates/bp-legacy/buddypress/embeds/header.php new file mode 100644 index 0000000..7a4bc8a
- + 1 2 <div id="wp-embed-header"> 3 <div class="wp-embed-avatar"> 4 <a href="<?php bp_displayed_user_link(); ?>"> 5 <?php bp_displayed_user_avatar( 'type=thumb&width=36&height=36' ); ?> 6 </a> 7 </div> 8 9 <p class="wp-embed-heading"> 10 <a href="<?php bp_displayed_user_link(); ?>"> 11 <?php bp_displayed_user_fullname(); ?> 12 </a> 13 </p> 14 15 <?php if ( bp_is_active( 'activity' ) && bp_activity_do_mentions() ) : ?> 16 <p class="wp-embed-mentionname">@<?php bp_displayed_user_mentionname(); ?></p> 17 <?php endif; ?> 18 </div> -
new file src/bp-templates/bp-legacy/buddypress/embeds/template.php
diff --git src/bp-templates/bp-legacy/buddypress/embeds/template.php src/bp-templates/bp-legacy/buddypress/embeds/template.php new file mode 100644 index 0000000..cb681df
- + 1 <?php 2 /** 3 * Generic embed template used by BuddyPress. 4 * 5 * When a BuddyPress item is embedded in an iframe, this file is used to 6 * create the output. 7 * 8 * This is a modified version of the bundled WordPress embed template 9 * included in WordPress 4.4+. 10 * 11 * @since 2.5.0 12 * 13 * @package BuddyPress 14 * @subpackage Embeds 15 */ 16 17 if ( ! headers_sent() ) { 18 header( 'X-WP-embed: true' ); 19 } 20 21 ?> 22 <!DOCTYPE html> 23 <html <?php language_attributes(); ?> class="no-js"> 24 <head> 25 <title><?php echo wp_get_document_title(); ?></title> 26 <meta http-equiv="X-UA-Compatible" content="IE=edge"> 27 <base target="_top" /> 28 <?php 29 /** This action is documented in wp-includes/embed-template.php */ 30 do_action( 'embed_head' ); 31 32 // This is used by r-a-y for testing purposes at the moment. 33 bp_get_template_part( 'embeds/css' ); 34 ?> 35 </head> 36 <body <?php body_class(); ?>> 37 <div <?php post_class( 'wp-embed' ); ?>> 38 <?php 39 bp_get_template_part( 'embeds/header', bp_current_component() ); 40 41 /** This action is documented in wp-includes/embed-template.php */ 42 do_action( 'embed_content' ); 43 44 bp_get_template_part( 'embeds/footer', bp_current_component() ); 45 ?> 46 47 </div> 48 49 <?php 50 /** This action is documented in wp-includes/embed-template.php */ 51 do_action( 'embed_footer' ); 52 ?> 53 </body> 54 </html> 55 No newline at end of file