示例#1
0
/**
 * Filter function that generates and embeds Schema.org metadata in the content.
 */
function amt_add_schemaorg_metadata_content_filter($post_body)
{
    if (apply_filters('amt_exclude_schemaorg_metadata', false)) {
        return $post_body;
    }
    // For AMT timings
    $t = microtime(true);
    // Get the options the DB
    $options = get_option("add_meta_tags_opts");
    // Get current post object
    $post = amt_get_queried_object();
    // Caching indicator
    $is_cached = 'no';
    // First, try to get cached metadata. Cache must be cleared if settings have changed.
    if (absint($options['transient_cache_expiration']) > 0 && apply_filters('amt_enable_metadata_cache_in_content_filter', true)) {
        $cached_content_metadata_arr = amt_get_transient_cache($post, $options, $where = 'content');
        if (!empty($cached_content_metadata_arr)) {
            $is_cached = 'yes';
            // For AMT timings
            if ($options['enable_timings'] == '1') {
                array_unshift($cached_content_metadata_arr, sprintf('<!-- Add-Meta-Tags Timings (milliseconds) - Block total time: %.3f msec - Cached: %s -->', (microtime(true) - $t) * 1000, $is_cached));
            }
            // Add our comment
            if ($options["omit_vendor_html_comments"] == "0") {
                array_unshift($cached_content_metadata_arr, "<!-- BEGIN Schema.org microdata added by the Add-Meta-Tags WordPress plugin -->");
            }
            array_unshift($cached_content_metadata_arr, "");
            // Intentionaly left empty
            if ($options["omit_vendor_html_comments"] == "0") {
                array_push($cached_content_metadata_arr, "<!-- END Schema.org microdata added by the Add-Meta-Tags WordPress plugin -->");
            }
            array_push($cached_content_metadata_arr, "");
            // Intentionaly left empty
            //
            // Non persistent cache for metadata review mode.
            //
            // The review mode's content filter should have bigger priority than this
            // filter (be executed after this one). This one by default has priority 9999
            // while the review mode filter has priority of 10000
            if (amt_check_run_metadata_review_code($options)) {
                // What happens here is this: we copy the metadata array and remove the
                // item that contains the content data, because it is not needed for
                // metadata review.
                // Then use non-persistent cache to store this new array.
                // Metadata Review mode's filtering function should be attached with a
                // priority bigger than this one, so that it is executed after this one.
                // There the data is loaded from the non-persistent cache.
                // This way, the timings are the same as in the source code and also
                // it is more efficient from a resources perspective.
                // WARNING: in order to work fine, set correct filter priorities.
                $metadata_arr_for_review = $cached_content_metadata_arr;
                if (array_key_exists('content_data', $metadata_arr_for_review)) {
                    $metadata_arr_for_review['content_data'] = '    <!-- The content has been removed from the metadata review. -->';
                }
                wp_cache_add('amt_cache_metadata_block_content_filter', $metadata_arr_for_review, $group = 'add-meta-tags');
                unset($metadata_arr_for_review);
            }
            // Return cached metadata (contains the post body)
            return implode(PHP_EOL, $cached_content_metadata_arr);
        }
    }
    $do_auto_schemaorg = $options["auto_schemaorg"] == "1" ? true : false;
    if (!$do_auto_schemaorg) {
        return $post_body;
    }
    // Check if the microdata or the JSON-LD schema.org generator should be used.
    if ($options["schemaorg_force_jsonld"] == "1") {
        return $post_body;
    }
    // Check for AMP page https://www.ampproject.org/
    // For AMP pages we do not generate Schema.org microdata around the post content,
    // but enforce the JSON+LD form.
    if ($do_auto_schemaorg && function_exists('is_amp_endpoint') && is_amp_endpoint()) {
        return $post_body;
    }
    if (is_feed()) {
        return $post_body;
    }
    if (!is_singular() || is_front_page()) {
        // is_front_page() is used for the case in which a static page is used as the front page.
        // In this filter function we only deal with content and attachments.
        return $post_body;
    }
    // Additional check to make sure we have a post.
    if ($post->ID == 0) {
        // Can happen with some BuddyPress pages (eg member page)
        return $post_body;
    }
    $metadata_arr = array();
    // Since this is a function that is hooked to the 'the_content' filter
    // of WordPress, the post type check has not run, so this happens here.
    // Check if metadata is supported on this content type.
    $post_type = get_post_type($post);
    if (!in_array($post_type, amt_get_supported_post_types())) {
        return $post_body;
    }
    // Get an array containing the attachments
    $attachments = amt_get_ordered_attachments($post);
    //var_dump($attachments);
    // Get an array containing the URLs of the embedded media
    $embedded_media = amt_get_embedded_media($post);
    //var_dump($embedded_media);
    // Custom content override
    if (amt_is_custom($post, $options)) {
        // Return metadata with:
        // add_filter( 'amt_custom_metadata_schemaorg_content_filter', 'my_function', 10, 5 );
        // Return an array of meta tags. Array item format: ['key_can_be_whatever'] = '<meta name="foo" content="bar" />'
        $metadata_arr = apply_filters('amt_custom_metadata_schemaorg_content_filter', $metadata_arr, $post, $options, $attachments, $embedded_media);
        // Products
    } elseif (amt_is_product()) {
        // Scope BEGIN: Product: http://schema.org/Product
        $metadata_arr[] = '<!-- Scope BEGIN: Product -->';
        $metadata_arr[] = '<div itemscope itemtype="http://schema.org/Product"' . amt_get_schemaorg_entity_id_as_itemid('product') . amt_get_schemaorg_itemref('product') . '>';
        // URL - Uses amt_get_permalink_for_multipage()
        $metadata_arr[] = '<meta itemprop="url" content="' . esc_url_raw(amt_get_permalink_for_multipage($post)) . '" />';
        // mainEntityOfPage
        $metadata_arr[] = '<meta itemprop="mainEntityOfPage" content="' . esc_url(amt_get_permalink_for_multipage($post)) . '" />';
        // name
        // Note: Contains multipage information through amt_process_paged()
        $metadata_arr[] = '<meta itemprop="name" content="' . esc_attr(amt_process_paged(strip_tags(get_the_title($post->ID)))) . '" />';
        // headline - contains title information
        //$metadata_arr['microdata:headline'] = '<meta itemprop="headline" content="' . esc_attr( amt_get_title_for_metadata($options, $post) ) . '" />';
        // Description - We use the description defined by Add-Meta-Tags
        // Note: Contains multipage information through amt_process_paged()
        $content_desc = amt_get_content_description($post);
        //if ( empty($content_desc) ) {
        //    // Use the post body as the description. Product objects do not support body text.
        //    $content_desc = sanitize_text_field( amt_sanitize_description( $post_body ) );
        //}
        if (!empty($content_desc)) {
            $metadata_arr[] = '<meta itemprop="description" content="' . esc_attr(amt_process_paged($content_desc)) . '" />';
        }
        // Dates
        $metadata_arr[] = '<meta itemprop="releaseDate" content="' . esc_attr(amt_iso8601_date($post->post_date)) . '" />';
        // Images
        // First check if a global image override URL has been entered.
        // If yes, use this image URL and override all other images.
        $image_data = amt_get_image_data(amt_get_post_meta_image_url($post->ID));
        if (!empty($image_data)) {
            $image_size = apply_filters('amt_image_size_product', 'full');
            $image_meta_tags = amt_get_schemaorg_image_metatags($options, $image_data, $size = $image_size);
            if (!empty($image_meta_tags)) {
                $metadata_arr[] = '<!-- Scope BEGIN: ImageObject -->';
                $metadata_arr[] = '<span itemprop="image" itemscope itemtype="http://schema.org/ImageObject">';
                $metadata_arr = array_merge($metadata_arr, $image_meta_tags);
                $metadata_arr[] = '</span> <!-- Scope END: ImageObject -->';
            }
            //$global_image_override_url = amt_get_post_meta_image_url($post->ID);
            //if ( ! empty( $global_image_override_url ) ) {
            //    $metadata_arr[] = '<!-- Scope BEGIN: ImageObject -->';
            //    $metadata_arr[] = '<span itemprop="image" itemscope itemtype="http://schema.org/ImageObject">';
            //    $metadata_arr[] = '<meta itemprop="url" content="' . esc_url_raw( $global_image_override_url ) . '" />';
            //    $metadata_arr[] = '<meta itemprop="contentUrl" content="' . esc_url_raw( $global_image_override_url ) . '" />';
            //    $metadata_arr[] = '</span> <!-- Scope END: ImageObject -->';
            // Further image processing
        } else {
            // Set to true if any image attachments are found. Use to finally add the default image
            // if no image attachments have been found.
            $has_images = false;
            // Scope BEGIN: ImageObject: http://schema.org/ImageObject
            // Image - Featured image is checked first, so that it can be the first associated image.
            if (function_exists('has_post_thumbnail') && has_post_thumbnail($post->ID)) {
                // Get the image attachment object
                $image = get_post(get_post_thumbnail_id($post->ID));
                // metadata BEGIN
                $metadata_arr[] = '<!-- Scope BEGIN: ImageObject -->';
                $metadata_arr[] = '<span itemprop="image" itemscope itemtype="http://schema.org/ImageObject">';
                // Allow filtering of the image size.
                $image_size = apply_filters('amt_image_size_product', 'full');
                // Get image metatags.
                $metadata_arr = array_merge($metadata_arr, amt_get_schemaorg_image_metatags($options, $image, $size = $image_size));
                // metadata END
                $metadata_arr[] = '</span> <!-- Scope END: ImageObject -->';
                // Images have been found.
                $has_images = true;
            }
            // Scope END: ImageObject
            // If no images have been found so far use the default image, if set.
            // Scope BEGIN: ImageObject: http://schema.org/ImageObject
            if ($has_images === false) {
                $image_data = amt_get_default_image_data();
                if (!empty($image_data)) {
                    $image_size = apply_filters('amt_image_size_product', 'full');
                    $image_meta_tags = amt_get_schemaorg_image_metatags($options, $image_data, $size = $image_size);
                    if (!empty($image_meta_tags)) {
                        $metadata_arr[] = '<!-- Scope BEGIN: ImageObject -->';
                        $metadata_arr[] = '<span itemprop="image" itemscope itemtype="http://schema.org/ImageObject">';
                        $metadata_arr = array_merge($metadata_arr, $image_meta_tags);
                        $metadata_arr[] = '</span> <!-- Scope END: ImageObject -->';
                    }
                }
                //$metadata_arr[] = '<!-- Scope BEGIN: ImageObject -->';
                //$metadata_arr[] = '<span itemprop="image" itemscope itemtype="http://schema.org/ImageObject">';
                //$metadata_arr[] = '<meta itemprop="url" content="' . esc_url_raw( $options["default_image_url"] ) . '" />';
                //$metadata_arr[] = '<meta itemprop="contentUrl" content="' . esc_url_raw( $options["default_image_url"] ) . '" />';
                //$metadata_arr[] = '</span> <!-- Scope END: ImageObject -->';
            }
            // Scope END: ImageObject
        }
        // Extend the current metadata with properties of the Product object.
        // See: http://schema.org/Product
        $metadata_arr = apply_filters('amt_product_data_schemaorg', $metadata_arr, $post);
        // Scope END: Product
        $metadata_arr[] = '</div> <!-- Scope END: Product -->';
        // Filtering of the generated Schema.org metadata
        $metadata_arr = apply_filters('amt_schemaorg_metadata_product', $metadata_arr);
        // Add post body
        // Remove last closing '</div>' tag, add post body and re-add the closing div afterwards.
        $closing_product_tag = array_pop($metadata_arr);
        // Product objects do not support a 'text' itemprop. We just add a div for now
        // for consistency with Article objects.
        // TODO: it should allow filtering '<div>'
        $metadata_arr[] = '<div> <!-- Product text body: BEGIN -->';
        $metadata_arr['content_data'] = $post_body;
        $metadata_arr[] = '</div> <!-- Product text body: END -->';
        // Now add closing tag for Article
        $metadata_arr[] = $closing_product_tag;
        // Attachemnts
    } elseif (is_attachment()) {
        $mime_type = get_post_mime_type($post->ID);
        //$attachment_type = strstr( $mime_type, '/', true );
        // See why we do not use strstr(): http://www.codetrax.org/issues/1091
        $attachment_type = preg_replace('#\\/[^\\/]*$#', '', $mime_type);
        // Early metatags - Scope starts
        if ('image' == $attachment_type) {
            // Scope BEGIN: ImageObject: http://schema.org/ImageObject
            $metadata_arr[] = '<!-- Scope BEGIN: ImageObject -->';
            $metadata_arr[] = '<div itemscope itemtype="http://schema.org/ImageObject"' . amt_get_schemaorg_itemref('attachment_image') . '>';
        } elseif ('video' == $attachment_type) {
            // Scope BEGIN: VideoObject: http://schema.org/VideoObject
            $metadata_arr[] = '<!-- Scope BEGIN: VideoObject -->';
            $metadata_arr[] = '<div itemscope itemtype="http://schema.org/VideoObject"' . amt_get_schemaorg_itemref('attachment_video') . '>';
        } elseif ('audio' == $attachment_type) {
            // Scope BEGIN: AudioObject: http://schema.org/AudioObject
            $metadata_arr[] = '<!-- Scope BEGIN: AudioObject -->';
            $metadata_arr[] = '<div itemscope itemtype="http://schema.org/AudioObject"' . amt_get_schemaorg_itemref('attachment_audio') . '>';
        } else {
            // we do not currently support other attachment types, so we stop processing here
            return $post_body;
        }
        // Metadata common to all attachments
        // Do not add a publisher on personal websites (static front page is source of author profile).
        if ($options['author_profile_source'] != 'frontpage' || !amt_has_page_on_front()) {
            // Publisher
            // Scope BEGIN: Organization: http://schema.org/Organization
            $metadata_arr[] = '<!-- Scope BEGIN: Organization -->';
            $metadata_arr[] = '<span itemprop="publisher" itemscope itemtype="http://schema.org/Organization"' . amt_get_schemaorg_itemref('organization') . '>';
            // Get publisher metatags
            $metadata_arr = array_merge($metadata_arr, amt_get_schemaorg_publisher_metatags($options, $post->post_author));
            // Scope END: Organization
            $metadata_arr[] = '</span> <!-- Scope END: Organization -->';
        }
        // Author
        // Scope BEGIN: Person: http://schema.org/Person
        $metadata_arr[] = '<!-- Scope BEGIN: Person -->';
        $metadata_arr[] = '<span itemprop="author" itemscope itemtype="http://schema.org/Person"' . amt_get_schemaorg_itemref('person_author') . '>';
        // Get author metatags
        $metadata_arr = array_merge($metadata_arr, amt_get_schemaorg_author_metatags($post->post_author, $options));
        // Scope END: Person
        $metadata_arr[] = '</span> <!-- Scope END: Person -->';
        // name
        $metadata_arr[] = '<meta itemprop="name" content="' . esc_attr(strip_tags(get_the_title($post->ID))) . '" />';
        // headline - contains title information
        $metadata_arr['microdata:headline'] = '<meta itemprop="headline" content="' . esc_attr(amt_get_title_for_metadata($options, $post)) . '" />';
        // Description - We use the description defined by Add-Meta-Tags
        $content_desc = amt_get_content_description($post);
        if (!empty($content_desc)) {
            $metadata_arr[] = '<meta itemprop="description" content="' . esc_attr($content_desc) . '" />';
        }
        // Dates
        $metadata_arr[] = '<meta itemprop="datePublished" content="' . esc_attr(amt_iso8601_date($post->post_date)) . '" />';
        $metadata_arr[] = '<meta itemprop="dateModified" content="' . esc_attr(amt_iso8601_date($post->post_modified)) . '" />';
        $metadata_arr[] = '<meta itemprop="copyrightYear" content="' . esc_attr(mysql2date('Y', $post->post_date)) . '" />';
        // Language
        $metadata_arr[] = '<meta itemprop="inLanguage" content="' . esc_attr(str_replace('-', '_', amt_get_language_content($options, $post))) . '" />';
        // Thumbnail
        // A featured image is supported by video and audio attachments.
        // If one is set, then it is set as the thumbnail of the video/audio object.
        if ('video' == $attachment_type || 'audio' == $attachment_type) {
            if (function_exists('has_post_thumbnail') && has_post_thumbnail($post->ID)) {
                // Thumbnail URL of the featured image
                $image_size = apply_filters('amt_image_size_attachment', 'full');
                $thumbnail_info = wp_get_attachment_image_src(get_post_thumbnail_id($post->ID), $image_size);
                $metadata_arr[] = '<meta itemprop="thumbnailUrl" content="' . esc_url_raw($thumbnail_info[0]) . '" />';
                // Currently we do not add a full ImageObject for the attachment's featured image.
                // TODO: future
            }
        }
        // mainEntityOfPage
        $metadata_arr[] = '<meta itemprop="mainEntityOfPage" content="' . esc_url(get_permalink($post->ID)) . '" />';
        // Metadata specific to each attachment type
        if ('image' == $attachment_type) {
            // Allow filtering of the image size.
            $image_size = apply_filters('amt_image_size_attachment', 'full');
            // Get image metatags. $post is an image object.
            $metadata_arr = array_merge($metadata_arr, amt_get_schemaorg_image_metatags($options, $post, $size = $image_size, $is_representative = true));
            // Add the post body here
            $metadata_arr['content_data'] = $post_body;
            // Scope END: ImageObject
            $metadata_arr[] = '</div> <!-- Scope END: ImageObject -->';
        } elseif ('video' == $attachment_type) {
            // Video specific metatags
            // URL (links to image file)
            //$metadata_arr[] = '<meta itemprop="url" content="' . esc_url_raw( get_permalink( $post->ID ) ) . '" />';
            $metadata_arr[] = '<meta itemprop="url" content="' . esc_url_raw(wp_get_attachment_url($post->ID)) . '" />';
            // sameAs (links to attachment page)
            $metadata_arr[] = '<meta itemprop="sameAs" content="' . esc_url_raw(get_permalink($post->ID)) . '" />';
            $metadata_arr[] = '<meta itemprop="contentUrl" content="' . esc_url_raw(wp_get_attachment_url($post->ID)) . '" />';
            $metadata_arr[] = '<meta itemprop="encodingFormat" content="' . esc_attr($mime_type) . '" />';
            // Required by Google
            $metadata_arr[] = '<meta itemprop="uploadDate" content="' . esc_attr(amt_iso8601_date($post->post_date)) . '" />';
            // Add the post body here
            $metadata_arr['content_data'] = $post_body;
            // Scope END: VideoObject
            $metadata_arr[] = '</div> <!-- Scope END: VideoObject -->';
        } elseif ('audio' == $attachment_type) {
            // Audio specific metatags
            // URL (links to image file)
            //$metadata_arr[] = '<meta itemprop="url" content="' . esc_url_raw( get_permalink( $post->ID ) ) . '" />';
            $metadata_arr[] = '<meta itemprop="url" content="' . esc_url_raw(wp_get_attachment_url($post->ID)) . '" />';
            // sameAs (links to attachment page)
            $metadata_arr[] = '<meta itemprop="sameAs" content="' . esc_url_raw(get_permalink($post->ID)) . '" />';
            $metadata_arr[] = '<meta itemprop="contentUrl" content="' . esc_url_raw(wp_get_attachment_url($post->ID)) . '" />';
            $metadata_arr[] = '<meta itemprop="encodingFormat" content="' . esc_attr($mime_type) . '" />';
            // Add the post body here
            $metadata_arr['content_data'] = $post_body;
            // Scope END: AudioObject
            $metadata_arr[] = '</div> <!-- Scope END: AudioObject -->';
        }
        // Filtering of the generated Schema.org metadata
        $metadata_arr = apply_filters('amt_schemaorg_metadata_attachment', $metadata_arr);
        // Content
    } else {
        // Set main metadata entity. By default this set to Article.
        $main_content_object = 'Article';
        // Check for Page
        // Main entity is set to WebPage on pages
        // DEV NOTE: Since many themes already set the WebPage itemscope on the
        // body element of the web page, set it to WebPage automatically would
        // result in duplicate entities. So this has to be done manually via
        // a filtering function.
        //        if  ( is_page() ) {
        //            $main_content_object = 'WebPage';
        //        }
        // Check for Review
        $review_data = amt_get_review_data($post);
        if (!empty($review_data)) {
            $main_content_object = 'Review';
        }
        // Allow filtering the main metadata object for content.
        $main_content_object = apply_filters('amt_schemaorg_object_main', $main_content_object);
        // Scope BEGIN: Article: http://schema.org/Article
        $metadata_arr[] = '<!-- Scope BEGIN: ' . esc_attr($main_content_object) . ' -->';
        $metadata_arr[] = '<div itemscope itemtype="http://schema.org/' . esc_attr($main_content_object) . '"' . amt_get_schemaorg_itemref('content') . '>';
        // Do not add a publisher on personal websites (static front page is source of author profile).
        if ($options['author_profile_source'] != 'frontpage' || !amt_has_page_on_front()) {
            // Publisher
            // Scope BEGIN: Organization: http://schema.org/Organization
            $metadata_arr[] = '<!-- Scope BEGIN: Organization -->';
            $metadata_arr[] = '<span itemprop="publisher" itemscope itemtype="http://schema.org/Organization"' . amt_get_schemaorg_itemref('organization') . '>';
            // Get publisher metatags
            $metadata_arr = array_merge($metadata_arr, amt_get_schemaorg_publisher_metatags($options, $post->post_author));
            // Scope END: Organization
            $metadata_arr[] = '</span> <!-- Scope END: Organization -->';
        }
        // Author
        // Scope BEGIN: Person: http://schema.org/Person
        $metadata_arr[] = '<!-- Scope BEGIN: Person -->';
        $metadata_arr[] = '<span itemprop="author" itemscope itemtype="http://schema.org/Person"' . amt_get_schemaorg_itemref('person_author') . '>';
        // Get publisher metatags
        $metadata_arr = array_merge($metadata_arr, amt_get_schemaorg_author_metatags($post->post_author, $options));
        // Scope END: Person
        $metadata_arr[] = '</span> <!-- Scope END: Person -->';
        // URL - Uses amt_get_permalink_for_multipage()
        $metadata_arr[] = '<meta itemprop="url" content="' . esc_url_raw(amt_get_permalink_for_multipage($post)) . '" />';
        // mainEntityOfPage
        $metadata_arr[] = '<meta itemprop="mainEntityOfPage" content="' . esc_url(amt_get_permalink_for_multipage($post)) . '" />';
        // Dates
        $metadata_arr[] = '<meta itemprop="datePublished" content="' . esc_attr(amt_iso8601_date($post->post_date)) . '" />';
        $metadata_arr[] = '<meta itemprop="dateModified" content="' . esc_attr(amt_iso8601_date($post->post_modified)) . '" />';
        $metadata_arr[] = '<meta itemprop="copyrightYear" content="' . esc_attr(mysql2date('Y', $post->post_date)) . '" />';
        // Language
        $metadata_arr[] = '<meta itemprop="inLanguage" content="' . esc_attr(str_replace('-', '_', amt_get_language_content($options, $post))) . '" />';
        // name
        // Note: Contains multipage information through amt_process_paged()
        $metadata_arr[] = '<meta itemprop="name" content="' . esc_attr(amt_process_paged(strip_tags(get_the_title($post->ID)))) . '" />';
        // headline - contains title information
        $metadata_arr['microdata:headline'] = '<meta itemprop="headline" content="' . esc_attr(amt_get_title_for_metadata($options, $post)) . '" />';
        // Description - We use the description defined by Add-Meta-Tags
        // Note: Contains multipage information through amt_process_paged()
        $content_desc = amt_get_content_description($post);
        if (!empty($content_desc)) {
            $metadata_arr[] = '<meta itemprop="description" content="' . esc_attr(amt_process_paged($content_desc)) . '" />';
        }
        /*
        // Section: We use the first category as the section
        $first_cat = sanitize_text_field( amt_sanitize_keywords( amt_get_first_category($post) ) );
        if (!empty($first_cat)) {
            $metadata_arr[] = '<meta itemprop="articleSection" content="' . esc_attr( $first_cat ) . '" />';
        }
        */
        // Add articleSection in Article object only.
        if ($main_content_object == 'Article') {
            $categories = get_the_category($post->ID);
            $categories = apply_filters('amt_post_categories_for_schemaorg', $categories);
            foreach ($categories as $cat) {
                $section = trim($cat->cat_name);
                if (!empty($section) && $cat->slug != 'uncategorized') {
                    $metadata_arr[] = '<meta itemprop="articleSection" content="' . esc_attr($section) . '" />';
                }
            }
        }
        // Add review properties if Review
        if ($main_content_object == 'Review') {
            $metadata_arr[] = '<!-- Review Information BEGIN -->';
            $metadata_arr[] = amt_get_review_info_box($review_data);
            $metadata_arr[] = '<!-- Review Information END -->';
        }
        // Keywords - We use the keywords defined by Add-Meta-Tags
        $keywords = amt_get_content_keywords($post);
        if (!empty($keywords)) {
            $metadata_arr[] = '<meta itemprop="keywords" content="' . esc_attr($keywords) . '" />';
        }
        // Referenced Items
        $referenced_url_list = amt_get_referenced_items($post);
        foreach ($referenced_url_list as $referenced_url) {
            $referenced_url = trim($referenced_url);
            if (!empty($referenced_url)) {
                $metadata_arr[] = '<meta itemprop="referencedItem" content="' . esc_url_raw($referenced_url) . '" />';
            }
        }
        // Images
        // First check if a global image override URL has been entered.
        // If yes, use this image URL and override all other images.
        $image_data = amt_get_image_data(amt_get_post_meta_image_url($post->ID));
        if (!empty($image_data)) {
            $image_size = apply_filters('amt_image_size_content', 'full');
            $image_meta_tags = amt_get_schemaorg_image_metatags($options, $image_data, $size = $image_size);
            if (!empty($image_meta_tags)) {
                $metadata_arr[] = '<!-- Scope BEGIN: ImageObject -->';
                $metadata_arr[] = '<span itemprop="image" itemscope itemtype="http://schema.org/ImageObject">';
                $metadata_arr = array_merge($metadata_arr, $image_meta_tags);
                $metadata_arr[] = '</span> <!-- Scope END: ImageObject -->';
            }
            //$global_image_override_url = amt_get_post_meta_image_url($post->ID);
            //if ( ! empty( $global_image_override_url ) ) {
            //    $metadata_arr[] = '<!-- Scope BEGIN: ImageObject -->';
            //    $metadata_arr[] = '<span itemprop="image" itemscope itemtype="http://schema.org/ImageObject">';
            //    $metadata_arr[] = '<meta itemprop="url" content="' . esc_url_raw( $global_image_override_url ) . '" />';
            //    $metadata_arr[] = '<meta itemprop="contentUrl" content="' . esc_url_raw( $global_image_override_url ) . '" />';
            //    $metadata_arr[] = '</span> <!-- Scope END: ImageObject -->';
            // Further image processing
        } else {
            // Media Limits
            $image_limit = amt_metadata_get_image_limit($options);
            $video_limit = amt_metadata_get_video_limit($options);
            $audio_limit = amt_metadata_get_audio_limit($options);
            // Counters
            $ic = 0;
            // image counter
            $vc = 0;
            // video counter
            $ac = 0;
            // audio counter
            // We store the featured image ID in this variable so that it can easily be excluded
            // when all images are parsed from the $attachments array.
            $featured_image_id = 0;
            // Set to true if any image attachments are found. Use to finally add the default image
            // if no image attachments have been found.
            $has_images = false;
            // Scope BEGIN: ImageObject: http://schema.org/ImageObject
            // Image - Featured image is checked first, so that it can be the first associated image.
            if (function_exists('has_post_thumbnail') && has_post_thumbnail($post->ID)) {
                // Thumbnail URL
                // First add the thumbnail URL of the featured image
                $thumbnail_info = wp_get_attachment_image_src(get_post_thumbnail_id($post->ID), 'thumbnail');
                $metadata_arr[] = '<meta itemprop="thumbnailUrl" content="' . esc_url_raw($thumbnail_info[0]) . '" />';
                // Add full image object for featured image.
                // Get the image attachment object
                $image = get_post(get_post_thumbnail_id($post->ID));
                // metadata BEGIN
                $metadata_arr[] = '<!-- Scope BEGIN: ImageObject -->';
                $metadata_arr[] = '<span itemprop="image" itemscope itemtype="http://schema.org/ImageObject">';
                // Allow filtering of the image size.
                $image_size = apply_filters('amt_image_size_content', 'full');
                // Get image metatags.
                $metadata_arr = array_merge($metadata_arr, amt_get_schemaorg_image_metatags($options, $image, $size = $image_size));
                // metadata END
                $metadata_arr[] = '</span> <!-- Scope END: ImageObject -->';
                // Finally, set the $featured_image_id
                $featured_image_id = get_post_thumbnail_id($post->ID);
                // Images have been found.
                $has_images = true;
                // Increase image counter
                $ic++;
            }
            // Scope END: ImageObject
            // Process all attachments and add metatags (featured image will be excluded)
            foreach ($attachments as $attachment) {
                // Excluded the featured image since
                if ($attachment->ID != $featured_image_id) {
                    $mime_type = get_post_mime_type($attachment->ID);
                    //$attachment_type = strstr( $mime_type, '/', true );
                    // See why we do not use strstr(): http://www.codetrax.org/issues/1091
                    $attachment_type = preg_replace('#\\/[^\\/]*$#', '', $mime_type);
                    if ('image' == $attachment_type && $ic < $image_limit) {
                        // metadata BEGIN
                        $metadata_arr[] = '<!-- Scope BEGIN: ImageObject -->';
                        $metadata_arr[] = '<span itemprop="image" itemscope itemtype="http://schema.org/ImageObject">';
                        // Allow filtering of the image size.
                        $image_size = apply_filters('amt_image_size_content', 'full');
                        // Get image metatags.
                        $metadata_arr = array_merge($metadata_arr, amt_get_schemaorg_image_metatags($options, $attachment, $size = $image_size));
                        // metadata END
                        $metadata_arr[] = '</span> <!-- Scope END: ImageObject -->';
                        // Images have been found.
                        $has_images = true;
                        // Increase image counter
                        $ic++;
                    } elseif ('video' == $attachment_type && $vc < $video_limit) {
                        // Scope BEGIN: VideoObject: http://schema.org/VideoObject
                        $metadata_arr[] = '<!-- Scope BEGIN: VideoObject -->';
                        $metadata_arr[] = '<span itemprop="video" itemscope itemtype="http://schema.org/VideoObject">';
                        // Video specific metatags
                        // URL (links to image file)
                        //$metadata_arr[] = '<meta itemprop="url" content="' . esc_url_raw( get_permalink( $attachment->ID ) ) . '" />';
                        $metadata_arr[] = '<meta itemprop="url" content="' . esc_url_raw(wp_get_attachment_url($attachment->ID)) . '" />';
                        // sameAs (links to attachment page)
                        $metadata_arr[] = '<meta itemprop="sameAs" content="' . esc_url_raw(get_permalink($attachment->ID)) . '" />';
                        $metadata_arr[] = '<meta itemprop="contentUrl" content="' . esc_url_raw(wp_get_attachment_url($attachment->ID)) . '" />';
                        $metadata_arr[] = '<meta itemprop="encodingFormat" content="' . esc_attr($mime_type) . '" />';
                        // name
                        $metadata_arr[] = '<meta itemprop="name" content="' . esc_attr(strip_tags(get_the_title($attachment->ID))) . '" />';
                        // Description - We use the description defined by Add-Meta-Tags
                        $content_desc = amt_get_content_description($attachment);
                        if (!empty($content_desc)) {
                            $metadata_arr[] = '<meta itemprop="description" content="' . esc_attr($content_desc) . '" />';
                        }
                        // Thumbnail
                        // A featured image is supported by video and audio attachments.
                        // If one is set, then it is set as the thumbnail of the video/audio object.
                        if (function_exists('has_post_thumbnail') && has_post_thumbnail($attachment->ID)) {
                            // Thumbnail URL of the featured image
                            $image_size = apply_filters('amt_image_size_content', 'full');
                            $thumbnail_info = wp_get_attachment_image_src(get_post_thumbnail_id($attachment->ID), $image_size);
                            $metadata_arr[] = '<meta itemprop="thumbnailUrl" content="' . esc_url_raw($thumbnail_info[0]) . '" />';
                            // Currently we do not add a full ImageObject for the attachment's featured image.
                            // TODO: future
                        }
                        // uploadDate
                        $metadata_arr[] = '<meta itemprop="uploadDate" content="' . esc_attr(amt_iso8601_date($attachment->post_date)) . '" />';
                        // Scope END: VideoObject
                        $metadata_arr[] = '</span> <!-- Scope END: VideoObject -->';
                        // Increase video counter
                        $vc++;
                    } elseif ('audio' == $attachment_type && $ac < $audio_limit) {
                        // Scope BEGIN: AudioObject: http://schema.org/AudioObject
                        $metadata_arr[] = '<!-- Scope BEGIN: AudioObject -->';
                        $metadata_arr[] = '<span itemprop="audio" itemscope itemtype="http://schema.org/AudioObject">';
                        // Audio specific metatags
                        // URL (links to image file)
                        //$metadata_arr[] = '<meta itemprop="url" content="' . esc_url_raw( get_permalink( $attachment->ID ) ) . '" />';
                        $metadata_arr[] = '<meta itemprop="url" content="' . esc_url_raw(wp_get_attachment_url($attachment->ID)) . '" />';
                        // sameAs (links to attachment page)
                        $metadata_arr[] = '<meta itemprop="sameAs" content="' . esc_url_raw(get_permalink($attachment->ID)) . '" />';
                        $metadata_arr[] = '<meta itemprop="contentUrl" content="' . esc_url_raw(wp_get_attachment_url($attachment->ID)) . '" />';
                        $metadata_arr[] = '<meta itemprop="encodingFormat" content="' . esc_attr($mime_type) . '" />';
                        // name
                        $metadata_arr[] = '<meta itemprop="name" content="' . esc_attr(strip_tags(get_the_title($attachment->ID))) . '" />';
                        // Description - We use the description defined by Add-Meta-Tags
                        $content_desc = amt_get_content_description($attachment);
                        if (!empty($content_desc)) {
                            $metadata_arr[] = '<meta itemprop="description" content="' . esc_attr($content_desc) . '" />';
                        }
                        // Thumbnail
                        // A featured image is supported by video and audio attachments.
                        // If one is set, then it is set as the thumbnail of the video/audio object.
                        if (function_exists('has_post_thumbnail') && has_post_thumbnail($attachment->ID)) {
                            // Thumbnail URL of the featured image
                            $image_size = apply_filters('amt_image_size_content', 'full');
                            $thumbnail_info = wp_get_attachment_image_src(get_post_thumbnail_id($attachment->ID), $image_size);
                            $metadata_arr[] = '<meta itemprop="thumbnailUrl" content="' . esc_url_raw($thumbnail_info[0]) . '" />';
                            // Currently we do not add a full ImageObject for the attachment's featured image.
                            // TODO: future
                        }
                        // uploadDate
                        $metadata_arr[] = '<meta itemprop="uploadDate" content="' . esc_attr(amt_iso8601_date($attachment->post_date)) . '" />';
                        // Scope END: AudioObject
                        $metadata_arr[] = '</span> <!-- Scope END: AudioObject -->';
                        // Increase audio counter
                        $ac++;
                    }
                }
            }
            // Embedded Media
            foreach ($embedded_media['images'] as $embedded_item) {
                if ($ic == $image_limit) {
                    break;
                }
                // Scope BEGIN: ImageObject: http://schema.org/ImageObject
                $metadata_arr[] = '<!-- Scope BEGIN: ImageObject -->';
                $metadata_arr[] = '<span itemprop="image" itemscope itemtype="http://schema.org/ImageObject">';
                // name (title)
                $metadata_arr[] = '<meta itemprop="name" content="' . esc_attr($embedded_item['alt']) . '" />';
                // caption
                $metadata_arr[] = '<meta itemprop="caption" content="' . esc_attr($embedded_item['alt']) . '" />';
                // alt
                $metadata_arr[] = '<meta itemprop="text" content="' . esc_attr($embedded_item['alt']) . '" />';
                // URL (links to image file)
                //$metadata_arr[] = '<meta itemprop="url" content="' . esc_url_raw( $embedded_item['page'] ) . '" />';
                $metadata_arr[] = '<meta itemprop="url" content="' . esc_url_raw($embedded_item['image']) . '" />';
                // sameAs (links to attachment page)
                $metadata_arr[] = '<meta itemprop="sameAs" content="' . esc_url_raw($embedded_item['page']) . '" />';
                // thumbnail url
                $metadata_arr[] = '<meta itemprop="thumbnailUrl" content="' . esc_url_raw($embedded_item['thumbnail']) . '" />';
                // main image
                $metadata_arr[] = '<meta itemprop="contentUrl" content="' . esc_url_raw($embedded_item['image']) . '" />';
                if (apply_filters('amt_extended_image_tags', true)) {
                    $metadata_arr[] = '<meta itemprop="width" content="' . esc_attr($embedded_item['width']) . '" />';
                    $metadata_arr[] = '<meta itemprop="height" content="' . esc_attr($embedded_item['height']) . '" />';
                    $metadata_arr[] = '<meta itemprop="encodingFormat" content="image/jpeg" />';
                }
                // embedURL
                $metadata_arr[] = '<meta itemprop="embedURL" content="' . esc_url_raw($embedded_item['player']) . '" />';
                // Scope END: ImageObject
                $metadata_arr[] = '</span> <!-- Scope END: ImageObject -->';
                // Images have been found.
                $has_images = true;
                // Increase image counter
                $ic++;
            }
            foreach ($embedded_media['videos'] as $embedded_item) {
                if ($vc == $video_limit) {
                    break;
                }
                // Scope BEGIN: VideoObject: http://schema.org/VideoObject
                // See: http://googlewebmastercentral.blogspot.gr/2012/02/using-schemaorg-markup-for-videos.html
                // See: https://support.google.com/webmasters/answer/2413309?hl=en
                $metadata_arr[] = '<!-- Scope BEGIN: VideoObject -->';
                $metadata_arr[] = '<span itemprop="video" itemscope itemtype="http://schema.org/VideoObject">';
                // Video Embed URL
                $metadata_arr[] = '<meta itemprop="embedURL" content="' . esc_url_raw($embedded_item['player']) . '" />';
                // playerType
                $metadata_arr[] = '<meta itemprop="playerType" content="application/x-shockwave-flash" />';
                // size
                $metadata_arr[] = '<meta itemprop="width" content="' . esc_attr($embedded_item['width']) . '" />';
                $metadata_arr[] = '<meta itemprop="height" content="' . esc_attr($embedded_item['height']) . '" />';
                // Scope END: VideoObject
                $metadata_arr[] = '</span> <!-- Scope END: VideoObject -->';
                // Increase video counter
                $vc++;
            }
            foreach ($embedded_media['sounds'] as $embedded_item) {
                if ($ac == $audio_limit) {
                    break;
                }
                // Scope BEGIN: AudioObject: http://schema.org/AudioObject
                $metadata_arr[] = '<!-- Scope BEGIN: AudioObject -->';
                $metadata_arr[] = '<span itemprop="audio" itemscope itemtype="http://schema.org/AudioObject">';
                // Audio Embed URL
                $metadata_arr[] = '<meta itemprop="embedURL" content="' . esc_url_raw($embedded_item['player']) . '" />';
                // playerType
                $metadata_arr[] = '<meta itemprop="playerType" content="application/x-shockwave-flash" />';
                // Scope END: AudioObject
                $metadata_arr[] = '</span> <!-- Scope END: AudioObject -->';
                // Increase audio counter
                $ac++;
            }
            // If no images have been found so far use the default image, if set.
            // Scope BEGIN: ImageObject: http://schema.org/ImageObject
            if ($has_images === false) {
                $image_data = amt_get_default_image_data();
                if (!empty($image_data)) {
                    $image_size = apply_filters('amt_image_size_content', 'full');
                    $image_meta_tags = amt_get_schemaorg_image_metatags($options, $image_data, $size = $image_size);
                    if (!empty($image_meta_tags)) {
                        $metadata_arr[] = '<!-- Scope BEGIN: ImageObject -->';
                        $metadata_arr[] = '<span itemprop="image" itemscope itemtype="http://schema.org/ImageObject">';
                        $metadata_arr = array_merge($metadata_arr, $image_meta_tags);
                        $metadata_arr[] = '</span> <!-- Scope END: ImageObject -->';
                    }
                }
                //$metadata_arr[] = '<!-- Scope BEGIN: ImageObject -->';
                //$metadata_arr[] = '<span itemprop="image" itemscope itemtype="http://schema.org/ImageObject">';
                //$metadata_arr[] = '<meta itemprop="url" content="' . esc_url_raw( $options["default_image_url"] ) . '" />';
                //$metadata_arr[] = '<meta itemprop="contentUrl" content="' . esc_url_raw( $options["default_image_url"] ) . '" />';
                //$metadata_arr[] = '</span> <!-- Scope END: ImageObject -->';
            }
            // Scope END: ImageObject
        }
        // Article Body
        // The article body is added after filtering the generated microdata below.
        // TODO: also check: comments, contributor, copyrightHolder, , creator, dateCreated, discussionUrl, editor, version (use post revision if possible)
        // Scope END: Article
        $metadata_arr[] = '</div> <!-- Scope END: ' . esc_attr($main_content_object) . ' -->';
        // Filtering of the generated Schema.org metadata
        $metadata_arr = apply_filters('amt_schemaorg_metadata_content', $metadata_arr);
        // Add articleBody to Artice
        // Now add the article. Remove last closing '</span>' tag, add articleBody and re-add the closing span afterwards.
        $closing_article_tag = array_pop($metadata_arr);
        // Use the 'text' itemprop by default for the main text body of the CreativeWork,
        // so it can be used by more subtypes than Article.
        // But set it explicitly to 'articleBody if the main entiry is 'Article'
        // or 'reviewBody' if the main entity is a 'Review'.
        $main_text_property = 'text';
        if ($main_content_object == 'Article') {
            $main_text_property = 'articleBody';
        } elseif ($main_content_object == 'Review') {
            $main_text_property = 'reviewBody';
        }
        // Allow filtering of the main text property.
        $main_text_property = apply_filters('amt_schemaorg_property_main_text', $main_text_property);
        $metadata_arr[] = '<div itemprop="' . esc_attr($main_text_property) . '">';
        $metadata_arr['content_data'] = $post_body;
        $metadata_arr[] = '</div> <!-- Itemprop END: ' . esc_attr($main_text_property) . ' -->';
        // Now add closing tag for Article
        $metadata_arr[] = $closing_article_tag;
    }
    // Store transient cache of content metadata
    if (absint($options['transient_cache_expiration']) > 0 && apply_filters('amt_enable_metadata_cache_in_content_filter', true)) {
        if (!empty($metadata_arr)) {
            amt_set_transient_cache($post, $options, $metadata_arr, $where = 'content');
        }
    }
    // Add our comment
    if (count($metadata_arr) > 0) {
        // For AMT timings
        if ($options['enable_timings'] == '1') {
            array_unshift($metadata_arr, sprintf('<!-- Add-Meta-Tags Timings (milliseconds) - Block total time: %.3f msec - Cached: %s -->', (microtime(true) - $t) * 1000, $is_cached));
        }
        if ($options["omit_vendor_html_comments"] == "0") {
            array_unshift($metadata_arr, "<!-- BEGIN Schema.org microdata added by the Add-Meta-Tags WordPress plugin -->");
        }
        array_unshift($metadata_arr, "");
        // Intentionaly left empty
        if ($options["omit_vendor_html_comments"] == "0") {
            array_push($metadata_arr, "<!-- END Schema.org microdata added by the Add-Meta-Tags WordPress plugin -->");
        }
        array_push($metadata_arr, "");
        // Intentionaly left empty
    }
    //
    // Non persistent cache for metadata review mode.
    //
    // The review mode's content filter should have bigger priority than this
    // filter (be executed after this one). This one by default has priority 9999
    // while the review mode filter has priority of 10000
    if (amt_check_run_metadata_review_code($options)) {
        // What happens here is this: we copy the metadata array and remove the
        // item that contains the content data, because it is not needed for
        // metadata review.
        // Then use non-persistent cache to store this new array.
        // Metadata Review mode's filtering function should be attached with a
        // priority bigger than this one, so that it is executed after this one.
        // There the data is loaded from the non-persistent cache.
        // This way, the timings are the same as in the source code and also
        // it is more efficient from a resources perspective.
        // WARNING: in order to work fine, set correct filter priorities.
        $metadata_arr_for_review = $metadata_arr;
        if (array_key_exists('content_data', $metadata_arr_for_review)) {
            $metadata_arr_for_review['content_data'] = '    <!-- The content has been removed from the metadata review. -->';
        }
        wp_cache_add('amt_cache_metadata_block_content_filter', $metadata_arr_for_review, $group = 'add-meta-tags');
        unset($metadata_arr_for_review);
    }
    //return $post_body;
    return implode(PHP_EOL, $metadata_arr);
}
示例#2
0
/**
 * Prints the generated metadata for the footer area.
 */
function amt_add_metadata_footer()
{
    // For AMT timings
    $t = microtime(true);
    // Get the options the DB
    $options = get_option("add_meta_tags_opts");
    // Get current post object
    $post = amt_get_queried_object();
    // Caching indicator
    $is_cached = 'no';
    // Get the metadata
    // NOTE: Currently metadata is cached for content pages only (is_singular())
    if (absint($options['transient_cache_expiration']) > 0 && apply_filters('amt_enable_metadata_cache', true)) {
        $metadata_arr = amt_get_transient_cache($post, $options, $where = 'footer');
        if (empty($metadata_arr)) {
            $metadata_arr = amt_get_metadata_footer($post, $options);
            // Cache the metadata
            if (!empty($metadata_arr)) {
                amt_set_transient_cache($post, $options, $metadata_arr, $where = 'footer');
            }
        } else {
            $is_cached = 'yes';
        }
    } else {
        $metadata_arr = amt_get_metadata_footer($post, $options);
    }
    // For AMT timings
    if (!empty($metadata_arr) && $options['enable_timings'] == '1') {
        array_unshift($metadata_arr, sprintf('<!-- Add-Meta-Tags Timings (milliseconds) - Block total time: %.3f msec - Cached: %s -->', (microtime(true) - $t) * 1000, $is_cached));
    }
    // Add our comment
    if ($options["omit_vendor_html_comments"] == "0") {
        if (count($metadata_arr) > 0) {
            array_unshift($metadata_arr, "<!-- BEGIN Metadata added by the Add-Meta-Tags WordPress plugin -->");
            array_push($metadata_arr, "<!-- END Metadata added by the Add-Meta-Tags WordPress plugin -->");
        }
    }
    // Return complete metadata array
    return $metadata_arr;
}