resolver = $resolver;
$this->settings = $settings;
$this->graph = $graph;
$this->trail = $trail;
}
/**
* Registers hooks.
*/
public function register() {
add_filter( 'pre_get_document_title', array( $this, 'filter_title' ), 20 );
add_filter( 'wp_robots', array( $this, 'filter_robots' ), 20 );
remove_action( 'wp_head', 'rel_canonical' );
add_action( 'wp_head', array( $this, 'print_tags' ), 1 );
}
/**
* Supplies the
through core's title-tag support.
*
* @param string $title Title from earlier filters.
* @return string Escaped title.
*/
public function filter_title( $title ) {
$data = $this->resolver->for_request();
if ( ! $data || '' === $data['title'] ) {
return $title;
}
// Core does not escape values returned from this filter.
return esc_html( $data['title'] );
}
/**
* Adds noindex/nofollow through core's wp_robots API so there is one robots tag.
*
* @param array $robots Directives.
* @return array
*/
public function filter_robots( $robots ) {
$data = $this->resolver->for_request();
if ( ! $data ) {
return $robots;
}
if ( $data['noindex'] ) {
$robots['noindex'] = true;
}
if ( $data['nofollow'] ) {
$robots['nofollow'] = true;
}
return $robots;
}
/**
* Prints description, canonical, Open Graph and Twitter tags.
*/
public function print_tags() {
$data = $this->resolver->for_request();
if ( ! $data ) {
// Unmanaged view (e.g. an attachment page): keep core's canonical.
if ( is_singular() ) {
rel_canonical();
}
return;
}
echo "\n\n";
foreach ( $this->tags( $data ) as $tag ) {
echo $tag . "\n"; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- built from escaped parts in tags().
}
if ( $this->settings->get( 'schema_enabled' ) ) {
$json = Graph::to_json( $this->graph->build( $data, $this->trail->for_request() ) );
echo '\n"; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- JSON encoded with JSON_HEX_TAG.
}
echo "\n\n";
}
/**
* Builds escaped tag strings.
*
* @param array $data Resolved values.
* @return string[]
*/
public function tags( array $data ) {
$tags = array();
$canonical = $data['noindex'] ? '' : $data['canonical'];
if ( '' !== $data['description'] ) {
$tags[] = $this->meta( 'name', 'description', $data['description'] );
}
if ( '' !== $canonical ) {
$tags[] = '';
}
$title = '' !== $data['title'] ? $data['title'] : wp_strip_all_tags( wp_get_document_title() );
$og_title = ! empty( $data['og_title'] ) ? $data['og_title'] : $title;
$og_desc = ! empty( $data['og_desc'] ) ? $data['og_desc'] : $data['description'];
$tags[] = $this->meta( 'property', 'og:locale', get_locale() );
$tags[] = $this->meta( 'property', 'og:type', $data['og_type'] );
$tags[] = $this->meta( 'property', 'og:title', $og_title );
if ( '' !== $og_desc ) {
$tags[] = $this->meta( 'property', 'og:description', $og_desc );
}
if ( '' !== $canonical ) {
$tags[] = '';
}
$tags[] = $this->meta( 'property', 'og:site_name', wp_strip_all_tags( get_bloginfo( 'name' ) ) );
if ( '' !== $data['image'] ) {
$tags[] = '';
}
if ( '' !== $data['published'] ) {
$tags[] = $this->meta( 'property', 'article:published_time', $data['published'] );
$tags[] = $this->meta( 'property', 'article:modified_time', $data['modified'] );
}
$tags[] = $this->meta( 'name', 'twitter:card', '' !== $data['image'] ? 'summary_large_image' : 'summary' );
$site = (string) $this->settings->get( 'twitter_site' );
if ( '' !== $site ) {
$tags[] = $this->meta( 'name', 'twitter:site', '@' . $site );
}
/**
* Filters the escaped head tags before printing.
*
* @param string[] $tags Tag strings.
* @param array $data Resolved values.
*/
return apply_filters( 'orbitstem_seo_head_tags', $tags, $data );
}
/**
* One escaped meta tag.
*
* @param string $attr 'name' or 'property'.
* @param string $key Attribute value.
* @param string $value Content.
* @return string
*/
private function meta( $attr, $key, $value ) {
return sprintf( '', $attr, esc_attr( $key ), esc_attr( $value ) );
}
}