PageRenderTime 38ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 1ms

/php/class-shortcodes.php

https://gitlab.com/Blueprint-Marketing/Yoast-theme-public
PHP | 417 lines | 236 code | 66 blank | 115 comment | 26 complexity | a835825aaf56518f52072a0ab1711762 MD5 | raw file
  1. <?php
  2. namespace Yoast\YoastCom\Theme;
  3. class Shortcodes {
  4. /**
  5. * Adds the themes shortcodes
  6. */
  7. public function add_shortcodes() {
  8. add_shortcode( 'banner', array( $this, 'banner' ) );
  9. add_shortcode( 'bundle', array( $this, 'bundle' ) );
  10. add_shortcode( 'plugin-info', array( $this, 'plugin_info' ) );
  11. add_shortcode( 'plugin-cta', array( $this, 'plugin_cta' ) );
  12. add_shortcode( 'plugin-stats', array( $this, 'plugin_stats' ) );
  13. add_shortcode( 'yst_review_box', array( $this, 'review_box' ) );
  14. add_shortcode( 'sidebar-content', array( $this, 'sidebar_content' ) );
  15. add_shortcode( 'aside', array( $this, 'sidebar_content' ) );
  16. add_shortcode( 'testimonial', array( $this, 'testimonial' ) );
  17. add_shortcode( 'announcement', array( $this, 'announcement' ) );
  18. add_shortcode( 'pdf-button', array( $this, 'pdf_button' ) );
  19. add_shortcode( 'readmore', array( $this, 'read_more_link' ) );
  20. add_shortcode( 'ebook-banner', array( $this, 'ebook_banner' ) );
  21. // Deprecated shortcodes.
  22. add_shortcode( 'box', array( $this, 'deprecate_box' ) );
  23. add_shortcode( 'download_button', array( $this, 'deprecated_download_button' ) );
  24. add_shortcode( 'support', array( $this, 'support' ) );
  25. add_shortcode( 'llms_take_quiz', array( $this, 'llms_complete_lesson' ) );
  26. }
  27. /**
  28. * Handler for the box shortcode, outputs nothing except a deprecation notice.
  29. */
  30. public function deprecate_box() {
  31. return '<!-- The "box" shortcode is deprecated -->';
  32. }
  33. /**
  34. * Handler for the box shortcode, outputs nothing except a deprecation notice.
  35. */
  36. public function deprecated_download_button() {
  37. return '<!-- The "download_button" shortcode is deprecated -->';
  38. }
  39. /**
  40. * Handler for the support shortcode. With this shortcode you used to be able to make a grid of boxes with content
  41. * in them.
  42. *
  43. * @param array $args The shortcode arguments.
  44. * @param string $content The content inside the shortcode.
  45. *
  46. * @return string HTML to output.
  47. */
  48. public function support( $args, $content ) {
  49. $class = '';
  50. if ( isset( $args['class'] ) ) {
  51. $class = $args['class'];
  52. }
  53. $name = 'Add a name attribute!';
  54. if ( isset( $args['name'] ) ) {
  55. $name = $args['name'];
  56. }
  57. return get_template_part( 'html_includes/shortcodes/support', array(
  58. 'return' => true,
  59. 'class' => $class,
  60. 'name' => $name,
  61. 'content' => $content,
  62. ) );
  63. }
  64. /**
  65. * Handler for the plugin-info shortcode. Outputs some information about the plugin
  66. *
  67. * @return string
  68. */
  69. public function plugin_info() {
  70. return
  71. $this->get_break_out_content()
  72. . get_template_part( 'html_includes/shortcodes/plugin-info', array( 'return' => true ) )
  73. . '<hr>'
  74. . $this->get_content_restart();
  75. }
  76. /**
  77. * Handler for the plugin-cta shortcode. Outputs the buttons to buy or download the plugin.
  78. *
  79. * @return string
  80. */
  81. public function plugin_cta() {
  82. return get_template_part( 'html_includes/shortcodes/plugin-cta', array( 'return' => true ) );
  83. }
  84. /**
  85. * Handler for the bundle shortcode
  86. *
  87. * @return string
  88. */
  89. public function bundle( $args ) {
  90. $heading = __( 'Bundle plugins and save money', 'yoastcom' );
  91. if ( isset( $args['heading'] ) ) {
  92. $heading = $args['heading'];
  93. }
  94. $bundles = array();
  95. if ( isset( $args['bundles'] ) ) {
  96. $bundles = explode( ',', $args['bundles'] );
  97. }
  98. if ( ! count( $bundles ) > 0 ) {
  99. return '<p><strong>You need to define the bundles to show using the <code>bundles</code> attribute, comma separated by ID, like this: <code>[bundle bundles="1,2"]</code>.</strong></p>';
  100. }
  101. $out = $this->get_break_out_content();
  102. $out .= get_template_part( 'html_includes/shortcodes/bundle', array(
  103. 'bundles' => $bundles,
  104. 'heading' => $heading,
  105. 'return' => true,
  106. )
  107. );
  108. $out .= $this->get_content_restart();
  109. return $out;
  110. }
  111. /**
  112. * Handler for the plugin-stats shortcode. Outputs some statistics about the plugin
  113. *
  114. * @return string
  115. */
  116. public function plugin_stats() {
  117. return $this->get_break_out_content() . get_template_part( 'html_includes/shortcodes/plugin-stats', array( 'return' => true ) ) . $this->get_content_restart();
  118. }
  119. /**
  120. * Handler for the yst_review_box shortcode. Outputs a price comparison box for the site reviews.
  121. *
  122. * @return string
  123. */
  124. public function review_box() {
  125. return $this->get_break_out_content() . '<section class="row">' . do_shortcode( post_meta( 'review-box' ) ) . '</section>' . $this->get_content_restart();
  126. }
  127. /**
  128. * Handler for the testimonial shortcode. Outputs a neat testimonial box with the possibility of an image.
  129. *
  130. * @param array $atts The shortcode attributes.
  131. * @param string $content The shortcode content.
  132. *
  133. * @return string
  134. */
  135. public function testimonial( $atts, $content ) {
  136. $args = array(
  137. 'return' => true,
  138. );
  139. if ( isset( $atts['image_url'] ) ) {
  140. $args['image_url'] = $atts['image_url'];
  141. }
  142. if ( isset( $atts['image_id'] ) ) {
  143. $args['image_id'] = $atts['image_id'];
  144. }
  145. if ( ! empty( $content ) ) {
  146. $args['testimonial'] = $content;
  147. }
  148. return $this->get_break_out_content() . get_template_part( 'html_includes/shortcodes/testimonial', $args ) . $this->get_content_restart();
  149. }
  150. /**
  151. * Allows putting the sidebar content higher up along the content than it would normally happen if there is other break out content
  152. *
  153. * @param array $atts
  154. * @param string $content
  155. *
  156. * @return string
  157. */
  158. public function sidebar_content( $atts, $content = null ) {
  159. $atts = wp_parse_args( $atts, array(
  160. 'id' => '',
  161. 'title' => false,
  162. ) );
  163. $out = $this->get_break_out_body();
  164. $out .= '<section class="alignright extra" id="' . $atts['id'] . '">';
  165. if ( $atts['title'] ) {
  166. $out .= '<h4>' . $atts['title'] . '</h4>';
  167. }
  168. if ( ! is_null( $content ) ) {
  169. $content = trim( $content );
  170. }
  171. if ( '' === $content ) {
  172. $content = wp_kses_post( post_meta( 'sidebar_content' ) );
  173. }
  174. $content = do_shortcode( shortcode_unautop( wpautop( $content ) ) );
  175. // Remove empty paragraphs.
  176. $content = str_replace( '<p></p>', '', $content );
  177. $out .= $content;
  178. $out .= '</section>';
  179. $out .= $this->get_restart_body();
  180. return $out;
  181. }
  182. /**
  183. * Generates a banner for eBooks
  184. *
  185. * @param array $atts
  186. *
  187. * @return string
  188. */
  189. public function ebook_banner( $atts ) {
  190. if ( ! isset( $atts['book'] ) ) {
  191. $atts['book'] = 'content-seo';
  192. }
  193. switch ( $atts['book'] ) {
  194. case 'content-seo':
  195. $atts['text'] = 'Want to learn more about content-writing, keyword research, and creating a good site structure? Get our Content SEO eBook &raquo;';
  196. $atts['url'] = 'https://yoast.com/ebooks/content-seo/';
  197. break;
  198. case 'ux-conversion':
  199. $atts['text'] = 'Want to improve your site\'s user experience and conversion? Get our eBook: UX & Conversion from a Holistic SEO perspective &raquo;';
  200. $atts['url'] = 'https://yoast.com/ebooks/ux-conversion-seo/';
  201. break;
  202. }
  203. $args = wp_parse_args( $atts, array(
  204. 'banner' => 'academy',
  205. 'icon' => 'book',
  206. 'class' => 'announcement--pointer',
  207. 'no-sticky' => true,
  208. 'return' => true,
  209. ) );
  210. return $this->get_break_out_content() . get_template_part( 'html_includes/partials/announcement', $args ) . $this->get_content_restart();
  211. }
  212. /**
  213. * Handler for the announcement shortcode.
  214. *
  215. * @param array $atts The shortcode attributes.
  216. *
  217. * @return string The content to output on the page.
  218. */
  219. public function announcement( $atts ) {
  220. $args = wp_parse_args( $atts, array(
  221. 'banner' => 'academy',
  222. 'text' => '',
  223. 'url' => '',
  224. 'no-sticky' => true,
  225. 'return' => true,
  226. ) );
  227. $template = 'html_includes/partials/fullbanner';
  228. if ( ! empty( $args['text'] ) && ! empty( $args['url'] ) ) {
  229. $template = 'html_includes/partials/banner-announcement';
  230. }
  231. return $this->get_break_out_content() . get_template_part( $template, $args ) . $this->get_content_restart();
  232. }
  233. /**
  234. * Handler for the banner shortcode.
  235. *
  236. * @param array $atts The shortcode attributes.
  237. *
  238. * @return string The content to output on the page.
  239. */
  240. public function banner( $atts ) {
  241. $args = wp_parse_args( $atts, array(
  242. 'text' => '',
  243. 'url' => '',
  244. 'icon' => '',
  245. 'class' => 'announcement--pointer',
  246. 'return' => true,
  247. ) );
  248. return $this->get_break_out_content() . get_template_part( 'html_includes/partials/announcement', $args ) . $this->get_content_restart();
  249. }
  250. /**
  251. * Handler for the PDF button shortcode
  252. *
  253. * @param array $atts The shortcode attributes
  254. *
  255. * @return string The content to output on the page.
  256. */
  257. public function pdf_button( $atts ) {
  258. $args = wp_parse_args( $atts, array(
  259. 'icon' => 'file-pdf-o',
  260. 'text' => 'Read this PDF',
  261. 'url' => '',
  262. ) );
  263. return '<p><a target="_blank" class="button default" href="' . esc_url( $args['url'] ) . '"><i class="fa fa-' . esc_attr( $args['icon'] ) . '"></i>' . esc_html( $args['text'] ) . '</a></p>';
  264. }
  265. /**
  266. * Break out of the article body
  267. *
  268. * @return string
  269. */
  270. public function get_break_out_body() {
  271. $break_out_content = '';
  272. if ( is_singular( array( 'yoast_plugins', 'yoast_courses' ) ) ) {
  273. $break_out_content = '</section>';
  274. } elseif ( is_page() || is_singular() ) {
  275. $break_out_content = '</div>';
  276. }
  277. return $break_out_content;
  278. }
  279. /**
  280. * Restart the article body
  281. *
  282. * @return string
  283. */
  284. public function get_restart_body() {
  285. $restart_content = '';
  286. if ( is_singular( array( 'yoast_plugins', 'yoast_courses' ) ) ) {
  287. $restart_content = '<section class="content">';
  288. } elseif ( is_page() || is_singular() ) {
  289. $restart_content = '<div class="content">';
  290. }
  291. return $restart_content;
  292. }
  293. /**
  294. * Handler for the read more link shortcode
  295. *
  296. * @param array $atts The shortcode attributes
  297. * @param string $content
  298. *
  299. * @return string The content to output on the page.
  300. */
  301. public function read_more_link( $atts, $content ) {
  302. $args = wp_parse_args( $atts, array(
  303. 'url' => '',
  304. 'prefix' => '',
  305. ) );
  306. if ( $args['url'] === '' || $content === '' ) {
  307. return '';
  308. }
  309. if ( $args['prefix'] === '' ) {
  310. global $readmore_counter;
  311. if ( ! isset( $readmore_counter ) || $readmore_counter > 2 ) {
  312. $readmore_counter = 0;
  313. }
  314. $prefixes = array(
  315. 'Read more',
  316. 'Keep reading',
  317. 'Read on',
  318. 'Keep on reading',
  319. );
  320. $args['prefix'] = $prefixes[ $readmore_counter ];
  321. $readmore_counter ++;
  322. }
  323. return '<p class="readmore"><a title="' . esc_attr( $content ) . '" data-prefix="' . esc_attr( $args['prefix'] ) . '" href="' . esc_attr( $args['url'] ) . '">' . $args['prefix'] . ': &lsquo;' . strip_tags( $content ) . '&rsquo; &raquo;</a></p>';
  324. }
  325. /**
  326. * Returns HTML tags to break out of the content container to allow for full width shortcodes
  327. *
  328. * @return string
  329. */
  330. private function get_break_out_content() {
  331. $break_out_content = '';
  332. if ( is_singular( array( 'yoast_plugins', 'yoast_courses' ) ) ) {
  333. $break_out_content = '</section></div>';
  334. } elseif ( is_singular() ) {
  335. $break_out_content = '</div></article>';
  336. }
  337. return $break_out_content;
  338. }
  339. /**
  340. * Restart the content area to make sure content after the shortcode is still valid
  341. */
  342. private function get_content_restart() {
  343. $restart_content = '';
  344. if ( is_singular( array( 'yoast_plugins', 'yoast_courses' ) ) ) {
  345. $restart_content = '<div class="row island iceberg"><section class="content">';
  346. } elseif ( is_singular() ) {
  347. $restart_content = '<article class="row"><div class="content">';
  348. }
  349. return $restart_content;
  350. }
  351. }