autocomplete.php 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. <?php
  2. if ( ! defined( 'ABSPATH' ) ) {
  3. die( '-1' );
  4. }
  5. /**
  6. * Class Vc_AutoComplete
  7. * Param type 'autocomplete'
  8. * Used to create input field with predefined or ajax values suggestions.
  9. * See usage example in bottom of this file.
  10. * @since 4.4
  11. */
  12. class Vc_AutoComplete {
  13. /**
  14. * @since 4.4
  15. * @var array $settings - param settings
  16. */
  17. protected $settings;
  18. /**
  19. * @since 4.4
  20. * @var string $value - current param value (if multiple it is splitted by ',' comma to make array)
  21. */
  22. protected $value;
  23. /**
  24. * @since 4.4
  25. * @var string $tag - shortcode name(base)
  26. */
  27. protected $tag;
  28. /**
  29. * @param array $settings - param settings (from vc_map)
  30. * @param string $value - current param value
  31. * @param string $tag - shortcode name(base)
  32. *
  33. * @since 4.4
  34. */
  35. public function __construct( $settings, $value, $tag ) {
  36. $this->tag = $tag;
  37. $this->settings = $settings;
  38. $this->value = $value;
  39. }
  40. /**
  41. * @return string
  42. * @since 4.4
  43. * vc_filter: vc_autocomplete_{shortcode_tag}_{param_name}_render - hook to define output for autocomplete item
  44. */
  45. public function render() {
  46. $output = sprintf( '<div class="vc_autocomplete-field"><ul class="vc_autocomplete%s">', ( isset( $this->settings['settings'], $this->settings['settings']['display_inline'] ) && true === $this->settings['settings']['display_inline'] ) ? ' vc_autocomplete-inline' : '' );
  47. if ( isset( $this->value ) && strlen( $this->value ) > 0 ) {
  48. $values = explode( ',', $this->value );
  49. foreach ( $values as $key => $val ) {
  50. $value = array(
  51. 'value' => trim( $val ),
  52. 'label' => trim( $val ),
  53. );
  54. if ( isset( $this->settings['settings'], $this->settings['settings']['values'] ) && ! empty( $this->settings['settings']['values'] ) ) {
  55. foreach ( $this->settings['settings']['values'] as $data ) {
  56. if ( trim( $data['value'] ) === trim( $val ) ) {
  57. $value['label'] = $data['label'];
  58. break;
  59. }
  60. }
  61. } else {
  62. // Magic is here. this filter is used to render value correctly ( must return array with 'value', 'label' keys )
  63. $value = apply_filters( 'vc_autocomplete_' . $this->tag . '_' . $this->settings['param_name'] . '_render', $value, $this->settings, $this->tag );
  64. }
  65. if ( is_array( $value ) && isset( $value['value'], $value['label'] ) ) {
  66. $output .= '<li data-value="' . $value['value'] . '" data-label="' . $value['label'] . '" data-index="' . $key . '" class="vc_autocomplete-label vc_data"><span class="vc_autocomplete-label">' . $value['label'] . '</span> <a class="vc_autocomplete-remove">&times;</a></li>';
  67. }
  68. }
  69. }
  70. $output .= sprintf( '<li class="vc_autocomplete-input"><span role="status" aria-live="polite" class="ui-helper-hidden-accessible"></span><input class="vc_auto_complete_param" type="text" placeholder="%s" value="%s" autocomplete="off"></li><li class="vc_autocomplete-clear"></li></ul>', esc_attr__( 'Click here and start typing...', 'js_composer' ), $this->value );
  71. $output .= sprintf( '<input name="%s" class="wpb_vc_param_value %s %s_field" type="hidden" value="%s" %s /></div>', $this->settings['param_name'], $this->settings['param_name'], $this->settings['type'], $this->value, ( isset( $this->settings['settings'] ) && ! empty( $this->settings['settings'] ) ) ? ' data-settings="' . htmlentities( wp_json_encode( $this->settings['settings'] ), ENT_QUOTES, 'utf-8' ) . '" ' : '' );
  72. return $output;
  73. }
  74. }
  75. /**
  76. * @action wp_ajax_vc_get_autocomplete_suggestion - since 4.4 used to hook ajax requests for autocomplete suggestions
  77. */
  78. add_action( 'wp_ajax_vc_get_autocomplete_suggestion', 'vc_get_autocomplete_suggestion' );
  79. /**
  80. * @since 4.4
  81. */
  82. function vc_get_autocomplete_suggestion() {
  83. vc_user_access()->checkAdminNonce()->validateDie()->wpAny( 'edit_posts', 'edit_pages' )->validateDie();
  84. $query = vc_post_param( 'query' );
  85. $tag = wp_strip_all_tags( vc_post_param( 'shortcode' ) );
  86. $param_name = vc_post_param( 'param' );
  87. vc_render_suggestion( $query, $tag, $param_name );
  88. }
  89. /**
  90. * @param $query
  91. * @param $tag
  92. * @param $param_name
  93. *
  94. * vc_filter: vc_autocomplete_{tag}_{param_name}_callback - hook to get suggestions from ajax. (here you need to hook).
  95. * @since 4.4
  96. *
  97. */
  98. function vc_render_suggestion( $query, $tag, $param_name ) {
  99. $suggestions = apply_filters( 'vc_autocomplete_' . stripslashes( $tag ) . '_' . stripslashes( $param_name ) . '_callback', $query, $tag, $param_name );
  100. if ( is_array( $suggestions ) && ! empty( $suggestions ) ) {
  101. die( wp_json_encode( $suggestions ) );
  102. }
  103. die( '' ); // if nothing found..
  104. }
  105. /**
  106. * Function for rendering param in edit form (add element)
  107. * Parse settings from vc_map and entered values.
  108. *
  109. * @param $settings
  110. * @param $value
  111. * @param $tag
  112. *
  113. * @return mixed rendered template for params in edit form
  114. * @since 4.4
  115. * vc_filter: vc_autocomplete_render_filter - hook to override output of edit for field "autocomplete"
  116. */
  117. function vc_autocomplete_form_field( $settings, $value, $tag ) {
  118. $auto_complete = new Vc_AutoComplete( $settings, $value, $tag );
  119. return apply_filters( 'vc_autocomplete_render_filter', $auto_complete->render() );
  120. }