Jetpack_SEO_Titles

Class containing utility static methods for managing SEO custom title formats.

Defined (1)

The class is defined in the following location(s).

/modules/seo-tools/jetpack-seo-titles.php  
  1. class Jetpack_SEO_Titles { 
  2. /** 
  3. * Site option name used to store custom title formats. 
  4. */ 
  5. const TITLE_FORMATS_OPTION = 'advanced_seo_title_formats'; 
  6.  
  7. /** 
  8. * Retrieves custom title formats from site option. 
  9. * @return array Array of custom title formats, or empty array. 
  10. */ 
  11. public static function get_custom_title_formats() { 
  12. if( Jetpack_SEO_Utils::is_enabled_jetpack_seo() ) { 
  13. return get_option( self::TITLE_FORMATS_OPTION, array() ); 
  14.  
  15. return array(); 
  16.  
  17. /** 
  18. * Returns tokens that are currently supported for each page type. 
  19. * @return array Array of allowed token strings. 
  20. */ 
  21. public static function get_allowed_tokens() { 
  22. return array( 
  23. 'front_page' => array( 'site_name', 'tagline' ),  
  24. 'posts' => array( 'site_name', 'tagline', 'post_title' ),  
  25. 'pages' => array( 'site_name', 'tagline', 'page_title' ),  
  26. 'groups' => array( 'site_name', 'tagline', 'group_title' ),  
  27. 'archives' => array( 'site_name', 'tagline', 'date' ),  
  28. ); 
  29.  
  30. /** 
  31. * Used to modify the default title with custom SEO title. 
  32. * @param string $default_title Default title for current page. 
  33. * @return string Custom title with replaced tokens or default title. 
  34. */ 
  35. public static function get_custom_title( $default_title = '' ) { 
  36. // Don't filter title for unsupported themes. 
  37. if ( self::is_conflicted_theme() ) { 
  38. return $default_title; 
  39.  
  40. $page_type = self::get_page_type(); 
  41.  
  42. // Keep default title if invalid page type is supplied. 
  43. if ( empty( $page_type ) ) { 
  44. return $default_title; 
  45.  
  46. $title_formats = self::get_custom_title_formats(); 
  47.  
  48. // Keep default title if user has not defined custom title for this page type. 
  49. if ( empty( $title_formats[ $page_type ] ) ) { 
  50. return $default_title; 
  51.  
  52. if ( ! Jetpack_SEO_Utils::is_enabled_jetpack_seo() ) { 
  53. return $default_title; 
  54.  
  55. $custom_title = ''; 
  56. $format_array = $title_formats[ $page_type ]; 
  57.  
  58. foreach ( $format_array as $item ) { 
  59. if ( 'token' == $item['type'] ) { 
  60. $custom_title .= self::get_token_value( $item['value'] ); 
  61. } else { 
  62. $custom_title .= $item['value']; 
  63.  
  64. return esc_html( $custom_title ); 
  65.  
  66. /** 
  67. * Returns string value for given token. 
  68. * @param string $token_name The token name value that should be replaced. 
  69. * @return string Token replacement for current site, or empty string for unknown token name. 
  70. */ 
  71. public static function get_token_value( $token_name ) { 
  72.  
  73. switch ( $token_name ) { 
  74. case 'site_name': 
  75. return get_bloginfo( 'name' ); 
  76.  
  77. case 'tagline': 
  78. return get_bloginfo( 'description' ); 
  79.  
  80. case 'post_title': 
  81. case 'page_title': 
  82. return get_the_title(); 
  83.  
  84. case 'group_title': 
  85. return single_tag_title( '', false ); 
  86.  
  87. case 'date': 
  88. return self::get_date_for_title(); 
  89.  
  90. default: 
  91. return ''; 
  92.  
  93. /** 
  94. * Returns page type for current page. We need this helper in order to determine what 
  95. * user defined title format should be used for custom title. 
  96. * @return string|bool Type of current page or false if unsupported. 
  97. */ 
  98. public static function get_page_type() { 
  99.  
  100. if ( is_front_page() ) { 
  101. return 'front_page'; 
  102.  
  103. if ( is_category() || is_tag() ) { 
  104. return 'groups'; 
  105.  
  106. if ( is_archive() && ! is_author() ) { 
  107. return 'archives'; 
  108.  
  109. if ( is_page() ) { 
  110. return 'pages'; 
  111.  
  112. if ( is_singular() ) { 
  113. return 'posts'; 
  114.  
  115. return false; 
  116.  
  117. /** 
  118. * Returns the value that should be used as a replacement for the date token,  
  119. * depending on the archive path specified. 
  120. * @return string Token replacement for a given date, or empty string if no date is specified. 
  121. */ 
  122. public static function get_date_for_title() { 
  123. // If archive year, month, and day are specified. 
  124. if ( is_day() ) { 
  125. return get_the_date(); 
  126.  
  127. // If archive year, and month are specified. 
  128. if ( is_month() ) { 
  129. return trim( single_month_title( ' ', false ) ); 
  130.  
  131. // Only archive year is specified. 
  132. if ( is_year() ) { 
  133. return get_query_var( 'year' ); 
  134.  
  135. return ''; 
  136.  
  137. /** 
  138. * Checks if current theme is defining custom title that won't work nicely 
  139. * with our custom SEO title override. 
  140. * @return bool True if current theme sets custom title, false otherwise. 
  141. */ 
  142. public static function is_conflicted_theme() { 
  143. /** 
  144. * Can be used to specify a list of themes that use their own custom title format. 
  145. * If current site is using one of the themes listed as conflicting,  
  146. * Jetpack SEO custom title formats will be disabled. 
  147. * @module seo-tools 
  148. * @since 4.4.0 
  149. * @param array List of conflicted theme names. Defaults to empty array. 
  150. */ 
  151. $conflicted_themes = apply_filters( 'jetpack_seo_custom_title_conflicted_themes', array() ); 
  152.  
  153. return isset( $conflicted_themes[ get_option( 'template' ) ] ); 
  154.  
  155. /** 
  156. * Checks if a given format conforms to predefined SEO title templates. 
  157. * Every format type and token must be whitelisted. 
  158. * @see get_allowed_tokens() 
  159. * @param array $title_formats Template of SEO title to check. 
  160. * @return bool True if the formats are valid, false otherwise. 
  161. */ 
  162. public static function are_valid_title_formats( $title_formats ) { 
  163. $allowed_tokens = self::get_allowed_tokens(); 
  164.  
  165. if ( ! is_array( $title_formats ) ) { 
  166. return false; 
  167.  
  168. foreach ( $title_formats as $format_type => $format_array ) { 
  169. if ( ! in_array( $format_type, array_keys( $allowed_tokens ) ) ) { 
  170. return false; 
  171.  
  172. if ( '' === $format_array ) { 
  173. continue; 
  174.  
  175. if ( ! is_array( $format_array ) ) { 
  176. return false; 
  177.  
  178. foreach ( $format_array as $item ) { 
  179. if ( empty( $item['type'] ) || empty( $item['value'] ) ) { 
  180. return false; 
  181.  
  182. if ( 'token' == $item['type'] ) { 
  183. if ( ! in_array( $item['value'], $allowed_tokens[ $format_type ] ) ) { 
  184. return false; 
  185.  
  186. return true; 
  187.  
  188. /** 
  189. * Combines the previous values of title formats, stored as array in site options,  
  190. * with the new values that are provided. 
  191. * @param array $new_formats Array containing new title formats. 
  192. * @return array $result Array of updated title formats, or empty array if no update was performed. 
  193. */ 
  194. public static function update_title_formats( $new_formats ) { 
  195. // Empty array signals that custom title shouldn't be used. 
  196. $empty_formats = array( 
  197. 'front_page' => array(),  
  198. 'posts' => array(),  
  199. 'pages' => array(),  
  200. 'groups' => array(),  
  201. 'archives' => array(),  
  202. ); 
  203.  
  204. $previous_formats = self::get_custom_title_formats(); 
  205.  
  206. $result = array_merge( $empty_formats, $previous_formats, $new_formats ); 
  207.  
  208. if ( update_option( self::TITLE_FORMATS_OPTION, $result ) ) { 
  209. return $result; 
  210.  
  211. return array();