p =& $plugin; if ( $this->p->debug->enabled ) { $this->p->debug->mark(); } $this->charset = get_bloginfo( $show = 'charset', $filter = 'raw' ); /* * Add information about the page $mod to the body tag class. */ add_filter( 'body_class', array( $this, 'add_body_class' ), 1000, 1 ); /* * Maybe add the Validators toolbar menu. */ $add_toolbar_validate = empty( $this->p->options[ 'plugin_add_toolbar_validate' ] ) ? false : true; $add_toolbar_validate = apply_filters( 'wpsso_add_toolbar_validate', $add_toolbar_validate ); if ( $add_toolbar_validate ) { if ( $this->p->debug->enabled ) { $this->p->debug->log( 'adding validators toolbar' ); } add_action( 'admin_bar_menu', array( $this, 'add_admin_bar_menu_validate' ), WPSSO_TB_VALIDATE_MENU_ORDER, 1 ); } elseif ( $this->p->debug->enabled ) { $this->p->debug->log( 'validators toolbar is disabled' ); } /* * Maybe add title tag filters. * * Since WordPress v4.4. * * See wordpress/wp-includes/general-template.php. */ if ( ! $this->p->util->is_title_tag_disabled() ) { if ( $this->p->debug->enabled ) { $this->p->debug->log( 'adding title tag filters' ); } add_filter( 'pre_get_document_title', array( $this, 'pre_get_document_title' ), WPSSO_TITLE_TAG_PRIORITY, 1 ); add_filter( 'document_title_separator', array( $this, 'document_title_separator' ), WPSSO_TITLE_TAG_PRIORITY, 1 ); add_filter( 'document_title_parts', array( $this, 'document_title_parts' ), WPSSO_TITLE_TAG_PRIORITY, 1 ); add_filter( 'document_title', array( $this, 'document_title' ), WPSSO_TITLE_TAG_PRIORITY, 1 ); add_filter( 'get_wp_title_rss', array( $this, 'get_wp_title_rss' ), WPSSO_TITLE_TAG_PRIORITY, 1 ); add_filter( 'get_bloginfo_rss', array( $this, 'get_bloginfo_rss' ), WPSSO_TITLE_TAG_PRIORITY, 2 ); } elseif ( $this->p->debug->enabled ) { $this->p->debug->log( 'title tag is disabled' ); } } /* * Add information about the page $mod to the body tag class. * * $classes = An array of body class names. */ public function add_body_class( array $classes ) { if ( $this->p->debug->enabled ) { $this->p->debug->log( 'required call to WpssoPage->get_mod()' ); } $mod = $this->get_mod(); $classes[] = 'wpsso-' . SucomUtil::get_mod_css_id( $mod ); return (array) apply_filters( 'wpsso_body_class', $classes, $mod ); } /* * This method is hooked to the 'admin_bar_menu' action and receives a reference to the $wp_admin_bar variable. * * WpssoPost->ajax_get_validate_submenu() also calls this method directly, supplying the post ID in $post_id. */ public function add_admin_bar_menu_validate( &$wp_admin_bar, $post_id = false ) { // Pass by reference OK. if ( ! $user_id = get_current_user_id() ) { // Just in case. return; } if ( $this->p->debug->enabled ) { $this->p->debug->log( 'required call to WpssoPage->get_mod()' ); } $mod = $this->get_mod( $post_id ); if ( $mod[ 'is_comment' ] ) { $capability = 'edit_comment'; } elseif ( $mod[ 'is_post' ] ) { $capability = 'page' === $mod[ 'post_type' ] ? 'edit_page' : 'edit_post'; } elseif ( $mod[ 'is_term' ] ) { $tax_obj = get_taxonomy( $mod[ 'tax_slug' ] ); $capability = $tax_obj->cap->edit_terms; } elseif ( $mod[ 'is_user' ] ) { $capability = 'edit_user'; } else return false; // Validators are only provided for known modules (post, term, and user). if ( ! current_user_can( $capability, $mod[ 'id' ] ) ) { if ( $this->p->debug->enabled ) { $this->p->debug->log( 'exiting early: cannot ' . $capability . ' for ' . $mod[ 'name' ] . ' id ' . $mod[ 'id' ] ); } return false; // Stop here. } /* * We do not want to validate settings pages in the back-end, so validators are only provided for known * modules (post, term, and user). If we're on the front-end, validating the current webpage URL is fine. */ $validators = $this->p->util->get_validators( $mod, $form = null ); if ( ! empty( $validators ) ) { $parent_id = 'wpsso-validate'; $menu_icon = ''; $menu_title = _x( 'Validators', 'toolbar menu title', 'wpsso' ); $menu_items = array(); foreach ( $validators as $key => $el ) { if ( empty( $el[ 'type' ] ) ) { continue; } $menu_items[ $el[ 'type' ] ] = array( 'id' => $parent_id . '-' . $key, 'title' => $el[ 'type' ], 'parent' => $parent_id, 'href' => $el[ 'url' ], 'group' => false, 'meta' => array( 'class' => empty( $el[ 'url' ] ) ? 'disabled' : '', 'target' => '_blank', 'title' => $el[ 'title' ], ), ); } SucomUtil::natksort( $menu_items ); $wp_admin_bar->add_node( array( 'id' => $parent_id, 'title' => $menu_icon . $menu_title, 'parent' => false, 'href' => false, 'group' => false, 'meta' => array( 'html' => '', ), ) ); foreach ( $menu_items as $menu_item ) { $wp_admin_bar->add_node( $menu_item ); } return $parent_id; } return false; } /* * Since WordPress v4.4. * * Filters the WordPress document title before it is generated. Returning a non-empty value skips the * 'document_title_separator', 'document_title_parts', and 'document_title' filters. * * See wordpress/wp-includes/general-template.php. */ public function pre_get_document_title( $pre_title = '' ) { if ( $this->p->debug->enabled ) { $this->p->debug->log( 'received pre_title value (' . gettype( $pre_title ) . ') = ' . $pre_title ); } /* * If $pre_title is not an empty string, then maybe force an empty string to make sure the * 'document_title_separator', 'document_title_parts', and 'document_title' filters are applied. */ if ( '' !== $pre_title ) { if ( 'wp_title' !== $this->p->options[ 'plugin_title_tag' ] ) { $pre_title = ''; if ( $this->p->debug->enabled ) { $this->p->debug->log( 'returning an empty string to use document_title filters' ); } } } return $pre_title; } /* * Since WordPress v4.4. * * Filters the separator for the document title. * * See wordpress/wp-includes/general-template.php. */ public function document_title_separator( $title_sep = '-' ) { if ( $this->p->debug->enabled ) { $this->p->debug->mark(); } $title_sep = $this->maybe_get_title_sep(); // Returns default title separator (decoded). return $title_sep; } /* * Since WordPress v4.4. * * Filters the parts of the document title. * * Array ( * [title] => A Title * [page] => Page 2 * [site] => Site Name * [tagline] => * ) * * The final array is imploded into a string using the $title_sep value. * * $title = implode( ' ' . $title_sep . ' ', array_filter( $title ) ); * * See wordpress/wp-includes/general-template.php. */ public function document_title_parts( $title_parts ) { if ( $this->p->debug->enabled ) { $this->p->debug->log_arr( 'title_parts (argument)', $title_parts ); $this->p->debug->log( 'required call to WpssoPage->get_mod()' ); } /* * Note that in_the_loop() can be true in both archive and singular pages. */ $use_post = apply_filters( 'wpsso_use_post', in_the_loop() ? true : false ); $mod = $this->get_mod( $use_post ); if ( $this->p->debug->enabled ) { $this->p->debug->log_arr( 'mod', $mod ); $this->p->debug->log( 'getting title for ' . $this->p->options[ 'plugin_title_tag' ] ); } if ( 'wp_title' === $this->p->options[ 'plugin_title_tag' ] ) { if ( ! empty( $title_parts[ 'site' ] ) && empty( $title_parts[ 'title' ] ) ) { $title_parts[ 'tagline' ] = true; // Add the tagline before returning the array. } } else { $md_key = $this->p->options[ 'plugin_title_tag' ]; $max_len = $this->p->options[ 'plugin_title_tag' ]; /* * Return a decoded title, which may be used in the RSS XML
]*>/Usi', '', $desc_text );
}
}
/*
* Fallback to the image alt value.
*/
if ( empty( $desc_text ) ) {
if ( $mod[ 'is_attachment' ] && 'image' === $mod[ 'post_mime_group' ] ) {
if ( $this->p->debug->enabled ) {
$this->p->debug->log( 'falling back to attachment image alt text' );
}
$desc_text = get_metadata( 'post', $mod[ 'id' ], '_wp_attachment_image_alt', $single = true );
}
}
}
} elseif ( $this->p->debug->enabled ) {
$this->p->debug->log( 'no post type' );
}
} elseif ( $mod[ 'is_term' ] ) {
if ( $mod[ 'wp_obj' ] instanceof WP_Term ) {
if ( isset( $mod[ 'wp_obj' ]->description ) ) {
$desc_text = $mod[ 'wp_obj' ]->description;
}
} elseif ( $mod[ 'id' ] ) {
$term_obj = SucomUtilWP::get_term_object( $mod[ 'id' ], $mod[ 'tax_slug' ] );
if ( isset( $term_obj->description ) ) {
$desc_text = $term_obj->description;
}
}
if ( '' === $desc_text ) {
$desc_text = $this->p->opt->get_text( 'plugin_term_page_desc' );
}
} elseif ( $mod[ 'is_user' ] ) {
if ( $mod[ 'wp_obj' ] instanceof WP_User ) {
if ( isset( $mod[ 'wp_obj' ]->description ) ) {
$desc_text = $mod[ 'wp_obj' ]->description;
}
} elseif ( $mod[ 'id' ] ) { // Just in case.
$user_obj = SucomUtilWP::get_user_object( $mod[ 'id' ] );
if ( isset( $user_obj->description ) ) {
$desc_text = $user_obj->description;
}
}
if ( '' === $desc_text ) {
$desc_text = $this->p->opt->get_text( 'plugin_author_page_desc' );
}
} elseif ( $mod[ 'is_404' ] ) {
$desc_text = $this->p->opt->get_text( 'plugin_404_page_desc' );
} elseif ( $mod[ 'is_search' ] ) {
$desc_text = $this->p->opt->get_text( 'plugin_search_page_desc' );
} elseif ( $mod[ 'is_archive' ] ) {
if ( $mod[ 'is_date' ] ) {
if ( $mod[ 'is_year' ] ) {
$desc_text = $this->p->opt->get_text( 'plugin_year_page_desc' );
} elseif ( $mod[ 'is_month' ] ) {
$desc_text = $this->p->opt->get_text( 'plugin_month_page_desc' );
} elseif ( $mod[ 'is_day' ] ) {
$desc_text = $this->p->opt->get_text( 'plugin_day_page_desc' );
}
}
}
return apply_filters( 'wpsso_the_description', $desc_text, $mod );
}
public function get_the_excerpt( array $mod ) {
if ( $this->p->debug->enabled ) {
$this->p->debug->mark();
}
$excerpt_text = '';
if ( $mod[ 'is_post' ] ) { // Only post objects have excerpts.
if ( $mod[ 'wp_obj' ] instanceof WP_Post ) {
$excerpt_text = get_post_field( 'post_excerpt', $mod[ 'wp_obj' ] );
if ( $this->p->debug->enabled ) {
$this->p->debug->log( 'get_post_field() for WP_Post = ' . $excerpt_text );
}
} elseif ( $mod[ 'id' ] ) {
$excerpt_text = get_post_field( 'post_excerpt', $mod[ 'id' ] );
if ( $this->p->debug->enabled ) {
$this->p->debug->log( 'get_post_field() for ' . $mod[ 'name' ] . ' id ' . $mod[ 'id' ] . ' = ' . $excerpt_text );
}
}
$filter_excerpt = empty( $this->p->options[ 'plugin_filter_excerpt' ] ) ? false : true;
$filter_excerpt = apply_filters( 'wpsso_the_excerpt_filter_excerpt', $filter_excerpt );
if ( $filter_excerpt ) {
$excerpt_text = $this->p->util->safe_apply_filters( array( 'get_the_excerpt', $excerpt_text, $mod[ 'wp_obj' ] ), $mod );
if ( ! is_string( $excerpt_text ) ) {
if ( $this->p->debug->enabled ) {
$this->p->debug->log( 'excerpt_text from "get_the_excerpt" is ' . gettype( $content ) );
}
$excerpt_text = '';
}
}
}
return apply_filters( 'wpsso_the_excerpt', $excerpt_text, $mod );
}
/*
* The cache is cleared by WpssoAbstractWpMeta->clear_mod_cache().
*/
public function clear_the_content( array $mod ) {
if ( $this->p->debug->enabled ) {
$this->p->debug->mark();
}
/*
* Note that the sort order, page number, locale, amp and embed checks are provided by
* WpssoHead->get_head_cache_index() and not SucomUtil::get_mod_salt().
*/
$canonical_url = $this->p->util->get_canonical_url( $mod );
$cache_md5_pre = 'wpsso_c_';
$cache_salt = __CLASS__ . '::the_content(' . SucomUtil::get_mod_salt( $mod, $canonical_url ) . ')';
$cache_id = $cache_md5_pre . md5( $cache_salt );
if ( $this->p->debug->enabled ) {
$this->p->debug->log( 'canonical url = ' . $canonical_url );
$this->p->debug->log( 'wp cache salt = ' . $cache_salt );
$this->p->debug->log( 'wp cache id = ' . $cache_id );
}
wp_cache_delete( $cache_id );
return;
}
/*
* The cache is cleared by WpssoAbstractWpMeta->clear_mod_cache().
*/
public function get_the_content( array $mod, $flatten = true ) {
if ( $this->p->debug->enabled ) {
$this->p->debug->mark(); // Log execution time and memory usage.
$this->p->debug->log_args( array(
'mod' => $mod,
) );
}
/*
* Note that the sort order, page number, locale, amp and embed checks are provided by
* WpssoHead->get_head_cache_index() and not SucomUtil::get_mod_salt().
*/
$filter_content = empty( $this->p->options[ 'plugin_filter_content' ] ) ? false : true;
$filter_content = apply_filters( 'wpsso_the_content_filter_content', $filter_content );
$filter_blocks = apply_filters( 'wpsso_the_content_filter_blocks', true );
$canonical_url = $this->p->util->get_canonical_url( $mod );
$cache_md5_pre = 'wpsso_c_';
$cache_exp_secs = $this->p->util->get_cache_exp_secs( $cache_md5_pre, $cache_type = 'wp_cache' );
$cache_salt = __CLASS__ . '::the_content(' . SucomUtil::get_mod_salt( $mod, $canonical_url ) . ')';
$cache_id = $cache_md5_pre . md5( $cache_salt );
$cache_index = 'locale:' . SucomUtilWP::get_locale( $mod ) . '_filter:' . ( $filter_content ? 'true' : 'false' );
$cache_array = array();
if ( $this->p->debug->enabled ) {
$this->p->debug->log( 'canonical url = ' . $canonical_url );
$this->p->debug->log( 'filter content = ' . ( $filter_content ? 'true' : 'false' ) );
$this->p->debug->log( 'wp cache expire = ' . $cache_exp_secs );
$this->p->debug->log( 'wp cache salt = ' . $cache_salt );
$this->p->debug->log( 'wp cache id = ' . $cache_id );
$this->p->debug->log( 'wp cache index = ' . $cache_index );
}
if ( $cache_exp_secs > 0 ) {
$cache_array = wp_cache_get( $cache_id, __METHOD__ );
if ( isset( $cache_array[ $cache_index ] ) ) {
if ( $this->p->debug->enabled ) {
$this->p->debug->log( 'exiting early: cache index found in wp_cache' );
}
$content =& $cache_array[ $cache_index ];
/*
* Maybe put everything on one line but do not cache the re-formatted content.
*/
return $flatten ? preg_replace( '/[\s\r\n]+/s', ' ', $content ) : $content;
} else {
if ( $this->p->debug->enabled ) {
$this->p->debug->log( 'cache index not in wp_cache' );
}
if ( ! is_array( $cache_array ) ) {
$cache_array = array();
}
}
}
if ( $this->p->debug->enabled ) {
$this->p->debug->log( 'initializing new wp cache element' );
}
$cache_array[ $cache_index ] = ''; // Initialize the cache element.
$content =& $cache_array[ $cache_index ]; // Reference the cache element.
/*
* Apply the seed filter.
*
* Return false to prevent the comment or post content from being used.
*
* See WpssoIntegEcomWooCommerce->filter_the_content_seed().
*/
$content = apply_filters( 'wpsso_the_content_seed', '', $mod );
/*
* Make sure that we have a string (empty or not) to work with.
*/
if ( ! is_string( $content ) ) {
if ( $this->p->debug->enabled ) {
$this->p->debug->log( 'content from "wpsso_the_content_seed" is ' . gettype( $content ) );
}
$content = '';
} elseif ( '' !== $content ) {
if ( $this->p->debug->enabled ) {
$this->p->debug->log( 'content seed = ' . $content );
}
} elseif ( $mod[ 'is_post' ] && $mod[ 'id' ] ) {
$content = (string) $mod[ 'wp_obj' ]->post_content;
} elseif ( $mod[ 'is_comment' ] && $mod[ 'id' ] ) {
$content = (string) $mod[ 'wp_obj' ]->comment_content;
}
/*
* Remove singlepics, which we detect and use before-hand.
*/
$count = null;
$content = preg_replace( '/\[singlepic[^\]]+\]/', '', $content, $limit = -1, $count );
if ( $count ) {
if ( $this->p->debug->enabled ) {
$this->p->debug->log( $count . ' singlepic shortcode(s) removed from content' );
}
}
/*
* Maybe apply 'the_content' filter to expand shortcodes and blocks.
*/
if ( $filter_content ) {
$use_bfo = SucomUtil::get_const( 'WPSSO_CONTENT_BLOCK_FILTER_OUTPUT', true );
$mtime_max = SucomUtil::get_const( 'WPSSO_CONTENT_FILTERS_MAX_TIME', 1.50 );
if ( $this->p->debug->enabled ) {
$this->p->debug->mark( 'applying filters "the_content"' ); // Begin timer.
}
$content = $this->p->util->safe_apply_filters( array( 'the_content', $content ), $mod, $mtime_max, $use_bfo );
if ( $this->p->debug->enabled ) {
$this->p->debug->mark( 'applying filters "the_content"' ); // End timer.
}
if ( ! is_string( $content ) ) {
if ( $this->p->debug->enabled ) {
$this->p->debug->log( 'content from "the_content" is ' . gettype( $content ) );
}
$content = '';
}
} else {
/*
* Maybe fallback and apply only the 'do_blocks' filters.
*/
if ( $filter_blocks ) {
if ( $this->p->debug->enabled ) {
$this->p->debug->mark( 'calling do_blocks()' ); // Begin timer.
}
$content = do_blocks( $content );
if ( $this->p->debug->enabled ) {
$this->p->debug->mark( 'calling do_blocks()' ); // End timer.
}
if ( ! is_string( $content ) ) {
if ( $this->p->debug->enabled ) {
$this->p->debug->log( 'content from do_blocks() is ' . gettype( $content ) );
}
$content = '';
}
}
/*
* When the content filter is disabled, fallback and apply our own shortcode filter.
*/
if ( false !== strpos( $content, '[' ) ) {
if ( $this->p->debug->enabled ) {
$this->p->debug->mark( 'applying filters "wpsso_do_shortcode"' ); // Begin timer.
}
$content = apply_filters( 'wpsso_do_shortcode', $content );
if ( $this->p->debug->enabled ) {
$this->p->debug->mark( 'applying filters "wpsso_do_shortcode"' ); // End timer.
}
if ( ! is_string( $content ) ) {
if ( $this->p->debug->enabled ) {
$this->p->debug->log( 'content from "wpsso_do_shortcode" is ' . gettype( $content ) );
}
$content = '';
}
}
}
/*
* Maybe use only a certain part of the content.
*/
if ( false !== strpos( $content, 'wpsso-content' ) ) {
$content = preg_replace( '/^.*(.*).*$/Us', '$1', $content );
}
/*
* Maybe remove text between ignore markers.
*/
if ( false !== strpos( $content, 'wpsso-ignore' ) ) {
$content = preg_replace( '/.*/Us', ' ', $content );
}
/*
* Remove "Google+" link and text.
*/
if ( false !== strpos( $content, '>Google+<' ) ) {
$content = preg_replace( '/Google\+<\/a>/', ' ', $content );
}
/*
* Prefix caption text.
*/
if ( false !== strpos( $content, ' ' ) ) {
$caption_prefix = $this->p->opt->get_text( 'plugin_p_cap_prefix' );
if ( ! empty( $caption_prefix ) ) {
$content = preg_replace( '/ /', '$0' . $caption_prefix . ' ', $content );
}
}
/*
* Apply the filter.
*/
$content = apply_filters( 'wpsso_the_content', $content, $mod );
if ( ! is_string( $content ) ) {
if ( $this->p->debug->enabled ) {
$this->p->debug->log( 'content from "wpsso_the_content" is ' . gettype( $content ) );
}
$content = '';
}
/*
* Save content to non-persistant cache.
*/
if ( $cache_exp_secs > 0 ) {
/*
* Adds a group or set of groups to the list of non-persistent groups.
*
* Note that only a few caching plugins support this feature.
*/
wp_cache_add_non_persistent_groups( array( __METHOD__ ) );
wp_cache_set( $cache_id, $cache_array, __METHOD__, $cache_exp_secs );
if ( $this->p->debug->enabled ) {
$this->p->debug->log( 'content array saved to wp_cache for ' . $cache_exp_secs . ' seconds');
}
}
/*
* Maybe put everything on one line but do not cache the re-formatted content.
*/
return $flatten ? preg_replace( '/[\s\r\n]+/s', ' ', $content ) : $content;
}
/*
* Returns the content text, stripped of all HTML tags.
*/
public function get_the_text( array $mod ) {
if ( $this->p->debug->enabled ) {
$this->p->debug->mark();
}
$text = $this->get_the_content( $mod );
$text = preg_replace( '//Us', '', $text );
$text = preg_replace( '/]*>.*<\/pre>/Us', '', $text );
$text = $this->p->util->cleanup_html_tags( $text, $strip_tags = true, $use_img_alt = true );
return apply_filters( 'wpsso_the_text', $text, $mod );
}
/*
* Returns a comma delimited text string of keywords (ie. post tag names).
*/
public function get_keywords_csv( array $mod, $md_key = null ) {
if ( $this->p->debug->enabled ) {
$this->p->debug->mark();
}
$keywords = '';
$is_custom = false;
/*
* Check for custom keywords if a metadata index key is provided.
*/
if ( ! empty( $md_key ) && 'none' !== $md_key ) { // $md_key can be a string or array.
if ( ! empty( $mod[ 'obj' ] ) && $mod[ 'id' ] ) { // Just in case.
$keywords = $mod[ 'obj' ]->get_options_multi( $mod[ 'id' ], $md_key );
if ( ! empty( $keywords ) ) {
$is_custom = false;
if ( $this->p->debug->enabled ) {
$this->p->debug->log( 'custom keywords = ' . $keywords );
}
}
}
}
/*
* If there's no custom keywords, then go ahead and generate the keywords value.
*/
if ( empty( $keywords ) ) {
$tags = $this->get_tag_names( $mod );
if ( ! empty( $tags ) ) {
$keywords = SucomUtil::array_to_keywords( $tags ); // Returns a comma delimited text string.
if ( $this->p->debug->enabled ) {
$this->p->debug->log( 'keywords = ' . $keywords );
}
}
}
return apply_filters( 'wpsso_keywords', $keywords, $mod, $md_key );
}
/*
* Returns a space delimited text string of hashtags.
*/
public function get_hashtags( array $mod, $num_hashtags = false ) {
if ( $this->p->debug->enabled ) {
$this->p->debug->mark();
}
$hashtags = apply_filters( 'wpsso_hashtags_seed', '', $mod, $num_hashtags );
if ( ! empty( $hashtags ) ) { // Seed hashtags returned.
if ( $this->p->debug->enabled ) {
$this->p->debug->log( 'hashtags seed = ' . $hashtags );
}
} elseif ( false !== $num_hashtags ) {
if ( true === $num_hashtags ) {
$num_hashtags = $this->p->options[ 'og_desc_hashtags' ];
}
if ( is_numeric( $num_hashtags ) && $num_hashtags >= 1 ) {
$tags = $this->get_tag_names( $mod );
$tags = array_slice( $tags, 0, $num_hashtags );
if ( ! empty( $tags ) ) {
$hashtags = SucomUtil::array_to_hashtags( $tags );
if ( $this->p->debug->enabled ) {
$this->p->debug->log( 'hashtags = ' . $hashtags );
}
}
}
}
return apply_filters( 'wpsso_hashtags', $hashtags, $mod, $num_hashtags );
}
/*
* Returns an array of post tags.
*/
public function get_tag_names( array $mod ) {
if ( $this->p->debug->enabled ) {
$this->p->debug->mark();
}
/*
* See WpssoIntegEcomWooCommerce->filter_tag_names_seed().
*/
$tags = apply_filters( 'wpsso_tag_names_seed', null, $mod );
if ( ! is_array( $tags ) ) {
if ( $mod[ 'is_post' ] ) {
if ( 'post' === $mod[ 'post_type' ] ) {
$taxonomy = 'post_tag';
} elseif ( 'page' === $mod[ 'post_type' ] && ! empty( $this->p->options[ 'plugin_page_tags' ] ) ) {
$taxonomy = SucomUtil::get_const( 'WPSSO_PAGE_TAG_TAXONOMY' );
} else $taxonomy = '';
if ( ! empty( $mod[ 'post_type' ] ) && is_string( $mod[ 'post_type' ] ) ) { // Not empty string.
$filter_name = SucomUtil::sanitize_hookname( 'wpsso_' . $mod[ 'post_type' ] . '_tag_taxonomy' );
$taxonomy = apply_filters( $filter_name, $taxonomy, $mod );
if ( ! empty( $taxonomy ) ) {
$tags = wp_get_post_terms( $mod[ 'id' ], $taxonomy, $args = array( 'fields' => 'names' ) );
}
unset( $filter_name, $taxonomy );
}
}
}
$tags = is_array( $tags ) ? array_unique( $tags ) : array();
$tags = apply_filters( 'wpsso_tag_names', $tags, $mod );
if ( $this->p->debug->enabled ) {
$this->p->debug->log_arr( 'tags', $tags );
}
return $tags;
}
/*
* Includes parent names in the term title by default, unless the $title_sep value is false.
*
* See WpssoUtilInline->replace_callback().
* See WpssoFaqShortcodeFaq->do_shortcode().
*/
public function get_term_title( $term_id = 0, $title_sep = null ) {
if ( $this->p->debug->enabled ) {
$this->p->debug->mark();
}
$term_obj = SucomUtilWP::get_term_object( $term_id );
$term_id = isset( $term_obj->term_id ) ? $term_obj->term_id : 0;
$title_text = isset( $term_obj->name ) ? $term_obj->name : '';
$title_sep = $this->maybe_get_title_sep( $title_sep ); // Returns default title separator (decoded) if not provided.
/*
* If we have a title separator and a parent, then redefine the title text with the parent list.
*/
if ( ! empty( $title_sep ) ) {
if ( ! empty( $term_obj->parent ) ) {
$term_parents = get_term_parents_list( $term_id, $term_obj->taxonomy, $args = array(
'format' => 'name', // Use term names or slugs for display.
'separator' => ' ' . $title_sep . ' ', // Separator for between the terms.
'link' => false, // Whether to format as a link.
'inclusive' => true, // Include the term to get the parents for.
) );
if ( $term_parents && ! is_wp_error( $term_parents ) ) {
/*
* Trim excess separator.
*/
$title_text = preg_replace( '/ *' . preg_quote( $title_sep, '/' ) . ' *$/', '', $term_parents );
}
}
}
return apply_filters( 'wpsso_term_title', $title_text, $term_id, $title_sep );
}
/*
* Returns an empty or formatted string (number with minutes).
*/
public function get_reading_time( array $mod ) {
$reading_mins = $this->get_reading_mins( $mod );
return $this->fmt_reading_mins( $reading_mins );
}
public function get_reading_mins( array $mod ) {
$content = $this->get_the_content( $mod );
$words_per_min = WPSSO_READING_WORDS_PER_MIN;
$reading_mins = null;
if ( $mod[ 'obj' ] && $mod[ 'id' ] ) { // Just in case.
$reading_mins = $mod[ 'obj' ]->get_options( $mod[ 'id' ], 'schema_reading_mins' );
}
if ( null === $reading_mins ) { // Default value or no custom value.
$reading_mins = round( str_word_count( wp_strip_all_tags( $content ) ) / $words_per_min );
}
return $reading_mins;
}
public function fmt_reading_mins( $reading_mins ) {
return $reading_mins ? sprintf( _n( '%s minute', '%s minutes', $reading_mins, 'wpsso' ), $reading_mins ) : '';
}
/*
* Add a separator and a value to the left/right hand side of the title.
*/
private function add_title_part( &$title, $title_sep, $part, $hand = 'right' ) {
if ( $part ) { // Adding an empty $part would leave a hanging separator.
if ( $title ) {
if ( 'left' === $hand ) {
$title = $part . ' ' . trim( $title_sep . ' ' . $title );
} else $title = trim( $title . ' ' . $title_sep ) . ' ' . $part;
} else $title = $part; // We have a part, but no title.
}
return trim( $title );
}
/*
* Public method to sanitize arguments or modify values for get_title(), get_description(), etc.
*
* Returns default ellipsis (decoded) if not provided (ie. $ellipsis = null).
*/
private function maybe_get_ellipsis( $ellipsis = null ) {
if ( null === $ellipsis ) {
$ellipsis = html_entity_decode( $this->p->options[ 'og_ellipsis' ], ENT_QUOTES, $this->charset );
}
return $ellipsis;
}
/*
* Public method to sanitize arguments or modify values for get_title(), get_description(), etc.
*
* Returns default title separator (decoded) if not provided (ie. $title_sep = null).
*/
private function maybe_get_title_sep( $title_sep = null ) {
if ( null === $title_sep ) {
$title_sep = html_entity_decode( $this->p->options[ 'og_title_sep' ], ENT_QUOTES, $this->charset );
}
return $title_sep;
}
/*
* Public method to sanitize arguments or modify values for get_title(), get_description(), etc.
*/
private function maybe_get_opt_multi( $mod, $md_key ) {
if ( ! empty( $md_key ) && 'none' !== $md_key ) { // Make sure we have something to work with.
if ( ! empty( $mod[ 'obj' ] ) && $mod[ 'id' ] ) { // Just in case.
return $mod[ 'obj' ]->get_options_multi( $mod[ 'id' ], $md_key );
}
}
return null;
}
/*
* Private method to sanitize arguments or modify values for get_title(), get_description(), etc.
*
* Returns an array of metadata keys (can be empty).
*
* $md_key = true | false | string | array
*/
private function sanitize_md_key( $md_key, $def_key = '' ) {
if ( false === $md_key || 'none' === $md_key || '' === $md_key ) { // Nothing to do.
return array();
} elseif ( true === $md_key || null === $md_key || $md_key === $def_key ) { // Return the default key array.
return WpssoConfig::get_md_keys_fallback( $def_key );
}
if ( ! is_array( $md_key ) ) {
$md_key = WpssoConfig::get_md_keys_fallback( $md_key );
}
foreach ( WpssoConfig::get_md_keys_fallback( $def_key ) as $key ) {
$md_key[] = $key;
}
$md_key = array_unique( $md_key ); // Just in case.
return $md_key;
}
/*
* Private method to sanitize arguments or modify values for get_title(), get_description(), etc.
*
* Return 0 by default.
*/
private function sanitize_max_len( $max_len ) {
if ( is_numeric( $max_len ) ) {
return (int) $max_len;
} elseif ( is_array( $max_len ) && isset( $max_len[ 'max' ] ) ) {
return (int) $max_len[ 'max' ];
} elseif ( is_string( $max_len ) ) {
$input_limits = WpssoConfig::get_input_limits( $max_len ); // Uses a local cache.
if ( ! empty( $input_limits[ 'max' ] ) ) {
return (int) $input_limits[ 'max' ];
}
}
return 0;
}
}
}