vc-basic-grid.php 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588
  1. <?php
  2. if ( ! defined( 'ABSPATH' ) ) {
  3. die( '-1' );
  4. }
  5. require_once vc_path_dir( 'SHORTCODES_DIR', 'paginator/class-vc-pageable.php' );
  6. require_once vc_path_dir( 'SHORTCODES_DIR', 'vc-btn.php' );
  7. /**
  8. * Class WPBakeryShortCode_Vc_Basic_Grid
  9. */
  10. class WPBakeryShortCode_Vc_Basic_Grid extends WPBakeryShortCode_Vc_Pageable {
  11. public $pagable_type = 'grid';
  12. public $items = array();
  13. public static $excluded_ids = array();
  14. protected $element_template = '';
  15. protected static $default_max_items = 1000;
  16. public $post_id = false;
  17. /** @var \Vc_Grid_Item $grid_item */
  18. public $grid_item = false;
  19. protected $filter_terms;
  20. public $attributes_defaults = array(
  21. 'initial_loading_animation' => 'zoomIn',
  22. 'full_width' => '',
  23. 'layout' => '',
  24. 'element_width' => '4',
  25. 'items_per_page' => '5',
  26. 'gap' => '',
  27. 'style' => 'all',
  28. 'show_filter' => '',
  29. 'filter_default_title' => 'all',
  30. 'exclude_filter' => '',
  31. 'filter_style' => '',
  32. 'filter_size' => 'md',
  33. 'filter_align' => '',
  34. 'filter_color' => '',
  35. 'arrows_design' => '',
  36. 'arrows_position' => '',
  37. 'arrows_color' => '',
  38. 'paging_design' => '',
  39. 'paging_color' => '',
  40. 'paging_animation_in' => '',
  41. 'paging_animation_out' => '',
  42. 'loop' => '',
  43. 'autoplay' => '',
  44. 'post_type' => 'post',
  45. 'filter_source' => 'category',
  46. 'orderby' => '',
  47. 'order' => 'DESC',
  48. // @codingStandardsIgnoreLine
  49. 'meta_key' => '',
  50. 'max_items' => '10',
  51. 'offset' => '0',
  52. 'taxonomies' => '',
  53. 'custom_query' => '',
  54. 'data_type' => 'query',
  55. 'include' => '',
  56. 'exclude' => '',
  57. 'item' => 'none',
  58. 'grid_id' => '',
  59. // disabled, needed for-BC:
  60. 'button_style' => '',
  61. 'button_color' => '',
  62. 'button_size' => '',
  63. // New button3:
  64. 'btn_title' => '',
  65. 'btn_style' => 'modern',
  66. 'btn_el_id' => '',
  67. 'btn_custom_background' => '#ededed',
  68. 'btn_custom_text' => '#666',
  69. 'btn_outline_custom_color' => '#666',
  70. 'btn_outline_custom_hover_background' => '#666',
  71. 'btn_outline_custom_hover_text' => '#fff',
  72. 'btn_shape' => 'rounded',
  73. 'btn_color' => 'blue',
  74. 'btn_size' => 'md',
  75. 'btn_align' => 'inline',
  76. 'btn_button_block' => '',
  77. 'btn_add_icon' => '',
  78. 'btn_i_align' => 'left',
  79. 'btn_i_type' => 'fontawesome',
  80. 'btn_i_icon_fontawesome' => 'fa fa-adjust',
  81. 'btn_i_icon_openiconic' => 'vc-oi vc-oi-dial',
  82. 'btn_i_icon_typicons' => 'typcn typcn-adjust-brightness',
  83. 'btn_i_icon_entypo' => 'entypo-icon entypo-icon-note',
  84. 'btn_i_icon_linecons' => 'vc_li vc_li-heart',
  85. 'btn_i_icon_pixelicons' => 'vc_pixel_icon vc_pixel_icon-alert',
  86. 'btn_custom_onclick' => '',
  87. 'btn_custom_onclick_code' => '',
  88. // fix template
  89. 'page_id' => '',
  90. );
  91. protected $grid_settings = array();
  92. protected $grid_id_unique_name = 'vc_gid'; // if you change this also change in hook-vc-grid.php
  93. /**
  94. * @var \WP_Query
  95. */
  96. protected $query;
  97. /**
  98. * WPBakeryShortCode_Vc_Basic_Grid constructor.
  99. * @param $settings
  100. */
  101. public function __construct( $settings ) {
  102. parent::__construct( $settings );
  103. $this->attributes_defaults['btn_title'] = esc_html__( 'Load more', 'js_composer' );
  104. $this->shortcodeScripts();
  105. }
  106. public function shortcodeScripts() {
  107. parent::shortcodeScripts();
  108. wp_register_script( 'vc_grid-js-imagesloaded', vc_asset_url( 'lib/bower/imagesloaded/imagesloaded.pkgd.min.js' ), array( 'jquery' ), WPB_VC_VERSION, true );
  109. wp_register_script( 'vc_grid', vc_asset_url( 'js/dist/vc_grid.min.js' ), array(
  110. 'jquery',
  111. 'underscore',
  112. 'vc_pageable_owl-carousel',
  113. 'vc_waypoints',
  114. // 'isotope',
  115. 'vc_grid-js-imagesloaded',
  116. ), WPB_VC_VERSION, true );
  117. }
  118. public function enqueueScripts() {
  119. parent::enqueueScripts();
  120. wp_enqueue_script( 'vc_grid-js-imagesloaded' );
  121. wp_enqueue_script( 'vc_grid' );
  122. }
  123. /**
  124. * @param $id
  125. */
  126. public static function addExcludedId( $id ) {
  127. self::$excluded_ids[] = $id;
  128. }
  129. /**
  130. * @return array
  131. */
  132. public static function excludedIds() {
  133. return self::$excluded_ids;
  134. }
  135. /**
  136. * @param $atts
  137. * @param $content
  138. * @return false|mixed|string|void
  139. */
  140. public function getId( $atts, $content ) {
  141. if ( vc_is_page_editable() || is_preview() ) {
  142. /*
  143. * We are in Frontend editor
  144. * We need to send RAW shortcode data, so hash is just json_encode of atts and content
  145. */
  146. return rawurlencode( wp_json_encode( array(
  147. 'tag' => $this->shortcode,
  148. 'atts' => $atts,
  149. 'content' => $content,
  150. ) ) );
  151. }
  152. $id_pattern = '/' . $this->grid_id_unique_name . '\:([\w\-_]+)/';
  153. $id_value = isset( $atts['grid_id'] ) ? $atts['grid_id'] : '';
  154. preg_match( $id_pattern, $id_value, $id_matches );
  155. $id_to_save = wp_json_encode( array( 'failed_to_get_id' => esc_attr( $id_value ) ) );
  156. if ( ! empty( $id_matches ) ) {
  157. $id_to_save = $id_matches[1];
  158. }
  159. return $id_to_save;
  160. }
  161. /**
  162. * @param $page_id
  163. * @param $grid_id
  164. * @return array|mixed|object|void
  165. */
  166. public function findPostShortcodeById( $page_id, $grid_id ) {
  167. if ( $this->currentUserCanManage( $page_id ) && preg_match( '/\"tag\"\:/', urldecode( $grid_id ) ) ) {
  168. return json_decode( urldecode( $grid_id ), true ); // if frontend, no hash exists - just RAW data
  169. }
  170. $post_meta = get_post_meta( (int) $page_id, '_vc_post_settings' );
  171. $shortcode = false;
  172. if ( is_array( $post_meta ) ) {
  173. foreach ( $post_meta as $meta ) {
  174. if ( isset( $meta['vc_grid_id'] ) && ! empty( $meta['vc_grid_id']['shortcodes'] ) && isset( $meta['vc_grid_id']['shortcodes'][ $grid_id ] ) ) {
  175. $shortcode = $meta['vc_grid_id']['shortcodes'][ $grid_id ];
  176. break;
  177. }
  178. }
  179. }
  180. return apply_filters( 'vc_basic_grid_find_post_shortcode', $shortcode, $page_id, $grid_id );
  181. }
  182. /**
  183. * @return string
  184. * @throws \Exception
  185. */
  186. public function renderItems() {
  187. $output = '';
  188. $items = '';
  189. $this->buildGridSettings();
  190. $atts = $this->atts;
  191. $settings = $this->grid_settings;
  192. $filter_terms = $this->filter_terms;
  193. $is_end = isset( $this->is_end ) && $this->is_end;
  194. $css_classes = 'vc_grid vc_row' . esc_attr( $atts['gap'] > 0 ? ' vc_grid-gutter-' . (int) $atts['gap'] . 'px' : '' );
  195. $currentScope = WPBMap::getScope();
  196. if ( is_array( $this->items ) && ! empty( $this->items ) ) {
  197. // Adding before vc_map
  198. WPBMap::setScope( Vc_Grid_Item_Editor::postType() );
  199. require_once vc_path_dir( 'PARAMS_DIR', 'vc_grid_item/class-vc-grid-item.php' );
  200. $this->grid_item = new Vc_Grid_Item();
  201. $this->grid_item->setGridAttributes( $atts );
  202. $this->grid_item->setIsEnd( $is_end );
  203. $this->grid_item->setTemplateById( $atts['item'] );
  204. $output .= $this->grid_item->addShortcodesCustomCss();
  205. ob_start();
  206. if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
  207. wp_print_styles();
  208. }
  209. $output .= ob_get_clean();
  210. $attributes = array(
  211. 'filter_terms' => $filter_terms,
  212. 'atts' => $atts,
  213. 'grid_item',
  214. $this->grid_item,
  215. );
  216. $output .= apply_filters( 'vc_basic_grid_template_filter', vc_get_template( 'shortcodes/vc_basic_grid_filter.php', $attributes ), $attributes );
  217. global $post;
  218. $backup = $post;
  219. foreach ( $this->items as $postItem ) {
  220. $this->query->setup_postdata( $postItem );
  221. // @codingStandardsIgnoreLine
  222. $post = $postItem;
  223. $items .= $this->grid_item->renderItem( $postItem );
  224. }
  225. wp_reset_postdata();
  226. $post = $backup;
  227. } else {
  228. return '';
  229. }
  230. $items = apply_filters( $this->shortcode . '_items_list', $items );
  231. $output .= $this->renderPagination( $atts['style'], $settings, $items, $css_classes );
  232. WPBMap::setScope( $currentScope );
  233. return $output;
  234. }
  235. public function setContentLimits() {
  236. $atts = $this->atts;
  237. if ( 'ids' === $this->atts['post_type'] ) {
  238. $this->atts['max_items'] = 0;
  239. $this->atts['offset'] = 0;
  240. $this->atts['items_per_page'] = apply_filters( 'vc_basic_grid_max_items', self::$default_max_items );
  241. } else {
  242. $offset = isset( $atts['offset'] ) ? (int) $atts['offset'] : $this->attributes_defaults['offset'];
  243. $this->atts['offset'] = $offset;
  244. $this->atts['max_items'] = isset( $atts['max_items'] ) ? (int) $atts['max_items'] : (int) $this->attributes_defaults['max_items'];
  245. $this->atts['items_per_page'] = ! isset( $atts['items_per_page'] ) ? (int) $this->attributes_defaults['items_per_page'] : (int) $atts['items_per_page'];
  246. if ( $this->atts['max_items'] < 1 ) {
  247. $this->atts['max_items'] = apply_filters( 'vc_basic_grid_max_items', self::$default_max_items );
  248. }
  249. }
  250. $this->setPagingAll( $this->atts['max_items'] );
  251. }
  252. /**
  253. * @param $max_items
  254. */
  255. protected function setPagingAll( $max_items ) {
  256. $atts = $this->atts;
  257. $this->atts['query_items_per_page'] = $max_items > 0 ? $max_items : apply_filters( 'vc_basic_grid_items_per_page_all_max_items', self::$default_max_items );
  258. $this->atts['items_per_page'] = $this->atts['query_items_per_page'];
  259. $this->atts['query_offset'] = isset( $atts['offset'] ) ? (int) $atts['offset'] : $this->attributes_defaults['offset'];
  260. }
  261. /**
  262. * @param $vc_request_param
  263. * @return false|mixed|string|void
  264. * @throws \Exception
  265. */
  266. public function renderAjax( $vc_request_param ) {
  267. $this->items = array(); // clear this items array (if used more than once);
  268. $id = isset( $vc_request_param['shortcode_id'] ) ? $vc_request_param['shortcode_id'] : false;
  269. $shortcode = false;
  270. if ( ! isset( $vc_request_param['page_id'] ) ) {
  271. return wp_json_encode( array( 'status' => 'Nothing found' ) );
  272. }
  273. if ( $id ) {
  274. $shortcode = $this->findPostShortcodeById( $vc_request_param['page_id'], $id );
  275. }
  276. if ( ! is_array( $shortcode ) ) {
  277. return wp_json_encode( array( 'status' => 'Nothing found' ) );
  278. }
  279. visual_composer()->registerAdminCss();
  280. visual_composer()->registerAdminJavascript();
  281. // Set post id
  282. $this->post_id = (int) $vc_request_param['page_id'];
  283. $shortcode_atts = $shortcode['atts'];
  284. $this->shortcode_content = $shortcode['content'];
  285. $this->buildAtts( $shortcode_atts, $shortcode['content'] );
  286. $this->buildItems();
  287. return $this->renderItems();
  288. }
  289. /**
  290. * @return bool|false|int
  291. */
  292. public function postID() {
  293. if ( ! $this->post_id ) {
  294. $this->post_id = get_the_ID();
  295. }
  296. return $this->post_id;
  297. }
  298. /**
  299. * @param $atts
  300. * @param $content
  301. * @throws \Exception
  302. */
  303. public function buildAtts( $atts, $content ) {
  304. $this->post_id = false;
  305. $this->grid_settings = array();
  306. $this->filter_terms = null;
  307. $this->items = array();
  308. $arr_keys = array_keys( $atts );
  309. $count = count( $atts );
  310. for ( $i = 0; $i < $count; $i ++ ) {
  311. $atts[ $arr_keys[ $i ] ] = html_entity_decode( $atts[ $arr_keys[ $i ] ], ENT_QUOTES, 'utf-8' );
  312. }
  313. if ( isset( $atts['grid_id'] ) && ! empty( $atts['grid_id'] ) ) {
  314. $id_to_save = $this->getId( $atts, $content );
  315. }
  316. $atts = $this->convertButton2ToButton3( $atts );
  317. $atts = shortcode_atts( $this->attributes_defaults, vc_map_get_attributes( $this->getShortcode(), $atts ) );
  318. $this->atts = $atts;
  319. if ( isset( $id_to_save ) ) {
  320. $this->atts['shortcode_id'] = $id_to_save;
  321. }
  322. $this->atts['page_id'] = $this->postID();
  323. $this->element_template = $content;
  324. // @since 4.4.3
  325. if ( 'custom' === $this->attr( 'post_type' ) ) {
  326. $this->atts['style'] = 'all';
  327. }
  328. }
  329. /**
  330. * Getter attribute.
  331. *
  332. * @param $key
  333. *
  334. * @return mixed|null
  335. */
  336. public function attr( $key ) {
  337. return isset( $this->atts[ $key ] ) ? $this->atts[ $key ] : null;
  338. }
  339. public function buildGridSettings() {
  340. $this->grid_settings = array(
  341. 'page_id' => $this->atts['page_id'],
  342. // used in basic grid for initialization
  343. 'style' => $this->atts['style'],
  344. 'action' => 'vc_get_vc_grid_data',
  345. );
  346. // used in ajax request for items
  347. if ( isset( $this->atts['shortcode_id'] ) && ! empty( $this->atts['shortcode_id'] ) ) {
  348. $this->grid_settings['shortcode_id'] = $this->atts['shortcode_id'];
  349. } elseif ( isset( $this->atts['shortcode_hash'] ) && ! empty( $this->atts['shortcode_hash'] ) ) {
  350. // @deprecated since 4.4.3
  351. $this->grid_settings['shortcode_hash'] = $this->atts['shortcode_hash'];
  352. }
  353. if ( 'load-more' === $this->atts['style'] ) {
  354. $this->grid_settings = array_merge( $this->grid_settings, array(
  355. // used in dispaly style load more button, lazy, pagination
  356. 'items_per_page' => $this->atts['items_per_page'],
  357. 'btn_data' => vc_map_integrate_parse_atts( $this->shortcode, 'vc_btn', $this->atts, 'btn_' ),
  358. ) );
  359. } elseif ( 'lazy' === $this->atts['style'] ) {
  360. $this->grid_settings = array_merge( $this->grid_settings, array(
  361. 'items_per_page' => $this->atts['items_per_page'],
  362. ) );
  363. } elseif ( 'pagination' === $this->atts['style'] ) {
  364. $this->grid_settings = array_merge( $this->grid_settings, array(
  365. 'items_per_page' => $this->atts['items_per_page'],
  366. // used in pagination style
  367. 'auto_play' => $this->atts['autoplay'] > 0 ? true : false,
  368. 'gap' => (int) $this->atts['gap'],
  369. // not used yet, but can be used in isotope..
  370. 'speed' => (int) $this->atts['autoplay'] * 1000,
  371. 'loop' => $this->atts['loop'],
  372. 'animation_in' => $this->atts['paging_animation_in'],
  373. 'animation_out' => $this->atts['paging_animation_out'],
  374. 'arrows_design' => $this->atts['arrows_design'],
  375. 'arrows_color' => $this->atts['arrows_color'],
  376. 'arrows_position' => $this->atts['arrows_position'],
  377. 'paging_design' => $this->atts['paging_design'],
  378. 'paging_color' => $this->atts['paging_color'],
  379. ) );
  380. }
  381. $this->grid_settings['tag'] = $this->shortcode;
  382. }
  383. // TODO: setter & getter to attributes
  384. /**
  385. * @param $atts
  386. * @return array
  387. */
  388. public function buildQuery( $atts ) {
  389. // Set include & exclude
  390. if ( 'ids' !== $atts['post_type'] && ! empty( $atts['exclude'] ) ) {
  391. $atts['exclude'] .= ',' . implode( ',', $this->excludedIds() );
  392. } else {
  393. $atts['exclude'] = implode( ',', $this->excludedIds() );
  394. }
  395. if ( 'ids' !== $atts['post_type'] ) {
  396. $settings = array(
  397. 'posts_per_page' => $atts['query_items_per_page'],
  398. 'offset' => $atts['query_offset'],
  399. 'orderby' => $atts['orderby'],
  400. 'order' => $atts['order'],
  401. 'meta_key' => in_array( $atts['orderby'], array(
  402. 'meta_value',
  403. 'meta_value_num',
  404. ), true ) ? $atts['meta_key'] : '',
  405. 'post_type' => $atts['post_type'],
  406. 'exclude' => $atts['exclude'],
  407. );
  408. if ( ! empty( $atts['taxonomies'] ) ) {
  409. $vc_taxonomies_types = get_taxonomies( array( 'public' => true ) );
  410. $terms = get_terms( array_keys( $vc_taxonomies_types ), array(
  411. 'hide_empty' => false,
  412. 'include' => $atts['taxonomies'],
  413. ) );
  414. $settings['tax_query'] = array();
  415. $tax_queries = array(); // List of taxnonimes
  416. foreach ( $terms as $term ) {
  417. if ( ! isset( $tax_queries[ $term->taxonomy ] ) ) {
  418. $tax_queries[ $term->taxonomy ] = array(
  419. 'taxonomy' => $term->taxonomy,
  420. 'field' => 'id',
  421. 'terms' => array( $term->term_id ),
  422. 'relation' => 'IN',
  423. );
  424. } else {
  425. $tax_queries[ $term->taxonomy ]['terms'][] = $term->term_id;
  426. }
  427. }
  428. $settings['tax_query'] = array_values( $tax_queries );
  429. $settings['tax_query']['relation'] = 'OR';
  430. }
  431. } else {
  432. if ( empty( $atts['include'] ) ) {
  433. $atts['include'] = - 1;
  434. } elseif ( ! empty( $atts['exclude'] ) ) {
  435. $include = array_map( 'trim', explode( ',', $atts['include'] ) );
  436. $exclude = array_map( 'trim', explode( ',', $atts['exclude'] ) );
  437. $diff = array_diff( $include, $exclude );
  438. $atts['include'] = implode( ', ', $diff );
  439. }
  440. $settings = array(
  441. 'include' => $atts['include'],
  442. 'posts_per_page' => $atts['query_items_per_page'],
  443. 'offset' => $atts['query_offset'],
  444. 'post_type' => 'any',
  445. 'orderby' => 'post__in',
  446. );
  447. $this->atts['items_per_page'] = - 1;
  448. }
  449. return $settings;
  450. }
  451. public function buildItems() {
  452. $this->filter_terms = $this->items = array();
  453. $this->query = new WP_Query();
  454. $this->setContentLimits();
  455. $this->addExcludedId( $this->postID() );
  456. if ( 'custom' === $this->atts['post_type'] && ! empty( $this->atts['custom_query'] ) ) {
  457. $query = html_entity_decode( vc_value_from_safe( $this->atts['custom_query'] ), ENT_QUOTES, 'utf-8' );
  458. $query = apply_filters( 'vc_basic_grid_filter_query_filters', $query, $this->atts, $this->shortcode );
  459. $post_data = $this->query->query( $query );
  460. $this->atts['items_per_page'] = - 1;
  461. } elseif ( false !== $this->atts['query_items_per_page'] ) {
  462. $settings = $this->filterQuerySettings( $this->buildQuery( $this->atts ) );
  463. $post_data = $this->query->query( $settings );
  464. } else {
  465. return;
  466. }
  467. if ( $this->atts['items_per_page'] > 0 && count( $post_data ) > $this->atts['items_per_page'] ) {
  468. $post_data = array_slice( $post_data, 0, $this->atts['items_per_page'] );
  469. }
  470. foreach ( $post_data as $post ) {
  471. $post->filter_terms = wp_get_object_terms( $post->ID, $this->atts['filter_source'], array( 'fields' => 'ids' ) );
  472. $this->filter_terms = wp_parse_args( $this->filter_terms, $post->filter_terms );
  473. $this->items[] = $post;
  474. }
  475. }
  476. /**
  477. * @param $args
  478. * @return array
  479. */
  480. public function filterQuerySettings( $args ) {
  481. $defaults = array(
  482. 'numberposts' => 5,
  483. 'offset' => 0,
  484. 'category' => 0,
  485. 'orderby' => 'date',
  486. 'order' => 'DESC',
  487. 'include' => array(),
  488. 'exclude' => array(),
  489. 'meta_key' => '',
  490. 'meta_value' => '',
  491. 'post_type' => 'post',
  492. 'suppress_filters' => apply_filters( 'vc_basic_grid_filter_query_suppress_filters', true ),
  493. 'public' => true,
  494. );
  495. $r = wp_parse_args( $args, $defaults );
  496. if ( empty( $r['post_status'] ) ) {
  497. $r['post_status'] = ( 'attachment' === $r['post_type'] ) ? 'inherit' : 'publish';
  498. }
  499. if ( ! empty( $r['numberposts'] ) && empty( $r['posts_per_page'] ) ) {
  500. $r['posts_per_page'] = $r['numberposts'];
  501. }
  502. if ( ! empty( $r['category'] ) ) {
  503. $r['cat'] = $r['category'];
  504. }
  505. if ( ! empty( $r['include'] ) ) {
  506. $incposts = wp_parse_id_list( $r['include'] );
  507. $r['posts_per_page'] = count( $incposts ); // only the number of posts included
  508. $r['post__in'] = $incposts;
  509. } elseif ( ! empty( $r['exclude'] ) ) {
  510. $r['post__not_in'] = wp_parse_id_list( $r['exclude'] );
  511. }
  512. $r['ignore_sticky_posts'] = true;
  513. $r['no_found_rows'] = true;
  514. return $r;
  515. }
  516. /**
  517. * @param $atts
  518. * @return mixed
  519. */
  520. public static function convertButton2ToButton3( $atts ) {
  521. if ( isset( $atts['button_style'] ) || isset( $atts['button_size'] ) || isset( $atts['button_color'] ) ) {
  522. // we use old button 2 attributes:
  523. $style = isset( $atts['button_style'] ) ? $atts['button_style'] : 'rounded';
  524. $size = isset( $atts['button_size'] ) ? $atts['button_size'] : 'md';
  525. $color = isset( $atts['button_color'] ) ? $atts['button_color'] : 'blue';
  526. $oldData = array(
  527. 'style' => $style,
  528. 'size' => $size,
  529. 'color' => str_replace( '_', '-', $color ),
  530. );
  531. // remove attributes on save
  532. $atts['button_style'] = '';
  533. $atts['button_size'] = '';
  534. $atts['button_color'] = '';
  535. $newData = WPBakeryShortCode_Vc_Btn::convertAttributesToButton3( $oldData );
  536. foreach ( $newData as $key => $value ) {
  537. $atts[ 'btn_' . $key ] = $value;
  538. }
  539. }
  540. return $atts;
  541. }
  542. }