hook-vc-grid.php 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. <?php
  2. if ( ! defined( 'ABSPATH' ) ) {
  3. die( '-1' );
  4. }
  5. /**
  6. * Class Vc_Hooks_Vc_Grid
  7. * @since 4.4
  8. */
  9. class Vc_Hooks_Vc_Grid {
  10. protected $grid_id_unique_name = 'vc_gid'; // if you change this also change in vc-basic-grid.php
  11. /**
  12. * Initializing hooks for grid element,
  13. * Add actions to save appended shortcodes to post meta (for rendering in preview with shortcode id)
  14. * And add action to hook request for grid data, to output it.
  15. * @since 4.4
  16. */
  17. public function load() {
  18. // Hook for set post settings meta with shortcodes data
  19. /**
  20. * @since 4.4.3
  21. */
  22. add_filter( 'vc_hooks_vc_post_settings', array(
  23. $this,
  24. 'gridSavePostSettingsId',
  25. ), 10, 3 );
  26. /**
  27. * Used to output shortcode data for ajax request. called on any page request.
  28. */
  29. add_action( 'wp_ajax_vc_get_vc_grid_data', array(
  30. $this,
  31. 'getGridDataForAjax',
  32. ) );
  33. add_action( 'wp_ajax_nopriv_vc_get_vc_grid_data', array(
  34. $this,
  35. 'getGridDataForAjax',
  36. ) );
  37. }
  38. /**
  39. * @return string
  40. * @since 4.4.3
  41. */
  42. private function getShortcodeRegexForId() {
  43. return '\\[' // Opening bracket
  44. . '(\\[?)' // 1: Optional second opening bracket for escaping shortcodes: [[tag]]
  45. . '([\\w\-_]+)' // 2: Shortcode name
  46. . '(?![\\w\-])' // Not followed by word character or hyphen
  47. . '(' // 3: Unroll the loop: Inside the opening shortcode tag
  48. . '[^\\]\\/]*' // Not a closing bracket or forward slash
  49. . '(?:' . '\\/(?!\\])' // A forward slash not followed by a closing bracket
  50. . '[^\\]\\/]*' // Not a closing bracket or forward slash
  51. . ')*?'
  52. . '(?:' . '(' . $this->grid_id_unique_name // 4: GridId must exist
  53. . '[^\\]\\/]*' // Not a closing bracket or forward slash
  54. . ')+' . ')'
  55. . ')' . '(?:' . '(\\/)' // 5: Self closing tag ...
  56. . '\\]' // ... and closing bracket
  57. . '|' . '\\]' // Closing bracket
  58. . '(?:' . '(' // 6: Unroll the loop: Optionally, anything between the opening and closing shortcode tags
  59. . '[^\\[]*+' // Not an opening bracket
  60. . '(?:' . '\\[(?!\\/\\2\\])' // An opening bracket not followed by the closing shortcode tag
  61. . '[^\\[]*+' // Not an opening bracket
  62. . ')*+' . ')' . '\\[\\/\\2\\]' // Closing shortcode tag
  63. . ')?' . ')' . '(\\]?)'; // 7: Optional second closing brocket for escaping shortcodes: [[tag]]
  64. }
  65. /**
  66. * @param array $settings
  67. * @param $post_id
  68. * @param $post
  69. *
  70. * @return array
  71. * @since 4.4.3
  72. *
  73. */
  74. public function gridSavePostSettingsId( array $settings, $post_id, $post ) {
  75. $pattern = $this->getShortcodeRegexForId();
  76. $content = stripslashes( $post->post_content );
  77. preg_match_all( "/$pattern/", $content, $found ); // fetch only needed shortcodes
  78. if ( is_array( $found ) && ! empty( $found[0] ) ) {
  79. $to_save = array();
  80. if ( isset( $found[1] ) && is_array( $found[1] ) ) {
  81. foreach ( $found[1] as $key => $parse_able ) {
  82. if ( empty( $parse_able ) || '[' !== $parse_able ) {
  83. $id_pattern = '/' . $this->grid_id_unique_name . '\:([\w\-_]+)/';
  84. $id_value = $found[4][ $key ];
  85. preg_match( $id_pattern, $id_value, $id_matches );
  86. if ( ! empty( $id_matches ) ) {
  87. $id_to_save = $id_matches[1];
  88. // why we need to check if shortcode is parse able?
  89. // 1: if it is escaped it must not be displayed (parsed)
  90. // 2: so if 1 is true it must not be saved in database meta
  91. $shortcode_tag = $found[2][ $key ];
  92. $shortcode_atts_string = $found[3][ $key ];
  93. /** @var array $atts */
  94. $atts = shortcode_parse_atts( $shortcode_atts_string );
  95. $content = $found[6][ $key ];
  96. $data = array(
  97. 'tag' => $shortcode_tag,
  98. 'atts' => $atts,
  99. 'content' => $content,
  100. );
  101. $to_save[ $id_to_save ] = $data;
  102. }
  103. }
  104. }
  105. }
  106. if ( ! empty( $to_save ) ) {
  107. $settings['vc_grid_id'] = array( 'shortcodes' => $to_save );
  108. }
  109. }
  110. return $settings;
  111. }
  112. /**
  113. * @throws \Exception
  114. * @since 4.4
  115. *
  116. * @output/@return string - grid data for ajax request.
  117. */
  118. public function getGridDataForAjax() {
  119. $tag = str_replace( '.', '', vc_request_param( 'tag' ) );
  120. $allowed = apply_filters( 'vc_grid_get_grid_data_access', vc_verify_public_nonce() && $tag, $tag );
  121. if ( $allowed ) {
  122. $shortcode_fishbone = visual_composer()->getShortCode( $tag );
  123. if ( is_object( $shortcode_fishbone ) && vc_get_shortcode( $tag ) ) {
  124. /** @var WPBakeryShortcode_Vc_Basic_Grid $vc_grid */
  125. $vc_grid = $shortcode_fishbone->shortcodeClass();
  126. if ( method_exists( $vc_grid, 'isObjectPageable' ) && $vc_grid->isObjectPageable() && method_exists( $vc_grid, 'renderAjax' ) ) {
  127. // @codingStandardsIgnoreLine
  128. wp_die( $vc_grid->renderAjax( vc_request_param( 'data' ) ) );
  129. }
  130. }
  131. }
  132. }
  133. }
  134. /**
  135. * @since 4.4
  136. * @var Vc_Hooks_Vc_Grid $hook
  137. */
  138. $hook = new Vc_Hooks_Vc_Grid();
  139. // when WPBakery Page Builder initialized let's trigger Vc_Grid hooks.
  140. add_action( 'vc_after_init', array(
  141. $hook,
  142. 'load',
  143. ) );
  144. if ( 'vc_edit_form' === vc_post_param( 'action' ) ) {
  145. VcShortcodeAutoloader::getInstance()->includeClass( 'WPBakeryShortCode_Vc_Basic_Grid' );
  146. add_filter( 'vc_edit_form_fields_attributes_vc_basic_grid', array(
  147. 'WPBakeryShortCode_Vc_Basic_Grid',
  148. 'convertButton2ToButton3',
  149. ) );
  150. add_filter( 'vc_edit_form_fields_attributes_vc_media_grid', array(
  151. 'WPBakeryShortCode_Vc_Basic_Grid',
  152. 'convertButton2ToButton3',
  153. ) );
  154. add_filter( 'vc_edit_form_fields_attributes_vc_masonry_grid', array(
  155. 'WPBakeryShortCode_Vc_Basic_Grid',
  156. 'convertButton2ToButton3',
  157. ) );
  158. add_filter( 'vc_edit_form_fields_attributes_vc_masonry_media_grid', array(
  159. 'WPBakeryShortCode_Vc_Basic_Grid',
  160. 'convertButton2ToButton3',
  161. ) );
  162. }