class-faq-block.php 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. <?php
  2. /**
  3. * WPSEO plugin file.
  4. *
  5. * @package WPSEO\Structured_Data_Blocks
  6. */
  7. /**
  8. * Class WPSEO_FAQ_Block
  9. */
  10. class WPSEO_FAQ_Block implements WPSEO_WordPress_Integration {
  11. /**
  12. * Registers the how-to block as a server-side rendered block.
  13. *
  14. * @return void
  15. */
  16. public function register_hooks() {
  17. if ( ! function_exists( 'register_block_type' ) ) {
  18. return;
  19. }
  20. register_block_type( 'yoast/faq-block', array(
  21. 'render_callback' => array( $this, 'render' ),
  22. ) );
  23. }
  24. /**
  25. * Renders the block.
  26. *
  27. * Because we can't save script tags in Gutenberg without sufficient user permissions, we render these server-side.
  28. *
  29. * @param array $attributes The attributes of the block.
  30. * @param string $content The HTML content of the block.
  31. *
  32. * @return string The block preceded by its JSON-LD script.
  33. */
  34. public function render( $attributes, $content ) {
  35. if ( ! is_array( $attributes ) || ! is_singular() ) {
  36. return $content;
  37. }
  38. $json_ld = $this->get_json_ld( $attributes );
  39. return '<script type="application/ld+json">' . wp_json_encode( $json_ld ) . '</script>' . $content;
  40. }
  41. /**
  42. * Returns the JSON-LD for a FAQ block in array form.
  43. *
  44. * @param array $attributes The attributes of the FAQ block.
  45. *
  46. * @return array The JSON-LD representation of the FAQ block in array form.
  47. */
  48. protected function get_json_ld( array $attributes ) {
  49. $json_ld = array(
  50. '@context' => 'https://schema.org',
  51. '@type' => 'FAQPage',
  52. );
  53. $post_title = get_the_title();
  54. if ( ! empty( $post_title ) ) {
  55. $json_ld['name'] = $post_title;
  56. }
  57. if ( ! array_key_exists( 'questions', $attributes ) || ! is_array( $attributes['questions'] ) ) {
  58. return $json_ld;
  59. }
  60. $main_entity = array();
  61. $questions = array_filter( $attributes['questions'], 'is_array' );
  62. foreach ( $questions as $question ) {
  63. $main_entity[] = $this->get_question_json_ld( $question );
  64. }
  65. $json_ld['mainEntity'] = $main_entity;
  66. return $json_ld;
  67. }
  68. /**
  69. * Returns the JSON-LD for a question in a FAQ block in array form.
  70. *
  71. * @param array $question The attributes of a question in the FAQ block.
  72. *
  73. * @return array The JSON-LD representation of the question in a FAQ block in array form.
  74. */
  75. protected function get_question_json_ld( array $question ) {
  76. $json_ld = array(
  77. '@type' => 'Question',
  78. );
  79. if ( ! empty( $question['jsonQuestion'] ) ) {
  80. $json_ld['name'] = $question['jsonQuestion'];
  81. }
  82. if ( ! empty( $question['jsonAnswer'] ) ) {
  83. $json_ld['answerCount'] = 1;
  84. $json_ld['acceptedAnswer'] = array(
  85. '@type' => 'Answer',
  86. 'text' => $question['jsonAnswer'],
  87. );
  88. if ( ! empty( $question['jsonImageSrc'] ) ) {
  89. $json_ld['acceptedAnswer']['image'] = array(
  90. '@type' => 'ImageObject',
  91. 'contentUrl' => $question['jsonImageSrc'],
  92. );
  93. }
  94. }
  95. return $json_ld;
  96. }
  97. }