WordPress Page Builder – Beaver Builder - Version 1.10.7

Version Description

Download this release

Release Info

Developer pross
Plugin Icon 128x128 WordPress Page Builder – Beaver Builder
Version 1.10.7
Comparing to
See all releases

Code changes from version 1.10.6.5 to 1.10.7

Files changed (126) hide show
  1. changelog.txt +22 -2
  2. classes/class-fl-builder-admin-posts.php +44 -51
  3. classes/class-fl-builder-admin.php +54 -61
  4. classes/class-fl-builder-ajax-layout.php +129 -153
  5. classes/class-fl-builder-ajax.php +36 -45
  6. classes/class-fl-builder-auto-suggest.php +121 -111
  7. classes/class-fl-builder-color.php +21 -24
  8. classes/class-fl-builder-export.php +28 -33
  9. classes/class-fl-builder-extensions.php +9 -10
  10. classes/class-fl-builder-fonts.php +4 -4
  11. classes/class-fl-builder-icons.php +33 -51
  12. classes/class-fl-builder-import.php +14 -16
  13. classes/class-fl-builder-importer.php +36 -37
  14. classes/class-fl-builder-loader.php +25 -34
  15. classes/class-fl-builder-loop.php +638 -141
  16. classes/class-fl-builder-model.php +835 -1095
  17. classes/class-fl-builder-module.php +103 -116
  18. classes/class-fl-builder-photo.php +36 -45
  19. classes/class-fl-builder-service-activecampaign.php +95 -104
  20. classes/class-fl-builder-service-aweber.php +77 -86
  21. classes/class-fl-builder-service-campaign-monitor.php +85 -86
  22. classes/class-fl-builder-service-campayn.php +101 -106
  23. classes/class-fl-builder-service-constant-contact.php +75 -83
  24. classes/class-fl-builder-service-convertkit.php +67 -69
  25. classes/class-fl-builder-service-drip.php +87 -94
  26. classes/class-fl-builder-service-email-address.php +17 -19
  27. classes/class-fl-builder-service-enormail.php +65 -70
  28. classes/class-fl-builder-service-getresponse.php +68 -72
  29. classes/class-fl-builder-service-godaddy-email-marketing.php +73 -80
  30. classes/class-fl-builder-service-hatchbuck.php +80 -83
  31. classes/class-fl-builder-service-icontact-pro.php +93 -103
  32. classes/class-fl-builder-service-icontact.php +81 -87
  33. classes/class-fl-builder-service-infusionsoft.php +94 -103
  34. classes/class-fl-builder-service-madmimi.php +74 -81
  35. classes/class-fl-builder-service-mailchimp.php +111 -117
  36. classes/class-fl-builder-service-mailerlite.php +66 -69
  37. classes/class-fl-builder-service-mailpoet.php +69 -66
  38. classes/class-fl-builder-service-mailrelay.php +48 -51
  39. classes/class-fl-builder-service-sendinblue.php +68 -75
  40. classes/class-fl-builder-service-sendy.php +62 -61
  41. classes/class-fl-builder-service.php +11 -12
  42. classes/class-fl-builder-services.php +48 -59
  43. classes/class-fl-builder-shortcodes.php +16 -21
  44. classes/class-fl-builder-update.php +187 -211
  45. classes/class-fl-builder-user-access.php +31 -34
  46. classes/class-fl-builder-utils.php +77 -84
  47. classes/class-fl-builder-wpcli-command.php +2 -2
  48. classes/class-fl-builder.php +450 -556
  49. classes/class-fl-jsmin.php +64 -66
  50. extensions/fl-builder-multisite/classes/class-fl-builder-multisite.php +36 -45
  51. extensions/fl-builder-multisite/fl-builder-multisite.php +2 -2
  52. fl-builder.php +1 -1
  53. includes/admin-posts.php +2 -2
  54. includes/admin-settings-js-config.php +8 -8
  55. includes/admin-settings-modules.php +19 -19
  56. includes/admin-settings-post-types.php +39 -37
  57. includes/admin-settings-tools.php +11 -11
  58. includes/admin-settings-upgrade.php +14 -10
  59. includes/admin-settings-user-access.php +11 -10
  60. includes/admin-settings-welcome.php +30 -30
  61. includes/admin-settings.php +1 -1
  62. includes/column-css.php +21 -21
  63. includes/column-group.php +1 -1
  64. includes/column-settings.php +192 -192
  65. includes/column.php +1 -1
  66. includes/compatibility.php +43 -31
  67. includes/export-filters.php +1 -1
  68. includes/export.php +58 -46
  69. includes/field-button.php +1 -1
  70. includes/field-code.php +25 -24
  71. includes/field-color.php +3 -3
  72. includes/field-editor.php +26 -26
  73. includes/field-font.php +2 -2
  74. includes/field-form.php +10 -12
  75. includes/field-icon.php +7 -6
  76. includes/field-layout.php +3 -3
  77. includes/field-link.php +4 -4
  78. includes/field-multiple-audios.php +10 -10
  79. includes/field-multiple-photos.php +11 -11
  80. includes/field-ordering.php +4 -4
  81. includes/field-photo-sizes.php +8 -8
  82. includes/field-photo.php +11 -10
  83. includes/field-post-type.php +4 -4
  84. includes/field-select.php +31 -32
  85. includes/field-suggest.php +1 -1
  86. includes/field-text.php +15 -11
  87. includes/field-textarea.php +3 -1
  88. includes/field-time.php +12 -12
  89. includes/field-timezone.php +5 -2
  90. includes/field-unit.php +1 -1
  91. includes/field-video.php +7 -6
  92. includes/field.php +32 -34
  93. includes/global-settings.php +64 -64
  94. includes/icon-selector.php +3 -3
  95. includes/jquery.php +1 -1
  96. includes/layout-js-config.php +1 -1
  97. includes/layout-settings.php +17 -17
  98. includes/loop-settings-matching.php +1 -1
  99. includes/loop-settings.php +57 -57
  100. includes/module-settings.php +57 -57
  101. includes/module.php +8 -2
  102. includes/row-css.php +17 -17
  103. includes/row-js.php +11 -11
  104. includes/row-settings.php +291 -290
  105. includes/row-video.php +17 -11
  106. includes/row.php +2 -2
  107. includes/service-settings.php +19 -17
  108. includes/settings.php +20 -18
  109. includes/template-selector.php +18 -8
  110. includes/ui-bar.php +1 -1
  111. includes/ui-fields.php +4 -2
  112. includes/ui-js-config.php +101 -97
  113. includes/ui-js-templates.php +15 -15
  114. includes/ui-panel-module-templates.php +1 -1
  115. includes/ui-panel-row-templates.php +1 -1
  116. includes/ui-panel.php +20 -16
  117. includes/updater-config.php +6 -6
  118. includes/updater/classes/class-fl-updater.php +62 -81
  119. includes/updater/includes/config.php +2 -2
  120. includes/updater/includes/form.php +34 -22
  121. includes/updater/includes/subscriptions.php +6 -6
  122. includes/updater/updater.php +8 -8
  123. includes/vendor/godaddy-email-marketing/class-godaddy-em.php +11 -11
  124. js/fl-builder-layout.js +2 -1
  125. js/fl-builder.js +18 -9
  126. js/fl-builder.min.js +1 -6
changelog.txt CHANGED
@@ -1,7 +1,26 @@
1
- <h4>1.10.6.5 8/03/2017</h4>
 
 
 
 
 
 
 
2
  <p><strong>Bug Fixes</strong></p>
3
  <ul>
4
- <li>Fixed Text Editor Module z-index issue introduced in WordPress 4.8.1</li>
 
 
 
 
 
 
 
 
 
 
 
 
5
  </ul>
6
 
7
  <h4>1.10.6.4 7/28/2017</h4>
@@ -9,6 +28,7 @@
9
  <ul>
10
  <li>Fixed PHP error produced by canonical redirection if the post_type is changed to an array by a plugin.</li>
11
  </ul>
 
12
  <h4>1.10.6.3 7/05/2017</h4>
13
  <p><strong>Bug Fixes</strong></p>
14
  <ul>
1
+ <h4>1.10.7 8/08/2017</h4>
2
+ <p><strong>Enhancements</strong></p>
3
+ <ul>
4
+ <li>Safemode for the builder added. If you append <code>&safemode</code> to your url when the builder is active all modules will be safely rendered without content.</li>
5
+ <li>Added custom field support for Map Module and SmugMug feed urls.</li>
6
+ <li>Reworked featured image placement options in Posts Module.</li>
7
+ <li>Updated language files.</li>
8
+ </ul>
9
  <p><strong>Bug Fixes</strong></p>
10
  <ul>
11
+ <li>Fixed Menu Module, mega menu only works with horizontal nav menus.</li>
12
+ <li>Fixed the missing image alt on Callout Module.</li>
13
+ <li>Fixed Contact Form Reply-To headers incorrectly set.</li>
14
+ <li>Fixed an issue with Agency version not being able to rename a child theme if the theme is not network enabled.</li>
15
+ <li>Fixed a JS error if Countdown Module visibility is set to never.</li>
16
+ <li>Fixed RTL issues in Post Grid Module.</li>
17
+ <li>Fixed issue with YouTube background videos showing related content on certain versions of IE.</li>
18
+ <li>Fixed PHP warning in Subscribe Module.</li>
19
+ <li>Fixed Posts Module pagination issues.</li>
20
+ <li>Fixed saving issue. Any modules using non UTF-8 chars would cause a JS fatal error when using `FL_BUILDER_MODSEC_FIX`.</li>
21
+ <li>Fixed a fatal PHP error when duplicating Woocommerce products.</li>
22
+ <li>Fixed repeater fields not working when registered in the global settings.</li>
23
+ <li>Fixed Text Editor Module z-index issue introduced in WordPress 4.8.1</li>
24
  </ul>
25
 
26
  <h4>1.10.6.4 7/28/2017</h4>
28
  <ul>
29
  <li>Fixed PHP error produced by canonical redirection if the post_type is changed to an array by a plugin.</li>
30
  </ul>
31
+
32
  <h4>1.10.6.3 7/05/2017</h4>
33
  <p><strong>Bug Fixes</strong></p>
34
  <ul>
classes/class-fl-builder-admin-posts.php CHANGED
@@ -1,42 +1,40 @@
1
  <?php
2
 
3
  /**
4
- * Handles logic for the post edit screen.
5
  *
6
  * @since 1.0
7
  */
8
  final class FLBuilderAdminPosts {
9
-
10
- /**
11
  * Initialize hooks.
12
  *
13
  * @since 1.8
14
  * @return void
15
  */
16
- static public function init()
17
- {
18
  /* Actions */
19
- add_action('current_screen', __CLASS__ . '::init_rendering');
20
-
21
  /* Filters */
22
- add_filter('redirect_post_location', __CLASS__ . '::redirect_post_location');
23
- add_filter('page_row_actions', __CLASS__ . '::render_row_actions_link');
24
- add_filter('post_row_actions', __CLASS__ . '::render_row_actions_link');
25
  }
26
-
27
- /**
28
  * Sets the body class, loads assets and renders the UI
29
  * if we are on a post type that supports the builder.
30
  *
31
  * @since 1.0
32
  * @return void
33
  */
34
- static public function init_rendering()
35
- {
36
  global $pagenow;
37
-
38
- if ( in_array( $pagenow, array( 'post.php', 'post-new.php') ) ) {
39
-
40
  $render_ui = apply_filters( 'fl_builder_render_admin_edit_ui', true );
41
  $post_types = FLBuilderModel::get_post_types();
42
  $screen = get_current_screen();
@@ -48,113 +46,108 @@ final class FLBuilderAdminPosts {
48
  }
49
  }
50
  }
51
-
52
  /**
53
  * Enqueues the CSS/JS for the post edit screen.
54
  *
55
  * @since 1.0
56
  * @return void
57
- */
58
- static public function styles_scripts()
59
- {
60
  global $wp_version;
61
-
62
  // Styles
63
  wp_enqueue_style( 'fl-builder-admin-posts', FL_BUILDER_URL . 'css/fl-builder-admin-posts.css', array(), FL_BUILDER_VERSION );
64
-
65
  // Legacy WP Styles (3.7 and below)
66
  if ( version_compare( $wp_version, '3.7', '<=' ) ) {
67
  wp_enqueue_style( 'fl-builder-admin-posts-legacy', FL_BUILDER_URL . 'css/fl-builder-admin-posts-legacy.css', array(), FL_BUILDER_VERSION );
68
  }
69
-
70
  // Scripts
71
  wp_enqueue_script( 'json2' );
72
  wp_enqueue_script( 'fl-builder-admin-posts', FL_BUILDER_URL . 'js/fl-builder-admin-posts.js', array(), FL_BUILDER_VERSION );
73
  }
74
-
75
  /**
76
  * Adds classes to the post edit screen body class.
77
  *
78
  * @since 1.0
79
  * @param string $classes The existing body classes.
80
  * @return string The body classes.
81
- */
82
- static public function body_class( $classes = '' )
83
- {
84
  global $wp_version;
85
-
86
  // Builder body class
87
  if ( FLBuilderModel::is_builder_enabled() ) {
88
  $classes .= ' fl-builder-enabled';
89
  }
90
-
91
  // Pre WP 3.8 body class
92
  if ( version_compare( $wp_version, '3.8', '<' ) ) {
93
  $classes .= ' fl-pre-wp-3-8';
94
  }
95
-
96
  return $classes;
97
  }
98
-
99
  /**
100
  * Renders the HTML for the post edit screen.
101
  *
102
  * @since 1.0
103
  * @return void
104
- */
105
- static public function render()
106
- {
107
  global $post;
108
-
109
  $post_type_obj = get_post_type_object( $post->post_type );
110
  $post_type_name = strtolower( $post_type_obj->labels->singular_name );
111
  $enabled = FLBuilderModel::is_builder_enabled();
112
-
113
  include FL_BUILDER_DIR . 'includes/admin-posts.php';
114
  }
115
-
116
  /**
117
  * Renders the action link for post listing pages.
118
  *
119
  * @since 1.0
120
  * @param array $actions
121
  * @return array The array of action data.
122
- */
123
- static public function render_row_actions_link( $actions = array() )
124
- {
125
  global $post;
126
-
127
  if ( 'trash' != $post->post_status && current_user_can( 'edit_post', $post->ID ) && wp_check_post_lock( $post->ID ) === false ) {
128
-
129
  $is_post_editable = (bool) apply_filters( 'fl_builder_is_post_editable', true, $post );
130
 
131
  $post_types = FLBuilderModel::get_post_types();
132
-
133
  if ( in_array( $post->post_type, $post_types ) && $is_post_editable ) {
134
  $enabled = get_post_meta( $post->ID, '_fl_builder_enabled', true );
135
  $dot = ' <span style="color:' . ( $enabled ? '#6bc373' : '#d9d9d9' ) . '; font-size:18px;">&bull;</span>';
136
  $actions['fl-builder'] = '<a href="' . FLBuilderModel::get_edit_url() . '">' . FLBuilderModel::get_branding() . $dot . '</a>';
137
  }
138
  }
139
-
140
  return $actions;
141
  }
142
-
143
  /**
144
  * Where to redirect this post on save.
145
  *
146
  * @since 1.0
147
  * @param string $location
148
  * @return string The location to redirect this post on save.
149
- */
150
- static public function redirect_post_location( $location )
151
- {
152
  if ( isset( $_POST['fl-builder-redirect'] ) ) {
153
  $location = $_POST['fl-builder-redirect'];
154
  }
155
-
156
  return $location;
157
  }
158
  }
159
 
160
- FLBuilderAdminPosts::init();
1
  <?php
2
 
3
  /**
4
+ * Handles logic for the post edit screen.
5
  *
6
  * @since 1.0
7
  */
8
  final class FLBuilderAdminPosts {
9
+
10
+ /**
11
  * Initialize hooks.
12
  *
13
  * @since 1.8
14
  * @return void
15
  */
16
+ static public function init() {
 
17
  /* Actions */
18
+ add_action( 'current_screen', __CLASS__ . '::init_rendering' );
19
+
20
  /* Filters */
21
+ add_filter( 'redirect_post_location', __CLASS__ . '::redirect_post_location' );
22
+ add_filter( 'page_row_actions', __CLASS__ . '::render_row_actions_link' );
23
+ add_filter( 'post_row_actions', __CLASS__ . '::render_row_actions_link' );
24
  }
25
+
26
+ /**
27
  * Sets the body class, loads assets and renders the UI
28
  * if we are on a post type that supports the builder.
29
  *
30
  * @since 1.0
31
  * @return void
32
  */
33
+ static public function init_rendering() {
 
34
  global $pagenow;
35
+
36
+ if ( in_array( $pagenow, array( 'post.php', 'post-new.php' ) ) ) {
37
+
38
  $render_ui = apply_filters( 'fl_builder_render_admin_edit_ui', true );
39
  $post_types = FLBuilderModel::get_post_types();
40
  $screen = get_current_screen();
46
  }
47
  }
48
  }
49
+
50
  /**
51
  * Enqueues the CSS/JS for the post edit screen.
52
  *
53
  * @since 1.0
54
  * @return void
55
+ */
56
+ static public function styles_scripts() {
 
57
  global $wp_version;
58
+
59
  // Styles
60
  wp_enqueue_style( 'fl-builder-admin-posts', FL_BUILDER_URL . 'css/fl-builder-admin-posts.css', array(), FL_BUILDER_VERSION );
61
+
62
  // Legacy WP Styles (3.7 and below)
63
  if ( version_compare( $wp_version, '3.7', '<=' ) ) {
64
  wp_enqueue_style( 'fl-builder-admin-posts-legacy', FL_BUILDER_URL . 'css/fl-builder-admin-posts-legacy.css', array(), FL_BUILDER_VERSION );
65
  }
66
+
67
  // Scripts
68
  wp_enqueue_script( 'json2' );
69
  wp_enqueue_script( 'fl-builder-admin-posts', FL_BUILDER_URL . 'js/fl-builder-admin-posts.js', array(), FL_BUILDER_VERSION );
70
  }
71
+
72
  /**
73
  * Adds classes to the post edit screen body class.
74
  *
75
  * @since 1.0
76
  * @param string $classes The existing body classes.
77
  * @return string The body classes.
78
+ */
79
+ static public function body_class( $classes = '' ) {
 
80
  global $wp_version;
81
+
82
  // Builder body class
83
  if ( FLBuilderModel::is_builder_enabled() ) {
84
  $classes .= ' fl-builder-enabled';
85
  }
86
+
87
  // Pre WP 3.8 body class
88
  if ( version_compare( $wp_version, '3.8', '<' ) ) {
89
  $classes .= ' fl-pre-wp-3-8';
90
  }
91
+
92
  return $classes;
93
  }
94
+
95
  /**
96
  * Renders the HTML for the post edit screen.
97
  *
98
  * @since 1.0
99
  * @return void
100
+ */
101
+ static public function render() {
 
102
  global $post;
103
+
104
  $post_type_obj = get_post_type_object( $post->post_type );
105
  $post_type_name = strtolower( $post_type_obj->labels->singular_name );
106
  $enabled = FLBuilderModel::is_builder_enabled();
107
+
108
  include FL_BUILDER_DIR . 'includes/admin-posts.php';
109
  }
110
+
111
  /**
112
  * Renders the action link for post listing pages.
113
  *
114
  * @since 1.0
115
  * @param array $actions
116
  * @return array The array of action data.
117
+ */
118
+ static public function render_row_actions_link( $actions = array() ) {
 
119
  global $post;
120
+
121
  if ( 'trash' != $post->post_status && current_user_can( 'edit_post', $post->ID ) && wp_check_post_lock( $post->ID ) === false ) {
122
+
123
  $is_post_editable = (bool) apply_filters( 'fl_builder_is_post_editable', true, $post );
124
 
125
  $post_types = FLBuilderModel::get_post_types();
126
+
127
  if ( in_array( $post->post_type, $post_types ) && $is_post_editable ) {
128
  $enabled = get_post_meta( $post->ID, '_fl_builder_enabled', true );
129
  $dot = ' <span style="color:' . ( $enabled ? '#6bc373' : '#d9d9d9' ) . '; font-size:18px;">&bull;</span>';
130
  $actions['fl-builder'] = '<a href="' . FLBuilderModel::get_edit_url() . '">' . FLBuilderModel::get_branding() . $dot . '</a>';
131
  }
132
  }
133
+
134
  return $actions;
135
  }
136
+
137
  /**
138
  * Where to redirect this post on save.
139
  *
140
  * @since 1.0
141
  * @param string $location
142
  * @return string The location to redirect this post on save.
143
+ */
144
+ static public function redirect_post_location( $location ) {
 
145
  if ( isset( $_POST['fl-builder-redirect'] ) ) {
146
  $location = $_POST['fl-builder-redirect'];
147
  }
148
+
149
  return $location;
150
  }
151
  }
152
 
153
+ FLBuilderAdminPosts::init();
classes/class-fl-builder-admin.php CHANGED
@@ -13,13 +13,12 @@ final class FLBuilderAdmin {
13
  * @since 1.8
14
  * @return void
15
  */
16
- static public function init()
17
- {
18
  $basename = plugin_basename( FL_BUILDER_FILE );
19
-
20
  // Activation
21
  register_activation_hook( FL_BUILDER_FILE, __CLASS__ . '::activate' );
22
-
23
  // Actions
24
  add_action( 'admin_init', __CLASS__ . '::show_activate_notice' );
25
 
@@ -28,37 +27,40 @@ final class FLBuilderAdmin {
28
  }
29
 
30
  /**
31
- * Called on plugin activation and checks to see if the correct
32
- * WordPress version is installed and multisite is supported. If
33
  * all checks are passed the install method is called.
34
  *
35
  * @since 1.0
36
  * @return void
37
  */
38
- static public function activate()
39
- {
40
  global $wp_version;
41
 
42
  // Check for WordPress 3.5 and above.
43
- if(!version_compare($wp_version, '3.5', '>=')) {
44
- self::show_activate_error(__('The <strong>Page Builder</strong> plugin requires WordPress version 3.5 or greater. Please update WordPress before activating the plugin.', 'fl-builder'));
45
  }
46
-
47
  // Allow extensions to hook activation.
48
  $activate = apply_filters( 'fl_builder_activate', true );
49
-
50
- // Should we continue with activation?
51
  if ( $activate ) {
52
 
53
  // Check for multisite.
54
- if(is_multisite()) {
55
- $url = FLBuilderModel::get_store_url( '', array( 'utm_medium' => 'bb-pro', 'utm_source' => 'plugins-admin-page', 'utm_campaign' => 'no-multisite-support' ) );
 
 
 
 
56
  self::show_activate_error( sprintf( __( 'This version of the <strong>Page Builder</strong> plugin is not compatible with WordPress Multisite. <a%s>Please upgrade</a> to the Multisite version of this plugin.', 'fl-builder' ), ' href="' . $url . '" target="_blank"' ) );
57
  }
58
-
59
  // Success! Run the install.
60
  self::install();
61
-
62
  // Trigger the activation notice.
63
  self::trigger_activate_notice();
64
 
@@ -71,15 +73,14 @@ final class FLBuilderAdmin {
71
  }
72
 
73
  /**
74
- * Show a message if there is an activation error and
75
  * deactivates the plugin.
76
  *
77
  * @since 1.0
78
  * @param string $message The message to show.
79
  * @return void
80
  */
81
- static public function show_activate_error($message)
82
- {
83
  deactivate_plugins( FLBuilderModel::plugin_basename(), false, is_network_admin() );
84
 
85
  die( $message );
@@ -92,22 +93,20 @@ final class FLBuilderAdmin {
92
  * @since 1.8
93
  * @return void
94
  */
95
- static public function trigger_activate_notice()
96
- {
97
  if ( current_user_can( 'delete_users' ) ) {
98
  set_transient( '_fl_builder_activation_admin_notice', true, 30 );
99
  }
100
  }
101
 
102
  /**
103
- * Shows the activation success message or redirects to the
104
  * welcome page.
105
  *
106
  * @since 1.0
107
  * @return void
108
  */
109
- static public function show_activate_notice()
110
- {
111
  // Bail if no activation transient is set.
112
  if ( ! get_transient( '_fl_builder_activation_admin_notice' ) ) {
113
  return;
@@ -118,12 +117,13 @@ final class FLBuilderAdmin {
118
 
119
  if ( isset( $_GET['activate-multi'] ) || is_multisite() ) {
120
  // Show the notice if we are activating multiple plugins or on multisite.
121
- add_action('admin_notices', __CLASS__ . '::activate_notice');
122
- add_action('network_admin_notices', __CLASS__ . '::activate_notice');
123
- }
124
- else {
125
  // Redirect to the welcome page.
126
- wp_safe_redirect( add_query_arg( array( 'page' => 'fl-builder-settings' ), admin_url( 'options-general.php' ) ) );
 
 
127
  }
128
  }
129
 
@@ -133,26 +133,24 @@ final class FLBuilderAdmin {
133
  * @since 1.0
134
  * @return void
135
  */
136
- static public function activate_notice()
137
- {
138
  if ( FL_BUILDER_LITE !== true ) {
139
  $hash = '#license';
140
  $message = __( 'Page Builder activated! <a%s>Click here</a> to enable remote updates.', 'fl-builder' );
141
- }
142
- else {
143
  $hash = '#welcome';
144
  $message = __( 'Page Builder activated! <a%s>Click here</a> to get started.', 'fl-builder' );
145
  }
146
-
147
  $url = apply_filters( 'fl_builder_activate_redirect_url', admin_url( '/options-general.php?page=fl-builder-settings' . $hash ) );
148
-
149
  echo '<div class="updated" style="background: #d3ebc1;">';
150
  echo '<p><strong>' . sprintf( $message, ' href="' . esc_url( $url ) . '"' ) . '</strong></p>';
151
  echo '</div>';
152
  }
153
 
154
  /**
155
- * Installs the builder upon successful activation.
156
  * Currently not used but may be in the future.
157
  *
158
  * @since 1.0
@@ -166,8 +164,7 @@ final class FLBuilderAdmin {
166
  * @since 1.0
167
  * @return void
168
  */
169
- static public function uninstall()
170
- {
171
  FLBuilderModel::uninstall_database();
172
  }
173
 
@@ -178,10 +175,13 @@ final class FLBuilderAdmin {
178
  * @param array $actions An array of row action links.
179
  * @return array
180
  */
181
- static public function render_plugin_action_links($actions)
182
- {
183
- if(FL_BUILDER_LITE === true) {
184
- $url = FLBuilderModel::get_store_url( '', array( 'utm_medium' => 'bb-lite', 'utm_source' => 'plugins-admin-page', 'utm_campaign' => 'plugins-admin-upgrade' ) );
 
 
 
185
  $actions[] = '<a href="' . $url . '" style="color:#3db634;" target="_blank">' . _x( 'Upgrade', 'Plugin action link label.', 'fl-builder' ) . '</a>';
186
  }
187
 
@@ -192,8 +192,7 @@ final class FLBuilderAdmin {
192
  * @since 1.0
193
  * @deprecated 1.8
194
  */
195
- static public function init_classes()
196
- {
197
  _deprecated_function( __METHOD__, '1.8' );
198
  }
199
 
@@ -201,8 +200,7 @@ final class FLBuilderAdmin {
201
  * @since 1.0
202
  * @deprecated 1.8
203
  */
204
- static public function init_settings()
205
- {
206
  _deprecated_function( __METHOD__, '1.8' );
207
  }
208
 
@@ -210,8 +208,7 @@ final class FLBuilderAdmin {
210
  * @since 1.0
211
  * @deprecated 1.8
212
  */
213
- static public function init_multisite()
214
- {
215
  _deprecated_function( __METHOD__, '1.8' );
216
  }
217
 
@@ -219,8 +216,7 @@ final class FLBuilderAdmin {
219
  * @since 1.0
220
  * @deprecated 1.8
221
  */
222
- static public function init_templates()
223
- {
224
  _deprecated_function( __METHOD__, '1.8' );
225
  }
226
 
@@ -228,10 +224,9 @@ final class FLBuilderAdmin {
228
  * @since 1.0
229
  * @deprecated 1.8
230
  */
231
- static public function white_label_plugins_page($plugins)
232
- {
233
  _deprecated_function( __METHOD__, '1.8', 'FLBuilderWhiteLabel::plugins_page()' );
234
-
235
  if ( class_exists( 'FLBuilderWhiteLabel' ) ) {
236
  return FLBuilderWhiteLabel::plugins_page( $plugins );
237
  }
@@ -243,14 +238,13 @@ final class FLBuilderAdmin {
243
  * @since 1.6.4.3
244
  * @deprecated 1.8
245
  */
246
- static public function white_label_themes_page( $themes )
247
- {
248
  _deprecated_function( __METHOD__, '1.8', 'FLBuilderWhiteLabel::themes_page()' );
249
-
250
  if ( class_exists( 'FLBuilderWhiteLabel' ) ) {
251
  return FLBuilderWhiteLabel::themes_page( $themes );
252
  }
253
-
254
  return $themes;
255
  }
256
 
@@ -258,12 +252,11 @@ final class FLBuilderAdmin {
258
  * @since 1.6.4.4
259
  * @deprecated 1.8
260
  */
261
- static public function white_label_theme_gettext( $text )
262
- {
263
  if ( class_exists( 'FLBuilderWhiteLabel' ) ) {
264
  return FLBuilderWhiteLabel::theme_gettext( $text );
265
  }
266
-
267
  return $text;
268
  }
269
  }
13
  * @since 1.8
14
  * @return void
15
  */
16
+ static public function init() {
 
17
  $basename = plugin_basename( FL_BUILDER_FILE );
18
+
19
  // Activation
20
  register_activation_hook( FL_BUILDER_FILE, __CLASS__ . '::activate' );
21
+
22
  // Actions
23
  add_action( 'admin_init', __CLASS__ . '::show_activate_notice' );
24
 
27
  }
28
 
29
  /**
30
+ * Called on plugin activation and checks to see if the correct
31
+ * WordPress version is installed and multisite is supported. If
32
  * all checks are passed the install method is called.
33
  *
34
  * @since 1.0
35
  * @return void
36
  */
37
+ static public function activate() {
 
38
  global $wp_version;
39
 
40
  // Check for WordPress 3.5 and above.
41
+ if ( ! version_compare( $wp_version, '3.5', '>=' ) ) {
42
+ self::show_activate_error( __( 'The <strong>Page Builder</strong> plugin requires WordPress version 3.5 or greater. Please update WordPress before activating the plugin.', 'fl-builder' ) );
43
  }
44
+
45
  // Allow extensions to hook activation.
46
  $activate = apply_filters( 'fl_builder_activate', true );
47
+
48
+ // Should we continue with activation?
49
  if ( $activate ) {
50
 
51
  // Check for multisite.
52
+ if ( is_multisite() ) {
53
+ $url = FLBuilderModel::get_store_url( '', array(
54
+ 'utm_medium' => 'bb-pro',
55
+ 'utm_source' => 'plugins-admin-page',
56
+ 'utm_campaign' => 'no-multisite-support',
57
+ ) );
58
  self::show_activate_error( sprintf( __( 'This version of the <strong>Page Builder</strong> plugin is not compatible with WordPress Multisite. <a%s>Please upgrade</a> to the Multisite version of this plugin.', 'fl-builder' ), ' href="' . $url . '" target="_blank"' ) );
59
  }
60
+
61
  // Success! Run the install.
62
  self::install();
63
+
64
  // Trigger the activation notice.
65
  self::trigger_activate_notice();
66
 
73
  }
74
 
75
  /**
76
+ * Show a message if there is an activation error and
77
  * deactivates the plugin.
78
  *
79
  * @since 1.0
80
  * @param string $message The message to show.
81
  * @return void
82
  */
83
+ static public function show_activate_error( $message ) {
 
84
  deactivate_plugins( FLBuilderModel::plugin_basename(), false, is_network_admin() );
85
 
86
  die( $message );
93
  * @since 1.8
94
  * @return void
95
  */
96
+ static public function trigger_activate_notice() {
 
97
  if ( current_user_can( 'delete_users' ) ) {
98
  set_transient( '_fl_builder_activation_admin_notice', true, 30 );
99
  }
100
  }
101
 
102
  /**
103
+ * Shows the activation success message or redirects to the
104
  * welcome page.
105
  *
106
  * @since 1.0
107
  * @return void
108
  */
109
+ static public function show_activate_notice() {
 
110
  // Bail if no activation transient is set.
111
  if ( ! get_transient( '_fl_builder_activation_admin_notice' ) ) {
112
  return;
117
 
118
  if ( isset( $_GET['activate-multi'] ) || is_multisite() ) {
119
  // Show the notice if we are activating multiple plugins or on multisite.
120
+ add_action( 'admin_notices', __CLASS__ . '::activate_notice' );
121
+ add_action( 'network_admin_notices', __CLASS__ . '::activate_notice' );
122
+ } else {
 
123
  // Redirect to the welcome page.
124
+ wp_safe_redirect( add_query_arg( array(
125
+ 'page' => 'fl-builder-settings',
126
+ ), admin_url( 'options-general.php' ) ) );
127
  }
128
  }
129
 
133
  * @since 1.0
134
  * @return void
135
  */
136
+ static public function activate_notice() {
 
137
  if ( FL_BUILDER_LITE !== true ) {
138
  $hash = '#license';
139
  $message = __( 'Page Builder activated! <a%s>Click here</a> to enable remote updates.', 'fl-builder' );
140
+ } else {
 
141
  $hash = '#welcome';
142
  $message = __( 'Page Builder activated! <a%s>Click here</a> to get started.', 'fl-builder' );
143
  }
144
+
145
  $url = apply_filters( 'fl_builder_activate_redirect_url', admin_url( '/options-general.php?page=fl-builder-settings' . $hash ) );
146
+
147
  echo '<div class="updated" style="background: #d3ebc1;">';
148
  echo '<p><strong>' . sprintf( $message, ' href="' . esc_url( $url ) . '"' ) . '</strong></p>';
149
  echo '</div>';
150
  }
151
 
152
  /**
153
+ * Installs the builder upon successful activation.
154
  * Currently not used but may be in the future.
155
  *
156
  * @since 1.0
164
  * @since 1.0
165
  * @return void
166
  */
167
+ static public function uninstall() {
 
168
  FLBuilderModel::uninstall_database();
169
  }
170
 
175
  * @param array $actions An array of row action links.
176
  * @return array
177
  */
178
+ static public function render_plugin_action_links( $actions ) {
179
+ if ( FL_BUILDER_LITE === true ) {
180
+ $url = FLBuilderModel::get_store_url( '', array(
181
+ 'utm_medium' => 'bb-lite',
182
+ 'utm_source' => 'plugins-admin-page',
183
+ 'utm_campaign' => 'plugins-admin-upgrade',
184
+ ) );
185
  $actions[] = '<a href="' . $url . '" style="color:#3db634;" target="_blank">' . _x( 'Upgrade', 'Plugin action link label.', 'fl-builder' ) . '</a>';
186
  }
187
 
192
  * @since 1.0
193
  * @deprecated 1.8
194
  */
195
+ static public function init_classes() {
 
196
  _deprecated_function( __METHOD__, '1.8' );
197
  }
198
 
200
  * @since 1.0
201
  * @deprecated 1.8
202
  */
203
+ static public function init_settings() {
 
204
  _deprecated_function( __METHOD__, '1.8' );
205
  }
206
 
208
  * @since 1.0
209
  * @deprecated 1.8
210
  */
211
+ static public function init_multisite() {
 
212
  _deprecated_function( __METHOD__, '1.8' );
213
  }
214
 
216
  * @since 1.0
217
  * @deprecated 1.8
218
  */
219
+ static public function init_templates() {
 
220
  _deprecated_function( __METHOD__, '1.8' );
221
  }
222
 
224
  * @since 1.0
225
  * @deprecated 1.8
226
  */
227
+ static public function white_label_plugins_page( $plugins ) {
 
228
  _deprecated_function( __METHOD__, '1.8', 'FLBuilderWhiteLabel::plugins_page()' );
229
+
230
  if ( class_exists( 'FLBuilderWhiteLabel' ) ) {
231
  return FLBuilderWhiteLabel::plugins_page( $plugins );
232
  }
238
  * @since 1.6.4.3
239
  * @deprecated 1.8
240
  */
241
+ static public function white_label_themes_page( $themes ) {
 
242
  _deprecated_function( __METHOD__, '1.8', 'FLBuilderWhiteLabel::themes_page()' );
243
+
244
  if ( class_exists( 'FLBuilderWhiteLabel' ) ) {
245
  return FLBuilderWhiteLabel::themes_page( $themes );
246
  }
247
+
248
  return $themes;
249
  }
250
 
252
  * @since 1.6.4.4
253
  * @deprecated 1.8
254
  */
255
+ static public function white_label_theme_gettext( $text ) {
 
256
  if ( class_exists( 'FLBuilderWhiteLabel' ) ) {
257
  return FLBuilderWhiteLabel::theme_gettext( $text );
258
  }
259
+
260
  return $text;
261
  }
262
  }
classes/class-fl-builder-ajax-layout.php CHANGED
@@ -24,33 +24,32 @@ final class FLBuilderAJAXLayout {
24
  * @param string $old_node_id The ID of a node that has been replaced in the layout.
25
  * @return array
26
  */
27
- static public function render( $node_id = null, $old_node_id = null )
28
- {
29
  do_action( 'fl_builder_before_render_ajax_layout' );
30
-
31
  // Update the node ID in the post data?
32
  if ( $node_id ) {
33
  FLBuilderModel::update_post_data( 'node_id', $node_id );
34
  }
35
-
36
  // Register scripts needed for shortcodes and widgets.
37
  self::register_scripts();
38
-
39
  // Dequeue scripts and styles to only capture those that are needed.
40
  self::dequeue_scripts_and_styles();
41
-
42
  // Get the partial refresh data.
43
  $partial_refresh_data = self::get_partial_refresh_data();
44
-
45
  // Render the markup.
46
  $html = self::render_html();
47
-
48
  // Render scripts and styles.
49
  $scripts_styles = self::render_scripts_and_styles();
50
-
51
  // Render the assets.
52
  $assets = self::render_assets();
53
-
54
  do_action( 'fl_builder_after_render_ajax_layout' );
55
 
56
  // Return the response.
@@ -62,7 +61,7 @@ final class FLBuilderAJAXLayout {
62
  'html' => $html,
63
  'scriptsStyles' => $scripts_styles,
64
  'css' => $assets['css'],
65
- 'js' => $assets['js']
66
  );
67
  }
68
 
@@ -76,43 +75,40 @@ final class FLBuilderAJAXLayout {
76
  * @param string $template_type The type of template. Either "user" or "core".
77
  * @return array
78
  */
79
- static public function render_new_row( $cols = '1-col', $position = false, $template_id = null, $template_type = 'user' )
80
- {
81
  // Add a row template?
82
  if ( null !== $template_id ) {
83
-
84
  if ( 'core' == $template_type ) {
85
  $template = FLBuilderModel::get_template( $template_id, 'row' );
86
  $row = FLBuilderModel::apply_node_template( $template_id, null, $position, $template );
87
- }
88
- else {
89
  $row = FLBuilderModel::apply_node_template( $template_id, null, $position );
90
  }
91
-
92
  // Return the response.
93
  return self::render( $row->node );
94
- }
95
- // Add a standard row.
96
  else {
97
-
98
  // Add the row.
99
  $row = FLBuilderModel::add_row( $cols, $position );
100
-
101
  do_action( 'fl_builder_before_render_ajax_layout_html' );
102
-
103
  // Render the row.
104
  ob_start();
105
  FLBuilder::render_row( $row );
106
  $html = ob_get_clean();
107
-
108
  do_action( 'fl_builder_after_render_ajax_layout_html' );
109
-
110
- // Return the response.
111
  return array(
112
  'partial' => true,
113
  'nodeType' => $row->type,
114
  'html' => $html,
115
- 'js' => 'FLBuilder._renderLayoutComplete();'
116
  );
117
  }
118
  }
@@ -124,10 +120,9 @@ final class FLBuilderAJAXLayout {
124
  * @param string $node_id The ID of a row to copy.
125
  * @return array
126
  */
127
- static public function copy_row( $node_id )
128
- {
129
  $row = FLBuilderModel::copy_row( $node_id );
130
-
131
  return self::render( $row->node );
132
  }
133
 
@@ -140,26 +135,25 @@ final class FLBuilderAJAXLayout {
140
  * @param int $position The position of the new column group in the row.
141
  * @return array
142
  */
143
- static public function render_new_column_group( $node_id, $cols = '1-col', $position = false )
144
- {
145
  // Add the group.
146
  $group = FLBuilderModel::add_col_group( $node_id, $cols, $position );
147
-
148
  do_action( 'fl_builder_before_render_ajax_layout_html' );
149
-
150
  // Render the group.
151
  ob_start();
152
  FLBuilder::render_column_group( $group );
153
  $html = ob_get_clean();
154
-
155
  do_action( 'fl_builder_after_render_ajax_layout_html' );
156
 
157
- // Return the response.
158
  return array(
159
  'partial' => true,
160
  'nodeType' => $group->type,
161
  'html' => $html,
162
- 'js' => 'FLBuilder._renderLayoutComplete();'
163
  );
164
  }
165
 
@@ -173,12 +167,11 @@ final class FLBuilderAJAXLayout {
173
  * @param boolean $nested Whether these columns are nested or not.
174
  * @return array
175
  */
176
- static public function render_new_columns( $node_id, $insert, $type, $nested )
177
- {
178
  // Add the column(s).
179
  $group = FLBuilderModel::add_cols( $node_id, $insert, $type, $nested );
180
 
181
- // Return the response.
182
  return self::render( $group->node );
183
  }
184
 
@@ -194,58 +187,51 @@ final class FLBuilderAJAXLayout {
194
  * @param string $template_type The type of template. Either "user" or "core".
195
  * @return array
196
  */
197
- static public function render_new_module( $parent_id, $position = false, $type = null, $alias = null, $template_id = null, $template_type = 'user' )
198
- {
199
  // Add a module template?
200
  if ( null !== $template_id ) {
201
-
202
  if ( 'core' == $template_type ) {
203
  $template = FLBuilderModel::get_template( $template_id, 'module' );
204
  $module = FLBuilderModel::apply_node_template( $template_id, $parent_id, $position, $template );
 
 
205
  }
206
- else {
207
- $module = FLBuilderModel::apply_node_template( $template_id, $parent_id, $position );
208
- }
209
- }
210
- // Add a standard module.
211
  else {
212
  $defaults = FLBuilderModel::get_module_alias_settings( $alias );
213
  $module = FLBuilderModel::add_default_module( $parent_id, $type, $position, $defaults );
214
  }
215
-
216
  // Render the new module's settings.
217
  $settings = FLBuilder::render_module_settings( $module->node, $module->settings->type, $module->parent, false );
218
 
219
  // Maybe render the module's parent for a partial refresh?
220
  if ( $module->partial_refresh ) {
221
-
222
  // Get the new module parent.
223
  $parent = ! $parent_id ? null : FLBuilderModel::get_node( $parent_id );
224
-
225
  // Get the node to render.
226
  if ( ! $parent ) {
227
  $row = FLBuilderModel::get_module_parent( 'row', $module );
228
  $render_id = $row->node;
229
- }
230
- else if ( $parent->type == 'row' ) {
231
  $group = FLBuilderModel::get_module_parent( 'column-group', $module );
232
  $render_id = $group->node;
233
- }
234
- else if ( $parent->type == 'column-group' ) {
235
  $render_id = $parent->node;
236
- }
237
- else {
238
  $render_id = $module->node;
239
  }
240
- }
241
- else {
242
  $render_id = null;
243
  }
244
-
245
  // Return the response.
246
  return array(
247
  'layout' => self::render( $render_id ),
248
- 'settings' => $settings['settings']
249
  );
250
  }
251
 
@@ -256,10 +242,9 @@ final class FLBuilderAJAXLayout {
256
  * @param string $node_id The ID of a module to copy.
257
  * @return array
258
  */
259
- static public function copy_module( $node_id )
260
- {
261
  $module = FLBuilderModel::copy_module( $node_id );
262
-
263
  return self::render( $module->node );
264
  }
265
 
@@ -270,50 +255,48 @@ final class FLBuilderAJAXLayout {
270
  * @access private
271
  * @return array
272
  */
273
- static private function get_partial_refresh_data()
274
- {
275
  // Get the data if it's not cached.
276
  if ( ! self::$partial_refresh_data ) {
277
-
278
  $post_data = FLBuilderModel::get_post_data();
279
  $partial_refresh = false;
280
-
281
  // Check for partial refresh if we have a node ID.
282
  if ( isset( $post_data['node_id'] ) ) {
283
-
284
- // Get the node.
285
  $node_id = $post_data['node_id'];
286
  $node = FLBuilderModel::get_node( $post_data['node_id'] );
287
-
288
  // Check a module for partial refresh.
289
  if ( $node && 'module' == $node->type ) {
290
  $node = FLBuilderModel::get_module( $node_id );
291
  $node_type = 'module';
292
  $partial_refresh = $node->partial_refresh;
293
- }
294
- // Always partial refresh rows and columns.
295
- else if ( $node ) {
296
  $node_type = $node->type;
297
  $partial_refresh = self::node_modules_support_partial_refresh( $node );
298
  }
299
  }
300
-
301
  // Clear the node data if we're not doing a partial refresh.
302
  if ( ! $partial_refresh ) {
303
  $node_id = null;
304
  $node = null;
305
  $node_type = null;
306
  }
307
-
308
  // Cache the partial refresh data.
309
  self::$partial_refresh_data = array(
310
  'is_partial_refresh' => $partial_refresh,
311
  'node_id' => $node_id,
312
  'node' => $node,
313
- 'node_type' => $node_type
314
  );
315
- }
316
-
317
  // Return the data.
318
  return self::$partial_refresh_data;
319
  }
@@ -326,19 +309,18 @@ final class FLBuilderAJAXLayout {
326
  * @param object $node The node to check.
327
  * @return bool
328
  */
329
- static private function node_modules_support_partial_refresh( $node )
330
- {
331
  $nodes = FLBuilderModel::get_categorized_nodes();
332
-
333
  if ( 'row' == $node->type ) {
334
-
335
  $template_post_id = FLBuilderModel::is_node_global( $node );
336
-
337
- foreach( $nodes['groups'] as $group ) {
338
  if ( $node->node == $group->parent || ( $template_post_id && $node->template_node_id == $group->parent ) ) {
339
- foreach( $nodes['columns'] as $column ) {
340
  if ( $group->node == $column->parent ) {
341
- foreach( $nodes['modules'] as $module ) {
342
  if ( $column->node == $module->parent ) {
343
  if ( ! $module->partial_refresh ) {
344
  return false;
@@ -349,11 +331,10 @@ final class FLBuilderAJAXLayout {
349
  }
350
  }
351
  }
352
- }
353
- else if ( 'column-group' == $node->type ) {
354
- foreach( $nodes['columns'] as $column ) {
355
  if ( $node->node == $column->parent ) {
356
- foreach( $nodes['modules'] as $module ) {
357
  if ( $column->node == $module->parent ) {
358
  if ( ! $module->partial_refresh ) {
359
  return false;
@@ -362,17 +343,16 @@ final class FLBuilderAJAXLayout {
362
  }
363
  }
364
  }
365
- }
366
- else if ( 'column' == $node->type ) {
367
- foreach( $nodes['modules'] as $module ) {
368
  if ( $node->node == $module->parent ) {
369
  if ( ! $module->partial_refresh ) {
370
  return false;
371
  }
372
  }
373
  }
374
- }
375
-
376
  return true;
377
  }
378
 
@@ -383,46 +363,44 @@ final class FLBuilderAJAXLayout {
383
  * @access private
384
  * @return string
385
  */
386
- static private function render_html()
387
- {
388
  do_action( 'fl_builder_before_render_ajax_layout_html' );
389
-
390
  // Get the partial refresh data.
391
  $partial_refresh_data = self::get_partial_refresh_data();
392
 
393
  // Start the output buffer.
394
  ob_start();
395
-
396
- // Render a node?
397
  if ( $partial_refresh_data['is_partial_refresh'] ) {
398
-
399
- switch ( $partial_refresh_data[ 'node' ]->type ) {
400
-
401
  case 'row':
402
- FLBuilder::render_row( $partial_refresh_data['node'] );
403
  break;
404
-
405
  case 'column-group':
406
- FLBuilder::render_column_group( $partial_refresh_data['node'] );
407
  break;
408
-
409
  case 'column':
410
- FLBuilder::render_column( $partial_refresh_data['node'] );
411
  break;
412
-
413
  case 'module':
414
- FLBuilder::render_module( $partial_refresh_data['node'] );
415
  break;
416
  }
417
- }
418
- // Render the layout.
419
  else {
420
  FLBuilder::render_nodes();
421
  }
422
-
423
  // Get the rendered HTML.
424
  $html = ob_get_clean();
425
-
426
  // Render shortcodes.
427
  if ( apply_filters( 'fl_builder_render_shortcodes', true ) ) {
428
  $html = apply_filters( 'fl_builder_before_render_shortcodes', $html );
@@ -430,9 +408,9 @@ final class FLBuilderAJAXLayout {
430
  echo do_shortcode( $html );
431
  $html = ob_get_clean();
432
  }
433
-
434
  do_action( 'fl_builder_after_render_ajax_layout_html' );
435
-
436
  // Return the rendered HTML.
437
  return $html;
438
  }
@@ -444,77 +422,77 @@ final class FLBuilderAJAXLayout {
444
  * @access private
445
  * @return array
446
  */
447
- static private function render_assets()
448
- {
449
  $partial_refresh_data = self::get_partial_refresh_data();
450
  $asset_info = FLBuilderModel::get_asset_info();
451
  $asset_ver = FLBuilderModel::get_asset_version();
452
- $assets = array( 'js' => '', 'css' => '' );
453
-
 
 
 
454
  // Ensure global assets are rendered.
455
  FLBuilder::clear_enqueued_global_assets();
456
-
457
  // Render the JS.
458
  if ( $partial_refresh_data['is_partial_refresh'] ) {
459
-
460
  if ( ! class_exists( 'FLJSMin' ) ) {
461
  include FL_BUILDER_DIR . 'classes/class-fl-jsmin.php';
462
  }
463
-
464
  switch ( $partial_refresh_data['node']->type ) {
465
-
466
  case 'row':
467
- $assets['js'] = FLBuilder::render_row_js( $partial_refresh_data['node'] );
468
- $assets['js'] .= FLBuilder::render_row_modules_js( $partial_refresh_data['node'] );
469
  break;
470
-
471
  case 'column':
472
- $assets['js'] = FLBuilder::render_column_modules_js( $partial_refresh_data['node'] );
473
  break;
474
-
475
  case 'module':
476
- $assets['js'] = FLBuilder::render_module_js( $partial_refresh_data['node'] );
477
  break;
478
  }
479
-
480
  $assets['js'] .= 'FLBuilder._renderLayoutComplete();';
481
 
482
  try {
483
- $min = FLJSMin::minify( $assets['js'] );
484
- } catch (Exception $e) {}
485
 
486
  if ( $min ) {
487
- $assets['js'] = $min;
488
  }
489
- }
490
- else {
491
  FLBuilder::render_js();
492
  $assets['js'] = $asset_info['js_url'] . '?ver=' . $asset_ver;
493
- }
494
-
495
  // Render the CSS.
496
  FLBuilder::render_css();
497
  $assets['css'] = $asset_info['css_url'] . '?ver=' . $asset_ver;
498
-
499
  // Return the assets.
500
  return $assets;
501
  }
502
 
503
  /**
504
- * Do the wp_enqueue_scripts action to register any scripts or
505
  * styles that might need to be registered for shortcodes or widgets.
506
  *
507
  * @since 1.7
508
  * @access private
509
  * @return void
510
  */
511
- static private function register_scripts()
512
- {
513
  // Running these isn't necessary and can cause performance issues.
514
  remove_action( 'wp_enqueue_scripts', 'FLBuilder::register_layout_styles_scripts' );
515
  remove_action( 'wp_enqueue_scripts', 'FLBuilder::enqueue_ui_styles_scripts' );
516
  remove_action( 'wp_enqueue_scripts', 'FLBuilder::enqueue_all_layouts_styles_scripts' );
517
-
518
  ob_start();
519
  do_action( 'wp_enqueue_scripts' );
520
  ob_end_clean();
@@ -528,8 +506,7 @@ final class FLBuilderAJAXLayout {
528
  * @access private
529
  * @return void
530
  */
531
- static private function dequeue_scripts_and_styles()
532
- {
533
  global $wp_scripts;
534
  global $wp_styles;
535
 
@@ -539,24 +516,23 @@ final class FLBuilderAJAXLayout {
539
  if ( isset( $wp_styles ) ) {
540
  $wp_styles->queue = array();
541
  }
542
-
543
  remove_action( 'wp_print_styles', 'print_emoji_styles' );
544
  }
545
 
546
  /**
547
- * Renders scripts and styles enqueued by shortcodes or widgets.
548
  *
549
  * @since 1.7
550
  * @access private
551
  * @return string
552
  */
553
- static private function render_scripts_and_styles()
554
- {
555
  global $wp_scripts;
556
  global $wp_styles;
557
-
558
  $scripts_styles = '';
559
-
560
  // Start the output buffer.
561
  ob_start();
562
 
@@ -568,8 +544,8 @@ final class FLBuilderAJAXLayout {
568
  if ( isset( $wp_styles ) ) {
569
  wp_print_styles( $wp_styles->queue );
570
  }
571
-
572
  // Return the scripts and styles markup.
573
  return ob_get_clean();
574
  }
575
- }
24
  * @param string $old_node_id The ID of a node that has been replaced in the layout.
25
  * @return array
26
  */
27
+ static public function render( $node_id = null, $old_node_id = null ) {
 
28
  do_action( 'fl_builder_before_render_ajax_layout' );
29
+
30
  // Update the node ID in the post data?
31
  if ( $node_id ) {
32
  FLBuilderModel::update_post_data( 'node_id', $node_id );
33
  }
34
+
35
  // Register scripts needed for shortcodes and widgets.
36
  self::register_scripts();
37
+
38
  // Dequeue scripts and styles to only capture those that are needed.
39
  self::dequeue_scripts_and_styles();
40
+
41
  // Get the partial refresh data.
42
  $partial_refresh_data = self::get_partial_refresh_data();
43
+
44
  // Render the markup.
45
  $html = self::render_html();
46
+
47
  // Render scripts and styles.
48
  $scripts_styles = self::render_scripts_and_styles();
49
+
50
  // Render the assets.
51
  $assets = self::render_assets();
52
+
53
  do_action( 'fl_builder_after_render_ajax_layout' );
54
 
55
  // Return the response.
61
  'html' => $html,
62
  'scriptsStyles' => $scripts_styles,
63
  'css' => $assets['css'],
64
+ 'js' => $assets['js'],
65
  );
66
  }
67
 
75
  * @param string $template_type The type of template. Either "user" or "core".
76
  * @return array
77
  */
78
+ static public function render_new_row( $cols = '1-col', $position = false, $template_id = null, $template_type = 'user' ) {
 
79
  // Add a row template?
80
  if ( null !== $template_id ) {
81
+
82
  if ( 'core' == $template_type ) {
83
  $template = FLBuilderModel::get_template( $template_id, 'row' );
84
  $row = FLBuilderModel::apply_node_template( $template_id, null, $position, $template );
85
+ } else {
 
86
  $row = FLBuilderModel::apply_node_template( $template_id, null, $position );
87
  }
88
+
89
  // Return the response.
90
  return self::render( $row->node );
91
+ } // End if().
 
92
  else {
93
+
94
  // Add the row.
95
  $row = FLBuilderModel::add_row( $cols, $position );
96
+
97
  do_action( 'fl_builder_before_render_ajax_layout_html' );
98
+
99
  // Render the row.
100
  ob_start();
101
  FLBuilder::render_row( $row );
102
  $html = ob_get_clean();
103
+
104
  do_action( 'fl_builder_after_render_ajax_layout_html' );
105
+
106
+ // Return the response.
107
  return array(
108
  'partial' => true,
109
  'nodeType' => $row->type,
110
  'html' => $html,
111
+ 'js' => 'FLBuilder._renderLayoutComplete();',
112
  );
113
  }
114
  }
120
  * @param string $node_id The ID of a row to copy.
121
  * @return array
122
  */
123
+ static public function copy_row( $node_id ) {
 
124
  $row = FLBuilderModel::copy_row( $node_id );
125
+
126
  return self::render( $row->node );
127
  }
128
 
135
  * @param int $position The position of the new column group in the row.
136
  * @return array
137
  */
138
+ static public function render_new_column_group( $node_id, $cols = '1-col', $position = false ) {
 
139
  // Add the group.
140
  $group = FLBuilderModel::add_col_group( $node_id, $cols, $position );
141
+
142
  do_action( 'fl_builder_before_render_ajax_layout_html' );
143
+
144
  // Render the group.
145
  ob_start();
146
  FLBuilder::render_column_group( $group );
147
  $html = ob_get_clean();
148
+
149
  do_action( 'fl_builder_after_render_ajax_layout_html' );
150
 
151
+ // Return the response.
152
  return array(
153
  'partial' => true,
154
  'nodeType' => $group->type,
155
  'html' => $html,
156
+ 'js' => 'FLBuilder._renderLayoutComplete();',
157
  );
158
  }
159
 
167
  * @param boolean $nested Whether these columns are nested or not.
168
  * @return array
169
  */
170
+ static public function render_new_columns( $node_id, $insert, $type, $nested ) {
 
171
  // Add the column(s).
172
  $group = FLBuilderModel::add_cols( $node_id, $insert, $type, $nested );
173
 
174
+ // Return the response.
175
  return self::render( $group->node );
176
  }
177
 
187
  * @param string $template_type The type of template. Either "user" or "core".
188
  * @return array
189
  */
190
+ static public function render_new_module( $parent_id, $position = false, $type = null, $alias = null, $template_id = null, $template_type = 'user' ) {
 
191
  // Add a module template?
192
  if ( null !== $template_id ) {
193
+
194
  if ( 'core' == $template_type ) {
195
  $template = FLBuilderModel::get_template( $template_id, 'module' );
196
  $module = FLBuilderModel::apply_node_template( $template_id, $parent_id, $position, $template );
197
+ } else {
198
+ $module = FLBuilderModel::apply_node_template( $template_id, $parent_id, $position );
199
  }
200
+ } // End if().
 
 
 
 
201
  else {
202
  $defaults = FLBuilderModel::get_module_alias_settings( $alias );
203
  $module = FLBuilderModel::add_default_module( $parent_id, $type, $position, $defaults );
204
  }
205
+
206
  // Render the new module's settings.
207
  $settings = FLBuilder::render_module_settings( $module->node, $module->settings->type, $module->parent, false );
208
 
209
  // Maybe render the module's parent for a partial refresh?
210
  if ( $module->partial_refresh ) {
211
+
212
  // Get the new module parent.
213
  $parent = ! $parent_id ? null : FLBuilderModel::get_node( $parent_id );
214
+
215
  // Get the node to render.
216
  if ( ! $parent ) {
217
  $row = FLBuilderModel::get_module_parent( 'row', $module );
218
  $render_id = $row->node;
219
+ } elseif ( 'row' == $parent->type ) {
 
220
  $group = FLBuilderModel::get_module_parent( 'column-group', $module );
221
  $render_id = $group->node;
222
+ } elseif ( 'column-group' == $parent->type ) {
 
223
  $render_id = $parent->node;
224
+ } else {
 
225
  $render_id = $module->node;
226
  }
227
+ } else {
 
228
  $render_id = null;
229
  }
230
+
231
  // Return the response.
232
  return array(
233
  'layout' => self::render( $render_id ),
234
+ 'settings' => $settings['settings'],
235
  );
236
  }
237
 
242
  * @param string $node_id The ID of a module to copy.
243
  * @return array
244
  */
245
+ static public function copy_module( $node_id ) {
 
246
  $module = FLBuilderModel::copy_module( $node_id );
247
+
248
  return self::render( $module->node );
249
  }
250
 
255
  * @access private
256
  * @return array
257
  */
258
+ static private function get_partial_refresh_data() {
 
259
  // Get the data if it's not cached.
260
  if ( ! self::$partial_refresh_data ) {
261
+
262
  $post_data = FLBuilderModel::get_post_data();
263
  $partial_refresh = false;
264
+
265
  // Check for partial refresh if we have a node ID.
266
  if ( isset( $post_data['node_id'] ) ) {
267
+
268
+ // Get the node.
269
  $node_id = $post_data['node_id'];
270
  $node = FLBuilderModel::get_node( $post_data['node_id'] );
271
+
272
  // Check a module for partial refresh.
273
  if ( $node && 'module' == $node->type ) {
274
  $node = FLBuilderModel::get_module( $node_id );
275
  $node_type = 'module';
276
  $partial_refresh = $node->partial_refresh;
277
+ } // End if().
278
+ elseif ( $node ) {
 
279
  $node_type = $node->type;
280
  $partial_refresh = self::node_modules_support_partial_refresh( $node );
281
  }
282
  }
283
+
284
  // Clear the node data if we're not doing a partial refresh.
285
  if ( ! $partial_refresh ) {
286
  $node_id = null;
287
  $node = null;
288
  $node_type = null;
289
  }
290
+
291
  // Cache the partial refresh data.
292
  self::$partial_refresh_data = array(
293
  'is_partial_refresh' => $partial_refresh,
294
  'node_id' => $node_id,
295
  'node' => $node,
296
+ 'node_type' => $node_type,
297
  );
298
+ }// End if().
299
+
300
  // Return the data.
301
  return self::$partial_refresh_data;
302
  }
309
  * @param object $node The node to check.
310
  * @return bool
311
  */
312
+ static private function node_modules_support_partial_refresh( $node ) {
 
313
  $nodes = FLBuilderModel::get_categorized_nodes();
314
+
315
  if ( 'row' == $node->type ) {
316
+
317
  $template_post_id = FLBuilderModel::is_node_global( $node );
318
+
319
+ foreach ( $nodes['groups'] as $group ) {
320
  if ( $node->node == $group->parent || ( $template_post_id && $node->template_node_id == $group->parent ) ) {
321
+ foreach ( $nodes['columns'] as $column ) {
322
  if ( $group->node == $column->parent ) {
323
+ foreach ( $nodes['modules'] as $module ) {
324
  if ( $column->node == $module->parent ) {
325
  if ( ! $module->partial_refresh ) {
326
  return false;
331
  }
332
  }
333
  }
334
+ } elseif ( 'column-group' == $node->type ) {
335
+ foreach ( $nodes['columns'] as $column ) {
 
336
  if ( $node->node == $column->parent ) {
337
+ foreach ( $nodes['modules'] as $module ) {
338
  if ( $column->node == $module->parent ) {
339
  if ( ! $module->partial_refresh ) {
340
  return false;
343
  }
344
  }
345
  }
346
+ } elseif ( 'column' == $node->type ) {
347
+ foreach ( $nodes['modules'] as $module ) {
 
348
  if ( $node->node == $module->parent ) {
349
  if ( ! $module->partial_refresh ) {
350
  return false;
351
  }
352
  }
353
  }
354
+ }// End if().
355
+
356
  return true;
357
  }
358
 
363
  * @access private
364
  * @return string
365
  */
366
+ static private function render_html() {
 
367
  do_action( 'fl_builder_before_render_ajax_layout_html' );
368
+
369
  // Get the partial refresh data.
370
  $partial_refresh_data = self::get_partial_refresh_data();
371
 
372
  // Start the output buffer.
373
  ob_start();
374
+
375
+ // Render a node?
376
  if ( $partial_refresh_data['is_partial_refresh'] ) {
377
+
378
+ switch ( $partial_refresh_data['node']->type ) {
379
+
380
  case 'row':
381
+ FLBuilder::render_row( $partial_refresh_data['node'] );
382
  break;
383
+
384
  case 'column-group':
385
+ FLBuilder::render_column_group( $partial_refresh_data['node'] );
386
  break;
387
+
388
  case 'column':
389
+ FLBuilder::render_column( $partial_refresh_data['node'] );
390
  break;
391
+
392
  case 'module':
393
+ FLBuilder::render_module( $partial_refresh_data['node'] );
394
  break;
395
  }
396
+ } // End if().
 
397
  else {
398
  FLBuilder::render_nodes();
399
  }
400
+
401
  // Get the rendered HTML.
402
  $html = ob_get_clean();
403
+
404
  // Render shortcodes.
405
  if ( apply_filters( 'fl_builder_render_shortcodes', true ) ) {
406
  $html = apply_filters( 'fl_builder_before_render_shortcodes', $html );
408
  echo do_shortcode( $html );
409
  $html = ob_get_clean();
410
  }
411
+
412
  do_action( 'fl_builder_after_render_ajax_layout_html' );
413
+
414
  // Return the rendered HTML.
415
  return $html;
416
  }
422
  * @access private
423
  * @return array
424
  */
425
+ static private function render_assets() {
 
426
  $partial_refresh_data = self::get_partial_refresh_data();
427
  $asset_info = FLBuilderModel::get_asset_info();
428
  $asset_ver = FLBuilderModel::get_asset_version();
429
+ $assets = array(
430
+ 'js' => '',
431
+ 'css' => '',
432
+ );
433
+
434
  // Ensure global assets are rendered.
435
  FLBuilder::clear_enqueued_global_assets();
436
+
437
  // Render the JS.
438
  if ( $partial_refresh_data['is_partial_refresh'] ) {
439
+
440
  if ( ! class_exists( 'FLJSMin' ) ) {
441
  include FL_BUILDER_DIR . 'classes/class-fl-jsmin.php';
442
  }
443
+
444
  switch ( $partial_refresh_data['node']->type ) {
445
+
446
  case 'row':
447
+ $assets['js'] = FLBuilder::render_row_js( $partial_refresh_data['node'] );
448
+ $assets['js'] .= FLBuilder::render_row_modules_js( $partial_refresh_data['node'] );
449
  break;
450
+
451
  case 'column':
452
+ $assets['js'] = FLBuilder::render_column_modules_js( $partial_refresh_data['node'] );
453
  break;
454
+
455
  case 'module':
456
+ $assets['js'] = FLBuilder::render_module_js( $partial_refresh_data['node'] );
457
  break;
458
  }
459
+
460
  $assets['js'] .= 'FLBuilder._renderLayoutComplete();';
461
 
462
  try {
463
+ $min = FLJSMin::minify( $assets['js'] );
464
+ } catch ( Exception $e ) {}
465
 
466
  if ( $min ) {
467
+ $assets['js'] = $min;
468
  }
469
+ } else {
 
470
  FLBuilder::render_js();
471
  $assets['js'] = $asset_info['js_url'] . '?ver=' . $asset_ver;
472
+ }// End if().
473
+
474
  // Render the CSS.
475
  FLBuilder::render_css();
476
  $assets['css'] = $asset_info['css_url'] . '?ver=' . $asset_ver;
477
+
478
  // Return the assets.
479
  return $assets;
480
  }
481
 
482
  /**
483
+ * Do the wp_enqueue_scripts action to register any scripts or
484
  * styles that might need to be registered for shortcodes or widgets.
485
  *
486
  * @since 1.7
487
  * @access private
488
  * @return void
489
  */
490
+ static private function register_scripts() {
 
491
  // Running these isn't necessary and can cause performance issues.
492
  remove_action( 'wp_enqueue_scripts', 'FLBuilder::register_layout_styles_scripts' );
493
  remove_action( 'wp_enqueue_scripts', 'FLBuilder::enqueue_ui_styles_scripts' );
494
  remove_action( 'wp_enqueue_scripts', 'FLBuilder::enqueue_all_layouts_styles_scripts' );
495
+
496
  ob_start();
497
  do_action( 'wp_enqueue_scripts' );
498
  ob_end_clean();
506
  * @access private
507
  * @return void
508
  */
509
+ static private function dequeue_scripts_and_styles() {
 
510
  global $wp_scripts;
511
  global $wp_styles;
512
 
516
  if ( isset( $wp_styles ) ) {
517
  $wp_styles->queue = array();
518
  }
519
+
520
  remove_action( 'wp_print_styles', 'print_emoji_styles' );
521
  }
522
 
523
  /**
524
+ * Renders scripts and styles enqueued by shortcodes or widgets.
525
  *
526
  * @since 1.7
527
  * @access private
528
  * @return string
529
  */
530
+ static private function render_scripts_and_styles() {
 
531
  global $wp_scripts;
532
  global $wp_styles;
533
+
534
  $scripts_styles = '';
535
+
536
  // Start the output buffer.
537
  ob_start();
538
 
544
  if ( isset( $wp_styles ) ) {
545
  wp_print_styles( $wp_styles->queue );
546
  }
547
+
548
  // Return the scripts and styles markup.
549
  return ob_get_clean();
550
  }
551
+ }
classes/class-fl-builder-ajax.php CHANGED
@@ -1,8 +1,8 @@
1
  <?php
2
 
3
  /**
4
- * Front-end AJAX handler for the builder interface. We use this
5
- * instead of wp_ajax because that only works in the admin and
6
  * certain things like some shortcodes won't render there. AJAX
7
  * requests handled through this method only run for logged in users
8
  * for extra security. Developers creating custom modules that need
@@ -27,8 +27,7 @@ final class FLBuilderAJAX {
27
  * @since 1.8
28
  * @return void
29
  */
30
- static public function init()
31
- {
32
  add_action( 'wp', __CLASS__ . '::run' );
33
  }
34
 
@@ -38,8 +37,7 @@ final class FLBuilderAJAX {
38
  * @since 1.7
39
  * @return void
40
  */
41
- static public function run()
42
- {
43
  self::add_actions();
44
  self::call_action();
45
  }
@@ -53,12 +51,11 @@ final class FLBuilderAJAX {
53
  * @param array $args An array of method arg names that are present in the post data.
54
  * @return void
55
  */
56
- static public function add_action( $action, $method, $args = array() )
57
- {
58
  self::$actions[ $action ] = array(
59
  'action' => $action,
60
  'method' => $method,
61
- 'args' => $args
62
  );
63
  }
64
 
@@ -69,8 +66,7 @@ final class FLBuilderAJAX {
69
  * @param string $action The action to remove.
70
  * @return void
71
  */
72
- static public function remove_action( $action )
73
- {
74
  if ( isset( self::$actions[ $action ] ) ) {
75
  unset( self::$actions[ $action ] );
76
  }
@@ -83,8 +79,7 @@ final class FLBuilderAJAX {
83
  * @access private
84
  * @return void
85
  */
86
- static private function add_actions()
87
- {
88
  // FLBuilder
89
  self::add_action( 'render_settings_form', 'FLBuilder::render_settings_form', array( 'type', 'settings' ) );
90
  self::add_action( 'render_row_settings', 'FLBuilder::render_row_settings', array( 'node_id' ) );
@@ -94,7 +89,7 @@ final class FLBuilderAJAX {
94
  self::add_action( 'render_global_settings', 'FLBuilder::render_global_settings' );
95
  self::add_action( 'render_template_selector', 'FLBuilder::render_template_selector' );
96
  self::add_action( 'render_icon_selector', 'FLBuilder::render_icon_selector' );
97
-
98
  // FLBuilderModel
99
  self::add_action( 'delete_node', 'FLBuilderModel::delete_node', array( 'node_id' ) );
100
  self::add_action( 'delete_col', 'FLBuilderModel::delete_col', array( 'node_id', 'new_width' ) );
@@ -116,7 +111,7 @@ final class FLBuilderAJAX {
116
  self::add_action( 'save_draft', 'FLBuilderModel::save_draft' );
117
  self::add_action( 'clear_draft_layout', 'FLBuilderModel::clear_draft_layout' );
118
  self::add_action( 'disable_builder', 'FLBuilderModel::disable' );
119
-
120
  // FLBuilderAJAXLayout
121
  self::add_action( 'render_layout', 'FLBuilderAJAXLayout::render' );
122
  self::add_action( 'render_new_row', 'FLBuilderAJAXLayout::render_new_row', array( 'cols', 'position', 'template_id', 'template_type' ) );
@@ -125,14 +120,14 @@ final class FLBuilderAJAX {
125
  self::add_action( 'render_new_columns', 'FLBuilderAJAXLayout::render_new_columns', array( 'node_id', 'insert', 'type', 'nested' ) );
126
  self::add_action( 'render_new_module', 'FLBuilderAJAXLayout::render_new_module', array( 'parent_id', 'position', 'type', 'alias', 'template_id', 'template_type' ) );
127
  self::add_action( 'copy_module', 'FLBuilderAJAXLayout::copy_module', array( 'node_id' ) );
128
-
129
  // FLBuilderServices
130
  self::add_action( 'render_service_settings', 'FLBuilderServices::render_settings' );
131
  self::add_action( 'render_service_fields', 'FLBuilderServices::render_fields' );
132
  self::add_action( 'connect_service', 'FLBuilderServices::connect_service' );
133
  self::add_action( 'delete_service_account', 'FLBuilderServices::delete_account' );
134
  self::add_action( 'delete_service_account', 'FLBuilderServices::delete_account' );
135
-
136
  // FLBuilderAutoSuggest
137
  self::add_action( 'fl_builder_autosuggest', 'FLBuilderAutoSuggest::init' );
138
  }
@@ -144,29 +139,28 @@ final class FLBuilderAJAX {
144
  * @access private
145
  * @return void
146
  */
147
- static private function call_action()
148
- {
149
  // Only run for logged in users.
150
  if ( ! is_user_logged_in() ) {
151
  return;
152
  }
153
-
154
  // Verify the AJAX nonce.
155
  if ( ! self::verify_nonce() ) {
156
- return;
157
  }
158
 
159
  // Get the $_POST data.
160
  $post_data = FLBuilderModel::get_post_data();
161
-
162
  // Get the post ID.
163
  $post_id = FLBuilderModel::get_post_id();
164
-
165
  // Make sure we have a post ID.
166
  if ( ! $post_id ) {
167
  return;
168
  }
169
-
170
  // Make sure the user can edit this post.
171
  if ( ! current_user_can( 'edit_post', $post_id ) ) {
172
  return;
@@ -175,29 +169,28 @@ final class FLBuilderAJAX {
175
  // Get the action.
176
  if ( ! empty( $_REQUEST['fl_action'] ) ) {
177
  $action = $_REQUEST['fl_action'];
178
- }
179
- else if( ! empty( $post_data['fl_action'] ) ) {
180
  $action = $post_data['fl_action'];
181
- }
182
- else {
183
  return;
184
  }
185
-
186
  // Allow developers to modify actions before they are called.
187
  do_action( 'fl_ajax_before_call_action', $action );
188
-
189
  // Make sure the action exists.
190
  if ( ! isset( self::$actions[ $action ] ) ) {
191
  return;
192
  }
193
-
194
  // Get the action data.
195
  $action = self::$actions[ $action ];
196
  $args = array();
197
  $keys_args = array();
198
-
199
  // Build the args array.
200
  foreach ( $action['args'] as $arg ) {
 
201
  $args[] = $keys_args[ $arg ] = isset( $post_data[ $arg ] ) ? $post_data[ $arg ] : null;
202
  }
203
 
@@ -205,19 +198,19 @@ final class FLBuilderAJAX {
205
  if ( ! defined( 'DOING_AJAX' ) ) {
206
  define( 'DOING_AJAX', true );
207
  }
208
-
209
  // Allow developers to hook before the action runs.
210
  do_action( 'fl_ajax_before_' . $action['action'], $keys_args );
211
 
212
  // Call the action and allow developers to filter the result.
213
  $result = apply_filters( 'fl_ajax_' . $action['action'], call_user_func_array( $action['method'], $args ), $keys_args );
214
-
215
  // Allow developers to hook after the action runs.
216
  do_action( 'fl_ajax_after_' . $action['action'], $keys_args );
217
-
218
  // JSON encode the result.
219
  echo json_encode( $result );
220
-
221
  // Complete the request.
222
  die();
223
  }
@@ -229,24 +222,22 @@ final class FLBuilderAJAX {
229
  * @access private
230
  * @return bool
231
  */
232
- static private function verify_nonce()
233
- {
234
  $post_data = FLBuilderModel::get_post_data();
235
  $nonce = false;
236
-
237
  if ( isset( $post_data['_wpnonce'] ) ) {
238
  $nonce = $post_data['_wpnonce'];
239
- }
240
- else if ( isset( $_REQUEST['_wpnonce'] ) ) {
241
  $nonce = $_REQUEST['_wpnonce'];
242
  }
243
-
244
  if ( ! $nonce || ! wp_verify_nonce( $nonce, 'fl_ajax_update' ) ) {
245
- return false;
246
  }
247
-
248
  return true;
249
  }
250
  }
251
 
252
- FLBuilderAJAX::init();
1
  <?php
2
 
3
  /**
4
+ * Front-end AJAX handler for the builder interface. We use this
5
+ * instead of wp_ajax because that only works in the admin and
6
  * certain things like some shortcodes won't render there. AJAX
7
  * requests handled through this method only run for logged in users
8
  * for extra security. Developers creating custom modules that need
27
  * @since 1.8
28
  * @return void
29
  */
30
+ static public function init() {
 
31
  add_action( 'wp', __CLASS__ . '::run' );
32
  }
33
 
37
  * @since 1.7
38
  * @return void
39
  */
40
+ static public function run() {
 
41
  self::add_actions();
42
  self::call_action();
43
  }
51
  * @param array $args An array of method arg names that are present in the post data.
52
  * @return void
53
  */
54
+ static public function add_action( $action, $method, $args = array() ) {
 
55
  self::$actions[ $action ] = array(
56
  'action' => $action,
57
  'method' => $method,
58
+ 'args' => $args,
59
  );
60
  }
61
 
66
  * @param string $action The action to remove.
67
  * @return void
68
  */
69
+ static public function remove_action( $action ) {
 
70
  if ( isset( self::$actions[ $action ] ) ) {
71
  unset( self::$actions[ $action ] );
72
  }
79
  * @access private
80
  * @return void
81
  */
82
+ static private function add_actions() {
 
83
  // FLBuilder
84
  self::add_action( 'render_settings_form', 'FLBuilder::render_settings_form', array( 'type', 'settings' ) );
85
  self::add_action( 'render_row_settings', 'FLBuilder::render_row_settings', array( 'node_id' ) );
89
  self::add_action( 'render_global_settings', 'FLBuilder::render_global_settings' );
90
  self::add_action( 'render_template_selector', 'FLBuilder::render_template_selector' );
91
  self::add_action( 'render_icon_selector', 'FLBuilder::render_icon_selector' );
92
+
93
  // FLBuilderModel
94
  self::add_action( 'delete_node', 'FLBuilderModel::delete_node', array( 'node_id' ) );
95
  self::add_action( 'delete_col', 'FLBuilderModel::delete_col', array( 'node_id', 'new_width' ) );
111
  self::add_action( 'save_draft', 'FLBuilderModel::save_draft' );
112
  self::add_action( 'clear_draft_layout', 'FLBuilderModel::clear_draft_layout' );
113
  self::add_action( 'disable_builder', 'FLBuilderModel::disable' );
114
+
115
  // FLBuilderAJAXLayout
116
  self::add_action( 'render_layout', 'FLBuilderAJAXLayout::render' );
117
  self::add_action( 'render_new_row', 'FLBuilderAJAXLayout::render_new_row', array( 'cols', 'position', 'template_id', 'template_type' ) );
120
  self::add_action( 'render_new_columns', 'FLBuilderAJAXLayout::render_new_columns', array( 'node_id', 'insert', 'type', 'nested' ) );
121
  self::add_action( 'render_new_module', 'FLBuilderAJAXLayout::render_new_module', array( 'parent_id', 'position', 'type', 'alias', 'template_id', 'template_type' ) );
122
  self::add_action( 'copy_module', 'FLBuilderAJAXLayout::copy_module', array( 'node_id' ) );
123
+
124
  // FLBuilderServices
125
  self::add_action( 'render_service_settings', 'FLBuilderServices::render_settings' );
126
  self::add_action( 'render_service_fields', 'FLBuilderServices::render_fields' );
127
  self::add_action( 'connect_service', 'FLBuilderServices::connect_service' );
128
  self::add_action( 'delete_service_account', 'FLBuilderServices::delete_account' );
129
  self::add_action( 'delete_service_account', 'FLBuilderServices::delete_account' );
130
+
131
  // FLBuilderAutoSuggest
132
  self::add_action( 'fl_builder_autosuggest', 'FLBuilderAutoSuggest::init' );
133
  }
139
  * @access private
140
  * @return void
141
  */
142
+ static private function call_action() {
 
143
  // Only run for logged in users.
144
  if ( ! is_user_logged_in() ) {
145
  return;
146
  }
147
+
148
  // Verify the AJAX nonce.
149
  if ( ! self::verify_nonce() ) {
150
+ return;
151
  }
152
 
153
  // Get the $_POST data.
154
  $post_data = FLBuilderModel::get_post_data();
155
+
156
  // Get the post ID.
157
  $post_id = FLBuilderModel::get_post_id();
158
+
159
  // Make sure we have a post ID.
160
  if ( ! $post_id ) {
161
  return;
162
  }
163
+
164
  // Make sure the user can edit this post.
165
  if ( ! current_user_can( 'edit_post', $post_id ) ) {
166
  return;
169
  // Get the action.
170
  if ( ! empty( $_REQUEST['fl_action'] ) ) {
171
  $action = $_REQUEST['fl_action'];
172
+ } elseif ( ! empty( $post_data['fl_action'] ) ) {
 
173
  $action = $post_data['fl_action'];
174
+ } else {
 
175
  return;
176
  }
177
+
178
  // Allow developers to modify actions before they are called.
179
  do_action( 'fl_ajax_before_call_action', $action );
180
+
181
  // Make sure the action exists.
182
  if ( ! isset( self::$actions[ $action ] ) ) {
183
  return;
184
  }
185
+
186
  // Get the action data.
187
  $action = self::$actions[ $action ];
188
  $args = array();
189
  $keys_args = array();
190
+
191
  // Build the args array.
192
  foreach ( $action['args'] as $arg ) {
193
+ // @codingStandardsIgnoreLine
194
  $args[] = $keys_args[ $arg ] = isset( $post_data[ $arg ] ) ? $post_data[ $arg ] : null;
195
  }
196
 
198
  if ( ! defined( 'DOING_AJAX' ) ) {
199
  define( 'DOING_AJAX', true );
200
  }
201
+
202
  // Allow developers to hook before the action runs.
203
  do_action( 'fl_ajax_before_' . $action['action'], $keys_args );
204
 
205
  // Call the action and allow developers to filter the result.
206
  $result = apply_filters( 'fl_ajax_' . $action['action'], call_user_func_array( $action['method'], $args ), $keys_args );
207
+
208
  // Allow developers to hook after the action runs.
209
  do_action( 'fl_ajax_after_' . $action['action'], $keys_args );
210
+
211
  // JSON encode the result.
212
  echo json_encode( $result );
213
+
214
  // Complete the request.
215
  die();
216
  }
222
  * @access private
223
  * @return bool
224
  */
225
+ static private function verify_nonce() {
 
226
  $post_data = FLBuilderModel::get_post_data();
227
  $nonce = false;
228
+
229
  if ( isset( $post_data['_wpnonce'] ) ) {
230
  $nonce = $post_data['_wpnonce'];
231
+ } elseif ( isset( $_REQUEST['_wpnonce'] ) ) {
 
232
  $nonce = $_REQUEST['_wpnonce'];
233
  }
234
+
235
  if ( ! $nonce || ! wp_verify_nonce( $nonce, 'fl_ajax_update' ) ) {
236
+ return false;
237
  }
238
+
239
  return true;
240
  }
241
  }
242
 
243
+ FLBuilderAJAX::init();
classes/class-fl-builder-auto-suggest.php CHANGED
@@ -13,36 +13,35 @@ final class FLBuilderAutoSuggest {
13
  *
14
  * @since 1.2.3
15
  * @return array
16
- */
17
- static public function init()
18
- {
19
- if(isset($_REQUEST['fl_as_action']) && isset($_REQUEST['fl_as_query'])) {
20
-
21
- switch($_REQUEST['fl_as_action']) {
22
-
23
  case 'fl_as_posts':
24
- $data = self::posts();
25
- break;
26
-
27
  case 'fl_as_terms':
28
- $data = self::terms();
29
- break;
30
-
31
  case 'fl_as_users':
32
- $data = self::users();
33
- break;
34
-
35
  case 'fl_as_links':
36
- $data = self::links();
37
- break;
38
  }
39
-
40
- if(isset($data)) {
41
  return $data;
42
  }
43
  }
44
  }
45
-
46
  /**
47
  * Returns a JSON encoded value for a suggest field.
48
  *
@@ -51,70 +50,66 @@ final class FLBuilderAutoSuggest {
51
  * @param string $value The current value.
52
  * @param string $data Additional auto suggest data.
53
  * @return string The JSON encoded value.
54
- */
55
- static public function get_value($action = '', $value = '', $data = '')
56
- {
57
- switch($action) {
58
-
59
  case 'fl_as_posts':
60
- $data = self::posts_value($value);
61
- break;
62
-
63
  case 'fl_as_terms':
64
- $data = self::terms_value($value, $data);
65
- break;
66
-
67
  case 'fl_as_users':
68
- $data = self::users_value($value);
69
- break;
70
-
71
- default :
72
-
73
- if(function_exists($action . '_value')) {
74
- $data = call_user_func_array($action . '_value', array($value, $data));
75
- }
76
-
77
  break;
78
  }
79
-
80
  return isset( $data ) ? str_replace( "'", '&#39;', json_encode( $data ) ) : '';
81
  }
82
-
83
  /**
84
  * Returns the SQL escaped like value for auto suggest queries.
85
  *
86
  * @since 1.2.3
87
  * @return string
88
- */
89
- static public function get_like()
90
- {
91
  global $wpdb;
92
-
93
  $like = stripslashes( urldecode( $_REQUEST['fl_as_query'] ) );
94
-
95
  if ( method_exists( $wpdb, 'esc_like' ) ) {
96
  $like = esc_sql( $wpdb->esc_like( $like ) );
97
- }
98
- else {
99
  $like = like_escape( esc_sql( $like ) );
100
  }
101
-
102
  return $like;
103
  }
104
-
105
  /**
106
  * Returns data for post auto suggest queries.
107
  *
108
  * @since 1.2.3
109
  * @return array
110
  */
111
- static public function posts()
112
- {
113
  global $wpdb;
114
 
115
  $data = array();
116
  $like = self::get_like();
117
- $type = esc_sql($_REQUEST['fl_as_action_data']);
118
 
119
  $posts = $wpdb->get_results( $wpdb->prepare( "
120
  SELECT ID, post_title FROM {$wpdb->posts}
@@ -123,8 +118,11 @@ final class FLBuilderAutoSuggest {
123
  AND post_status = 'publish'
124
  ", '%' . $like . '%', $type ) );
125
 
126
- foreach($posts as $post) {
127
- $data[] = array('name' => $post->post_title, 'value' => $post->ID);
 
 
 
128
  }
129
 
130
  return $data;
@@ -137,19 +135,18 @@ final class FLBuilderAutoSuggest {
137
  * @param string $ids The selected post ids.
138
  * @return array An array of post data.
139
  */
140
- static public function posts_value($ids)
141
- {
142
  global $wpdb;
143
 
144
  $data = array();
145
 
146
- if( ! empty( $ids ) ) {
147
 
148
- $order = implode(",", array_filter(explode(",", $ids), 'intval'));
149
  $list = explode( ',', $ids );
150
- $how_many = count($list);
151
- $placeholders = array_fill(0, $how_many, '%d');
152
- $format = implode(', ', $placeholders);
153
 
154
  $query = "SELECT ID, post_title FROM {$wpdb->posts} WHERE ID IN ($format) ORDER BY FIELD(ID, $order)";
155
 
@@ -157,8 +154,11 @@ final class FLBuilderAutoSuggest {
157
  $posts = $wpdb->get_results( $wpdb->prepare( $query, $list ) );
158
  // @codingStandardsIgnoreEnd
159
 
160
- foreach($posts as $post) {
161
- $data[] = array('name' => $post->post_title, 'value' => $post->ID);
 
 
 
162
  }
163
  }
164
 
@@ -170,22 +170,24 @@ final class FLBuilderAutoSuggest {
170
  *
171
  * @since 1.2.3
172
  * @return array
173
- */
174
- static public function terms()
175
- {
176
- $data = array();
177
  $cats = get_categories(array(
178
- 'hide_empty' => 0,
179
- 'taxonomy' => $_REQUEST['fl_as_action_data']
180
  ));
181
-
182
- foreach($cats as $cat) {
183
- $data[] = array('name' => $cat->name, 'value' => $cat->term_id);
 
 
 
184
  }
185
-
186
  return $data;
187
  }
188
-
189
  /**
190
  * Returns data for selected terms.
191
  *
@@ -193,43 +195,47 @@ final class FLBuilderAutoSuggest {
193
  * @param string $ids The selected term ids.
194
  * @param string $taxonomy The taxonomy to look in.
195
  * @return array An array of term data.
196
- */
197
- static public function terms_value($ids, $taxonomy)
198
- {
199
  $data = array();
200
-
201
- if(!empty($ids)) {
202
 
203
  $cats = get_categories(array(
204
- 'hide_empty' => 0,
205
  'taxonomy' => $taxonomy,
206
- 'include' => $ids
207
  ));
208
-
209
- foreach($cats as $cat) {
210
- $data[] = array('name' => $cat->name, 'value' => $cat->term_id);
 
 
 
211
  }
212
  }
213
-
214
  return $data;
215
  }
216
-
217
  /**
218
  * Returns data for user auto suggest queries.
219
  *
220
  * @since 1.2.3
221
  * @return array
222
  */
223
- static public function users()
224
- {
225
  global $wpdb;
226
 
227
  $data = array();
228
  $like = self::get_like();
229
  $users = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$wpdb->users} WHERE user_login LIKE %s", '%' . $like . '%' ) );
230
 
231
- foreach($users as $user) {
232
- $data[] = array('name' => $user->user_login, 'value' => $user->ID);
 
 
 
233
  }
234
 
235
  return $data;
@@ -242,18 +248,17 @@ final class FLBuilderAutoSuggest {
242
  * @param string $ids The selected user ids.
243
  * @return array An array of user data.
244
  */
245
- static public function users_value($ids)
246
- {
247
  global $wpdb;
248
 
249
  $data = array();
250
 
251
- if(!empty($ids)) {
252
 
253
  $list = explode( ',', $ids );
254
- $how_many = count($list);
255
- $placeholders = array_fill(0, $how_many, '%d');
256
- $format = implode(', ', $placeholders);
257
 
258
  $query = "SELECT * FROM {$wpdb->users} WHERE ID IN ($format)";
259
 
@@ -261,8 +266,11 @@ final class FLBuilderAutoSuggest {
261
  $users = $wpdb->get_results( $wpdb->prepare( $query, $list ) );
262
  // @codingStandardsIgnoreEnd
263
 
264
- foreach($users as $user) {
265
- $data[] = array('name' => $user->user_login, 'value' => $user->ID);
 
 
 
266
  }
267
  }
268
  return $data;
@@ -273,18 +281,17 @@ final class FLBuilderAutoSuggest {
273
  *
274
  * @since 1.3.9
275
  * @return array
276
- */
277
- static public function links()
278
- {
279
  global $wpdb;
280
-
281
- $data = array();
282
  $like = self::get_like();
283
  $types = FLBuilderLoop::post_types();
284
  $slugs = array();
285
 
286
- foreach($types as $slug => $type) {
287
- $slugs[] = esc_sql($slug);
288
  }
289
 
290
  // we cant use an array of arrays for prepare() so use sprintf 1st.
@@ -292,15 +299,18 @@ final class FLBuilderAutoSuggest {
292
  WHERE post_title LIKE %%s
293
  AND post_type IN ('%s')
294
  AND post_status = 'publish'",
295
- implode("', '", $slugs)
296
  );
297
 
298
  // @codingStandardsIgnoreStart
299
  $posts = $wpdb->get_results( $wpdb->prepare( $query, '%' . esc_sql( $like ) . '%' ) );
300
  // @codingStandardsIgnoreEnd
301
 
302
- foreach($posts as $post) {
303
- $data[] = array('name' => $post->post_title, 'value' => get_permalink($post->ID));
 
 
 
304
  }
305
 
306
  return $data;
13
  *
14
  * @since 1.2.3
15
  * @return array
16
+ */
17
+ static public function init() {
18
+ if ( isset( $_REQUEST['fl_as_action'] ) && isset( $_REQUEST['fl_as_query'] ) ) {
19
+
20
+ switch ( $_REQUEST['fl_as_action'] ) {
21
+
 
22
  case 'fl_as_posts':
23
+ $data = self::posts();
24
+ break;
25
+
26
  case 'fl_as_terms':
27
+ $data = self::terms();
28
+ break;
29
+
30
  case 'fl_as_users':
31
+ $data = self::users();
32
+ break;
33
+
34
  case 'fl_as_links':
35
+ $data = self::links();
36
+ break;
37
  }
38
+
39
+ if ( isset( $data ) ) {
40
  return $data;
41
  }
42
  }
43
  }
44
+
45
  /**
46
  * Returns a JSON encoded value for a suggest field.
47
  *
50
  * @param string $value The current value.
51
  * @param string $data Additional auto suggest data.
52
  * @return string The JSON encoded value.
53
+ */
54
+ static public function get_value( $action = '', $value = '', $data = '' ) {
55
+ switch ( $action ) {
56
+
 
57
  case 'fl_as_posts':
58
+ $data = self::posts_value( $value );
59
+ break;
60
+
61
  case 'fl_as_terms':
62
+ $data = self::terms_value( $value, $data );
63
+ break;
64
+
65
  case 'fl_as_users':
66
+ $data = self::users_value( $value );
67
+ break;
68
+
69
+ default :
70
+
71
+ if ( function_exists( $action . '_value' ) ) {
72
+ $data = call_user_func_array( $action . '_value', array( $value, $data ) );
73
+ }
74
+
75
  break;
76
  }
77
+
78
  return isset( $data ) ? str_replace( "'", '&#39;', json_encode( $data ) ) : '';
79
  }
80
+
81
  /**
82
  * Returns the SQL escaped like value for auto suggest queries.
83
  *
84
  * @since 1.2.3
85
  * @return string
86
+ */
87
+ static public function get_like() {
 
88
  global $wpdb;
89
+
90
  $like = stripslashes( urldecode( $_REQUEST['fl_as_query'] ) );
91
+
92
  if ( method_exists( $wpdb, 'esc_like' ) ) {
93
  $like = esc_sql( $wpdb->esc_like( $like ) );
94
+ } else {
 
95
  $like = like_escape( esc_sql( $like ) );
96
  }
97
+
98
  return $like;
99
  }
100
+
101
  /**
102
  * Returns data for post auto suggest queries.
103
  *
104
  * @since 1.2.3
105
  * @return array
106
  */
107
+ static public function posts() {
 
108
  global $wpdb;
109
 
110
  $data = array();
111
  $like = self::get_like();
112
+ $type = esc_sql( $_REQUEST['fl_as_action_data'] );
113
 
114
  $posts = $wpdb->get_results( $wpdb->prepare( "
115
  SELECT ID, post_title FROM {$wpdb->posts}
118
  AND post_status = 'publish'
119
  ", '%' . $like . '%', $type ) );
120
 
121
+ foreach ( $posts as $post ) {
122
+ $data[] = array(
123
+ 'name' => $post->post_title,
124
+ 'value' => $post->ID,
125
+ );
126
  }
127
 
128
  return $data;
135
  * @param string $ids The selected post ids.
136
  * @return array An array of post data.
137
  */
138
+ static public function posts_value( $ids ) {
 
139
  global $wpdb;
140
 
141
  $data = array();
142
 
143
+ if ( ! empty( $ids ) ) {
144
 
145
+ $order = implode( ',', array_filter( explode( ',', $ids ), 'intval' ) );
146
  $list = explode( ',', $ids );
147
+ $how_many = count( $list );
148
+ $placeholders = array_fill( 0, $how_many, '%d' );
149
+ $format = implode( ', ', $placeholders );
150
 
151
  $query = "SELECT ID, post_title FROM {$wpdb->posts} WHERE ID IN ($format) ORDER BY FIELD(ID, $order)";
152
 
154
  $posts = $wpdb->get_results( $wpdb->prepare( $query, $list ) );
155
  // @codingStandardsIgnoreEnd
156
 
157
+ foreach ( $posts as $post ) {
158
+ $data[] = array(
159
+ 'name' => $post->post_title,
160
+ 'value' => $post->ID,
161
+ );
162
  }
163
  }
164
 
170
  *
171
  * @since 1.2.3
172
  * @return array
173
+ */
174
+ static public function terms() {
175
+ $data = array();
 
176
  $cats = get_categories(array(
177
+ 'hide_empty' => 0,
178
+ 'taxonomy' => $_REQUEST['fl_as_action_data'],
179
  ));
180
+
181
+ foreach ( $cats as $cat ) {
182
+ $data[] = array(
183
+ 'name' => $cat->name,
184
+ 'value' => $cat->term_id,
185
+ );
186
  }
187
+
188
  return $data;
189
  }
190
+
191
  /**
192
  * Returns data for selected terms.
193
  *
195
  * @param string $ids The selected term ids.
196
  * @param string $taxonomy The taxonomy to look in.
197
  * @return array An array of term data.
198
+ */
199
+ static public function terms_value( $ids, $taxonomy ) {
 
200
  $data = array();
201
+
202
+ if ( ! empty( $ids ) ) {
203
 
204
  $cats = get_categories(array(
205
+ 'hide_empty' => 0,
206
  'taxonomy' => $taxonomy,
207
+ 'include' => $ids,
208
  ));
209
+
210
+ foreach ( $cats as $cat ) {
211
+ $data[] = array(
212
+ 'name' => $cat->name,
213
+ 'value' => $cat->term_id,
214
+ );
215
  }
216
  }
217
+
218
  return $data;
219
  }
220
+
221
  /**
222
  * Returns data for user auto suggest queries.
223
  *
224
  * @since 1.2.3
225
  * @return array
226
  */
227
+ static public function users() {
 
228
  global $wpdb;
229
 
230
  $data = array();
231
  $like = self::get_like();
232
  $users = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$wpdb->users} WHERE user_login LIKE %s", '%' . $like . '%' ) );
233
 
234
+ foreach ( $users as $user ) {
235
+ $data[] = array(
236
+ 'name' => $user->user_login,
237
+ 'value' => $user->ID,
238
+ );
239
  }
240
 
241
  return $data;
248
  * @param string $ids The selected user ids.
249
  * @return array An array of user data.
250
  */
251
+ static public function users_value( $ids ) {
 
252
  global $wpdb;
253
 
254
  $data = array();
255
 
256
+ if ( ! empty( $ids ) ) {
257
 
258
  $list = explode( ',', $ids );
259
+ $how_many = count( $list );
260
+ $placeholders = array_fill( 0, $how_many, '%d' );
261
+ $format = implode( ', ', $placeholders );
262
 
263
  $query = "SELECT * FROM {$wpdb->users} WHERE ID IN ($format)";
264
 
266
  $users = $wpdb->get_results( $wpdb->prepare( $query, $list ) );
267
  // @codingStandardsIgnoreEnd
268
 
269
+ foreach ( $users as $user ) {
270
+ $data[] = array(
271
+ 'name' => $user->user_login,
272
+ 'value' => $user->ID,
273
+ );
274
  }
275
  }
276
  return $data;
281
  *
282
  * @since 1.3.9
283
  * @return array
284
+ */
285
+ static public function links() {
 
286
  global $wpdb;
287
+
288
+ $data = array();
289
  $like = self::get_like();
290
  $types = FLBuilderLoop::post_types();
291
  $slugs = array();
292
 
293
+ foreach ( $types as $slug => $type ) {
294
+ $slugs[] = esc_sql( $slug );
295
  }
296
 
297
  // we cant use an array of arrays for prepare() so use sprintf 1st.
299
  WHERE post_title LIKE %%s
300
  AND post_type IN ('%s')
301
  AND post_status = 'publish'",
302
+ implode( "', '", $slugs )
303
  );
304
 
305
  // @codingStandardsIgnoreStart
306
  $posts = $wpdb->get_results( $wpdb->prepare( $query, '%' . esc_sql( $like ) . '%' ) );
307
  // @codingStandardsIgnoreEnd
308
 
309
+ foreach ( $posts as $post ) {
310
+ $data[] = array(
311
+ 'name' => $post->post_title,
312
+ 'value' => get_permalink( $post->ID ),
313
+ );
314
  }
315