diff --git a/js/modules/aioseop_module.js b/js/modules/aioseop_module.js index da1319074..fcbaa4955 100644 --- a/js/modules/aioseop_module.js +++ b/js/modules/aioseop_module.js @@ -855,7 +855,12 @@ function aioseop_overflow_border( el ) { } function aiospinitAll(){ - if ( jQuery( '.aiseop-date' ).length > 0 && jQuery( '.aiseop-date' ).eq( 0 ).prop( 'type' ).toLowerCase() === 'text' ) { + aiospinitSocialMetaInPosts(jQuery); + aiospinitCalendar(); +} + +function aiospinitCalendar(){ + if ( jQuery( '.aiseop-date' ).length > 0 && jQuery( '.aiseop-date' ).eq( 0 ).prop( 'type' ).toLowerCase() === 'text' ) { jQuery( '.aiseop-date' ).datepicker( { dateFormat: "yy-mm-dd" @@ -864,6 +869,15 @@ function aiospinitAll(){ } } +function aiospinitSocialMetaInPosts($) { + // clear the radio buttons when the user clicks the upload button. + $('input[name="aioseop_opengraph_settings_customimg_checker"] ~ .aioseop_upload_image_button').on('click', function(e){ + $('input[name="aioseop_opengraph_settings_image"]').attr('checked', false); + }); +} + + + function aiospinitCounting(){ /* count them characters */ jQuery( '.aioseop_count_chars' ).on('keyup keydown', function(){ diff --git a/modules/aioseop_sitemap.php b/modules/aioseop_sitemap.php index b5ccfcb46..c08c65312 100644 --- a/modules/aioseop_sitemap.php +++ b/modules/aioseop_sitemap.php @@ -2808,16 +2808,9 @@ private function get_images_from_post( $post ) { $content = ''; $content = $post->post_content; - // Check images galleries in the content. DO NOT run the_content filter here as it might cause issues with other shortcodes. - if ( has_shortcode( $content, 'gallery' ) ) { - $galleries = get_post_galleries( $post, false ); - if ( $galleries ) { - foreach ( $galleries as $gallery ) { - $images = array_merge( $images, $gallery['src'] ); - } - } - } + $this->get_gallery_images( $post, $images ); + $content .= $this->get_content_from_galleries( $content ); $this->parse_content_for_images( $content, $images ); if ( $images ) { @@ -2839,6 +2832,128 @@ private function get_images_from_post( $post ) { return $images; } + /** + * Fetch images from WP, Jetpack and WooCommerce galleries. + * + * @param string $post The post. + * @param array $images the array of images. + * + * @since 2.4.2 + */ + private function get_gallery_images( $post, &$images ) { + if ( false === apply_filters( 'aioseo_include_images_in_wp_gallery', true ) ) { + return; + } + + // Check images galleries in the content. DO NOT run the_content filter here as it might cause issues with other shortcodes. + if ( has_shortcode( $post->post_content, 'gallery' ) ) { + // Get the jetpack gallery images. + if ( class_exists( 'Jetpack_PostImages' ) ) { + $jetpack = Jetpack_PostImages::get_images( $post->ID ); + if ( $jetpack ) { + foreach ( $jetpack as $jetpack_image ) { + $images[] = $jetpack_image['src']; + } + } + } + + // Get the default WP gallery images. + $galleries = get_post_galleries( $post, false ); + if ( $galleries ) { + foreach ( $galleries as $gallery ) { + $images = array_merge( $images, $gallery['src'] ); + } + } + } + + // Check WooCommerce product gallery. + if ( class_exists( 'WooCommerce' ) ) { + $woo_images = get_post_meta( $post->ID, '_product_image_gallery', true ); + if ( ! empty( $woo_images ) ) { + $woo_images = array_filter( explode( ',', $woo_images ) ); + if ( is_array( $woo_images ) ) { + foreach ( $woo_images as $id ) { + $images[] = wp_get_attachment_url( $id ); + } + } + } + } + + $images = array_unique( $images ); + } + + /** + * Parses the content to find out if specified images galleries exist and if they do, parse them for images. + * Supports NextGen. + * + * @param string $content The post content. + * + * @since 2.4.2 + * + * @return string + */ + private function get_content_from_galleries( $content ) { + // Support for NextGen Gallery. + static $gallery_types = array( 'ngg_images' ); + $types = apply_filters( 'aioseop_gallery_shortcodes', $gallery_types ); + + $gallery_content = ''; + + if ( ! $types ) { + return $gallery_content; + } + + $found = array(); + if ( $types ) { + foreach ( $types as $type ) { + if ( has_shortcode( $content, $type ) ) { + $found[] = $type; + } + } + } + + // If none of the shortcodes-of-interest are found, bail. + if ( empty( $found ) ) { + return $gallery_content; + } + + $galleries = array(); + + if ( ! preg_match_all( '/' . get_shortcode_regex() . '/s', $content, $matches, PREG_SET_ORDER ) ) { + return $gallery_content; + } + + // Collect the shortcodes and their attributes. + foreach ( $found as $type ) { + foreach ( $matches as $shortcode ) { + if ( $type === $shortcode[2] ) { + + $attributes = shortcode_parse_atts( $shortcode[3] ); + + if ( '' === $attributes ) { // Valid shortcode without any attributes. + $attributes = array(); + } + + $galleries[ $shortcode[2] ] = $attributes; + } + } + } + + // Recreate the shortcodes and then render them to get the HTML content. + if ( $galleries ) { + foreach ( $galleries as $shortcode => $attributes ) { + $code = '[' . $shortcode; + foreach ( $attributes as $key => $value ) { + $code .= " $key=$value"; + } + $code .= ']'; + $gallery_content .= do_shortcode( $code ); + } + } + + return $gallery_content; + } + /** * Cleans the URL so that its acceptable in the sitemap. * diff --git a/tests/modules/sitemap/test-sitemap.php b/tests/modules/sitemap/test-sitemap.php index df10a2cd0..8aef7735a 100644 --- a/tests/modules/sitemap/test-sitemap.php +++ b/tests/modules/sitemap/test-sitemap.php @@ -125,6 +125,53 @@ public function test_exclude_images() { ); } + /** + * Add WooCommerce product gallery images to XML sitemap. + * + * @ticket 366 Add WooCommerce product gallery images to XML sitemap + */ + public function test_woocommerce_gallery() { + $woo = 'woocommerce/woocommerce.php'; + $file = dirname( dirname( AIOSEOP_UNIT_TESTING_DIR ) ) . '/'; + + if ( ! file_exists( $file . $woo ) ) { + $this->markTestSkipped( 'WooCommerce not installed. Skipping.' ); + } + + $this->plugin_to_load = $file . $woo; + tests_add_filter( 'muplugins_loaded', array( $this, 'filter_muplugins_loaded' ) ) ; + + activate_plugin( $woo ); + + if ( ! is_plugin_active( $woo ) ) { + $this->markTestSkipped( 'WooCommerce not activated. Skipping.' ); + } + + // create 4 attachments. + $attachments = array(); + for ( $x = 0; $x < 4; $x++ ) { + $attachments[] = $this->upload_image_and_maybe_attach( str_replace( '\\', '/', AIOSEOP_UNIT_TESTING_DIR . '/resources/images/footer-logo.png' ) ); + } + + $id = $this->factory->post->create( array( 'post_type' => 'product' ) ); + update_post_meta( $id, '_product_image_gallery', implode( ',', $attachments ) ); + $url = get_permalink( $id ); + + $custom_options = array(); + $custom_options['aiosp_sitemap_indexes'] = ''; + $custom_options['aiosp_sitemap_images'] = ''; + $custom_options['aiosp_sitemap_gzipped'] = ''; + $custom_options['aiosp_sitemap_posttypes'] = array( 'product' ); + $this->_setup_options( 'sitemap', $custom_options ); + $this->validate_sitemap( + array( + $url => array( + 'image' => true, + ), + ) + ); + } + /** * Adds posts to taxonomies, enables only taxonomies in the sitemap. */ @@ -165,6 +212,13 @@ public function test_only_taxonomies() { ); } + /** + * Loads the specified plugin. + */ + public function filter_muplugins_loaded() { + require $this->plugin_to_load; + } + /** * @requires PHPUnit 5.7 * Creates posts with schemeless images in the content and checks if they are being correctly included in the sitemap.