/** * 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); }
function amt_local_author_profile_url($author_id = null, $display = true) { $options = get_option("add_meta_tags_opts"); if (empty($options)) { return ''; } if (is_null($author_id)) { $post = amt_get_queried_object($options); if (is_null($post) || $post->ID == 0) { return ''; } $author_id = get_the_author_meta('ID', $post->post_author); } if ($display) { echo esc_url(amt_get_local_author_profile_url($author_id, $options)); } else { return esc_url(amt_get_local_author_profile_url($author_id, $options)); } }
function amt_metadata_analysis($default_text, $metadata_block_head, $metadata_block_footer, $metadata_block_content_filter) { // Analysis is appended only o content pages if (!is_singular()) { return $default_text; } // Check the filter based switch if (!apply_filters('amt_metadata_analysis_enable', true)) { return $default_text; } // // Collect data // $options = amt_get_options(); $post = amt_get_queried_object(); if (!isset($post->ID) || $post->ID <= 0) { return $default_text; } // Content and stats // Post content $post_content = strtolower(amt_get_clean_post_content($options, $post)); $post_content_length = strlen($post_content); //var_dump($post_content); // Total words if (function_exists('wordstats_words')) { $post_word_count = wordstats_words($post_content); // provided by the word-statistics-plugin by FD } else { $post_word_count = str_word_count($post_content); } // Total sentences if (function_exists('wordstats_sentences')) { $post_sentence_count = wordstats_sentences($post_content); // provided by the word-statistics-plugin by FD } else { $post_sentence_count = preg_match_all('/[.!?\\r]/', $post_content, $dummy); } // Total syllables // TODO: Find better function $post_syllable_count = preg_match_all('/[aeiouy]/', $post_content, $dummy); // Titles // Original $post_title = strtolower(strip_tags(get_the_title($post->ID))); // Title HTML element if ($options['enable_advanced_title_management'] == '1') { // If Advanced Title management is enabled, use this directly: $post_title_html_element = strtolower(amt_get_title_for_title_element($options, $post)); } else { if (version_compare(get_bloginfo('version'), '4.4', '>=')) { // Since WP 4.4 // - https://make.wordpress.org/core/2015/10/20/document-title-in-4-4/ //$post_title_html_element = strtolower( apply_filters('document_title_parts', array('title' => $post_title) ) ); //$post_title_html_element = wp_get_document_title(); $post_title_html_element = strtolower(get_wp_title_rss()); } else { // Reverting back to the one argument version of the fitlering function. //$post_title_html_element = strtolower( apply_filters('wp_title', $post_title) ); // Until testing is performed on old WP versions we just use post title $post_title_html_element = $post_title; } } //var_dump($post_title_html_element); // Title in metadata $post_title_metadata = strtolower(amt_get_title_for_metadata($options, $post)); //var_dump($post_title_metadata); // URL $post_url = str_replace(get_bloginfo('url'), '', amt_get_permalink_for_multipage($post)); //var_dump($post_url); // Description $description = ''; if (array_key_exists('basic:description', $metadata_block_head)) { $description = strtolower(preg_replace('#^.*content="([^"]+)".*$#', '$1', $metadata_block_head['basic:description'])); } //var_dump($description); // Keywords $keywords = array(); if (array_key_exists('basic:keywords', $metadata_block_head)) { $keywords_content = strtolower(preg_replace('#^.*content="([^"]+)".*$#', '$1', $metadata_block_head['basic:keywords'])); $keywords = explode(',', str_replace(', ', ',', $keywords_content)); } //var_dump($keywords); // Keyword matching pattern //$keyword_matching_pattern = '#(?:%s)#'; //$keyword_matching_pattern = '#(?:%s)[[:^alpha:]]#'; //$keyword_matching_pattern = '#(?:%s)[[:^alpha:]]?#'; $keyword_matching_pattern = '#(?:%s)(?:[[:^alpha:]]|$)#'; $keyword_matching_pattern = apply_filters('amt_metadata_analysis_keyword_matching_pattern', $keyword_matching_pattern); // Whether to use topic keywords field or the keywords from the 'keywords' meta tag. $use_keywords = false; // First check for a field that contains topic keywords. $topic_keywords_field_name = apply_filters('amt_metadata_analysis_topic_keywords_field', 'topic_keywords'); $topic_keywords_field_value = get_post_meta($post->ID, $topic_keywords_field_name, true); if (!empty($topic_keywords_field_value)) { $topic_keywords = explode(',', str_replace(', ', ',', $topic_keywords_field_value)); } else { $topic_keywords = $keywords; $use_keywords = true; //var_dump($topic_keywords); } $BR = PHP_EOL; if ($options['review_mode_omit_notices'] == '0') { $output = $default_text . $BR . $BR; //$output .= $BR . '<span class="">Text analysis</span>' . $BR; } else { $output = ''; } if ($options['review_mode_omit_notices'] == '0') { $output .= 'Metadata Overview' . $BR; $output .= '=================' . $BR; //$output .= 'This overview has been generated by the Add-Meta-Tags plugin for statistical and' . $BR; //$output .= 'informational purposes only. Please do not modify or base your work upon this report.' . $BR . $BR; $output .= 'NOTICE: Add-Meta-Tags does not provide SEO advice and does not rate your content.' . $BR; $output .= 'This <a target="_blank" href="http://www.codetrax.org/projects/wp-add-meta-tags/wiki/Metadata_Overview">overview</a> has been generated for statistical and informational purposes only.' . $BR . $BR; //$output .= '<a target="_blank" href="http://www.codetrax.org/projects/wp-add-meta-tags/wiki/FAQ#Is-Add-Meta-Tags-an-SEO-plugin">Read more</a> about the mentality upon which the development of this plugin has been based.' . $BR; //$output .= 'Please use this statistical information to identify keyword overstuffing' . $BR; //$output .= 'and stay away from following any patterns or being bound by the numbers.' . $BR . $BR; } if ($use_keywords) { $output .= sprintf('This overview has been based on post keywords, because the Custom Field \'<em>%s</em>\' could not be found.', $topic_keywords_field_name) . $BR; } else { $output .= sprintf('This overview has been based on <em>topic keywords</em> retrieved from the Custom Field \'<em>%s</em>\'.', $topic_keywords_field_name) . $BR; } if ($options['review_mode_omit_notices'] == '0') { $output .= 'Keyword Analysis' . $BR; $output .= '----------------' . $BR; } else { $output .= $BR; } $output .= '<table class="amt-ht-table">'; $output .= '<tr> <th>Topic Keyword</th> <th>Content</th> <th>Description</th> <th>Keywords</th> <th>Post Title</th> <th>HTML title</th> <th>Metadata titles</th> <th>Post URL</th> </tr>'; foreach ($topic_keywords as $topic_keyword) { $output .= sprintf('<tr> <td>%s</td>', $topic_keyword); $is_into = array(); // Check content $is_into['content'] = ''; $occurrences = preg_match_all(sprintf($keyword_matching_pattern, $topic_keyword), $post_content, $matches); if ($occurrences) { // Only for content $topic_keyword_desnity = round($occurrences / $post_word_count * 100, 2); $output .= sprintf(' <td>%d (%.2f%%)</td>', $occurrences, $topic_keyword_desnity); } else { $output .= '<td> </td>'; } // Check description $occurrences = preg_match_all(sprintf($keyword_matching_pattern, $topic_keyword), $description, $matches); if ($occurrences) { $output .= sprintf(' <td>%d</td>', $occurrences); } else { $output .= '<td> </td>'; } // Check keywords if ($use_keywords) { $output .= '<td>N/A</td>'; $is_into['keywords'] = 'N/A'; } elseif (in_array($topic_keyword, $keywords)) { // Always 1 $output .= '<td>1</td>'; } else { $output .= '<td> </td>'; } // Check original title $occurrences = preg_match_all(sprintf($keyword_matching_pattern, $topic_keyword), $post_title, $matches); if ($occurrences) { $output .= sprintf(' <td>%d</td>', $occurrences); } else { $output .= '<td> </td>'; } // Check title element $occurrences = preg_match_all(sprintf($keyword_matching_pattern, $topic_keyword), $post_title_html_element, $matches); if ($occurrences) { $output .= sprintf(' <td>%d</td>', $occurrences); } else { $output .= '<td> </td>'; } // Check metadata titles $occurrences = preg_match_all(sprintf($keyword_matching_pattern, $topic_keyword), $post_title_metadata, $matches); if ($occurrences) { $output .= sprintf(' <td>%d</td>', $occurrences); } else { $output .= '<td> </td>'; } // Check post URL $occurrences = preg_match_all(sprintf($keyword_matching_pattern, $topic_keyword), $post_url, $matches); if ($occurrences) { $output .= sprintf(' <td>%d</td>', $occurrences); } else { $output .= '<td> </td>'; } // Close row $output .= ' </tr>' . $BR; } $output .= '</table>' . $BR; // Topic Keywords Distribution Graph if ($options['review_mode_omit_notices'] == '0') { $output .= 'Topic Keywords Distribution Graph' . $BR; $output .= '---------------------------------' . $BR; $output .= 'The following text based graph shows how the <em>topic keywords</em> are distributed within your content.' . $BR; $output .= 'You can use it to identify incidents of keyword overstuffing.' . $BR . $BR; } //$output .= $BR . $BR; $total_bars = 39; // zero based $step = $post_content_length / $total_bars; // Debug //$output .= $BR . $post_content_length . ' ' . $step . $BR; $max_weight = null; $weights = array(); // Reset weights for ($x = 0; $x <= $total_bars; $x++) { $weights[$x] = 1; } foreach ($topic_keywords as $topic_keyword) { // Use preg_match_all with PREG_OFFSET_CAPTURE -- http://php.net/manual/en/function.preg-match-all.php $topic_keyword_occurrences = preg_match_all(sprintf($keyword_matching_pattern, $topic_keyword), $post_content, $matches, PREG_OFFSET_CAPTURE); //var_dump($matches); if (!empty($topic_keyword_occurrences)) { foreach ($matches[0] as $match) { $pos = $match[1]; $step_index = absint($pos / $step); $weights[$step_index] = $weights[$step_index] + 1; if ($weights[$step_index] > $max_weight) { $max_weight = $weights[$step_index]; } // Debug //$output .= sprintf('kw: %s, pos: %s, step index: %s, step weight: %s', $topic_keyword, $pos, $step_index, $weights[$step_index]) . $BR; } } } //var_dump($weights); for ($x = $max_weight - 1; $x >= 1; $x--) { $line = ''; for ($y = 0; $y <= $total_bars; $y++) { if ($weights[$y] > $x) { $line .= '#'; } else { $line .= ' '; } } $output .= $line . $BR; } // Currently this text based ruler is used as base line. $output .= str_repeat('---------+', ($total_bars + 1) / 10) . $BR; if ($options['review_mode_omit_notices'] == '0') { $output .= $BR . '<code>#</code>: indicates a single occurrence of a <em>topic keyword</em>.' . $BR; } else { $output .= $BR; } // Stats and scores by algos provided by the word-statistics-plugin by FD if (function_exists('wordstats_words')) { // Readability Tests if ($options['review_mode_omit_notices'] == '0') { $output .= $BR . 'Readability Scores and Text Statistics' . $BR; $output .= '--------------------------------------' . $BR; $output .= 'These readability scores and text statistics are based on algorithms provided by the <em>FD Word Statistics Plugin</em>.' . $BR . $BR; } if (function_exists('wordstats_words')) { $output .= sprintf(' ● Total words: <strong>%d</strong>', wordstats_words($post_content)) . $BR; } if (function_exists('wordstats_sentences')) { $output .= sprintf(' ● Total sentences: <strong>%d</strong>', wordstats_sentences($post_content)) . $BR; } if (function_exists('wordstats_flesch_kincaid')) { $output .= sprintf(' ● Flesch-Kincaid US grade level: <strong>%.1f</strong> <em>(For instance, a score of 9.3 means suitable for a 9th grade student in the US, <a target="_blank" href="%s">read more</a>.)</em>', wordstats_flesch_kincaid($post_content), 'https://en.wikipedia.org/wiki/Flesch%E2%80%93Kincaid_readability_tests#Flesch.E2.80.93Kincaid_grade_level') . $BR; } if (function_exists('wordstats_flesch')) { $output .= sprintf(' ● Flesch reading ease: <strong>%.1f%%</strong> <em>(avg 11 y.o. student: 90-100%%, 13-15 y.o. students: 60-70%%, university graduates: 0-30%%, <a target="_blank" href="%s">read more</a>.)</em>', wordstats_flesch($post_content), 'https://en.wikipedia.org/wiki/Flesch%E2%80%93Kincaid_readability_tests#Flesch_reading_ease') . $BR; } if (function_exists('wordstats_fog')) { $output .= sprintf(' ● Gunning fog index: <strong>%.1f</strong> <em>(wide audience: < 12, near universal understanding: < 8, <a target="_blank" href="%s">read more</a>.)</em>', wordstats_fog($post_content), 'https://en.wikipedia.org/wiki/Gunning_fog_index') . $BR; } $output .= $BR; } else { if ($options['review_mode_omit_notices'] == '0') { $output .= $BR . $BR . 'Note: There is experimental support for <em>FD Word Statistics Plugin</em>.'; $output .= $BR . 'If installed, you can get some readability scores and text statistics here.' . $BR . $BR; } } return $output; }
function amt_get_term_image_info($size = 'thumbnail', $term_id = null) { // Initial checks if (empty($term_id)) { if (is_category() || is_tag() || is_tax()) { // The post object is the term object $post = amt_get_queried_object(); if (!isset($post->term_id)) { return false; } $term_id = $post->term_id; } else { return false; } } elseif (!is_numeric($term_id)) { return false; } // Get data from Custom Field $custom_image_url_value = amt_get_term_meta_image_url($term_id); // Get image data $image_data = amt_get_image_data(amt_esc_id_or_url_notation(stripslashes($custom_image_url_value))); // Construct image info array $image_info = array('url' => null, 'width' => null, 'height' => null); if (is_numeric($image_data['id'])) { $main_size_meta = wp_get_attachment_image_src($image_data['id'], $size); if (empty($main_size_meta)) { return false; } $image_info['url'] = $main_size_meta[0]; $image_info['width'] = $main_size_meta[1]; $image_info['height'] = $main_size_meta[2]; } elseif (!is_null($image_data['url'])) { $image_info['url'] = $main_size_meta[0]; $image_info['width'] = $main_size_meta[1]; $image_info['height'] = $main_size_meta[2]; } else { return false; } return $image_info; }
function amt_get_breadcrumbs($user_options) { // Get plugin options $plugin_options = get_option("add_meta_tags_opts"); // Get post object $post = amt_get_queried_object($plugin_options); // Default Options $default_options = array('list_id' => 'breadcrumbs', 'show_home' => true, 'home_link_text' => 'Home', 'show_last' => true, 'show_last_as_link' => true, 'separator' => '>'); // Final options. $options = array_merge($default_options, $user_options); $bc_arr = array(); $bc_arr[] = '<!-- BEGIN Metadata added by Add-Meta-Tags WordPress plugin -->'; $bc_arr[] = '<!-- Scope BEGIN: BreadcrumbList -->'; $bc_arr[] = '<ul id="' . $options['list_id'] . '" itemprop="breadcrumb" itemscope itemtype="http://schema.org/BreadcrumbList">'; // Item counter $counter = 1; // Home link if ($options['show_home']) { $bc_arr['bc-home'] = '<li class="list-item list-item-' . $counter . '" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a class="breadcrumb breadcrumb-' . $counter . '" itemprop="item" title="' . esc_attr(get_bloginfo('name')) . '" href="' . esc_url_raw(trailingslashit(get_bloginfo('url'))) . '"><span itemprop="name">' . $options['home_link_text'] . '</span></a></li>'; //$bc_arr['bc-home-pos'] = '<meta itemprop="position" content="' . $counter . '" />'; $counter++; } // Generate breadcrumbs for parent pages, if any. if ($post->post_parent) { // Get the parent pages $ancestors = get_post_ancestors($post->ID); // Set ancestors in reverse order $ancestors = array_reverse($ancestors); // Generate items foreach ($ancestors as $ancestor) { // Add separator if (!empty($options['separator'])) { $bc_arr['bc-sep-' . $counter] = '<span class="separator separator-' . $counter . '"> ' . esc_attr($options['separator']) . ' </span>'; } $bc_arr['bc-item-' . $counter] = '<li class="list-item list-item-' . $counter . '" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a class="breadcrumb breadcrumb-' . $counter . '" itemprop="item" title="' . esc_attr(strip_tags(get_the_title($ancestor))) . '" href="' . esc_url_raw(get_permalink($ancestor)) . '"><span itemprop="name">' . esc_attr(strip_tags(get_the_title($ancestor))) . '</span></a></li>'; //$bc_arr['bc-item-' . $counter . '-pos'] = '<meta itemprop="position" content="' . $counter . '" />'; $counter++; } } // Last link if ($options['show_last']) { // Add separator if (!empty($options['separator'])) { $bc_arr['bc-sep-' . $counter] = '<span class="separator separator-' . $counter . ' separator-current"> ' . esc_attr($options['separator']) . ' </span>'; } if ($options['show_last_as_link']) { $bc_arr['bc-item-' . $counter] = '<li class="list-item list-item-' . $counter . ' list-item-current" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a class="breadcrumb breadcrumb-' . $counter . ' breadcrumb-current" itemprop="item" title="' . esc_attr(strip_tags(get_the_title($post))) . '" href="' . esc_url_raw(get_permalink($post)) . '"><span itemprop="name">' . esc_attr(strip_tags(get_the_title($post))) . '</span></a></li>'; } else { $bc_arr['bc-item-' . $counter] = '<li class="list-item list-item-' . $counter . ' list-item-current" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><span itemprop="item"><span itemprop="name">' . esc_attr(strip_tags(get_the_title($post))) . '</span></span></li>'; } //$bc_arr['bc-item-' . $counter . '-pos'] = '<meta itemprop="position" content="' . $counter . '" />'; $counter++; } $bc_arr[] = '<!-- END Metadata added by Add-Meta-Tags WordPress plugin -->'; // Allow filtering of the generated $bc_arr = apply_filters('amt_breadcrumbs', $bc_arr); return PHP_EOL . implode(PHP_EOL, $bc_arr) . PHP_EOL . PHP_EOL; }
function amt_add_metadata_review($post_body) { // Only works in content pages if (!is_singular()) { return $post_body; } $options = get_option("add_meta_tags_opts"); // Only administrators can see the review box if is_singular() is true. if (amt_check_run_metadata_review_code($options)) { if (!apply_filters('amt_metadata_review_mode_enable_alternative', false)) { return $post_body; } // Get current post object $post = amt_get_queried_object(); if (is_null($post)) { return $post_body; } // 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; } $post_body = amt_get_metadata_review($options) . '<br /><br />' . $post_body; } return $post_body; }