/** * Retrieve link url and text based on post id * * @param int $id Post ID. * * @return array Array of link text and url */ private function get_link_info_for_id($id) { $link = array(); $link['url'] = get_permalink($id); $link['text'] = YMBESEO_Meta::get_value('bctitle', $id); if ($link['text'] === '') { $link['text'] = strip_tags(get_the_title($id)); } /** * Filter: 'wp_seo_get_bc_title' - Allow developer to filter the Yoast SEO Breadcrumb title. * * @api string $link_text The Breadcrumb title text * * @param int $link_id The post ID */ $link['text'] = apply_filters('wp_seo_get_bc_title', $link['text'], $id); return $link; }
/** * Retrieve the post/page/cpt's focus keyword for use as replacement string. * * @return string|null */ private function retrieve_focuskw() { $replacement = null; if (!empty($this->args->ID)) { $focus_kw = YMBESEO_Meta::get_value('focuskw', $this->args->ID); if ($focus_kw !== '') { $replacement = $focus_kw; } } return $replacement; }
/** * Retrieve images from the post meta values * * @return bool */ private function image_from_meta_values_output() { foreach (array('twitter-image', 'opengraph-image') as $tag) { $img = YMBESEO_Meta::get_value($tag); if ($img !== '') { $this->image_output($img); return true; } } return false; }
/** * Based on the redirect meta value, this function determines whether it should redirect the current post / page. * * @return boolean */ function page_redirect() { if (is_singular()) { global $post; if (!isset($post) || !is_object($post)) { return false; } $redir = YMBESEO_Meta::get_value('redirect', $post->ID); if ($redir !== '') { wp_redirect($redir, 301); exit; } } return false; }
/** * Adds an SEO admin bar menu with several options. If the current user is an admin he can also go straight to several settings menu's from here. */ function YMBESEO_admin_bar_menu() { // If the current user can't write posts, this is all of no use, so let's not output an admin menu. if (!current_user_can('edit_posts')) { return; } global $wp_admin_bar, $post; $focuskw = ''; $score = ''; $seo_url = get_admin_url(null, 'admin.php?page=YMBESEO_dashboard'); if ((is_singular() || is_admin() && in_array($GLOBALS['pagenow'], array('post.php', 'post-new.php'), true)) && isset($post) && is_object($post) && apply_filters('YMBESEO_use_page_analysis', true) === true) { $focuskw = YMBESEO_Meta::get_value('focuskw', $post->ID); $perc_score = YMBESEO_Meta::get_value('linkdex', $post->ID); $calc_score = YMBESEO_Utils::calc($perc_score, '/', 10, true); $txtscore = YMBESEO_Utils::translate_score($calc_score); $title = YMBESEO_Utils::translate_score($calc_score, false); $score = '<div title="' . esc_attr($title) . '" class="' . esc_attr('wpseo-score-icon ' . $txtscore . ' ' . $perc_score) . '"></div>'; $seo_url = get_edit_post_link($post->ID); if ($txtscore !== 'na') { $seo_url .= '#YMBESEO_linkdex'; } } $wp_admin_bar->add_menu(array('id' => 'wpseo-menu', 'title' => __('SEO', 'ymbeseo') . $score, 'href' => $seo_url)); $wp_admin_bar->add_menu(array('parent' => 'wpseo-menu', 'id' => 'wpseo-kwresearch', 'title' => __('Keyword Research', 'ymbeseo'), '#')); $wp_admin_bar->add_menu(array('parent' => 'wpseo-kwresearch', 'id' => 'wpseo-adwordsexternal', 'title' => __('AdWords External', 'ymbeseo'), 'href' => 'http://adwords.google.com/keywordplanner', 'meta' => array('target' => '_blank'))); $wp_admin_bar->add_menu(array('parent' => 'wpseo-kwresearch', 'id' => 'wpseo-googleinsights', 'title' => __('Google Insights', 'ymbeseo'), 'href' => 'http://www.google.com/insights/search/#q=' . urlencode($focuskw) . '&cmpt=q', 'meta' => array('target' => '_blank'))); $wp_admin_bar->add_menu(array('parent' => 'wpseo-kwresearch', 'id' => 'wpseo-wordtracker', 'title' => __('SEO Book', 'ymbeseo'), 'href' => 'http://tools.seobook.com/keyword-tools/seobook/?keyword=' . urlencode($focuskw), 'meta' => array('target' => '_blank'))); if (!is_admin()) { $url = YMBESEO_Frontend::get_instance()->canonical(false); if (is_string($url)) { $wp_admin_bar->add_menu(array('parent' => 'wpseo-menu', 'id' => 'wpseo-analysis', 'title' => __('Analyze this page', 'ymbeseo'), '#')); $wp_admin_bar->add_menu(array('parent' => 'wpseo-analysis', 'id' => 'wpseo-inlinks-ose', 'title' => __('Check Inlinks (OSE)', 'ymbeseo'), 'href' => '//moz.com/researchtools/ose/links?site=' . urlencode($url), 'meta' => array('target' => '_blank'))); $wp_admin_bar->add_menu(array('parent' => 'wpseo-analysis', 'id' => 'wpseo-kwdensity', 'title' => __('Check Keyword Density', 'ymbeseo'), 'href' => '//www.zippy.co.uk/keyworddensity/index.php?url=' . urlencode($url) . '&keyword=' . urlencode($focuskw), 'meta' => array('target' => '_blank'))); $wp_admin_bar->add_menu(array('parent' => 'wpseo-analysis', 'id' => 'wpseo-cache', 'title' => __('Check Google Cache', 'ymbeseo'), 'href' => '//webcache.googleusercontent.com/search?strip=1&q=cache:' . urlencode($url), 'meta' => array('target' => '_blank'))); $wp_admin_bar->add_menu(array('parent' => 'wpseo-analysis', 'id' => 'wpseo-header', 'title' => __('Check Headers', 'ymbeseo'), 'href' => '//quixapp.com/headers/?r=' . urlencode($url), 'meta' => array('target' => '_blank'))); $wp_admin_bar->add_menu(array('parent' => 'wpseo-analysis', 'id' => 'wpseo-richsnippets', 'title' => __('Check Rich Snippets', 'ymbeseo'), 'href' => '//www.google.com/webmasters/tools/richsnippets?q=' . urlencode($url), 'meta' => array('target' => '_blank'))); $wp_admin_bar->add_menu(array('parent' => 'wpseo-analysis', 'id' => 'wpseo-facebookdebug', 'title' => __('Facebook Debugger', 'ymbeseo'), 'href' => '//developers.facebook.com/tools/debug/og/object?q=' . urlencode($url), 'meta' => array('target' => '_blank'))); $wp_admin_bar->add_menu(array('parent' => 'wpseo-analysis', 'id' => 'wpseo-pinterestvalidator', 'title' => __('Pinterest Rich Pins Validator', 'ymbeseo'), 'href' => '//developers.pinterest.com/rich_pins/validator/?link=' . urlencode($url), 'meta' => array('target' => '_blank'))); $wp_admin_bar->add_menu(array('parent' => 'wpseo-analysis', 'id' => 'wpseo-htmlvalidation', 'title' => __('HTML Validator', 'ymbeseo'), 'href' => '//validator.w3.org/check?uri=' . urlencode($url), 'meta' => array('target' => '_blank'))); $wp_admin_bar->add_menu(array('parent' => 'wpseo-analysis', 'id' => 'wpseo-cssvalidation', 'title' => __('CSS Validator', 'ymbeseo'), 'href' => '//jigsaw.w3.org/css-validator/validator?uri=' . urlencode($url), 'meta' => array('target' => '_blank'))); $wp_admin_bar->add_menu(array('parent' => 'wpseo-analysis', 'id' => 'wpseo-pagespeed', 'title' => __('Google Page Speed Test', 'ymbeseo'), 'href' => '//developers.google.com/speed/pagespeed/insights/?url=' . urlencode($url), 'meta' => array('target' => '_blank'))); $wp_admin_bar->add_menu(array('parent' => 'wpseo-analysis', 'id' => 'wpseo-modernie', 'title' => __('Modern IE Site Scan', 'ymbeseo'), 'href' => '//www.modern.ie/en-us/report#' . urlencode($url), 'meta' => array('target' => '_blank'))); $wp_admin_bar->add_menu(array('parent' => 'wpseo-analysis', 'id' => 'wpseo-google-mobile-friendly', 'title' => __('Mobile-Friendly Test', 'ymbeseo'), 'href' => 'https://www.google.com/webmasters/tools/mobile-friendly/?url=' . urlencode($url), 'meta' => array('target' => '_blank'))); } } $admin_menu = current_user_can('manage_options'); if (!$admin_menu && is_multisite()) { $options = get_site_option('YMBESEO_ms'); $admin_menu = $options['access'] === 'superadmin' && is_super_admin(); } // @todo: add links to bulk title and bulk description edit pages. if ($admin_menu) { $wp_admin_bar->add_menu(array('parent' => 'wpseo-menu', 'id' => 'wpseo-settings', 'title' => __('SEO Settings', 'ymbeseo'))); $wp_admin_bar->add_menu(array('parent' => 'wpseo-settings', 'id' => 'wpseo-general', 'title' => __('General', 'ymbeseo'), 'href' => admin_url('admin.php?page=YMBESEO_dashboard'))); $wp_admin_bar->add_menu(array('parent' => 'wpseo-settings', 'id' => 'wpseo-titles', 'title' => __('Titles & Metas', 'ymbeseo'), 'href' => admin_url('admin.php?page=YMBESEO_titles'))); $wp_admin_bar->add_menu(array('parent' => 'wpseo-settings', 'id' => 'wpseo-social', 'title' => __('Social', 'ymbeseo'), 'href' => admin_url('admin.php?page=YMBESEO_social'))); $wp_admin_bar->add_menu(array('parent' => 'wpseo-settings', 'id' => 'wpseo-xml', 'title' => __('XML Sitemaps', 'ymbeseo'), 'href' => admin_url('admin.php?page=YMBESEO_xml'))); $wp_admin_bar->add_menu(array('parent' => 'wpseo-settings', 'id' => 'wpseo-YMBESEO_advanced', 'title' => __('Advanced', 'ymbeseo'), 'href' => admin_url('admin.php?page=YMBESEO_advanced'))); $wp_admin_bar->add_menu(array('parent' => 'wpseo-settings', 'id' => 'wpseo-licenses', 'title' => __('Extensions', 'ymbeseo'), 'href' => admin_url('admin.php?page=YMBESEO_licenses'))); } }
/** * Build a sub-sitemap for a specific post type -- example.com/post_type-sitemap.xml * * @param string $post_type Registered post type's slug. */ function build_post_type_map($post_type) { global $wpdb; if (isset($this->options['post_types-' . $post_type . '-not_in_sitemap']) && $this->options['post_types-' . $post_type . '-not_in_sitemap'] === true || in_array($post_type, array('revision', 'nav_menu_item')) || apply_filters('YMBESEO_sitemap_exclude_post_type', false, $post_type)) { $this->bad_sitemap = true; return; } $output = ''; $steps = 100 > $this->max_entries ? $this->max_entries : 100; $n = (int) $this->n; $offset = $n > 1 ? ($n - 1) * $this->max_entries : 0; $total = $offset + $this->max_entries; $join_filter = apply_filters('YMBESEO_typecount_join', '', $post_type); $where_filter = apply_filters('YMBESEO_typecount_where', '', $post_type); $query = $wpdb->prepare("SELECT COUNT(ID) FROM {$wpdb->posts} {$join_filter} WHERE post_status IN ('publish','inherit') AND post_password = '' AND post_date != '0000-00-00 00:00:00' AND post_type = %s " . $where_filter, $post_type); $typecount = $wpdb->get_var($query); if ($total > $typecount) { $total = $typecount; } if ($n === 1) { $front_id = get_option('page_on_front'); if (!$front_id && ($post_type == 'post' || $post_type == 'page')) { $output .= $this->sitemap_url(array('loc' => $this->home_url, 'pri' => 1, 'chf' => $this->filter_frequency('homepage', 'daily', $this->home_url))); } elseif ($front_id && $post_type == 'post') { $page_for_posts = get_option('page_for_posts'); if ($page_for_posts) { $page_for_posts_url = get_permalink($page_for_posts); $output .= $this->sitemap_url(array('loc' => $page_for_posts_url, 'pri' => 1, 'chf' => $this->filter_frequency('blogpage', 'daily', $page_for_posts_url))); unset($page_for_posts_url); } } $archive_url = get_post_type_archive_link($post_type); /** * Filter: 'YMBESEO_sitemap_post_type_archive_link' - Allow changing the URL Yoast SEO uses in the XML sitemap for this post type archive. * * @api float $archive_url The URL of this archive * * @param string $post_type The post type this archive is for. */ $archive_url = apply_filters('YMBESEO_sitemap_post_type_archive_link', $archive_url, $post_type); if ($archive_url) { /** * Filter: 'YMBESEO_xml_post_type_archive_priority' - Allow changing the priority of the URL Yoast SEO uses in the XML sitemap. * * @api float $priority The priority for this URL, ranging from 0 to 1 * * @param string $post_type The post type this archive is for. */ $output .= $this->sitemap_url(array('loc' => $archive_url, 'pri' => apply_filters('YMBESEO_xml_post_type_archive_priority', 0.8, $post_type), 'chf' => $this->filter_frequency($post_type . '_archive', 'weekly', $archive_url), 'mod' => $this->get_last_modified($post_type))); } } if ($typecount == 0 && empty($archive)) { $this->bad_sitemap = true; return; } $stackedurls = array(); // Make sure you're wpdb->preparing everything you throw into this!! $join_filter = apply_filters('YMBESEO_posts_join', false, $post_type); $where_filter = apply_filters('YMBESEO_posts_where', false, $post_type); $status = $post_type == 'attachment' ? 'inherit' : 'publish'; $parsed_home = parse_url($this->home_url); $host = ''; $scheme = 'http'; if (isset($parsed_home['host']) && !empty($parsed_home['host'])) { $host = str_replace('www.', '', $parsed_home['host']); } if (isset($parsed_home['scheme']) && !empty($parsed_home['scheme'])) { $scheme = $parsed_home['scheme']; } /** * We grab post_date, post_name and post_status too so we can throw these objects * into get_permalink, which saves a get_post call for each permalink. */ while ($total > $offset) { // Optimized query per this thread: http://wordpress.org/support/topic/plugin-wordpress-seo-by-yoast-performance-suggestion. // Also see http://explainextended.com/2009/10/23/mysql-order-by-limit-performance-late-row-lookups/. $query = $wpdb->prepare("SELECT l.ID, post_title, post_content, post_name, post_parent, post_modified_gmt, post_date, post_date_gmt FROM ( SELECT ID FROM {$wpdb->posts} {$join_filter} WHERE post_status = '%s' AND post_password = '' AND post_type = '%s' AND post_date != '0000-00-00 00:00:00' {$where_filter} ORDER BY post_modified ASC LIMIT %d OFFSET %d ) o JOIN {$wpdb->posts} l ON l.ID = o.ID ORDER BY l.ID", $status, $post_type, $steps, $offset); $posts = $wpdb->get_results($query); $post_ids = array(); foreach ($posts as $p) { $post_ids[] = $p->ID; } unset($p); if (count($post_ids) > 0) { update_meta_cache('post', $post_ids); $imploded_post_ids = implode($post_ids, ','); $attachments = $this->get_attachments($imploded_post_ids); $thumbnails = $this->get_thumbnails($imploded_post_ids); $this->do_attachment_ids_caching($attachments, $thumbnails); unset($imploded_post_ids); } unset($post_ids); $offset = $offset + $steps; $posts_to_exclude = explode(',', $this->options['excluded-posts']); if (is_array($posts) && $posts !== array()) { foreach ($posts as $p) { $p->post_type = $post_type; $p->post_status = 'publish'; $p->filter = 'sample'; if (YMBESEO_Meta::get_value('meta-robots-noindex', $p->ID) === '1') { continue; } if (in_array($p->ID, $posts_to_exclude)) { continue; } $url = array(); if (isset($p->post_modified_gmt) && $p->post_modified_gmt != '0000-00-00 00:00:00' && $p->post_modified_gmt > $p->post_date_gmt) { $url['mod'] = $p->post_modified_gmt; } else { if ('0000-00-00 00:00:00' != $p->post_date_gmt) { $url['mod'] = $p->post_date_gmt; } else { $url['mod'] = $p->post_date; // TODO does this ever happen? will wreck timezone later R. } } $url['loc'] = get_permalink($p); /** * Filter: 'YMBESEO_xml_sitemap_post_url' - Allow changing the URL Yoast SEO uses in the XML sitemap. * * Note that only absolute local URLs are allowed as the check after this removes external URLs. * * @api string $url URL to use in the XML sitemap * * @param object $p Post object for the URL. */ $url['loc'] = apply_filters('YMBESEO_xml_sitemap_post_url', $url['loc'], $p); $url['chf'] = $this->filter_frequency($post_type . '_single', 'weekly', $url['loc']); /** * Do not include external URLs. * @see https://wordpress.org/plugins/page-links-to/ can rewrite permalinks to external URLs. */ if (false === strpos($url['loc'], $this->home_url)) { continue; } $canonical = YMBESEO_Meta::get_value('canonical', $p->ID); if ($canonical !== '' && $canonical !== $url['loc']) { /* Let's assume that if a canonical is set for this page and it's different from the URL of this post, that page is either already in the XML sitemap OR is on an external site, either way, we shouldn't include it here. */ continue; } else { if ($this->options['trailingslash'] === true && $p->post_type != 'post') { $url['loc'] = trailingslashit($url['loc']); } } unset($canonical); $url['pri'] = $this->calculate_priority($p); $url['images'] = array(); $content = $p->post_content; $content = '<p><img src="' . $this->image_url(get_post_thumbnail_id($p->ID)) . '" alt="' . $p->post_title . '" /></p>' . $content; if (preg_match_all('`<img [^>]+>`', $content, $matches)) { $url['images'] = $this->parse_matched_images($matches, $p, $scheme, $host); } unset($content, $matches, $img); if (strpos($p->post_content, '[gallery') !== false) { if (is_array($attachments) && $attachments !== array()) { $url['images'] = $this->parse_attachments($attachments, $p); } unset($attachment, $src, $image, $alt); } $url['images'] = apply_filters('YMBESEO_sitemap_urlimages', $url['images'], $p->ID); if (!in_array($url['loc'], $stackedurls)) { // Use this filter to adjust the entry before it gets added to the sitemap. $url = apply_filters('YMBESEO_sitemap_entry', $url, 'post', $p); if (is_array($url) && $url !== array()) { $output .= $this->sitemap_url($url); $stackedurls[] = $url['loc']; } } // Clear the post_meta and the term cache for the post // wp_cache_delete( $p->ID, 'post_meta' ); // clean_object_term_cache( $p->ID, $post_type ); // as we no longer need it now. } unset($p, $url); } } if (empty($output)) { $this->bad_sitemap = true; return; } $this->sitemap = '<urlset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:image="http://www.google.com/schemas/sitemap-image/1.1" '; $this->sitemap .= 'xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd" '; $this->sitemap .= 'xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">' . "\n"; $this->sitemap .= $output; // Filter to allow adding extra URLs, only do this on the first XML sitemap, not on all. if ($n === 1) { $this->sitemap .= apply_filters('YMBESEO_sitemap_' . $post_type . '_content', ''); } $this->sitemap .= '</urlset>'; }
/** * If opengraph-image is set, call add_image and return true * * @return bool */ private function get_opengraph_image() { $ogimg = YMBESEO_Meta::get_value('opengraph-image'); if ($ogimg !== '') { $this->add_image($ogimg); return true; } }
/** * Output the Google+ specific image */ public function google_plus_image() { if (is_singular()) { $image = YMBESEO_Meta::get_value('google-plus-image'); /** * Filter: 'YMBESEO_googleplus_image' - Allow changing the Google+ image * * @api string $img Image URL string */ $image = trim(apply_filters('YMBESEO_googleplus_image', $image)); if (is_string($image) && $image !== '') { echo '<meta itemprop="image" content="', esc_url($image), '">', "\n"; } } }
/** * Get the value from the post custom values * * @deprecated 1.5.0 * @deprecated use YMBESEO_Meta::get_value() * @see YMBESEO_Meta::get_value() * * @param string $val Internal name of the value to get. * @param int $postid Post ID of the post to get the value for. * * @return string */ function YMBESEO_get_value($val, $postid = 0) { _deprecated_function(__FUNCTION__, 'WPSEO 1.5.0', 'YMBESEO_Meta::get_value()'); return YMBESEO_Meta::get_value($val, $postid); }