WPSEO_Replace_Vars

Class: WPSEO_Replace_Vars.

Defined (1)

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

/inc/class-wpseo-replace-vars.php  
  1. class WPSEO_Replace_Vars { 
  2.  
  3. /** 
  4. * @var array Default post/page/cpt information 
  5. */ 
  6. protected $defaults = array( 
  7. 'ID' => '',  
  8. 'name' => '',  
  9. 'post_author' => '',  
  10. 'post_content' => '',  
  11. 'post_date' => '',  
  12. 'post_excerpt' => '',  
  13. 'post_modified' => '',  
  14. 'post_title' => '',  
  15. 'taxonomy' => '',  
  16. 'term_id' => '',  
  17. 'term404' => '',  
  18. ); 
  19.  
  20. /** 
  21. * @var object Current post/page/cpt information 
  22. */ 
  23. protected $args; 
  24.  
  25. /** 
  26. * @var array Help texts for use in WPSEO -> Titles and Meta's help tabs 
  27. */ 
  28. protected static $help_texts = array(); 
  29.  
  30. /** 
  31. * @var array Register of additional variable replacements registered by other plugins/themes 
  32. */ 
  33. protected static $external_replacements = array(); 
  34.  
  35.  
  36. /** 
  37. * Constructor 
  38. * @return \WPSEO_Replace_Vars 
  39. */ 
  40. public function __construct() { 
  41.  
  42.  
  43. /** 
  44. * Setup the help texts and external replacements as statics so they will be available to all instances 
  45. */ 
  46. public static function setup_statics_once() { 
  47. if ( self::$help_texts === array() ) { 
  48. self::set_basic_help_texts(); 
  49. self::set_advanced_help_texts(); 
  50.  
  51. if ( self::$external_replacements === array() ) { 
  52. /** 
  53. * Action: 'wpseo_register_extra_replacements' - Allows for registration of additional 
  54. * variables to replace 
  55. */ 
  56. do_action( 'wpseo_register_extra_replacements' ); 
  57.  
  58.  
  59. /** 
  60. * Register new replacement %%variables%% 
  61. * For use by other plugins/themes to register extra variables 
  62. * @see wpseo_register_var_replacement() for a usage example 
  63. * @param string $var The name of the variable to replace, i.e. '%%var%%' 
  64. * - the surrounding %% are optional. 
  65. * @param mixed $replace_function Function or method to call to retrieve the replacement value for the variable 
  66. * Uses the same format as add_filter/add_action function parameter and 
  67. * should *return* the replacement value. DON'T echo it. 
  68. * @param string $type Type of variable: 'basic' or 'advanced', defaults to 'advanced'. 
  69. * @param string $help_text Help text to be added to the help tab for this variable. 
  70. * @return bool Whether the replacement function was succesfully registered 
  71. */ 
  72. public static function register_replacement( $var, $replace_function, $type = 'advanced', $help_text = '' ) { 
  73. $success = false; 
  74.  
  75. if ( is_string( $var ) && $var !== '' ) { 
  76. $var = self::remove_var_delimiter( $var ); 
  77.  
  78. if ( preg_match( '`^[A-Z0-9_-]+$`i', $var ) === false ) { 
  79. trigger_error( __( 'A replacement variable can only contain alphanumeric characters, an underscore or a dash. Try renaming your variable.', 'wordpress-seo' ), E_USER_WARNING ); 
  80. elseif ( strpos( $var, 'cf_' ) === 0 || strpos( $var, 'ct_' ) === 0 ) { 
  81. trigger_error( __( 'A replacement variable can not start with "%%cf_" or "%%ct_" as these are reserved for the WPSEO standard variable variables for custom fields and custom taxonomies. Try making your variable name unique.', 'wordpress-seo' ), E_USER_WARNING ); 
  82. elseif ( ! method_exists( __CLASS__, 'retrieve_' . $var ) ) { 
  83. if ( ! isset( self::$external_replacements[ $var ] ) ) { 
  84. self::$external_replacements[ $var ] = $replace_function; 
  85. self::register_help_text( $type, $var, $help_text ); 
  86. $success = true; 
  87. else { 
  88. trigger_error( __( 'A replacement variable with the same name has already been registered. Try making your variable name unique.', 'wordpress-seo' ), E_USER_WARNING ); 
  89. else { 
  90. trigger_error( __( 'You cannot overrule a WPSEO standard variable replacement by registering a variable with the same name. Use the "wpseo_replacements" filter instead to adjust the replacement value.', 'wordpress-seo' ), E_USER_WARNING ); 
  91.  
  92. return $success; 
  93.  
  94.  
  95. /** 
  96. * Replace `%%variable_placeholders%%` with their real value based on the current requested page/post/cpt/etc 
  97. * @param string $string the string to replace the variables in. 
  98. * @param array $args the object some of the replacement values might come from,  
  99. * could be a post, taxonomy or term. 
  100. * @param array $omit variables that should not be replaced by this function. 
  101. * @return string 
  102. */ 
  103. public function replace( $string, $args, $omit = array() ) { 
  104.  
  105. $string = strip_tags( $string ); 
  106.  
  107. // Let's see if we can bail super early. 
  108. if ( strpos( $string, '%%' ) === false ) { 
  109. return WPSEO_Utils::standardize_whitespace( $string ); 
  110.  
  111. $args = (array) $args; 
  112. if ( isset( $args['post_content'] ) && ! empty( $args['post_content'] ) ) { 
  113. $args['post_content'] = WPSEO_Utils::strip_shortcode( $args['post_content'] ); 
  114. if ( isset( $args['post_excerpt'] ) && ! empty( $args['post_excerpt'] ) ) { 
  115. $args['post_excerpt'] = WPSEO_Utils::strip_shortcode( $args['post_excerpt'] ); 
  116. $this->args = (object) wp_parse_args( $args, $this->defaults ); 
  117.  
  118. // Clean $omit array. 
  119. if ( is_array( $omit ) && $omit !== array() ) { 
  120. $omit = array_map( array( __CLASS__, 'remove_var_delimiter' ), $omit ); 
  121.  
  122. $replacements = array(); 
  123. if ( preg_match_all( '`%%([^%]+(%%single)?)%%?`iu', $string, $matches ) ) { 
  124. $replacements = $this->set_up_replacements( $matches, $omit ); 
  125.  
  126. /** 
  127. * Filter: 'wpseo_replacements' - Allow customization of the replacements before they are applied 
  128. * @api array $replacements The replacements 
  129. */ 
  130. $replacements = apply_filters( 'wpseo_replacements', $replacements ); 
  131.  
  132. // Do the actual replacements. 
  133. if ( is_array( $replacements ) && $replacements !== array() ) { 
  134. $string = str_replace( array_keys( $replacements ), array_values( $replacements ), $string ); 
  135.  
  136. /** 
  137. * Filter: 'wpseo_replacements_final' - Allow overruling of whether or not to remove placeholders 
  138. * which didn't yield a replacement 
  139. * @example <code>add_filter( 'wpseo_replacements_final', '__return_false' );</code> 
  140. * @api bool $final 
  141. */ 
  142. if ( apply_filters( 'wpseo_replacements_final', true ) === true && ( isset( $matches[1] ) && is_array( $matches[1] ) ) ) { 
  143. // Remove non-replaced variables. 
  144. $remove = array_diff( $matches[1], $omit ); // Make sure the $omit variables do not get removed. 
  145. $remove = array_map( array( __CLASS__, 'add_var_delimiter' ), $remove ); 
  146. $string = str_replace( $remove, '', $string ); 
  147.  
  148. // Undouble separators which have nothing between them, i.e. where a non-replaced variable was removed. 
  149. if ( isset( $replacements['%%sep%%'] ) && ( is_string( $replacements['%%sep%%'] ) && $replacements['%%sep%%'] !== '' ) ) { 
  150. $q_sep = preg_quote( $replacements['%%sep%%'], '`' ); 
  151. $string = preg_replace( '`' . $q_sep . '(?:\s*' . $q_sep . ')*`u', $replacements['%%sep%%'], $string ); 
  152.  
  153. // Remove superfluous whitespace. 
  154. $string = WPSEO_Utils::standardize_whitespace( $string ); 
  155.  
  156. return trim( $string ); 
  157.  
  158.  
  159. /** 
  160. * Retrieve the replacements for the variables found. 
  161. * @param array $matches variables found in the original string - regex result. 
  162. * @param array $omit variables that should not be replaced by this function. 
  163. * @return array retrieved replacements - this might be a smaller array as some variables 
  164. * may not yield a replacement in certain contexts. 
  165. */ 
  166. private function set_up_replacements( $matches, $omit ) { 
  167.  
  168. $replacements = array(); 
  169.  
  170. // @todo -> figure out a way to deal with external functions starting with cf_/ct_. 
  171. foreach ( $matches[1] as $k => $var ) { 
  172.  
  173. // Don't set up replacements which should be omitted. 
  174. if ( in_array( $var, $omit, true ) ) { 
  175. continue; 
  176.  
  177. // Deal with variable variable names first. 
  178. if ( strpos( $var, 'cf_' ) === 0 ) { 
  179. $replacement = $this->retrieve_cf_custom_field_name( $var ); 
  180. elseif ( strpos( $var, 'ct_desc_' ) === 0 ) { 
  181. $replacement = $this->retrieve_ct_desc_custom_tax_name( $var ); 
  182. elseif ( strpos( $var, 'ct_' ) === 0 ) { 
  183. $single = ( isset( $matches[2][ $k ] ) && $matches[2][ $k ] !== '' ) ? true : false; 
  184. $replacement = $this->retrieve_ct_custom_tax_name( $var, $single ); 
  185. } // Deal with non-variable variable names. 
  186. elseif ( method_exists( $this, 'retrieve_' . $var ) ) { 
  187. $method_name = 'retrieve_' . $var; 
  188. $replacement = $this->$method_name(); 
  189. } // Deal with externally defined variable names. 
  190. elseif ( isset( self::$external_replacements[ $var ] ) && ! is_null( self::$external_replacements[ $var ] ) ) { 
  191. $replacement = call_user_func( self::$external_replacements[ $var ], $var, $this->args ); 
  192.  
  193. // Replacement retrievals can return null if no replacement can be determined, root those outs. 
  194. if ( isset( $replacement ) ) { 
  195. $var = self::add_var_delimiter( $var ); 
  196. $replacements[ $var ] = $replacement; 
  197. unset( $replacement, $single, $method_name ); 
  198.  
  199. return $replacements; 
  200.  
  201.  
  202.  
  203. /** *********************** BASIC VARIABLES ************************** */ 
  204.  
  205. /** 
  206. * Retrieve the post/cpt categories (comma separated) for use as replacement string. 
  207. * @return string|null 
  208. */ 
  209. private function retrieve_category() { 
  210. $replacement = null; 
  211.  
  212. if ( ! empty( $this->args->ID ) ) { 
  213. $cat = $this->get_terms( $this->args->ID, 'category' ); 
  214. if ( $cat !== '' ) { 
  215. $replacement = $cat; 
  216.  
  217. if ( ( ! isset( $replacement ) || $replacement === '' ) && ( isset( $this->args->cat_name ) && ! empty( $this->args->cat_name ) ) ) { 
  218. $replacement = $this->args->cat_name; 
  219.  
  220. return $replacement; 
  221.  
  222. /** 
  223. * Retrieve the category description for use as replacement string. 
  224. * @return string|null 
  225. */ 
  226. private function retrieve_category_description() { 
  227. return $this->retrieve_term_description(); 
  228.  
  229. /** 
  230. * Retrieve the date of the post/page/cpt for use as replacement string. 
  231. * @return string|null 
  232. */ 
  233. private function retrieve_date() { 
  234. $replacement = null; 
  235.  
  236. if ( $this->args->post_date !== '' ) { 
  237. $replacement = mysql2date( get_option( 'date_format' ), $this->args->post_date, true ); 
  238. else { 
  239. if ( get_query_var( 'day' ) && get_query_var( 'day' ) !== '' ) { 
  240. $replacement = get_the_date(); 
  241. else { 
  242. if ( single_month_title( ' ', false ) && single_month_title( ' ', false ) !== '' ) { 
  243. $replacement = single_month_title( ' ', false ); 
  244. elseif ( get_query_var( 'year' ) !== '' ) { 
  245. $replacement = get_query_var( 'year' ); 
  246.  
  247. return $replacement; 
  248.  
  249. /** 
  250. * Retrieve the post/page/cpt excerpt for use as replacement string. 
  251. * The excerpt will be auto-generated if it does not exist. 
  252. * @return string|null 
  253. */ 
  254. private function retrieve_excerpt() { 
  255. $replacement = null; 
  256.  
  257. if ( ! empty( $this->args->ID ) ) { 
  258. if ( $this->args->post_excerpt !== '' ) { 
  259. $replacement = strip_tags( $this->args->post_excerpt ); 
  260. elseif ( $this->args->post_content !== '' ) { 
  261. $replacement = wp_html_excerpt( strip_shortcodes( $this->args->post_content ), 155 ); 
  262.  
  263. return $replacement; 
  264.  
  265. /** 
  266. * Retrieve the post/page/cpt excerpt for use as replacement string (without auto-generation). 
  267. * @return string|null 
  268. */ 
  269. private function retrieve_excerpt_only() { 
  270. $replacement = null; 
  271.  
  272. if ( ! empty( $this->args->ID ) && $this->args->post_excerpt !== '' ) { 
  273. $replacement = strip_tags( $this->args->post_excerpt ); 
  274.  
  275. return $replacement; 
  276.  
  277. /** 
  278. * Retrieve the title of the parent page of the current page/cpt for use as replacement string. 
  279. * Only applicable for hierarchical post types. 
  280. * @todo - check: shouldn't this use $this->args as well ? 
  281. * @return string|null 
  282. */ 
  283. private function retrieve_parent_title() { 
  284. $replacement = null; 
  285.  
  286. if ( ! isset( $replacement ) && ( ( is_singular() || is_admin() ) && isset( $GLOBALS['post'] ) ) ) { 
  287. if ( isset( $GLOBALS['post']->post_parent ) && 0 !== $GLOBALS['post']->post_parent ) { 
  288. $replacement = get_the_title( $GLOBALS['post']->post_parent ); 
  289.  
  290. return $replacement; 
  291.  
  292. /** 
  293. * Retrieve the current search phrase for use as replacement string. 
  294. * @return string|null 
  295. */ 
  296. private function retrieve_searchphrase() { 
  297. $replacement = null; 
  298.  
  299. if ( ! isset( $replacement ) ) { 
  300. $search = get_query_var( 's' ); 
  301. if ( $search !== '' ) { 
  302. $replacement = esc_html( $search ); 
  303.  
  304. return $replacement; 
  305.  
  306. /** 
  307. * Retrieve the separator for use as replacement string. 
  308. * @return string 
  309. */ 
  310. private function retrieve_sep() { 
  311. return WPSEO_Utils::get_title_separator(); 
  312.  
  313. /** 
  314. * Retrieve the site's tag line / description for use as replacement string. 
  315. * @return string|null 
  316. */ 
  317. private function retrieve_sitedesc() { 
  318. static $replacement; 
  319.  
  320. if ( ! isset( $replacement ) ) { 
  321. $description = trim( strip_tags( get_bloginfo( 'description' ) ) ); 
  322. if ( $description !== '' ) { 
  323. $replacement = $description; 
  324.  
  325. return $replacement; 
  326.  
  327.  
  328. /** 
  329. * Retrieve the site's name for use as replacement string. 
  330. * @return string|null 
  331. */ 
  332. private function retrieve_sitename() { 
  333. static $replacement; 
  334.  
  335. if ( ! isset( $replacement ) ) { 
  336. $sitename = WPSEO_Utils::get_site_name(); 
  337. if ( $sitename !== '' ) { 
  338. $replacement = $sitename; 
  339.  
  340. return $replacement; 
  341.  
  342. /** 
  343. * Retrieve the current tag/tags for use as replacement string. 
  344. * @return string|null 
  345. */ 
  346. private function retrieve_tag() { 
  347. $replacement = null; 
  348.  
  349. if ( isset( $this->args->ID ) ) { 
  350. $tags = $this->get_terms( $this->args->ID, 'post_tag' ); 
  351. if ( $tags !== '' ) { 
  352. $replacement = $tags; 
  353.  
  354. return $replacement; 
  355.  
  356. /** 
  357. * Retrieve the tag description for use as replacement string. 
  358. * @return string|null 
  359. */ 
  360. private function retrieve_tag_description() { 
  361. return $this->retrieve_term_description(); 
  362.  
  363. /** 
  364. * Retrieve the term description for use as replacement string. 
  365. * @return string|null 
  366. */ 
  367. private function retrieve_term_description() { 
  368. $replacement = null; 
  369.  
  370. if ( isset( $this->args->term_id ) && ! empty( $this->args->taxonomy ) ) { 
  371. $term_desc = get_term_field( 'description', $this->args->term_id, $this->args->taxonomy ); 
  372. if ( $term_desc !== '' ) { 
  373. $replacement = trim( strip_tags( $term_desc ) ); 
  374.  
  375. return $replacement; 
  376.  
  377. /** 
  378. * Retrieve the term name for use as replacement string. 
  379. * @return string|null 
  380. */ 
  381. private function retrieve_term_title() { 
  382. $replacement = null; 
  383.  
  384. if ( ! empty( $this->args->taxonomy ) && ! empty( $this->args->name ) ) { 
  385. $replacement = $this->args->name; 
  386.  
  387. return $replacement; 
  388.  
  389. /** 
  390. * Retrieve the title of the post/page/cpt for use as replacement string. 
  391. * @return string|null 
  392. */ 
  393. private function retrieve_title() { 
  394. $replacement = null; 
  395.  
  396. if ( is_string( $this->args->post_title ) && $this->args->post_title !== '' ) { 
  397. $replacement = stripslashes( $this->args->post_title ); 
  398.  
  399. return $replacement; 
  400.  
  401. /** 
  402. * Retrieve primary category for use as replacement string. 
  403. * @return bool|int|null 
  404. */ 
  405. private function retrieve_primary_category() { 
  406. $primary_category = null; 
  407.  
  408. if ( ! empty( $this->args->ID ) ) { 
  409. $wpseo_primary_category = new WPSEO_Primary_Term( 'category', $this->args->ID ); 
  410.  
  411. $term_id = $wpseo_primary_category->get_primary_term(); 
  412. $term = get_term( $term_id ); 
  413.  
  414. if ( ! is_wp_error( $term ) && ! empty( $term ) ) { 
  415. $primary_category = $term->name; 
  416.  
  417. return $primary_category; 
  418.  
  419.  
  420. /** *********************** ADVANCED VARIABLES ************************** */ 
  421.  
  422. /** 
  423. * Determine the page numbering of the current post/page/cpt 
  424. * @param string $request 'nr'|'max' - whether to return the page number or the max number of pages. 
  425. * @return int|null 
  426. */ 
  427. private function determine_pagenumbering( $request = 'nr' ) { 
  428. global $wp_query, $post; 
  429. $max_num_pages = null; 
  430. $page_number = null; 
  431.  
  432. $max_num_pages = 1; 
  433.  
  434. if ( ! is_singular() ) { 
  435. $page_number = get_query_var( 'paged' ); 
  436. if ( $page_number === 0 || $page_number === '' ) { 
  437. $page_number = 1; 
  438.  
  439. if ( isset( $wp_query->max_num_pages ) && ( $wp_query->max_num_pages != '' && $wp_query->max_num_pages != 0 ) ) { 
  440. $max_num_pages = $wp_query->max_num_pages; 
  441. else { 
  442. $page_number = get_query_var( 'page' ); 
  443. if ( $page_number === 0 || $page_number === '' ) { 
  444. $page_number = 1; 
  445.  
  446. if ( isset( $post->post_content ) ) { 
  447. $max_num_pages = ( substr_count( $post->post_content, '<!--nextpage-->' ) + 1 ); 
  448.  
  449. $return = null; 
  450.  
  451. switch ( $request ) { 
  452. case 'nr': 
  453. $return = $page_number; 
  454. break; 
  455. case 'max': 
  456. $return = $max_num_pages; 
  457. break; 
  458.  
  459. return $return; 
  460.  
  461.  
  462. /** 
  463. * Determine the post type names for the current post/page/cpt 
  464. * @param string $request 'single'|'plural' - whether to return the single or plural form. 
  465. * @return string|null 
  466. */ 
  467. private function determine_pt_names( $request = 'single' ) { 
  468. global $wp_query; 
  469. $pt_single = null; 
  470. $pt_plural = null; 
  471.  
  472. if ( isset( $wp_query->query_vars['post_type'] ) && ( ( is_string( $wp_query->query_vars['post_type'] ) && $wp_query->query_vars['post_type'] !== '' ) || ( is_array( $wp_query->query_vars['post_type'] ) && $wp_query->query_vars['post_type'] !== array() ) ) ) { 
  473. $post_type = $wp_query->query_vars['post_type']; 
  474. elseif ( isset( $this->args->post_type ) && ( is_string( $this->args->post_type ) && $this->args->post_type !== '' ) ) { 
  475. $post_type = $this->args->post_type; 
  476. else { 
  477. // Make it work in preview mode. 
  478. $post_type = $wp_query->get_queried_object()->post_type; 
  479.  
  480. if ( is_array( $post_type ) ) { 
  481. $post_type = reset( $post_type ); 
  482.  
  483. if ( $post_type !== '' ) { 
  484. $pt = get_post_type_object( $post_type ); 
  485. $pt_plural = $pt_single = $pt->name; 
  486. if ( isset( $pt->labels->singular_name ) ) { 
  487. $pt_single = $pt->labels->singular_name; 
  488. if ( isset( $pt->labels->name ) ) { 
  489. $pt_plural = $pt->labels->name; 
  490.  
  491. $return = null; 
  492.  
  493. switch ( $request ) { 
  494. case 'single': 
  495. $return = $pt_single; 
  496. break; 
  497. case 'plural': 
  498. $return = $pt_plural; 
  499. break; 
  500.  
  501. return $return; 
  502.  
  503. /** 
  504. * Retrieve the attachment caption for use as replacement string. 
  505. * @return string|null 
  506. */ 
  507. private function retrieve_caption() { 
  508. return $this->retrieve_excerpt_only(); 
  509.  
  510.  
  511. /** 
  512. * Retrieve a post/page/cpt's custom field value for use as replacement string 
  513. * @param string $var The complete variable to replace which includes the name of 
  514. * the custom field which value is to be retrieved. 
  515. * @return string|null 
  516. */ 
  517. private function retrieve_cf_custom_field_name( $var ) { 
  518. global $post; 
  519. $replacement = null; 
  520.  
  521. if ( is_string( $var ) && $var !== '' ) { 
  522. $field = substr( $var, 3 ); 
  523. if ( ( is_singular() || is_admin() ) && ( is_object( $post ) && isset( $post->ID ) ) ) { 
  524. $name = get_post_meta( $post->ID, $field, true ); 
  525. if ( $name !== '' ) { 
  526. $replacement = $name; 
  527.  
  528. return $replacement; 
  529.  
  530.  
  531. /** 
  532. * Retrieve a post/page/cpt's custom taxonomies for use as replacement string 
  533. * @param string $var The complete variable to replace which includes the name of 
  534. * the custom taxonomy which value(s) is to be retrieved. 
  535. * @param bool $single Whether to retrieve only the first or all values for the taxonomy. 
  536. * @return string|null 
  537. */ 
  538. private function retrieve_ct_custom_tax_name( $var, $single = false ) { 
  539. $replacement = null; 
  540.  
  541. if ( ( is_string( $var ) && $var !== '' ) && ! empty( $this->args->ID ) ) { 
  542. $tax = substr( $var, 3 ); 
  543. $name = $this->get_terms( $this->args->ID, $tax, $single ); 
  544. if ( $name !== '' ) { 
  545. $replacement = $name; 
  546.  
  547. return $replacement; 
  548.  
  549.  
  550. /** 
  551. * Retrieve a post/page/cpt's custom taxonomies description for use as replacement string 
  552. * @param string $var The complete variable to replace which includes the name of 
  553. * the custom taxonomy which description is to be retrieved. 
  554. * @return string|null 
  555. */ 
  556. private function retrieve_ct_desc_custom_tax_name( $var ) { 
  557. global $post; 
  558. $replacement = null; 
  559.  
  560. if ( is_string( $var ) && $var !== '' ) { 
  561. $tax = substr( $var, 8 ); 
  562. if ( is_object( $post ) && isset( $post->ID ) ) { 
  563. $terms = get_the_terms( $post->ID, $tax ); 
  564. if ( is_array( $terms ) && $terms !== array() ) { 
  565. $term = current( $terms ); 
  566. $term_desc = get_term_field( 'description', $term->term_id, $tax ); 
  567. if ( $term_desc !== '' ) { 
  568. $replacement = trim( strip_tags( $term_desc ) ); 
  569.  
  570. return $replacement; 
  571.  
  572. /** 
  573. * Retrieve the current date for use as replacement string. 
  574. * @return string 
  575. */ 
  576. private function retrieve_currentdate() { 
  577. static $replacement; 
  578.  
  579. if ( ! isset( $replacement ) ) { 
  580. $replacement = date_i18n( get_option( 'date_format' ) ); 
  581.  
  582. return $replacement; 
  583.  
  584. /** 
  585. * Retrieve the current day for use as replacement string. 
  586. * @return string 
  587. */ 
  588. private function retrieve_currentday() { 
  589. static $replacement; 
  590.  
  591. if ( ! isset( $replacement ) ) { 
  592. $replacement = date_i18n( 'j' ); 
  593.  
  594. return $replacement; 
  595.  
  596. /** 
  597. * Retrieve the current month for use as replacement string. 
  598. * @return string 
  599. */ 
  600. private function retrieve_currentmonth() { 
  601. static $replacement; 
  602.  
  603. if ( ! isset( $replacement ) ) { 
  604. $replacement = date_i18n( 'F' ); 
  605.  
  606. return $replacement; 
  607.  
  608. /** 
  609. * Retrieve the current time for use as replacement string. 
  610. * @return string 
  611. */ 
  612. private function retrieve_currenttime() { 
  613. static $replacement; 
  614.  
  615. if ( ! isset( $replacement ) ) { 
  616. $replacement = date_i18n( get_option( 'time_format' ) ); 
  617.  
  618. return $replacement; 
  619.  
  620. /** 
  621. * Retrieve the current year for use as replacement string. 
  622. * @return string 
  623. */ 
  624. private function retrieve_currentyear() { 
  625. static $replacement; 
  626.  
  627. if ( ! isset( $replacement ) ) { 
  628. $replacement = date_i18n( 'Y' ); 
  629.  
  630. return $replacement; 
  631.  
  632. /** 
  633. * Retrieve the post/page/cpt's focus keyword for use as replacement string. 
  634. * @return string|null 
  635. */ 
  636. private function retrieve_focuskw() { 
  637. $replacement = null; 
  638.  
  639. if ( ! empty( $this->args->ID ) ) { 
  640. $focus_kw = WPSEO_Meta::get_value( 'focuskw', $this->args->ID ); 
  641. if ( $focus_kw !== '' ) { 
  642. $replacement = $focus_kw; 
  643.  
  644. return $replacement; 
  645.  
  646. /** 
  647. * Retrieve the post/page/cpt ID for use as replacement string. 
  648. * @return string|null 
  649. */ 
  650. private function retrieve_id() { 
  651. $replacement = null; 
  652.  
  653. if ( ! empty( $this->args->ID ) ) { 
  654. $replacement = $this->args->ID; 
  655.  
  656. return $replacement; 
  657.  
  658. /** 
  659. * Retrieve the post/page/cpt modified time for use as replacement string. 
  660. * @return string|null 
  661. */ 
  662. private function retrieve_modified() { 
  663. $replacement = null; 
  664.  
  665. if ( ! empty( $this->args->post_modified ) ) { 
  666. $replacement = mysql2date( get_option( 'date_format' ), $this->args->post_modified, true ); 
  667.  
  668. return $replacement; 
  669.  
  670. /** 
  671. * Retrieve the post/page/cpt author's "nice name" for use as replacement string. 
  672. * @return string|null 
  673. */ 
  674. private function retrieve_name() { 
  675. $replacement = null; 
  676.  
  677. $user_id = $this->retrieve_userid(); 
  678. $name = get_the_author_meta( 'display_name', $user_id ); 
  679. if ( $name !== '' ) { 
  680. $replacement = $name; 
  681.  
  682. return $replacement; 
  683.  
  684. /** 
  685. * Retrieve the post/page/cpt author's users description for use as a replacement string. 
  686. * @return null|string 
  687. */ 
  688. private function retrieve_user_description() { 
  689. $replacement = null; 
  690.  
  691. $user_id = $this->retrieve_userid(); 
  692. $description = get_the_author_meta( 'description', $user_id ); 
  693. if ( $description != '' ) { 
  694. $replacement = $description; 
  695.  
  696. return $replacement; 
  697.  
  698. /** 
  699. * Retrieve the current page number with context (i.e. 'page 2 of 4') for use as replacement string. 
  700. * @return string 
  701. */ 
  702. private function retrieve_page() { 
  703. $replacement = null; 
  704.  
  705. $max = $this->determine_pagenumbering( 'max' ); 
  706. $nr = $this->determine_pagenumbering( 'nr' ); 
  707. $sep = $this->retrieve_sep(); 
  708.  
  709. if ( $max > 1 && $nr > 1 ) { 
  710. $replacement = sprintf( $sep . ' ' . __( 'Page %1$d of %2$d', 'wordpress-seo' ), $nr, $max ); 
  711.  
  712. return $replacement; 
  713.  
  714. /** 
  715. * Retrieve the current page number for use as replacement string. 
  716. * @return string|null 
  717. */ 
  718. private function retrieve_pagenumber() { 
  719. $replacement = null; 
  720.  
  721. $nr = $this->determine_pagenumbering( 'nr' ); 
  722. if ( isset( $nr ) && $nr > 0 ) { 
  723. $replacement = (string) $nr; 
  724.  
  725. return $replacement; 
  726.  
  727. /** 
  728. * Retrieve the current page total for use as replacement string. 
  729. * @return string|null 
  730. */ 
  731. private function retrieve_pagetotal() { 
  732. $replacement = null; 
  733.  
  734. $max = $this->determine_pagenumbering( 'max' ); 
  735. if ( isset( $max ) && $max > 0 ) { 
  736. $replacement = (string) $max; 
  737.  
  738. return $replacement; 
  739.  
  740. /** 
  741. * Retrieve the post type plural label for use as replacement string. 
  742. * @return string|null 
  743. */ 
  744. private function retrieve_pt_plural() { 
  745. $replacement = null; 
  746.  
  747. $name = $this->determine_pt_names( 'plural' ); 
  748. if ( isset( $name ) && $name !== '' ) { 
  749. $replacement = $name; 
  750.  
  751. return $replacement; 
  752.  
  753. /** 
  754. * Retrieve the post type single label for use as replacement string. 
  755. * @return string|null 
  756. */ 
  757. private function retrieve_pt_single() { 
  758. $replacement = null; 
  759.  
  760. $name = $this->determine_pt_names( 'single' ); 
  761. if ( isset( $name ) && $name !== '' ) { 
  762. $replacement = $name; 
  763.  
  764. return $replacement; 
  765.  
  766. /** 
  767. * Retrieve the slug which caused the 404 for use as replacement string. 
  768. * @return string|null 
  769. */ 
  770. private function retrieve_term404() { 
  771. $replacement = null; 
  772.  
  773. if ( $this->args->term404 !== '' ) { 
  774. $replacement = sanitize_text_field( str_replace( '-', ' ', $this->args->term404 ) ); 
  775. else { 
  776. $error_request = get_query_var( 'pagename' ); 
  777. if ( $error_request !== '' ) { 
  778. $replacement = sanitize_text_field( str_replace( '-', ' ', $error_request ) ); 
  779. else { 
  780. $error_request = get_query_var( 'name' ); 
  781. if ( $error_request !== '' ) { 
  782. $replacement = sanitize_text_field( str_replace( '-', ' ', $error_request ) ); 
  783.  
  784. return $replacement; 
  785.  
  786. /** 
  787. * Retrieve the post/page/cpt author's user id for use as replacement string. 
  788. * @return string 
  789. */ 
  790. private function retrieve_userid() { 
  791. $replacement = ! empty( $this->args->post_author ) ? $this->args->post_author : get_query_var( 'author' ); 
  792.  
  793. return $replacement; 
  794.  
  795.  
  796.  
  797. /** *********************** HELP TEXT RELATED ************************** */ 
  798.  
  799. /** 
  800. * Create a variable help text table 
  801. * @param string $type Either 'basic' or 'advanced'. 
  802. * @return string Help text table 
  803. */ 
  804. private static function create_variable_help_table( $type ) { 
  805. if ( ! in_array( $type, array( 'basic', 'advanced' ), true ) ) { 
  806. return ''; 
  807.  
  808. $table = ' 
  809. <table class="yoast_help yoast-table-scrollable"> 
  810. <thead> 
  811. <tr> 
  812. <th scope="col">' . esc_html__( 'Variable', 'wordpress-seo' ) . '</th> 
  813. <th scope="col">' . esc_html__( 'Description', 'wordpress-seo' ) . '</th> 
  814. </tr> 
  815. </thead> 
  816. <tbody>'; 
  817.  
  818. foreach ( self::$help_texts[ $type ] as $replace => $help_text ) { 
  819. $table .= ' 
  820. <tr> 
  821. <td class="yoast-variable-name">%%' . esc_html( $replace ) . '%%</td> 
  822. <td class="yoast-variable-desc">' . $help_text . '</td> 
  823. </tr>'; 
  824.  
  825. $table .= ' 
  826. </tbody> 
  827. </table>'; 
  828.  
  829. return $table; 
  830.  
  831. /** 
  832. * Create the help text table for the basic variables for use in a help tab 
  833. * @return string 
  834. */ 
  835. public static function get_basic_help_texts() { 
  836. return self::create_variable_help_table( 'basic' ); 
  837.  
  838.  
  839. /** 
  840. * Create the help text table for the advanced variables for use in a help tab 
  841. * @return string 
  842. */ 
  843. public static function get_advanced_help_texts() { 
  844. return self::create_variable_help_table( 'advanced' ); 
  845.  
  846.  
  847. /** 
  848. * Set the help text for a user/plugin/theme defined extra variable. 
  849. * @param string $type Type of variable: 'basic' or 'advanced'. 
  850. * @param string $replace Variable to replace, i.e. '%%var%%'. 
  851. * @param string $help_text The actual help text string. 
  852. */ 
  853. private static function register_help_text( $type, $replace, $help_text = '' ) { 
  854. if ( is_string( $replace ) && $replace !== '' ) { 
  855. $replace = self::remove_var_delimiter( $replace ); 
  856.  
  857. if ( ( is_string( $type ) && in_array( $type, array( 
  858. 'basic',  
  859. 'advanced',  
  860. ), true ) ) && ( $replace !== '' && ! isset( self::$help_texts[ $type ][ $replace ] ) ) 
  861. ) { 
  862. self::$help_texts[ $type ][ $replace ] = $help_text; 
  863.  
  864.  
  865. /** 
  866. * Set/translate the help texts for the WPSEO standard basic variables. 
  867. */ 
  868. private static function set_basic_help_texts() { 
  869. self::$help_texts['basic'] = array( 
  870. 'date' => __( 'Replaced with the date of the post/page', 'wordpress-seo' ),  
  871. 'title' => __( 'Replaced with the title of the post/page', 'wordpress-seo' ),  
  872. 'parent_title' => __( 'Replaced with the title of the parent page of the current page', 'wordpress-seo' ),  
  873. 'sitename' => __( 'The site\'s name', 'wordpress-seo' ),  
  874. 'sitedesc' => __( 'The site\'s tag line / description', 'wordpress-seo' ),  
  875. 'excerpt' => __( 'Replaced with the post/page excerpt (or auto-generated if it does not exist)', 'wordpress-seo' ),  
  876. 'excerpt_only' => __( 'Replaced with the post/page excerpt (without auto-generation)', 'wordpress-seo' ),  
  877. 'tag' => __( 'Replaced with the current tag/tags', 'wordpress-seo' ),  
  878. 'category' => __( 'Replaced with the post categories (comma separated)', 'wordpress-seo' ),  
  879. 'primary_category' => __( 'Replaced with the primary category of the post/page', 'wordpress-seo' ),  
  880. 'category_description' => __( 'Replaced with the category description', 'wordpress-seo' ),  
  881. 'tag_description' => __( 'Replaced with the tag description', 'wordpress-seo' ),  
  882. 'term_description' => __( 'Replaced with the term description', 'wordpress-seo' ),  
  883. 'term_title' => __( 'Replaced with the term name', 'wordpress-seo' ),  
  884. 'searchphrase' => __( 'Replaced with the current search phrase', 'wordpress-seo' ),  
  885. 'sep' => sprintf( 
  886. /** translators: %s: wp_title() function */ 
  887. __( 'The separator defined in your theme\'s %s tag.', 'wordpress-seo' ),  
  888. '<code>wp_title()</code>' 
  889. ),  
  890. ); 
  891.  
  892. /** 
  893. * Set/translate the help texts for the WPSEO standard advanced variables. 
  894. */ 
  895. private static function set_advanced_help_texts() { 
  896. self::$help_texts['advanced'] = array( 
  897. 'pt_single' => __( 'Replaced with the post type single label', 'wordpress-seo' ),  
  898. 'pt_plural' => __( 'Replaced with the post type plural label', 'wordpress-seo' ),  
  899. 'modified' => __( 'Replaced with the post/page modified time', 'wordpress-seo' ),  
  900. 'id' => __( 'Replaced with the post/page ID', 'wordpress-seo' ),  
  901. 'name' => __( 'Replaced with the post/page author\'s \'nicename\'', 'wordpress-seo' ),  
  902. 'user_description' => __( 'Replaced with the post/page author\'s \'Biographical Info\'', 'wordpress-seo' ),  
  903. 'userid' => __( 'Replaced with the post/page author\'s userid', 'wordpress-seo' ),  
  904. 'currenttime' => __( 'Replaced with the current time', 'wordpress-seo' ),  
  905. 'currentdate' => __( 'Replaced with the current date', 'wordpress-seo' ),  
  906. 'currentday' => __( 'Replaced with the current day', 'wordpress-seo' ),  
  907. 'currentmonth' => __( 'Replaced with the current month', 'wordpress-seo' ),  
  908. 'currentyear' => __( 'Replaced with the current year', 'wordpress-seo' ),  
  909. 'page' => __( 'Replaced with the current page number with context (i.e. page 2 of 4)', 'wordpress-seo' ),  
  910. 'pagetotal' => __( 'Replaced with the current page total', 'wordpress-seo' ),  
  911. 'pagenumber' => __( 'Replaced with the current page number', 'wordpress-seo' ),  
  912. 'caption' => __( 'Attachment caption', 'wordpress-seo' ),  
  913. 'focuskw' => __( 'Replaced with the posts focus keyword', 'wordpress-seo' ),  
  914. 'term404' => __( 'Replaced with the slug which caused the 404', 'wordpress-seo' ),  
  915. 'cf_<custom-field-name>' => __( 'Replaced with a posts custom field value', 'wordpress-seo' ),  
  916. 'ct_<custom-tax-name>' => __( 'Replaced with a posts custom taxonomies, comma separated.', 'wordpress-seo' ),  
  917. 'ct_desc_<custom-tax-name>' => __( 'Replaced with a custom taxonomies description', 'wordpress-seo' ),  
  918. ); 
  919.  
  920.  
  921.  
  922.  
  923. /** *********************** GENERAL HELPER METHODS ************************** */ 
  924.  
  925. /** 
  926. * Remove the '%%' delimiters from a variable string 
  927. * @param string $string Variable string to be cleaned. 
  928. * @return string 
  929. */ 
  930. private static function remove_var_delimiter( $string ) { 
  931. return trim( $string, '%' ); 
  932.  
  933. /** 
  934. * Add the '%%' delimiters to a variable string 
  935. * @param string $string Variable string to be delimited. 
  936. * @return string 
  937. */ 
  938. private static function add_var_delimiter( $string ) { 
  939. return '%%' . $string . '%%'; 
  940.  
  941. /** 
  942. * Retrieve a post's terms, comma delimited. 
  943. * @param int $id ID of the post to get the terms for. 
  944. * @param string $taxonomy The taxonomy to get the terms for this post from. 
  945. * @param bool $return_single If true, return the first term. 
  946. * @return string either a single term or a comma delimited string of terms. 
  947. */ 
  948. public function get_terms( $id, $taxonomy, $return_single = false ) { 
  949.  
  950. $output = ''; 
  951.  
  952. // If we're on a specific tag, category or taxonomy page, use that. 
  953. if ( is_category() || is_tag() || is_tax() ) { 
  954. $term = $GLOBALS['wp_query']->get_queried_object(); 
  955. $output = $term->name; 
  956. elseif ( ! empty( $id ) && ! empty( $taxonomy ) ) { 
  957. $terms = get_the_terms( $id, $taxonomy ); 
  958. if ( is_array( $terms ) && $terms !== array() ) { 
  959. foreach ( $terms as $term ) { 
  960. if ( $return_single ) { 
  961. $output = $term->name; 
  962. break; 
  963. else { 
  964. $output .= $term->name . ', '; 
  965. $output = rtrim( trim( $output ), ', ' ); 
  966. unset( $terms, $term ); 
  967.  
  968. /** 
  969. * Allows filtering of the terms list used to replace %%category%%, %%tag%% and %%ct_<custom-tax-name>%% variables 
  970. * @api string $output Comma-delimited string containing the terms 
  971. */ 
  972. return apply_filters( 'wpseo_terms', $output ); 
  973. } /** End of class WPSEO_Replace_Vars */