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
 
316
  return $data;
classes/class-fl-builder-color.php CHANGED
@@ -14,17 +14,16 @@ final class FLBuilderColor {
14
  * @param string $hex A hex color value without the # sign.
15
  * @return array An array of RGB values.
16
  */
17
- static public function hex_to_rgb($hex)
18
- {
19
  return array(
20
- 'r' => hexdec(substr($hex,0,2)),
21
- 'g' => hexdec(substr($hex,2,2)),
22
- 'b' => hexdec(substr($hex,4,2))
23
  );
24
  }
25
 
26
  /**
27
- * Adjusts the brightness of a hex color value based on
28
  * the number of steps provided.
29
  *
30
  * @since 1.0
@@ -33,33 +32,31 @@ final class FLBuilderColor {
33
  * @param string $type The type of adjustment to make. Either lighten, darken or reverse.
34
  * @return string The adjusted hex string.
35
  */
36
- static public function adjust_brightness($hex, $steps, $type)
37
- {
38
  // Get rgb vars.
39
- $rgb = self::hex_to_rgb($hex);
40
  $r = $rgb['r'];
41
  $g = $rgb['g'];
42
  $b = $rgb['b'];
43
 
44
  // Should we darken the color?
45
- if($type == 'reverse' && $r + $g + $b > 382){
46
  $steps = -$steps;
47
- }
48
- else if($type == 'darken') {
49
  $steps = -$steps;
50
  }
51
-
52
  // Build the new color.
53
- $steps = max(-255, min(255, $steps));
54
-
55
- $r = max(0,min(255,$r + $steps));
56
- $g = max(0,min(255,$g + $steps));
57
- $b = max(0,min(255,$b + $steps));
58
-
59
- $r_hex = str_pad(dechex($r), 2, '0', STR_PAD_LEFT);
60
- $g_hex = str_pad(dechex($g), 2, '0', STR_PAD_LEFT);
61
- $b_hex = str_pad(dechex($b), 2, '0', STR_PAD_LEFT);
62
-
63
  return $r_hex . $g_hex . $b_hex;
64
  }
65
- }
14
  * @param string $hex A hex color value without the # sign.
15
  * @return array An array of RGB values.
16
  */
17
+ static public function hex_to_rgb( $hex ) {
 
18
  return array(
19
+ 'r' => hexdec( substr( $hex,0,2 ) ),
20
+ 'g' => hexdec( substr( $hex,2,2 ) ),
21
+ 'b' => hexdec( substr( $hex,4,2 ) ),
22
  );
23
  }
24
 
25
  /**
26
+ * Adjusts the brightness of a hex color value based on
27
  * the number of steps provided.
28
  *
29
  * @since 1.0
32
  * @param string $type The type of adjustment to make. Either lighten, darken or reverse.
33
  * @return string The adjusted hex string.
34
  */
35
+ static public function adjust_brightness( $hex, $steps, $type ) {
 
36
  // Get rgb vars.
37
+ $rgb = self::hex_to_rgb( $hex );
38
  $r = $rgb['r'];
39
  $g = $rgb['g'];
40
  $b = $rgb['b'];
41
 
42
  // Should we darken the color?
43
+ if ( 'reverse' == $type && $r + $g + $b > 382 ) {
44
  $steps = -$steps;
45
+ } elseif ( 'darken' == $type ) {
 
46
  $steps = -$steps;
47
  }
48
+
49
  // Build the new color.
50
+ $steps = max( -255, min( 255, $steps ) );
51
+
52
+ $r = max( 0,min( 255,$r + $steps ) );
53
+ $g = max( 0,min( 255,$g + $steps ) );
54
+ $b = max( 0,min( 255,$b + $steps ) );
55
+
56
+ $r_hex = str_pad( dechex( $r ), 2, '0', STR_PAD_LEFT );
57
+ $g_hex = str_pad( dechex( $g ), 2, '0', STR_PAD_LEFT );
58
+ $b_hex = str_pad( dechex( $b ), 2, '0', STR_PAD_LEFT );
59
+
60
  return $r_hex . $g_hex . $b_hex;
61
  }
62
+ }
classes/class-fl-builder-export.php CHANGED
@@ -7,86 +7,81 @@
7
  */
8
  final class FLBuilderExport {
9
 
10
- /**
11
  * @since 1.8
12
  * @return void
13
- */
14
- static public function init()
15
- {
16
  add_action( 'admin_enqueue_scripts', 'FLBuilderExport::enqueue_scripts' );
17
  add_action( 'export_filters', 'FLBuilderExport::filters' );
18
  add_action( 'wp_ajax_fl_builder_export_templates_data', 'FLBuilderExport::templates_data' );
19
  add_action( 'export_wp', 'FLBuilderExport::export' );
20
  }
21
 
22
- /**
23
  * Enqueues the export scripts and styles.
24
  *
25
  * @since 1.8
26
  * @return void
27
- */
28
- static public function enqueue_scripts()
29
- {
30
  global $pagenow;
31
-
32
  if ( 'export.php' != $pagenow ) {
33
  return;
34
  }
35
-
36
  wp_enqueue_style( 'fl-builder-export', FL_BUILDER_URL . 'css/fl-builder-export.css', array(), FL_BUILDER_VERSION );
37
  wp_enqueue_script( 'fl-builder-export', FL_BUILDER_URL . 'js/fl-builder-export.js', array(), FL_BUILDER_VERSION, true );
38
  }
39
 
40
- /**
41
  * Renders the export filters markup.
42
  *
43
  * @since 1.8
44
  * @return void
45
- */
46
- static public function filters()
47
- {
48
  include FL_BUILDER_DIR . 'includes/export-filters.php';
49
  }
50
 
51
- /**
52
  * Called via AJAX and returns the data used for selecting
53
  * templates for export.
54
- *
55
  * @since 1.8
56
  * @return void
57
- */
58
- static public function templates_data()
59
- {
60
  $type = isset( $_POST['type'] ) ? sanitize_text_field( $_POST['type'] ) : 'fl-builder-template';
61
  $data = array();
62
  $query = new WP_Query( array(
63
  'post_type' => $type,
64
  'orderby' => 'title',
65
  'order' => 'ASC',
66
- 'posts_per_page' => '-1'
67
  ) );
68
-
69
- foreach( $query->posts as $post ) {
70
  $data[] = array(
71
  'id' => $post->ID,
72
- 'title' => $post->post_title
73
  );
74
  }
75
-
76
  echo json_encode( $data );
77
-
78
  die();
79
  }
80
 
81
- /**
82
  * Download the export file.
83
  *
84
  * @since 1.8
85
  * @param array $args
86
  * @return void
87
- */
88
- static public function export( $args )
89
- {
90
  if ( ! current_user_can( 'export' ) ) {
91
  return;
92
  }
@@ -102,13 +97,13 @@ final class FLBuilderExport {
102
  if ( ! is_array( $_REQUEST['fl-builder-export-template'] ) ) {
103
  return;
104
  }
105
-
106
  require_once FL_BUILDER_DIR . 'includes/export.php';
107
-
108
  fl_export_wp( $_REQUEST['fl-builder-export-template'] );
109
-
110
  die();
111
  }
112
  }
113
 
114
- FLBuilderExport::init();
7
  */
8
  final class FLBuilderExport {
9
 
10
+ /**
11
  * @since 1.8
12
  * @return void
13
+ */
14
+ static public function init() {
 
15
  add_action( 'admin_enqueue_scripts', 'FLBuilderExport::enqueue_scripts' );
16
  add_action( 'export_filters', 'FLBuilderExport::filters' );
17
  add_action( 'wp_ajax_fl_builder_export_templates_data', 'FLBuilderExport::templates_data' );
18
  add_action( 'export_wp', 'FLBuilderExport::export' );
19
  }
20
 
21
+ /**
22
  * Enqueues the export scripts and styles.
23
  *
24
  * @since 1.8
25
  * @return void
26
+ */
27
+ static public function enqueue_scripts() {
 
28
  global $pagenow;
29
+
30
  if ( 'export.php' != $pagenow ) {
31
  return;
32
  }
33
+
34
  wp_enqueue_style( 'fl-builder-export', FL_BUILDER_URL . 'css/fl-builder-export.css', array(), FL_BUILDER_VERSION );
35
  wp_enqueue_script( 'fl-builder-export', FL_BUILDER_URL . 'js/fl-builder-export.js', array(), FL_BUILDER_VERSION, true );
36
  }
37
 
38
+ /**
39
  * Renders the export filters markup.
40
  *
41
  * @since 1.8
42
  * @return void
43
+ */
44
+ static public function filters() {
 
45
  include FL_BUILDER_DIR . 'includes/export-filters.php';
46
  }
47
 
48
+ /**
49
  * Called via AJAX and returns the data used for selecting
50
  * templates for export.
51
+ *
52
  * @since 1.8
53
  * @return void
54
+ */
55
+ static public function templates_data() {
 
56
  $type = isset( $_POST['type'] ) ? sanitize_text_field( $_POST['type'] ) : 'fl-builder-template';
57
  $data = array();
58
  $query = new WP_Query( array(
59
  'post_type' => $type,
60
  'orderby' => 'title',
61
  'order' => 'ASC',
62
+ 'posts_per_page' => '-1',
63
  ) );
64
+
65
+ foreach ( $query->posts as $post ) {
66
  $data[] = array(
67
  'id' => $post->ID,
68
+ 'title' => $post->post_title,
69
  );
70
  }
71
+
72
  echo json_encode( $data );
73
+
74
  die();
75
  }
76
 
77
+ /**
78
  * Download the export file.
79
  *
80
  * @since 1.8
81
  * @param array $args
82
  * @return void
83
+ */
84
+ static public function export( $args ) {
 
85
  if ( ! current_user_can( 'export' ) ) {
86
  return;
87
  }
97
  if ( ! is_array( $_REQUEST['fl-builder-export-template'] ) ) {
98
  return;
99
  }
100
+
101
  require_once FL_BUILDER_DIR . 'includes/export.php';
102
+
103
  fl_export_wp( $_REQUEST['fl-builder-export-template'] );
104
+
105
  die();
106
  }
107
  }
108
 
109
+ FLBuilderExport::init();
classes/class-fl-builder-extensions.php CHANGED
@@ -6,7 +6,7 @@
6
  * @since 1.0
7
  */
8
  final class FLBuilderExtensions {
9
-
10
  /**
11
  * Initalizes any extensions found in the extensions directory.
12
  *
@@ -14,23 +14,22 @@ final class FLBuilderExtensions {
14
  * @param string $path Path to extensions to initalize.
15
  * @return void
16
  */
17
- static public function init( $path = null )
18
- {
19
  $path = $path ? trailingslashit( $path ) : FL_BUILDER_DIR . 'extensions/';
20
  $extensions = glob( $path . '*' );
21
-
22
  if ( ! is_array( $extensions ) ) {
23
  return;
24
  }
25
-
26
  foreach ( $extensions as $extension ) {
27
-
28
  if ( ! is_dir( $extension ) ) {
29
- continue;
30
  }
31
-
32
  $path = trailingslashit( $extension ) . basename( $extension ) . '.php';
33
-
34
  if ( file_exists( $path ) ) {
35
  require_once $path;
36
  }
@@ -38,4 +37,4 @@ final class FLBuilderExtensions {
38
  }
39
  }
40
 
41
- FLBuilderExtensions::init();
6
  * @since 1.0
7
  */
8
  final class FLBuilderExtensions {
9
+
10
  /**
11
  * Initalizes any extensions found in the extensions directory.
12
  *
14
  * @param string $path Path to extensions to initalize.
15
  * @return void
16
  */
17
+ static public function init( $path = null ) {
 
18
  $path = $path ? trailingslashit( $path ) : FL_BUILDER_DIR . 'extensions/';
19
  $extensions = glob( $path . '*' );
20
+
21
  if ( ! is_array( $extensions ) ) {
22
  return;
23
  }
24
+
25
  foreach ( $extensions as $extension ) {
26
+
27
  if ( ! is_dir( $extension ) ) {
28
+ continue;
29
  }
30
+
31
  $path = trailingslashit( $extension ) . basename( $extension ) . '.php';
32
+
33
  if ( file_exists( $path ) ) {
34
  require_once $path;
35
  }
37
  }
38
  }
39
 
40
+ FLBuilderExtensions::init();
classes/class-fl-builder-fonts.php CHANGED
@@ -70,7 +70,7 @@ final class FLBuilderFonts {
70
  * @return void
71
  */
72
  static public function display_select_weight( $font, $weight ) {
73
- if ( $font == 'Default' ) {
74
  echo '<option value="default">' . __( 'Default', 'fl-builder' ) . '</option>';
75
  } else {
76
  $system_fonts = apply_filters( 'fl_builder_font_families_system', FLBuilderFontFamilies::$system );
@@ -162,7 +162,7 @@ final class FLBuilderFonts {
162
  $fields = FLBuilderModel::get_settings_form_fields( $module->form );
163
 
164
  foreach ( $fields as $name => $field ) {
165
- if ( $field['type'] == 'font' && isset( $module->settings->$name ) ) {
166
  self::add_font( $module->settings->$name );
167
  } elseif ( isset( $field['form'] ) ) {
168
  $form = FLBuilderModel::$settings_forms[ $field['form'] ];
@@ -185,7 +185,7 @@ final class FLBuilderFonts {
185
  $fields = FLBuilderModel::get_settings_form_fields( $form );
186
 
187
  foreach ( $fields as $name => $field ) {
188
- if ( $field['type'] == 'font' && isset( $module->settings->$setting ) ) {
189
  foreach ( $module->settings->$setting as $key => $val ) {
190
  if ( isset( $val->$name ) ) {
191
  self::add_font( (array) $val->$name );
@@ -230,7 +230,7 @@ final class FLBuilderFonts {
230
  */
231
  static public function add_font( $font ) {
232
 
233
- if ( $font['family'] != 'Default' ) {
234
 
235
  $system_fonts = apply_filters( 'fl_builder_font_families_system', FLBuilderFontFamilies::$system );
236
 
70
  * @return void
71
  */
72
  static public function display_select_weight( $font, $weight ) {
73
+ if ( 'Default' == $font ) {
74
  echo '<option value="default">' . __( 'Default', 'fl-builder' ) . '</option>';
75
  } else {
76
  $system_fonts = apply_filters( 'fl_builder_font_families_system', FLBuilderFontFamilies::$system );
162
  $fields = FLBuilderModel::get_settings_form_fields( $module->form );
163
 
164
  foreach ( $fields as $name => $field ) {
165
+ if ( 'font' == $field['type'] && isset( $module->settings->$name ) ) {
166
  self::add_font( $module->settings->$name );
167
  } elseif ( isset( $field['form'] ) ) {
168
  $form = FLBuilderModel::$settings_forms[ $field['form'] ];
185
  $fields = FLBuilderModel::get_settings_form_fields( $form );
186
 
187
  foreach ( $fields as $name => $field ) {
188
+ if ( 'font' == $field['type'] && isset( $module->settings->$setting ) ) {
189
  foreach ( $module->settings->$setting as $key => $val ) {
190
  if ( isset( $val->$name ) ) {
191
  self::add_font( (array) $val->$name );
230
  */
231
  static public function add_font( $font ) {
232
 
233
+ if ( 'Default' != $font['family'] ) {
234
 
235
  $system_fonts = apply_filters( 'fl_builder_font_families_system', FLBuilderFontFamilies::$system );
236
 
classes/class-fl-builder-icons.php CHANGED
@@ -23,15 +23,14 @@ final class FLBuilderIcons {
23
  * @since 1.4.6
24
  * @return array An array of data for each icon set.
25
  */
26
- static public function get_sets()
27
- {
28
  // Return the sets if already registered.
29
  if ( self::$sets ) {
30
  return self::$sets;
31
  }
32
 
33
  // Check to see if we should pull sets from the main site.
34
- if ( is_multisite()) {
35
 
36
  $blog_id = defined( 'BLOG_ID_CURRENT_SITE' ) ? BLOG_ID_CURRENT_SITE : 1;
37
  $enabled_icons = get_option( '_fl_builder_enabled_icons' );
@@ -64,8 +63,7 @@ final class FLBuilderIcons {
64
  * @since 1.4.6
65
  * @return array An array of data for each icon set.
66
  */
67
- static public function get_sets_for_current_site()
68
- {
69
  if ( ! is_multisite() ) {
70
  return self::get_sets();
71
  }
@@ -94,8 +92,7 @@ final class FLBuilderIcons {
94
  * @param string $key The key for the set to remove.
95
  * @return void
96
  */
97
- static public function remove_set( $key )
98
- {
99
  if ( self::$sets && isset( self::$sets[ $key ] ) ) {
100
  unset( self::$sets[ $key ] );
101
  }
@@ -108,8 +105,7 @@ final class FLBuilderIcons {
108
  * @param string $path The path to retrieve a key for.
109
  * @return string The icon set key.
110
  */
111
- static public function get_key_from_path( $path )
112
- {
113
  $sets = self::get_sets();
114
 
115
  foreach ( $sets as $key => $set ) {
@@ -126,22 +122,21 @@ final class FLBuilderIcons {
126
  * @access private
127
  * @return void
128
  */
129
- static private function register_core_sets()
130
- {
131
  $enabled_icons = FLBuilderModel::get_enabled_icons();
132
  $core_sets = apply_filters( 'fl_builder_core_icon_sets', array(
133
  'font-awesome' => array(
134
  'name' => 'Font Awesome',
135
- 'prefix' => 'fa'
136
  ),
137
  'foundation-icons' => array(
138
  'name' => 'Foundation Icons',
139
- 'prefix' => ''
140
  ),
141
  'dashicons' => array(
142
  'name' => 'WordPress Dashicons',
143
- 'prefix' => 'dashicons dashicons-before'
144
- )
145
  ) );
146
 
147
  // Add the core sets.
@@ -150,7 +145,7 @@ final class FLBuilderIcons {
150
  self::$sets[ $set_key ] = array(
151
  'name' => $set_data['name'],
152
  'prefix' => $set_data['prefix'],
153
- 'type' => 'core'
154
  );
155
  }
156
  }
@@ -173,15 +168,14 @@ final class FLBuilderIcons {
173
  * @access private
174
  * @return void
175
  */
176
- static private function register_custom_sets()
177
- {
178
  // Get uploaded sets.
179
  $enabled_icons = FLBuilderModel::get_enabled_icons();
180
  $upload_info = FLBuilderModel::get_cache_dir( 'icons' );
181
  $folders = glob( $upload_info['path'] . '*' );
182
 
183
  // Make sure we have an array.
184
- if( ! is_array( $folders ) ) {
185
  return;
186
  }
187
 
@@ -213,7 +207,7 @@ final class FLBuilderIcons {
213
  'path' => $folder,
214
  'url' => $url,
215
  'stylesheet' => $url . 'style.css',
216
- 'icons' => array()
217
  );
218
 
219
  foreach ( $data->icons as $icon ) {
@@ -222,9 +216,9 @@ final class FLBuilderIcons {
222
  $postfix = isset( $prefs->postfix ) ? $prefs->postfix : '';
223
 
224
  if ( isset( $prefs->selector ) && 'class' == $prefs->selector ) {
 
225
  $selector = trim( str_replace( '.', ' ', $prefs->classSelector ) ) . ' ';
226
- }
227
- else {
228
  $selector = '';
229
  }
230
 
@@ -232,9 +226,8 @@ final class FLBuilderIcons {
232
  }
233
  }
234
  }
235
- }
236
- // This is a Fontello font.
237
- else if ( file_exists( $folder . 'config.json' ) ) {
238
 
239
  $data = json_decode( file_get_contents( $folder . 'config.json' ) );
240
  $key = basename( $folder );
@@ -262,21 +255,20 @@ final class FLBuilderIcons {
262
  'path' => $folder,
263
  'url' => $url,
264
  'stylesheet' => $url . 'css/' . $style . '.css',
265
- 'icons' => array()
266
  );
267
 
268
  foreach ( $data->glyphs as $icon ) {
269
  if ( $data->css_use_suffix ) {
270
  self::$sets[ $key ]['icons'][] = $icon->css . $data->css_prefix_text;
271
- }
272
- else {
273
  self::$sets[ $key ]['icons'][] = $data->css_prefix_text . $icon->css;
274
  }
275
  }
276
  }
277
  }
278
  }
279
- }
280
  }
281
 
282
  /**
@@ -285,8 +277,7 @@ final class FLBuilderIcons {
285
  * @since 1.4.6
286
  * @return void
287
  */
288
- static public function enqueue_all_custom_icons_styles()
289
- {
290
  $sets = self::get_sets();
291
 
292
  foreach ( $sets as $key => $data ) {
@@ -308,16 +299,14 @@ final class FLBuilderIcons {
308
  * @param object $module The module to enqueue for.
309
  * @return void
310
  */
311
- static public function enqueue_styles_for_module( $module )
312
- {
313
  $fields = FLBuilderModel::get_settings_form_fields( $module->form );
314
 
315
  foreach ( $fields as $name => $field ) {
316
  if ( isset( $field['form'] ) ) {
317
  $form = FLBuilderModel::$settings_forms[ $field['form'] ];
318
  self::enqueue_styles_for_nested_module_form( $module, $form['tabs'], $name );
319
- }
320
- else if ( $field['type'] == 'icon' && isset( $module->settings->$name ) ) {
321
  self::enqueue_styles_for_icon( $module->settings->$name );
322
  }
323
  }
@@ -333,17 +322,15 @@ final class FLBuilderIcons {
333
  * @param string $setting The nested form setting key.
334
  * @return void
335
  */
336
- static private function enqueue_styles_for_nested_module_form( $module, $form, $setting )
337
- {
338
  $fields = FLBuilderModel::get_settings_form_fields( $form );
339
 
340
  foreach ( $fields as $name => $field ) {
341
- if ( $field['type'] == 'icon' && ! empty( $module->settings->$setting ) ) {
342
  foreach ( $module->settings->$setting as $key => $val ) {
343
  if ( isset( $val->$name ) ) {
344
  self::enqueue_styles_for_icon( $val->$name );
345
- }
346
- else if( $name == $key && ! empty( $val ) ) {
347
  self::enqueue_styles_for_icon( $val );
348
  }
349
  }
@@ -359,21 +346,17 @@ final class FLBuilderIcons {
359
  * @param string $icon The icon CSS classname.
360
  * @return void
361
  */
362
- static private function enqueue_styles_for_icon( $icon )
363
- {
364
  do_action( 'fl_builder_enqueue_styles_for_icon', $icon );
365
 
366
  // Is this a core icon?
367
  if ( stristr( $icon, 'fa-' ) ) {
368
  wp_enqueue_style( 'font-awesome' );
369
- }
370
- else if ( stristr( $icon, 'fi-' ) ) {
371
  wp_enqueue_style( 'foundation-icons' );
372
- }
373
- else if ( stristr( $icon, 'dashicon' ) ) {
374
  wp_enqueue_style( 'dashicons' );
375
- }
376
- // It must be a custom icon.
377
  else {
378
 
379
  $sets = self::get_sets();
@@ -394,8 +377,7 @@ final class FLBuilderIcons {
394
  * @param string $key The icon set key.
395
  * @return void
396
  */
397
- static private function enqueue_custom_styles_by_key( $key )
398
- {
399
  if ( apply_filters( 'fl_builder_enqueue_custom_styles_by_key', true, $key ) ) {
400
  $sets = self::get_sets();
401
 
@@ -412,4 +394,4 @@ final class FLBuilderIcons {
412
  }
413
  }
414
  }
415
- }
23
  * @since 1.4.6
24
  * @return array An array of data for each icon set.
25
  */
26
+ static public function get_sets() {
 
27
  // Return the sets if already registered.
28
  if ( self::$sets ) {
29
  return self::$sets;
30
  }
31
 
32
  // Check to see if we should pull sets from the main site.
33
+ if ( is_multisite() ) {
34
 
35
  $blog_id = defined( 'BLOG_ID_CURRENT_SITE' ) ? BLOG_ID_CURRENT_SITE : 1;
36
  $enabled_icons = get_option( '_fl_builder_enabled_icons' );
63
  * @since 1.4.6
64
  * @return array An array of data for each icon set.
65
  */
66
+ static public function get_sets_for_current_site() {
 
67
  if ( ! is_multisite() ) {
68
  return self::get_sets();
69
  }
92
  * @param string $key The key for the set to remove.
93
  * @return void
94
  */
95
+ static public function remove_set( $key ) {
 
96
  if ( self::$sets && isset( self::$sets[ $key ] ) ) {
97
  unset( self::$sets[ $key ] );
98
  }
105
  * @param string $path The path to retrieve a key for.
106
  * @return string The icon set key.
107
  */
108
+ static public function get_key_from_path( $path ) {
 
109
  $sets = self::get_sets();
110
 
111
  foreach ( $sets as $key => $set ) {
122
  * @access private
123
  * @return void
124
  */
125
+ static private function register_core_sets() {
 
126
  $enabled_icons = FLBuilderModel::get_enabled_icons();
127
  $core_sets = apply_filters( 'fl_builder_core_icon_sets', array(
128
  'font-awesome' => array(
129
  'name' => 'Font Awesome',
130
+ 'prefix' => 'fa',
131
  ),
132
  'foundation-icons' => array(
133
  'name' => 'Foundation Icons',
134
+ 'prefix' => '',
135
  ),
136
  'dashicons' => array(
137
  'name' => 'WordPress Dashicons',
138
+ 'prefix' => 'dashicons dashicons-before',
139
+ ),
140
  ) );
141
 
142
  // Add the core sets.
145
  self::$sets[ $set_key ] = array(
146
  'name' => $set_data['name'],
147
  'prefix' => $set_data['prefix'],
148
+ 'type' => 'core',
149
  );
150
  }
151
  }
168
  * @access private
169
  * @return void
170
  */
171
+ static private function register_custom_sets() {
 
172
  // Get uploaded sets.
173
  $enabled_icons = FLBuilderModel::get_enabled_icons();
174
  $upload_info = FLBuilderModel::get_cache_dir( 'icons' );
175
  $folders = glob( $upload_info['path'] . '*' );
176
 
177
  // Make sure we have an array.
178
+ if ( ! is_array( $folders ) ) {
179
  return;
180
  }
181
 
207
  'path' => $folder,
208
  'url' => $url,
209
  'stylesheet' => $url . 'style.css',
210
+ 'icons' => array(),
211
  );
212
 
213
  foreach ( $data->icons as $icon ) {
216
  $postfix = isset( $prefs->postfix ) ? $prefs->postfix : '';
217
 
218
  if ( isset( $prefs->selector ) && 'class' == $prefs->selector ) {
219
+ // @codingStandardsIgnoreLine
220
  $selector = trim( str_replace( '.', ' ', $prefs->classSelector ) ) . ' ';
221
+ } else {
 
222
  $selector = '';
223
  }
224
 
226
  }
227
  }
228
  }
229
+ } // End if().
230
+ elseif ( file_exists( $folder . 'config.json' ) ) {
 
231
 
232
  $data = json_decode( file_get_contents( $folder . 'config.json' ) );
233
  $key = basename( $folder );
255
  'path' => $folder,
256
  'url' => $url,
257
  'stylesheet' => $url . 'css/' . $style . '.css',
258
+ 'icons' => array(),
259
  );
260
 
261
  foreach ( $data->glyphs as $icon ) {
262
  if ( $data->css_use_suffix ) {
263
  self::$sets[ $key ]['icons'][] = $icon->css . $data->css_prefix_text;
264
+ } else {
 
265
  self::$sets[ $key ]['icons'][] = $data->css_prefix_text . $icon->css;
266
  }
267
  }
268
  }
269
  }
270
  }
271
+ }// End foreach().
272
  }
273
 
274
  /**
277
  * @since 1.4.6
278
  * @return void
279
  */
280
+ static public function enqueue_all_custom_icons_styles() {
 
281
  $sets = self::get_sets();
282
 
283
  foreach ( $sets as $key => $data ) {
299
  * @param object $module The module to enqueue for.
300
  * @return void
301
  */
302
+ static public function enqueue_styles_for_module( $module ) {
 
303
  $fields = FLBuilderModel::get_settings_form_fields( $module->form );
304
 
305
  foreach ( $fields as $name => $field ) {
306
  if ( isset( $field['form'] ) ) {
307
  $form = FLBuilderModel::$settings_forms[ $field['form'] ];
308
  self::enqueue_styles_for_nested_module_form( $module, $form['tabs'], $name );
309
+ } elseif ( 'icon' == $field['type'] && isset( $module->settings->$name ) ) {
 
310
  self::enqueue_styles_for_icon( $module->settings->$name );
311
  }
312
  }
322
  * @param string $setting The nested form setting key.
323
  * @return void
324
  */
325
+ static private function enqueue_styles_for_nested_module_form( $module, $form, $setting ) {
 
326
  $fields = FLBuilderModel::get_settings_form_fields( $form );
327
 
328
  foreach ( $fields as $name => $field ) {
329
+ if ( 'icon' == $field['type'] && ! empty( $module->settings->$setting ) ) {
330
  foreach ( $module->settings->$setting as $key => $val ) {
331
  if ( isset( $val->$name ) ) {
332
  self::enqueue_styles_for_icon( $val->$name );
333
+ } elseif ( $name == $key && ! empty( $val ) ) {
 
334
  self::enqueue_styles_for_icon( $val );
335
  }
336
  }
346
  * @param string $icon The icon CSS classname.
347
  * @return void
348
  */
349
+ static private function enqueue_styles_for_icon( $icon ) {
 
350
  do_action( 'fl_builder_enqueue_styles_for_icon', $icon );
351
 
352
  // Is this a core icon?
353
  if ( stristr( $icon, 'fa-' ) ) {
354
  wp_enqueue_style( 'font-awesome' );
355
+ } elseif ( stristr( $icon, 'fi-' ) ) {
 
356
  wp_enqueue_style( 'foundation-icons' );
357
+ } elseif ( stristr( $icon, 'dashicon' ) ) {
 
358
  wp_enqueue_style( 'dashicons' );
359
+ } // End if().
 
360
  else {
361
 
362
  $sets = self::get_sets();
377
  * @param string $key The icon set key.
378
  * @return void
379
  */
380
+ static private function enqueue_custom_styles_by_key( $key ) {
 
381
  if ( apply_filters( 'fl_builder_enqueue_custom_styles_by_key', true, $key ) ) {
382
  $sets = self::get_sets();
383
 
394
  }
395
  }
396
  }
397
+ }
classes/class-fl-builder-import.php CHANGED
@@ -1,7 +1,7 @@
1
  <?php
2
 
3
  /**
4
- * The WordPress importer plugin has a few issues that break
5
  * serialized data in certain cases. This class overrides the
6
  * WordPress importer with our own patched version that fixes
7
  * these issues.
@@ -10,41 +10,39 @@
10
  */
11
  final class FLBuilderImport {
12
 
13
- /**
14
  * @since 1.8
15
  * @return void
16
- */
17
- static public function init()
18
- {
19
  if ( ! defined( 'WP_LOAD_IMPORTERS' ) || ! class_exists( 'WP_Import' ) || ! class_exists( 'WXR_Parser_Regex' ) ) {
20
  return;
21
  }
22
-
23
  if ( defined( 'FL_BUILDER_IMPORTER_FIX' ) && ! FL_BUILDER_IMPORTER_FIX ) {
24
  return;
25
  }
26
-
27
  require_once FL_BUILDER_DIR . '/classes/class-fl-builder-importer.php';
28
-
29
  // Remove the WordPress importer.
30
  remove_action( 'admin_init', 'wordpress_importer_init' );
31
-
32
  // Add our importer.
33
  add_action( 'admin_init', 'FLBuilderImport::load' );
34
  }
35
 
36
- /**
37
  * @since 1.8
38
  * @return void
39
- */
40
- static public function load()
41
- {
42
  load_plugin_textdomain( 'wordpress-importer', false, 'wordpress-importer/languages' );
43
 
44
  $GLOBALS['wp_import'] = new FLBuilderImporter();
45
-
46
- register_importer( 'wordpress', 'WordPress', __('Import <strong>posts, pages, comments, custom fields, categories, and tags</strong> from a WordPress export file.', 'fl-builder'), array( $GLOBALS['wp_import'], 'dispatch' ) );
47
  }
48
  }
49
 
50
- add_action( 'plugins_loaded', 'FLBuilderImport::init' );
1
  <?php
2
 
3
  /**
4
+ * The WordPress importer plugin has a few issues that break
5
  * serialized data in certain cases. This class overrides the
6
  * WordPress importer with our own patched version that fixes
7
  * these issues.
10
  */
11
  final class FLBuilderImport {
12
 
13
+ /**
14
  * @since 1.8
15
  * @return void
16
+ */
17
+ static public function init() {
 
18
  if ( ! defined( 'WP_LOAD_IMPORTERS' ) || ! class_exists( 'WP_Import' ) || ! class_exists( 'WXR_Parser_Regex' ) ) {
19
  return;
20
  }
21
+
22
  if ( defined( 'FL_BUILDER_IMPORTER_FIX' ) && ! FL_BUILDER_IMPORTER_FIX ) {
23
  return;
24
  }
25
+
26
  require_once FL_BUILDER_DIR . '/classes/class-fl-builder-importer.php';
27
+
28
  // Remove the WordPress importer.
29
  remove_action( 'admin_init', 'wordpress_importer_init' );
30
+
31
  // Add our importer.
32
  add_action( 'admin_init', 'FLBuilderImport::load' );
33
  }
34
 
35
+ /**
36
  * @since 1.8
37
  * @return void
38
+ */
39
+ static public function load() {
 
40
  load_plugin_textdomain( 'wordpress-importer', false, 'wordpress-importer/languages' );
41
 
42
  $GLOBALS['wp_import'] = new FLBuilderImporter();
43
+
44
+ register_importer( 'wordpress', 'WordPress', __( 'Import <strong>posts, pages, comments, custom fields, categories, and tags</strong> from a WordPress export file.', 'fl-builder' ), array( $GLOBALS['wp_import'], 'dispatch' ) );
45
  }
46
  }
47
 
48
+ add_action( 'plugins_loaded', 'FLBuilderImport::init' );
classes/class-fl-builder-importer.php CHANGED
@@ -1,18 +1,18 @@
1
  <?php
2
 
3
  /**
4
- * The WordPress importer plugin has a few issues that break
5
- * serialized data in certain cases. This class is our own
6
  * patched version that fixes these issues.
7
  *
8
  * @since 1.8
9
  */
10
  class FLBuilderImporter extends WP_Import {
11
 
12
- /**
13
  * @since 1.8
14
  * @return array
15
- */
16
  function parse( $file ) {
17
  $parser = new FLBuilderImportParserRegex();
18
  return $parser->parse( $file );
@@ -21,7 +21,7 @@ class FLBuilderImporter extends WP_Import {
21
 
22
  /**
23
  * The Regex parser is the only parser we have found that
24
- * doesn't break serialized data. It does have two bugs
25
  * that can break serialized data. Those are calling rtrim
26
  * on each $importline and adding a newline to each $importline.
27
  * This class fixes those bugs.
@@ -30,11 +30,12 @@ class FLBuilderImporter extends WP_Import {
30
  */
31
  class FLBuilderImportParserRegex extends WXR_Parser_Regex {
32
 
33
- /**
34
  * @since 1.8
35
  * @return array
36
- */
37
  function parse( $file ) {
 
38
  $wxr_version = $in_post = false;
39
 
40
  $fp = $this->fopen( $file, 'r' );
@@ -42,8 +43,9 @@ class FLBuilderImportParserRegex extends WXR_Parser_Regex {
42
  while ( ! $this->feof( $fp ) ) {
43
  $importline = $this->fgets( $fp );
44
 
45
- if ( ! $wxr_version && preg_match( '|<wp:wxr_version>(\d+\.\d+)</wp:wxr_version>|', $importline, $version ) )
46
  $wxr_version = $version[1];
 
47
 
48
  if ( false !== strpos( $importline, '<wp:base_site_url>' ) ) {
49
  preg_match( '|<wp:base_site_url>(.*?)</wp:base_site_url>|is', $importline, $url );
@@ -52,31 +54,31 @@ class FLBuilderImportParserRegex extends WXR_Parser_Regex {
52
  }
53
  if ( false !== strpos( $importline, '<wp:category>' ) ) {
54
  preg_match( '|<wp:category>(.*?)</wp:category>|is', $importline, $category );
55
- if ( isset($category[1]) ) {
56
  $this->categories[] = $this->process_category( $category[1] );
57
  }
58
  continue;
59
  }
60
  if ( false !== strpos( $importline, '<wp:tag>' ) ) {
61
  preg_match( '|<wp:tag>(.*?)</wp:tag>|is', $importline, $tag );
62
- if ( isset($tag[1]) ) {
63
  $this->tags[] = $this->process_tag( $tag[1] );
64
  }
65
  continue;
66
  }
67
  if ( false !== strpos( $importline, '<wp:term>' ) ) {
68
  preg_match( '|<wp:term>(.*?)</wp:term>|is', $importline, $term );
69
- if ( isset($term[1]) ) {
70
  $this->terms[] = $this->process_term( $term[1] );
71
  }
72
  continue;
73
  }
74
  if ( false !== strpos( $importline, '<wp:author>' ) ) {
75
  preg_match( '|<wp:author>(.*?)</wp:author>|is', $importline, $author );
76
- if ( isset($author[1]) ) {
77
  $a = $this->process_author( $author[1] );
78
  }
79
- $this->authors[$a['author_login']] = $a;
80
  continue;
81
  }
82
  if ( false !== strpos( $importline, '<item>' ) ) {
@@ -92,10 +94,10 @@ class FLBuilderImportParserRegex extends WXR_Parser_Regex {
92
  if ( $in_post ) {
93
  $post .= $importline;
94
  }
95
- }
 
 
96
 
97
- $this->fclose($fp);
98
-
99
  // Try to fix any broken builder data.
100
  foreach ( $this->posts as $post_index => $post ) {
101
  if ( ! isset( $post['postmeta'] ) || ! is_array( $post['postmeta'] ) ) {
@@ -107,10 +109,11 @@ class FLBuilderImportParserRegex extends WXR_Parser_Regex {
107
  }
108
  }
109
  }
110
- }
111
 
112
- if ( ! $wxr_version )
113
  return new WP_Error( 'WXR_parse_error', __( 'This does not appear to be a WXR file, missing/invalid WXR version number', 'fl-builder' ) );
 
114
 
115
  return array(
116
  'authors' => $this->authors,
@@ -119,7 +122,7 @@ class FLBuilderImportParserRegex extends WXR_Parser_Regex {
119
  'tags' => $this->tags,
120
  'terms' => $this->terms,
121
  'base_url' => $this->base_url,
122
- 'version' => $wxr_version
123
  );
124
  }
125
  }
@@ -137,17 +140,16 @@ final class FLBuilderImporterDataFix {
137
  * @since 1.8
138
  * @return string
139
  */
140
- static public function run( $data )
141
- {
142
  // return if empty
143
- if( empty( $data ) ) {
144
  return $data;
145
  }
146
 
147
  $data = maybe_unserialize( $data );
148
 
149
  // return if maybe_unserialize() returns an object or array, this is good.
150
- if( is_object( $data ) || is_array( $data ) ) {
151
  return $data;
152
  }
153
 
@@ -158,15 +160,14 @@ final class FLBuilderImporterDataFix {
158
  * @since 1.8
159
  * @return string
160
  */
161
- static public function regex_callback( $matches )
162
- {
163
  if ( ! isset( $matches[3] ) ) {
164
  return $matches[0];
165
  }
166
-
167
  return 's:' . strlen( self::unescape_mysql( $matches[3] ) ) . ':"' . self::unescape_quotes( $matches[3] ) . '";';
168
  }
169
-
170
  /**
171
  * Unescape to avoid dump-text issues.
172
  *
@@ -174,13 +175,12 @@ final class FLBuilderImporterDataFix {
174
  * @access private
175
  * @return string
176
  */
177
- static private function unescape_mysql( $value )
178
- {
179
- return str_replace( array( "\\\\", "\\0", "\\n", "\\r", "\Z", "\'", '\"' ),
180
- array( "\\", "\0", "\n", "\r", "\x1a", "'", '"' ),
181
- $value );
182
  }
183
-
184
  /**
185
  * Fix strange behaviour if you have escaped quotes in your replacement.
186
  *
@@ -188,8 +188,7 @@ final class FLBuilderImporterDataFix {
188
  * @access private
189
  * @return string
190
  */
191
- static private function unescape_quotes( $value )
192
- {
193
  return str_replace( '\"', '"', $value );
194
- }
195
- }
1
  <?php
2
 
3
  /**
4
+ * The WordPress importer plugin has a few issues that break
5
+ * serialized data in certain cases. This class is our own
6
  * patched version that fixes these issues.
7
  *
8
  * @since 1.8
9
  */
10
  class FLBuilderImporter extends WP_Import {
11
 
12
+ /**
13
  * @since 1.8
14
  * @return array
15
+ */
16
  function parse( $file ) {
17
  $parser = new FLBuilderImportParserRegex();
18
  return $parser->parse( $file );
21
 
22
  /**
23
  * The Regex parser is the only parser we have found that
24
+ * doesn't break serialized data. It does have two bugs
25
  * that can break serialized data. Those are calling rtrim
26
  * on each $importline and adding a newline to each $importline.
27
  * This class fixes those bugs.
30
  */
31
  class FLBuilderImportParserRegex extends WXR_Parser_Regex {
32
 
33
+ /**
34
  * @since 1.8
35
  * @return array
36
+ */
37
  function parse( $file ) {
38
+ // @codingStandardsIgnoreLine
39
  $wxr_version = $in_post = false;
40
 
41
  $fp = $this->fopen( $file, 'r' );
43
  while ( ! $this->feof( $fp ) ) {
44
  $importline = $this->fgets( $fp );
45
 
46
+ if ( ! $wxr_version && preg_match( '|<wp:wxr_version>(\d+\.\d+)</wp:wxr_version>|', $importline, $version ) ) {
47
  $wxr_version = $version[1];
48
+ }
49
 
50
  if ( false !== strpos( $importline, '<wp:base_site_url>' ) ) {
51
  preg_match( '|<wp:base_site_url>(.*?)</wp:base_site_url>|is', $importline, $url );
54
  }
55
  if ( false !== strpos( $importline, '<wp:category>' ) ) {
56
  preg_match( '|<wp:category>(.*?)</wp:category>|is', $importline, $category );
57
+ if ( isset( $category[1] ) ) {
58
  $this->categories[] = $this->process_category( $category[1] );
59
  }
60
  continue;
61
  }
62
  if ( false !== strpos( $importline, '<wp:tag>' ) ) {
63
  preg_match( '|<wp:tag>(.*?)</wp:tag>|is', $importline, $tag );
64
+ if ( isset( $tag[1] ) ) {
65
  $this->tags[] = $this->process_tag( $tag[1] );
66
  }
67
  continue;
68
  }
69
  if ( false !== strpos( $importline, '<wp:term>' ) ) {
70
  preg_match( '|<wp:term>(.*?)</wp:term>|is', $importline, $term );
71
+ if ( isset( $term[1] ) ) {
72
  $this->terms[] = $this->process_term( $term[1] );
73
  }
74
  continue;
75
  }
76
  if ( false !== strpos( $importline, '<wp:author>' ) ) {
77
  preg_match( '|<wp:author>(.*?)</wp:author>|is', $importline, $author );
78
+ if ( isset( $author[1] ) ) {
79
  $a = $this->process_author( $author[1] );
80
  }
81
+ $this->authors[ $a['author_login'] ] = $a;
82
  continue;
83
  }
84
  if ( false !== strpos( $importline, '<item>' ) ) {
94
  if ( $in_post ) {
95
  $post .= $importline;
96
  }
97
+ }// End while().
98
+
99
+ $this->fclose( $fp );
100
 
 
 
101
  // Try to fix any broken builder data.
102
  foreach ( $this->posts as $post_index => $post ) {
103
  if ( ! isset( $post['postmeta'] ) || ! is_array( $post['postmeta'] ) ) {
109
  }
110
  }
111
  }
112
+ }// End if().
113
 
114
+ if ( ! $wxr_version ) {
115
  return new WP_Error( 'WXR_parse_error', __( 'This does not appear to be a WXR file, missing/invalid WXR version number', 'fl-builder' ) );
116
+ }
117
 
118
  return array(
119
  'authors' => $this->authors,
122
  'tags' => $this->tags,
123
  'terms' => $this->terms,
124
  'base_url' => $this->base_url,
125
+ 'version' => $wxr_version,
126
  );
127
  }
128
  }
140
  * @since 1.8
141
  * @return string
142
  */
143
+ static public function run( $data ) {
 
144
  // return if empty
145
+ if ( empty( $data ) ) {
146
  return $data;
147
  }
148
 
149
  $data = maybe_unserialize( $data );
150
 
151
  // return if maybe_unserialize() returns an object or array, this is good.
152
+ if ( is_object( $data ) || is_array( $data ) ) {
153
  return $data;
154
  }
155
 
160
  * @since 1.8
161
  * @return string
162
  */
163
+ static public function regex_callback( $matches ) {
 
164
  if ( ! isset( $matches[3] ) ) {
165
  return $matches[0];
166
  }
167
+
168
  return 's:' . strlen( self::unescape_mysql( $matches[3] ) ) . ':"' . self::unescape_quotes( $matches[3] ) . '";';
169
  }
170
+
171
  /**
172
  * Unescape to avoid dump-text issues.
173
  *
175
  * @access private
176
  * @return string
177
  */
178
+ static private function unescape_mysql( $value ) {
179
+ return str_replace( array( '\\\\', "\\0", "\\n", "\\r", '\Z', "\'", '\"' ),
180
+ array( '\\', "\0", "\n", "\r", "\x1a", "'", '"' ),
181
+ $value );
 
182
  }
183
+
184
  /**
185
  * Fix strange behaviour if you have escaped quotes in your replacement.
186
  *
188
  * @access private
189
  * @return string
190
  */
191
+ static private function unescape_quotes( $value ) {
 
192
  return str_replace( '\"', '"', $value );
193
+ }
194
+ }
classes/class-fl-builder-loader.php CHANGED
@@ -16,8 +16,7 @@ if ( ! class_exists( 'FLBuilderLoader' ) ) {
16
  * @since 1.8
17
  * @return void
18
  */
19
- static public function init()
20
- {
21
  if ( ! function_exists( 'is_plugin_active' ) ) {
22
  include_once ABSPATH . 'wp-admin/includes/plugin.php';
23
  }
@@ -27,8 +26,8 @@ if ( ! class_exists( 'FLBuilderLoader' ) ) {
27
  $plugin_dirname = basename( dirname( dirname( __FILE__ ) ) );
28
 
29
  if ( class_exists( 'FLBuilder' ) || ( $plugin_dirname != $lite_dirname && $lite_active ) ) {
30
- add_action('admin_notices', __CLASS__ . '::double_install_admin_notice');
31
- add_action('network_admin_notices', __CLASS__ . '::double_install_admin_notice');
32
  return;
33
  }
34
 
@@ -43,19 +42,18 @@ if ( ! class_exists( 'FLBuilderLoader' ) ) {
43
  * @since 1.8
44
  * @return void
45
  */
46
- static private function define_constants()
47
- {
48
- define('FL_BUILDER_VERSION', '1.10.6.5');
49
- define('FL_BUILDER_FILE', trailingslashit(dirname(dirname(__FILE__))) . 'fl-builder.php');
50
- define('FL_BUILDER_DIR', plugin_dir_path(FL_BUILDER_FILE));
51
- define('FL_BUILDER_URL', plugins_url('/', FL_BUILDER_FILE));
52
- define('FL_BUILDER_LITE', true);
53
- define('FL_BUILDER_SUPPORT_URL', 'https://www.wpbeaverbuilder.com/support/'); // Deprecated, do not use.
54
- define('FL_BUILDER_UPGRADE_URL', 'https://www.wpbeaverbuilder.com/'); // Deprecated, do not use.
55
- define('FL_BUILDER_STORE_URL', 'https://www.wpbeaverbuilder.com/');
56
- define('FL_BUILDER_DEMO_URL', 'http://demos.wpbeaverbuilder.com');
57
- define('FL_BUILDER_OLD_DEMO_URL', 'http://demos.fastlinemedia.com');
58
- define('FL_BUILDER_DEMO_CACHE_URL', 'http://demos.wpbeaverbuilder.com/wp-content/uploads/bb-plugin/cache/');
59
  }
60
 
61
  /**
@@ -64,8 +62,7 @@ if ( ! class_exists( 'FLBuilderLoader' ) ) {
64
  * @since 1.8
65
  * @return void
66
  */
67
- static private function load_files()
68
- {
69
  /* Classes */
70
  require_once FL_BUILDER_DIR . 'classes/class-fl-builder.php';
71
  require_once FL_BUILDER_DIR . 'classes/class-fl-builder-admin.php';
@@ -109,16 +106,15 @@ if ( ! class_exists( 'FLBuilderLoader' ) ) {
109
  * @access private
110
  * @return void
111
  */
112
- static private function check_permissions()
113
- {
114
  if ( isset( $_REQUEST['page'] ) && in_array( $_REQUEST['page'], array( 'fl-builder-settings', 'fl-builder-multisite-settings' ) ) ) {
115
 
116
  $wp_upload_dir = wp_upload_dir();
117
  $bb_upload_dir = FLBuilderModel::get_upload_dir();
118
 
119
  if ( ! is_writable( $wp_upload_dir['basedir'] ) || ! is_writable( $bb_upload_dir['path'] ) ) {
120
- add_action('admin_notices', __CLASS__ . '::permissions_admin_notice');
121
- add_action('network_admin_notices', __CLASS__ . '::permissions_admin_notice');
122
  }
123
  }
124
  }
@@ -129,8 +125,7 @@ if ( ! class_exists( 'FLBuilderLoader' ) ) {
129
  * @since 1.8.2
130
  * @return void
131
  */
132
- static public function permissions_admin_notice()
133
- {
134
  $message = __( 'Beaver Builder may not be functioning correctly as it does not have permission to write files to the WordPress uploads directory on your server. Please update the WordPress uploads directory permissions before continuing or contact your host for assistance.', 'fl-builder' );
135
 
136
  self::render_admin_notice( $message, 'error' );
@@ -143,8 +138,7 @@ if ( ! class_exists( 'FLBuilderLoader' ) ) {
143
  * @since 1.8
144
  * @return void
145
  */
146
- static public function double_install_admin_notice()
147
- {
148
  $message = __( 'You currently have two versions of Beaver Builder active on this site. Please <a href="%s">deactivate one</a> before continuing.', 'fl-builder' );
149
 
150
  self::render_admin_notice( sprintf( $message, admin_url( 'plugins.php' ) ), 'error' );
@@ -159,15 +153,12 @@ if ( ! class_exists( 'FLBuilderLoader' ) ) {
159
  * @param string $type
160
  * @return void
161
  */
162
- static private function render_admin_notice( $message, $type = 'update' )
163
- {
164
  if ( ! is_admin() ) {
165
  return;
166
- }
167
- else if ( ! is_user_logged_in() ) {
168
  return;
169
- }
170
- else if ( ! current_user_can( 'update_plugins' ) ) {
171
  return;
172
  }
173
 
@@ -176,6 +167,6 @@ if ( ! class_exists( 'FLBuilderLoader' ) ) {
176
  echo '</div>';
177
  }
178
  }
179
- }
180
 
181
  FLBuilderLoader::init();
16
  * @since 1.8
17
  * @return void
18
  */
19
+ static public function init() {
 
20
  if ( ! function_exists( 'is_plugin_active' ) ) {
21
  include_once ABSPATH . 'wp-admin/includes/plugin.php';
22
  }
26
  $plugin_dirname = basename( dirname( dirname( __FILE__ ) ) );
27
 
28
  if ( class_exists( 'FLBuilder' ) || ( $plugin_dirname != $lite_dirname && $lite_active ) ) {
29
+ add_action( 'admin_notices', __CLASS__ . '::double_install_admin_notice' );
30
+ add_action( 'network_admin_notices', __CLASS__ . '::double_install_admin_notice' );
31
  return;
32
  }
33
 
42
  * @since 1.8
43
  * @return void
44
  */
45
+ static private function define_constants() {
46
+ define( 'FL_BUILDER_VERSION', '1.10.7' );
47
+ define( 'FL_BUILDER_FILE', trailingslashit( dirname( dirname( __FILE__ ) ) ) . 'fl-builder.php' );
48
+ define( 'FL_BUILDER_DIR', plugin_dir_path( FL_BUILDER_FILE ) );
49
+ define( 'FL_BUILDER_URL', plugins_url( '/', FL_BUILDER_FILE ) );
50
+ define( 'FL_BUILDER_LITE', true );
51
+ define( 'FL_BUILDER_SUPPORT_URL', 'https://www.wpbeaverbuilder.com/support/' ); // Deprecated, do not use.
52
+ define( 'FL_BUILDER_UPGRADE_URL', 'https://www.wpbeaverbuilder.com/' ); // Deprecated, do not use.
53
+ define( 'FL_BUILDER_STORE_URL', 'https://www.wpbeaverbuilder.com/' );
54
+ define( 'FL_BUILDER_DEMO_URL', 'http://demos.wpbeaverbuilder.com' );
55
+ define( 'FL_BUILDER_OLD_DEMO_URL', 'http://demos.fastlinemedia.com' );
56
+ define( 'FL_BUILDER_DEMO_CACHE_URL', 'http://demos.wpbeaverbuilder.com/wp-content/uploads/bb-plugin/cache/' );
 
57
  }
58
 
59
  /**
62
  * @since 1.8
63
  * @return void
64
  */
65
+ static private function load_files() {
 
66
  /* Classes */
67
  require_once FL_BUILDER_DIR . 'classes/class-fl-builder.php';
68
  require_once FL_BUILDER_DIR . 'classes/class-fl-builder-admin.php';
106
  * @access private
107
  * @return void
108
  */
109
+ static private function check_permissions() {
 
110
  if ( isset( $_REQUEST['page'] ) && in_array( $_REQUEST['page'], array( 'fl-builder-settings', 'fl-builder-multisite-settings' ) ) ) {
111
 
112
  $wp_upload_dir = wp_upload_dir();
113
  $bb_upload_dir = FLBuilderModel::get_upload_dir();
114
 
115
  if ( ! is_writable( $wp_upload_dir['basedir'] ) || ! is_writable( $bb_upload_dir['path'] ) ) {
116
+ add_action( 'admin_notices', __CLASS__ . '::permissions_admin_notice' );
117
+ add_action( 'network_admin_notices', __CLASS__ . '::permissions_admin_notice' );
118
  }
119
  }
120
  }
125
  * @since 1.8.2
126
  * @return void
127
  */
128
+ static public function permissions_admin_notice() {
 
129
  $message = __( 'Beaver Builder may not be functioning correctly as it does not have permission to write files to the WordPress uploads directory on your server. Please update the WordPress uploads directory permissions before continuing or contact your host for assistance.', 'fl-builder' );
130
 
131
  self::render_admin_notice( $message, 'error' );
138
  * @since 1.8
139
  * @return void
140
  */
141
+ static public function double_install_admin_notice() {
 
142
  $message = __( 'You currently have two versions of Beaver Builder active on this site. Please <a href="%s">deactivate one</a> before continuing.', 'fl-builder' );
143
 
144
  self::render_admin_notice( sprintf( $message, admin_url( 'plugins.php' ) ), 'error' );
153
  * @param string $type
154
  * @return void
155
  */
156
+ static private function render_admin_notice( $message, $type = 'update' ) {
 
157
  if ( ! is_admin() ) {
158
  return;
159
+ } elseif ( ! is_user_logged_in() ) {
 
160
  return;
161
+ } elseif ( ! current_user_can( 'update_plugins' ) ) {
 
162
  return;
163
  }
164
 
167
  echo '</div>';
168
  }
169
  }
170
+ }// End if().
171
 
172
  FLBuilderLoader::init();
classes/class-fl-builder-loop.php CHANGED
@@ -15,21 +15,63 @@ final class FLBuilderLoop {
15
  */
16
  static public $loop_counter = 0;
17
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
  /**
19
  * Initializes hooks.
20
  *
21
  * @since 1.8
22
  * @return void
23
  */
24
- static public function init()
25
- {
26
  // Actions
27
  add_action( 'fl_builder_before_control_suggest', __CLASS__ . '::render_match_select', 10, 4 );
28
- add_action( 'init', __CLASS__ . '::init_rewrite_rules' );
 
 
 
29
 
30
  // Filters
31
  add_filter( 'found_posts', __CLASS__ . '::found_posts', 1, 2 );
32
  add_filter( 'redirect_canonical', __CLASS__ . '::override_canonical', 1, 2 );
 
 
33
  }
34
 
35
  /**
@@ -40,15 +82,16 @@ final class FLBuilderLoop {
40
  * @param object $settings Module settings to use for the query.
41
  * @return object A WP_Query instance.
42
  */
43
- static public function query( $settings )
44
- {
45
  $settings = apply_filters( 'fl_builder_loop_before_query_settings', $settings );
46
  do_action( 'fl_builder_loop_before_query', $settings );
47
 
 
 
 
48
  if ( isset( $settings->data_source ) && 'main_query' == $settings->data_source ) {
49
  $query = self::main_query();
50
- }
51
- else {
52
  $query = self::custom_query( $settings );
53
  }
54
 
@@ -58,18 +101,30 @@ final class FLBuilderLoop {
58
  }
59
 
60
  /**
61
- * Returns a clone of the main query with the post data reset.
 
62
  *
63
  * @since 1.10
64
  * @return object A WP_Query instance.
65
  */
66
- static public function main_query()
67
- {
68
- global $wp_query;
 
 
69
 
70
- $query = clone $wp_query;
71
- $query->rewind_posts();
72
- $query->reset_postdata();
 
 
 
 
 
 
 
 
 
73
 
74
  return $query;
75
  }
@@ -82,32 +137,27 @@ final class FLBuilderLoop {
82
  * @param object $settings Module settings to use for the query.
83
  * @return object A WP_Query instance.
84
  */
85
- static public function custom_query($settings)
86
- {
87
- $posts_per_page = empty($settings->posts_per_page) ? 10 : $settings->posts_per_page;
88
- $post_type = empty($settings->post_type) ? 'post' : $settings->post_type;
89
- $order_by = empty($settings->order_by) ? 'date' : $settings->order_by;
90
- $order = empty($settings->order) ? 'DESC' : $settings->order;
91
- $users = empty($settings->users) ? '' : $settings->users;
92
- $fields = empty($settings->fields) ? '' : $settings->fields;
93
 
94
- // Count how many times this method has been called
95
- self::$loop_counter++;
96
  $paged = self::get_paged();
97
 
98
  // Get the offset.
99
- if ( ! isset( $settings->offset ) || ! is_int( ( int )$settings->offset ) ) {
100
  $offset = 0;
101
- }
102
- else {
103
  $offset = $settings->offset;
104
  }
105
 
106
  // Get the paged offset.
107
  if ( $paged < 2 ) {
108
  $paged_offset = $offset;
109
- }
110
- else {
111
  $paged_offset = $offset + ( ( $paged - 1 ) * $posts_per_page );
112
  }
113
 
@@ -118,12 +168,14 @@ final class FLBuilderLoop {
118
  'post_type' => $post_type,
119
  'orderby' => $order_by,
120
  'order' => $order,
121
- 'tax_query' => array('relation' => 'AND'),
 
 
122
  'ignore_sticky_posts' => true,
123
  'offset' => $paged_offset,
124
  'fl_original_offset' => $offset,
125
  'fl_builder_loop' => true,
126
- 'fields' => $fields
127
  ) );
128
 
129
  // Order by meta value arg.
@@ -141,7 +193,7 @@ final class FLBuilderLoop {
141
  $arg = 'author__in';
142
 
143
  // Set to NOT IN if matching is present and set to 0.
144
- if(isset($settings->users_matching) && !$settings->users_matching) {
145
  $arg = 'author__not_in';
146
  }
147
 
@@ -149,61 +201,60 @@ final class FLBuilderLoop {
149
  }
150
 
151
  // Build the taxonomy query.
152
- $taxonomies = self::taxonomies($post_type);
153
 
154
- foreach($taxonomies as $tax_slug => $tax) {
155
 
156
  $tax_value = '';
157
  $operator = 'IN';
158
 
159
  // Set to NOT IN if matching is present and set to 0.
160
- if(isset($settings->{'tax_' . $post_type . '_' . $tax_slug . '_matching'})) {
161
- if (!$settings->{'tax_' . $post_type . '_' . $tax_slug . '_matching'}) {
162
  $operator = 'NOT IN';
163
  }
164
  }
165
 
166
  // New settings slug.
167
- if(isset($settings->{'tax_' . $post_type . '_' . $tax_slug})) {
168
  $tax_value = $settings->{'tax_' . $post_type . '_' . $tax_slug};
169
- }
170
- // Legacy settings slug.
171
- else if(isset($settings->{'tax_' . $tax_slug})) {
172
  $tax_value = $settings->{'tax_' . $tax_slug};
173
  }
174
 
175
- if(!empty($tax_value)) {
176
 
177
  $args['tax_query'][] = array(
178
  'taxonomy' => $tax_slug,
179
  'field' => 'id',
180
- 'terms' => explode(',', $tax_value),
181
- 'operator' => $operator
182
  );
183
  }
184
  }
185
 
186
  // Post in/not in query.
187
- if(isset($settings->{'posts_' . $post_type})) {
188
 
189
  $ids = $settings->{'posts_' . $post_type};
190
  $arg = 'post__in';
191
 
192
  // Set to NOT IN if matching is present and set to 0.
193
- if(isset($settings->{'posts_' . $post_type . '_matching'})) {
194
- if (!$settings->{'posts_' . $post_type . '_matching'}) {
195
  $arg = 'post__not_in';
196
  }
197
  }
198
 
199
  // Add the args if we have IDs.
200
- if(!empty($ids)) {
201
- $args[ $arg ] = explode(',', $settings->{'posts_' . $post_type});
202
  }
203
  }
204
 
205
  // Build the query.
206
- $query = new WP_Query($args);
207
 
208
  // Return the query.
209
  return $query;
@@ -218,8 +269,7 @@ final class FLBuilderLoop {
218
  * @param object $query An instance of WP_Query.
219
  * @return int
220
  */
221
- static public function found_posts( $found_posts, $query )
222
- {
223
  if ( isset( $query->query ) && isset( $query->query['fl_builder_loop'] ) ) {
224
  return $found_posts - $query->query['fl_original_offset'];
225
  }
@@ -235,16 +285,267 @@ final class FLBuilderLoop {
235
  * @since 1.9.5
236
  * @return void
237
  */
238
- static public function init_rewrite_rules()
239
- {
240
- for ( $x = 2; $x <= 10; $x++ ) {
241
- add_rewrite_rule( 'paged-'. $x .'/([0-9]*)/?', 'index.php?page_id=' . get_option( 'page_on_front' ) . '&flpaged'. $x .'=$matches[1]', 'top' );
242
- add_rewrite_rule( 'paged-'. $x .'/?([0-9]{1,})/?$', 'index.php?&flpaged'. $x .'=$matches[1]', 'top');
243
- add_rewrite_rule( '(.?.+?)/paged-'. $x .'/?([0-9]{1,})/?$', 'index.php?pagename=$matches[1]&flpaged'. $x .'=$matches[2]', 'top');
244
- add_rewrite_rule( '([^/]+)/paged-'. $x .'/?([0-9]{1,})/?$', 'index.php?name=$matches[1]&flpaged'. $x .'=$matches[2]', 'top');
245
- add_rewrite_rule( '(.?.+?)/([^/]+)/paged-'. $x .'/?([0-9]{1,})/?$', 'index.php?post_type=$matches[1]&name=$matches[2]&flpaged'. $x .'=$matches[3]', 'top');
246
- add_rewrite_tag( "%flpaged{$x}%", '([^&]+)');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
247
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
248
  }
249
 
250
  /**
@@ -260,29 +561,82 @@ final class FLBuilderLoop {
260
  static public function override_canonical( $redirect_url, $requested_url ) {
261
  global $wp_the_query;
262
 
263
- if ( is_array($wp_the_query->query) ) {
264
- foreach ($wp_the_query->query as $key => $value) {
265
- if (strpos($key, 'flpaged') === 0 && is_page() && get_option( 'page_on_front' )) {
266
  $redirect_url = false;
267
  break;
268
  }
269
  }
270
 
271
- $supported_post_types = self::post_types();
 
 
 
 
 
 
 
 
 
 
272
 
273
- // Disable canonical on CPT single
274
- if ( isset( $wp_the_query->query_vars['post_type'] )
275
- && ! is_array( $wp_the_query->query_vars['post_type'] )
276
- && isset( $supported_post_types[ $wp_the_query->query_vars['post_type'] ] )
277
- && true === $wp_the_query->is_singular
278
- && - 1 == $wp_the_query->current_post
279
- && true === $wp_the_query->is_paged
280
- ) {
281
- $redirect_url = false;
282
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
283
  }
284
 
285
- return $redirect_url;
 
 
 
 
 
 
 
 
 
 
 
286
  }
287
 
288
  /**
@@ -292,60 +646,185 @@ final class FLBuilderLoop {
292
  * @param object $query An instance of WP_Query.
293
  * @return void
294
  */
295
- static public function pagination($query)
296
- {
297
  $total_pages = $query->max_num_pages;
298
- $permalink_structure = get_option('permalink_structure');
299
  $paged = self::get_paged();
300
- $base = get_pagenum_link();
301
 
302
- if($total_pages > 1) {
303
 
304
- if(!$current_page = $paged) {
305
  $current_page = 1;
306
  }
307
 
308
- if ( self::$loop_counter > 1 ) {
309
- $page_prefix = 'paged-'. self::$loop_counter;
310
- }
311
- else {
312
- $page_prefix = empty($permalink_structure) ? 'paged' : 'page';
313
- }
314
 
315
- if(empty($permalink_structure) || is_search()) {
316
- $format = '&'. $page_prefix .'=%#%';
317
- }
318
- else if ("/" == substr($base, -1)) {
319
- $format = $page_prefix . '/%#%/';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
320
  }
321
- else {
322
- $format = '/'. $page_prefix .'/%#%';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
323
  }
324
 
325
- // Fix for wpml pagination
326
- // @since 1.10.2
327
- if( ! empty( $permalink_structure ) && isset( $_GET['lang'] ) ) {
328
- $base = untrailingslashit( add_query_arg( array( 'lang' => false ), $base ) );
329
  }
330
 
331
- $pos = strrpos($base, "paged-");
332
- if ( $pos ) {
333
- $base = substr_replace( $base, '', $pos, strlen( $base ) );
 
 
 
 
334
  }
 
335
 
336
- // Remove query string from base URL since paginate_links() adds it automatically.
337
- if ( ! empty( $permalink_structure ) && count( $_GET ) > 0 ) {
338
- $base = untrailingslashit( strtok( $base, '?' ) );
339
- }
340
 
341
- echo paginate_links(array(
342
- 'base' => $base . '%_%',
343
- 'format' => $format,
344
- 'current' => $current_page,
345
- 'total' => $total_pages,
346
- 'type' => 'list'
347
- ));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
348
  }
 
 
349
  }
350
 
351
  /**
@@ -354,26 +833,41 @@ final class FLBuilderLoop {
354
  * @since 1.9.5
355
  * @return int
356
  */
357
- static public function get_paged()
358
- {
359
  global $wp_the_query, $paged;
360
 
361
  // Check first for custom pagination from post module
362
- $flpaged = $wp_the_query->get( 'flpaged'. self::$loop_counter );
363
 
364
- if ( is_numeric( $flpaged ) ) {
 
 
 
 
365
  return $flpaged;
366
- }
367
- else if ( self::$loop_counter > 1 ) {
368
- // If we have multiple paginations, make sure it won't affect the other loops.
369
- return 0;
370
- }
371
 
372
- // Check the 'page' query var.
373
- $page_qv = $wp_the_query->get( 'page' );
 
374
 
375
- if ( is_numeric( $page_qv ) ) {
376
- return $page_qv;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
377
  }
378
 
379
  // Check the 'paged' query var.
@@ -383,6 +877,13 @@ final class FLBuilderLoop {
383
  return $paged_qv;
384
  }
385
 
 
 
 
 
 
 
 
386
  // Check the $paged global?
387
  if ( is_numeric( $paged ) ) {
388
  return $paged;
@@ -398,16 +899,15 @@ final class FLBuilderLoop {
398
  * @since 1.2.3
399
  * @return array
400
  */
401
- static public function post_types()
402
- {
403
  $post_types = get_post_types(array(
404
  'public' => true,
405
- 'show_ui' => true
406
  ), 'objects');
407
 
408
- unset($post_types['attachment']);
409
- unset($post_types['fl-builder-template']);
410
- unset($post_types['fl-theme-layout']);
411
 
412
  return $post_types;
413
  }
@@ -419,18 +919,17 @@ final class FLBuilderLoop {
419
  * @param string $post_type The post type to get taxonomies for.
420
  * @return array
421
  */
422
- static public function taxonomies($post_type)
423
- {
424
- $taxonomies = get_object_taxonomies($post_type, 'objects');
425
  $data = array();
426
 
427
- foreach($taxonomies as $tax_slug => $tax) {
428
 
429
- if(!$tax->public || !$tax->show_ui) {
430
  continue;
431
  }
432
 
433
- $data[$tax_slug] = $tax;
434
  }
435
 
436
  return apply_filters( 'fl_builder_loop_taxonomies', $data, $taxonomies, $post_type );
@@ -443,8 +942,7 @@ final class FLBuilderLoop {
443
  * @param string $format The date format to use.
444
  * @return void
445
  */
446
- static public function post_date( $format = 'default' )
447
- {
448
  if ( 'default' == $format ) {
449
  $format = get_option( 'date_format' );
450
  }
@@ -463,8 +961,7 @@ final class FLBuilderLoop {
463
  * @param object $settings
464
  * @return void
465
  */
466
- static public function render_match_select( $name, $value, $field, $settings )
467
- {
468
  if ( ! isset( $field['matching'] ) || ! $field['matching'] ) {
469
  return;
470
  }
15
  */
16
  static public $loop_counter = 0;
17
 
18
+ /**
19
+ * Custom pagination regex base.
20
+ *
21
+ * @since 1.10.7
22
+ * @var string
23
+ */
24
+ static public $paged_regex_base = 'paged-[0-9]{1,}';
25
+
26
+ /**
27
+ * Cache the custom pagination data.
28
+ * Format:
29
+ * array(
30
+ * 'current_page' => '',
31
+ * 'current_loop' => '',
32
+ * 'paged' => ''
33
+ * )
34
+ *
35
+ * @since 1.10.7
36
+ * @var array
37
+ */
38
+ static public $custom_paged_data = array();
39
+
40
+ /**
41
+ * Flag for flushing post type rewrite rules.
42
+ *
43
+ * @since 1.10.7
44
+ * @var bool
45
+ */
46
+ static private $_rewrote_post_type = false;
47
+
48
+ /**
49
+ * Flag for flushing taxonomy rewrite rules.
50
+ *
51
+ * @since 1.10.7
52
+ * @var bool
53
+ */
54
+ static private $_rewrote_taxonomy = false;
55
+
56
  /**
57
  * Initializes hooks.
58
  *
59
  * @since 1.8
60
  * @return void
61
  */
62
+ static public function init() {
 
63
  // Actions
64
  add_action( 'fl_builder_before_control_suggest', __CLASS__ . '::render_match_select', 10, 4 );
65
+ add_action( 'init', __CLASS__ . '::init_rewrite_rules', 20 );
66
+ add_action( 'registered_post_type', __CLASS__ . '::post_type_rewrite_rules', 10, 2 );
67
+ add_action( 'registered_taxonomy', __CLASS__ . '::taxonomy_rewrite_rules', 10, 3 );
68
+ add_action( 'wp_loaded', __CLASS__ . '::flush_rewrite_rules', 1 );
69
 
70
  // Filters
71
  add_filter( 'found_posts', __CLASS__ . '::found_posts', 1, 2 );
72
  add_filter( 'redirect_canonical', __CLASS__ . '::override_canonical', 1, 2 );
73
+ add_filter( 'pre_handle_404', __CLASS__ . '::pre_404_pagination', 1, 2 );
74
+ add_filter( 'paginate_links', __CLASS__ . '::filter_paginate_links', 1 );
75
  }
76
 
77
  /**
82
  * @param object $settings Module settings to use for the query.
83
  * @return object A WP_Query instance.
84
  */
85
+ static public function query( $settings ) {
 
86
  $settings = apply_filters( 'fl_builder_loop_before_query_settings', $settings );
87
  do_action( 'fl_builder_loop_before_query', $settings );
88
 
89
+ // Count how many times this method has been called
90
+ self::$loop_counter++;
91
+
92
  if ( isset( $settings->data_source ) && 'main_query' == $settings->data_source ) {
93
  $query = self::main_query();
94
+ } else {
 
95
  $query = self::custom_query( $settings );
96
  }
97
 
101
  }
102
 
103
  /**
104
+ * Returns new instance query if we have multiple paginations on a page.
105
+ * Else, returns a clone of the main query with the post data reset.
106
  *
107
  * @since 1.10
108
  * @return object A WP_Query instance.
109
  */
110
+ static public function main_query() {
111
+ global $wp_query, $wp_the_query;
112
+
113
+ // Setup a new WP_Query instance if we have multiple paginations on a page.
114
+ if ( self::$loop_counter > 1 || $wp_the_query->is_singular( 'fl-theme-layout' ) ) {
115
 
116
+ $query_args = $wp_query->query_vars;
117
+
118
+ $query_args['paged'] = self::get_paged();
119
+ $query_args['fl_original_offset'] = 0;
120
+ $query_args['fl_builder_loop'] = true;
121
+
122
+ $query = new WP_Query( $query_args );
123
+ } else {
124
+ $query = clone $wp_query;
125
+ $query->rewind_posts();
126
+ $query->reset_postdata();
127
+ }
128
 
129
  return $query;
130
  }
137
  * @param object $settings Module settings to use for the query.
138
  * @return object A WP_Query instance.
139
  */
140
+ static public function custom_query( $settings ) {
141
+ $posts_per_page = empty( $settings->posts_per_page ) ? 10 : $settings->posts_per_page;
142
+ $post_type = empty( $settings->post_type ) ? 'post' : $settings->post_type;
143
+ $order_by = empty( $settings->order_by ) ? 'date' : $settings->order_by;
144
+ $order = empty( $settings->order ) ? 'DESC' : $settings->order;
145
+ $users = empty( $settings->users ) ? '' : $settings->users;
146
+ $fields = empty( $settings->fields ) ? '' : $settings->fields;
 
147
 
 
 
148
  $paged = self::get_paged();
149
 
150
  // Get the offset.
151
+ if ( ! isset( $settings->offset ) || ! is_int( (int) $settings->offset ) ) {
152
  $offset = 0;
153
+ } else {
 
154
  $offset = $settings->offset;
155
  }
156
 
157
  // Get the paged offset.
158
  if ( $paged < 2 ) {
159
  $paged_offset = $offset;
160
+ } else {
 
161
  $paged_offset = $offset + ( ( $paged - 1 ) * $posts_per_page );
162
  }
163
 
168
  'post_type' => $post_type,
169
  'orderby' => $order_by,
170
  'order' => $order,
171
+ 'tax_query' => array(
172
+ 'relation' => 'AND',
173
+ ),
174
  'ignore_sticky_posts' => true,
175
  'offset' => $paged_offset,
176
  'fl_original_offset' => $offset,
177
  'fl_builder_loop' => true,
178
+ 'fields' => $fields,
179
  ) );
180
 
181
  // Order by meta value arg.
193
  $arg = 'author__in';
194
 
195
  // Set to NOT IN if matching is present and set to 0.
196
+ if ( isset( $settings->users_matching ) && ! $settings->users_matching ) {
197
  $arg = 'author__not_in';
198
  }
199
 
201
  }
202
 
203
  // Build the taxonomy query.
204
+ $taxonomies = self::taxonomies( $post_type );
205
 
206
+ foreach ( $taxonomies as $tax_slug => $tax ) {
207
 
208
  $tax_value = '';
209
  $operator = 'IN';
210
 
211
  // Set to NOT IN if matching is present and set to 0.
212
+ if ( isset( $settings->{'tax_' . $post_type . '_' . $tax_slug . '_matching'} ) ) {
213
+ if ( ! $settings->{'tax_' . $post_type . '_' . $tax_slug . '_matching'} ) {
214
  $operator = 'NOT IN';
215
  }
216
  }
217
 
218
  // New settings slug.
219
+ if ( isset( $settings->{'tax_' . $post_type . '_' . $tax_slug} ) ) {
220
  $tax_value = $settings->{'tax_' . $post_type . '_' . $tax_slug};
221
+ } // End if().
222
+ elseif ( isset( $settings->{'tax_' . $tax_slug} ) ) {
 
223
  $tax_value = $settings->{'tax_' . $tax_slug};
224
  }
225
 
226
+ if ( ! empty( $tax_value ) ) {
227
 
228
  $args['tax_query'][] = array(
229
  'taxonomy' => $tax_slug,
230
  'field' => 'id',
231
+ 'terms' => explode( ',', $tax_value ),
232
+ 'operator' => $operator,
233
  );
234
  }
235
  }
236
 
237
  // Post in/not in query.
238
+ if ( isset( $settings->{'posts_' . $post_type} ) ) {
239
 
240
  $ids = $settings->{'posts_' . $post_type};
241
  $arg = 'post__in';
242
 
243
  // Set to NOT IN if matching is present and set to 0.
244
+ if ( isset( $settings->{'posts_' . $post_type . '_matching'} ) ) {
245
+ if ( ! $settings->{'posts_' . $post_type . '_matching'} ) {
246
  $arg = 'post__not_in';
247
  }
248
  }
249
 
250
  // Add the args if we have IDs.
251
+ if ( ! empty( $ids ) ) {
252
+ $args[ $arg ] = explode( ',', $settings->{'posts_' . $post_type} );
253
  }
254
  }
255
 
256
  // Build the query.
257
+ $query = new WP_Query( $args );
258
 
259
  // Return the query.
260
  return $query;
269
  * @param object $query An instance of WP_Query.
270
  * @return int
271
  */
272
+ static public function found_posts( $found_posts, $query ) {
 
273
  if ( isset( $query->query ) && isset( $query->query['fl_builder_loop'] ) ) {
274
  return $found_posts - $query->query['fl_original_offset'];
275
  }
285
  * @since 1.9.5
286
  * @return void
287
  */
288
+ static public function init_rewrite_rules() {
289
+ $custom_paged = self::get_custom_paged();
290
+ if ( empty( $custom_paged ) && ! is_admin() ) {
291
+ return;
292
+ }
293
+
294
+ $fronts = self::get_rewrite_fronts();
295
+ $paged_regex = self::$paged_regex_base;
296
+
297
+ $flpaged_rules = array(
298
+
299
+ // Category archive
300
+ $fronts['category'] . '/(.+?)/' . $paged_regex . '/?([0-9]{1,})/?$' => 'index.php?category_name=$matches[1]&flpaged=$matches[2]',
301
+
302
+ // Tag archive
303
+ $fronts['tag'] . '/([^/]+)/' . $paged_regex . '/?([0-9]{1,})/?$' => 'index.php?tag=$matches[1]&flpaged=$matches[2]',
304
+
305
+ // Year archive
306
+ $fronts['date'] . '([0-9]{4})/' . $paged_regex . '/?([0-9]{1,})/?$' => 'index.php?year=$matches[1]&flpaged=$matches[2]',
307
+
308
+ // Year/month archive
309
+ $fronts['date'] . '([0-9]{4})/([0-9]{1,2})/' . $paged_regex . '/?([0-9]{1,})/?$' => 'index.php?year=$matches[1]&monthnum=$matches[2]&flpaged=$matches[3]',
310
+
311
+ // Day archive
312
+ $fronts['date'] . '([0-9]{4})/([0-9]{1,2})/([0-9]{1,2})/' . $paged_regex . '/?([0-9]{1,})/?$' => 'index.php?year=$matches[1]&monthnum=$matches[2]&day=$matches[3]&flpaged=$matches[4]',
313
+
314
+ // Author archive
315
+ $fronts['author'] . '([^/]+)/' . $paged_regex . '/?([0-9]{1,})/?$' => 'index.php?author_name=$matches[1]&flpaged=$matches[2]',
316
+
317
+ // Post single - Numeric permastruct (/archives/%post_id%)
318
+ $fronts['default'] . '([0-9]+)/' . $paged_regex . '/?([0-9]{1,})/?$' => 'index.php?p=$matches[1]&flpaged=$matches[2]',
319
+
320
+ // CPT single
321
+ '(.+?)/([^/]+)/' . $paged_regex . '/?([0-9]{1,})/?$' => 'index.php?post_type=$matches[1]&name=$matches[2]&flpaged=$matches[3]',
322
+
323
+ // Page
324
+ '(.?.+?)/' . $paged_regex . '/?([0-9]{1,})/?$' => 'index.php?pagename=$matches[1]&flpaged=$matches[2]',
325
+
326
+ // Post single
327
+ '(.+?)/' . $paged_regex . '/?([0-9]{1,})/?$' => 'index.php?name=$matches[1]&flpaged=$matches[2]',
328
+ );
329
+
330
+ // Frontpage static
331
+ if ( get_option( 'page_on_front' ) ) {
332
+ $flpaged_rules[ $paged_regex . '/([0-9]*)/?' ] = 'index.php?page_id=' . get_option( 'page_on_front' ) . '&flpaged=$matches[1]';
333
+ }
334
+ // Generic Rule for Homepage / Search
335
+ $flpaged_rules[ $paged_regex . '/?([0-9]{1,})/?$' ] = 'index.php?&flpaged=$matches[1]';
336
+
337
+ foreach ( $flpaged_rules as $regex => $redirect ) {
338
+ add_rewrite_rule( $regex, $redirect, 'top' );
339
+ }
340
+
341
+ add_rewrite_tag( '%flpaged%', '([^&]+)' );
342
+ }
343
+
344
+ /**
345
+ * Get the rewrite front for the generic rules.
346
+ *
347
+ * @since 1.10.7
348
+ * @return array
349
+ */
350
+ static public function get_rewrite_fronts() {
351
+ global $wp_rewrite;
352
+
353
+ $front = substr( $wp_rewrite->front, 1 );
354
+
355
+ $category_base = get_option( 'category_base' );
356
+ if ( ! $category_base ) {
357
+ $category_base = $front . 'category';
358
+ }
359
+
360
+ $tag_base = get_option( 'tag_base' );
361
+ if ( ! $tag_base ) {
362
+ $tag_base = $front . 'tag';
363
+ }
364
+
365
+ $date_base = $front;
366
+ if ( strpos( $wp_rewrite->permalink_structure, '%post_id%' ) !== false ) {
367
+ $date_base = $front . 'date/';
368
+ }
369
+
370
+ $author_base = $front . $wp_rewrite->author_base . '/';
371
+
372
+ return array(
373
+ 'category' => $category_base,
374
+ 'tag' => $tag_base,
375
+ 'date' => $date_base,
376
+ 'author' => $author_base,
377
+ 'default' => $front,
378
+ );
379
+ }
380
+
381
+ /**
382
+ * Adding custom rewrite rules for the current post type pagination.
383
+ *
384
+ * @param string $post_type
385
+ * @param array $args
386
+ * @since 1.10.7
387
+ * @return void
388
+ */
389
+ static public function post_type_rewrite_rules( $post_type, $args ) {
390
+ global $wp_rewrite;
391
+
392
+ if ( $args->_builtin or ! $args->publicly_queryable ) {
393
+ return;
394
+ }
395
+
396
+ if ( false === $args->rewrite ) {
397
+ return;
398
  }
399
+
400
+ // Get our custom pagination if sets.
401
+ $custom_paged = self::get_custom_paged();
402
+
403
+ if ( ! $custom_paged || empty( $custom_paged ) || ! isset( $custom_paged['current_page'] ) ) {
404
+ return;
405
+ }
406
+
407
+ $is_single = false;
408
+
409
+ // Check if it's a CPT archive or CPT single.
410
+ if ( $custom_paged['current_page'] != $post_type ) {
411
+
412
+ // Is a child post of the current post type?
413
+ $post_object = get_page_by_path( $custom_paged['current_page'], OBJECT, $post_type );
414
+
415
+ if ( $post_object ) {
416
+ $is_single = true;
417
+ } else {
418
+ return;
419
+ }
420
+ }
421
+
422
+ $slug = $args->rewrite['slug'];
423
+
424
+ if ( is_string( $args->has_archive ) ) {
425
+ $slug = $args->has_archive;
426
+ }
427
+
428
+ if ( $args->rewrite['with_front'] ) {
429
+ $slug = substr( $wp_rewrite->front, 1 ) . $slug;
430
+ }
431
+
432
+ // Append $custom_paged[ 'current_page' ] to slug if it's single.
433
+ if ( $is_single ) {
434
+ $regex = $slug . '/' . $custom_paged['current_page'] . '/' . self::$paged_regex_base . '/?([0-9]{1,})/?$';
435
+ $redirect = 'index.php?post_type=' . $post_type . '&name=' . $custom_paged['current_page'] . '&flpaged=$matches[1]';
436
+ } else {
437
+ $regex = $slug . '/' . self::$paged_regex_base . '/?([0-9]{1,})/?$';
438
+ $redirect = 'index.php?post_type=' . $post_type . '&flpaged=$matches[1]';
439
+ }
440
+
441
+ add_rewrite_rule( $regex, $redirect, 'top' );
442
+
443
+ // Set true for flushing.
444
+ self::$_rewrote_post_type = true;
445
+ }
446
+
447
+ /**
448
+ * Adding custom rewrite rules for taxonomy pagination.
449
+ *
450
+ * @param string $taxonomy
451
+ * @param string $object_type
452
+ * @param array $args
453
+ * @since 1.10.7
454
+ * @return void
455
+ */
456
+ static public function taxonomy_rewrite_rules( $taxonomy, $object_type, $args ) {
457
+ global $wp_rewrite;
458
+
459
+ // For 4.7
460
+ $args = (array) $args;
461
+
462
+ if ( ! empty( $args['_builtin'] ) ) {
463
+ return;
464
+ }
465
+
466
+ if ( false === $args['rewrite'] ) {
467
+ return;
468
+ }
469
+
470
+ // Get our custom pagination request data.
471
+ $custom_paged = self::get_custom_paged();
472
+
473
+ // Taxonomy checks.
474
+ if ( empty( $custom_paged['parent_page'] ) || ! isset( $custom_paged['parent_page'] ) ) {
475
+ return;
476
+ }
477
+
478
+ // Term checks.
479
+ if ( ! $custom_paged || empty( $custom_paged ) || ! isset( $custom_paged['current_page'] ) ) {
480
+ return;
481
+ }
482
+
483
+ // Add rewrite to the registered tax only.
484
+ if ( isset( $custom_paged['parent_page'] ) && $custom_paged['parent_page'] != $taxonomy ) {
485
+ return;
486
+ }
487
+
488
+ // Make sure we have a valid term.
489
+ if ( ! term_exists( $custom_paged['current_page'], $taxonomy ) ) {
490
+ return;
491
+ }
492
+
493
+ if ( 'category' == $taxonomy ) {
494
+ $taxonomy_slug = ( $cb = get_option( 'category_base' ) ) ? $cb : $taxonomy; // @codingStandardsIgnoreLine
495
+ $taxonomy_key = 'category_name';
496
+ } else {
497
+ if ( isset( $args['rewrite']['slug'] ) ) {
498
+ $taxonomy_slug = $args['rewrite']['slug'];
499
+ } else {
500
+ $taxonomy_slug = $taxonomy;
501
+ }
502
+
503
+ $taxonomy_key = $taxonomy;
504
+ }
505
+
506
+ if ( $args['rewrite']['with_front'] ) {
507
+ $taxonomy_slug = substr( $wp_rewrite->front, 1 ) . $taxonomy_slug;
508
+ }
509
+
510
+ $rules = array(
511
+ // Year
512
+ '%s/(.+?)/date/([0-9]{4})/' . self::$paged_regex_base . '/?([0-9]{1,})/?$' => "index.php?{$taxonomy_key}=\$matches[1]&year=\$matches[2]&flpaged=\$matches[3]",
513
+
514
+ // Month
515
+ '%s/(.+?)/date/([0-9]{4})/([0-9]{1,2})/' . self::$paged_regex_base . '/?([0-9]{1,})/?$' => "index.php?{$taxonomy_key}=\$matches[1]&year=\$matches[2]&monthnum=\$matches[3]&flpaged=\$matches[4]",
516
+
517
+ // Day
518
+ '%s/(.+?)/date/([0-9]{4})/([0-9]{1,2})/([0-9]{1,2})/' . self::$paged_regex_base . '/?([0-9]{1,})/?$' => "index.php?{$taxonomy_key}=\$matches[1]&year=\$matches[2]&monthnum=\$matches[3]&day=\$matches[4]&flpaged=\$matches[5]",
519
+
520
+ // Tax Archive
521
+ '%s/(.+?)/' . self::$paged_regex_base . '/?([0-9]{1,})/?$' => "index.php?{$taxonomy_key}=\$matches[1]&flpaged=\$matches[2]",
522
+ );
523
+
524
+ foreach ( $rules as $regex => $redirect ) {
525
+ $regex = sprintf( $regex, "{$taxonomy_slug}" );
526
+ add_rewrite_rule( $regex, $redirect, 'top' );
527
+ }
528
+
529
+ // Set 'true' for flushing.
530
+ self::$_rewrote_taxonomy = true;
531
+ }
532
+
533
+ /**
534
+ * Flush rewrite rules ONLY when necessary.
535
+ *
536
+ * @since 1.10.7
537
+ * @return void
538
+ */
539
+ static public function flush_rewrite_rules() {
540
+ global $wp_rewrite;
541
+
542
+ if ( self::$_rewrote_post_type || self::$_rewrote_taxonomy ) {
543
+ // Need to flush (soft) so our custom rules will work.
544
+ $wp_rewrite->flush_rules( false );
545
+ }
546
+
547
+ self::$_rewrote_post_type = false;
548
+ self::$_rewrote_taxonomy = false;
549
  }
550
 
551
  /**
561
  static public function override_canonical( $redirect_url, $requested_url ) {
562
  global $wp_the_query;
563
 
564
+ if ( is_array( $wp_the_query->query ) ) {
565
+ foreach ( $wp_the_query->query as $key => $value ) {
566
+ if ( strpos( $key, 'flpaged' ) === 0 && is_page() && get_option( 'page_on_front' ) ) {
567
  $redirect_url = false;
568
  break;
569
  }
570
  }
571
 
572
+ // Disable canonical on single post pagination for all post types.
573
+ if ( true === $wp_the_query->is_singular
574
+ && - 1 == $wp_the_query->current_post
575
+ && true === $wp_the_query->is_paged
576
+ ) {
577
+ $redirect_url = false;
578
+ }
579
+ }
580
+
581
+ return $redirect_url;
582
+ }
583
 
584
+ /**
585
+ * Theme Builder support - Check to see if current page has Themer layout.
586
+ * Short-circuit default header status handling when paginating on themer layout content.
587
+ *
588
+ * @param bool $prevent_404 Whether to short-circuit default header status handling. Default false.
589
+ * @param object $query WP Query object.
590
+ * @since 1.10.7
591
+ * @return bool
592
+ */
593
+ static public function pre_404_pagination( $prevent_404, $query ) {
594
+ global $wp_actions;
595
+
596
+ if ( ! class_exists( 'FLThemeBuilder' ) ) {
597
+ return false;
598
+ }
599
+
600
+ if ( ! $query->is_paged ) {
601
+ return false;
602
+ }
603
+
604
+ if ( ! $query->is_archive && ! $query->is_home ) {
605
+ return false;
606
+ }
607
+
608
+ $is_global_hack = false;
609
+ $layout_type = '';
610
+
611
+ // Manually set globals since filter `pre_handle_404`
612
+ // doesn't reach `$wp_query->register_globals()`.
613
+ if ( ! isset( $wp_actions['wp'] ) ) {
614
+
615
+ // This would prevent from throwing PHP Notice
616
+ // from FLThemeBuilderRulesLocation::get_current_page_location().
617
+ $wp_actions['wp'] = 1;
618
+
619
+ if ( $query->is_post_type_archive ) {
620
+ $post = new stdClass();
621
+ $post->post_type = $query->get( 'post_type' );
622
+ $GLOBALS['post'] = $post;
623
+ }
624
+
625
+ $is_global_hack = true;
626
  }
627
 
628
+ if ( FLThemeBuilder::has_layout() ) {
629
+
630
+ // Reset the hacks.
631
+ if ( $is_global_hack ) {
632
+ unset( $wp_actions['wp'] );
633
+ $GLOBALS['post'] = null;
634
+ }
635
+
636
+ return true;
637
+ }
638
+
639
+ return false;
640
  }
641
 
642
  /**
646
  * @param object $query An instance of WP_Query.
647
  * @return void
648
  */
649
+ static public function pagination( $query ) {
 
650
  $total_pages = $query->max_num_pages;
651
+ $permalink_structure = get_option( 'permalink_structure' );
652
  $paged = self::get_paged();
653
+ $base = untrailingslashit( html_entity_decode( get_pagenum_link() ) );
654
 
655
+ if ( $total_pages > 1 ) {
656
 
657
+ if ( ! $current_page = $paged ) { // @codingStandardsIgnoreLine
658
  $current_page = 1;
659
  }
660
 
661
+ $base = self::build_base_url( $permalink_structure, $base );
662
+ $format = self::paged_format( $permalink_structure, $base );
 
 
 
 
663
 
664
+ echo paginate_links(array(
665
+ 'base' => $base . '%_%',
666
+ 'format' => $format,
667
+ 'current' => $current_page,
668
+ 'total' => $total_pages,
669
+ 'type' => 'list',
670
+ ));
671
+ }
672
+ }
673
+
674
+ /**
675
+ * Fix our custom pagination link on the single post when permalink structure is set to Plain or default.
676
+ * For some reason WP automatically appending URL parameters to each page link.
677
+ *
678
+ * @param string $link Pagination link
679
+ * @since 1.10.7
680
+ * @return string
681
+ */
682
+ static public function filter_paginate_links( $link ) {
683
+ $permalink_structure = get_option( 'permalink_structure' );
684
+ $base = html_entity_decode( get_pagenum_link() );
685
+
686
+ if ( empty( $permalink_structure ) && strrpos( $base, 'paged-' ) ) {
687
+
688
+ // Compare $link with the current 'paged-' parameter.
689
+ $base_params = wp_parse_url( $base, PHP_URL_QUERY );
690
+ wp_parse_str( $base_params, $base_args );
691
+ $current_paged_args = array_values( preg_grep( '/^paged-(\d+)/', array_keys( $base_args ) ) );
692
+
693
+ if ( ! empty( $current_paged_args ) ) {
694
+ $current_flpaged = $current_paged_args[0];
695
+ $current_paged_param = $current_flpaged . '=' . $base_args[ $current_flpaged ];
696
+
697
+ $link_params = wp_parse_url( $link, PHP_URL_QUERY );
698
+ $link_params = str_replace( $current_paged_param, '' , $link_params );
699
+ wp_parse_str( $link_params, $link_args );
700
+
701
+ $link = strtok( $link, '?' );
702
+ $link = add_query_arg( $link_args, $link );
703
  }
704
+ }
705
+
706
+ return $link;
707
+ }
708
+
709
+ /**
710
+ * Build base URL for our custom pagination.
711
+ *
712
+ * @param string $permalink_structure The current permalink structure.
713
+ * @param string $base The base URL to parse
714
+ * @since 1.10.7
715
+ * @return string
716
+ */
717
+ static public function build_base_url( $permalink_structure, $base ) {
718
+ // Check to see if we are using pretty permalinks
719
+ if ( ! empty( $permalink_structure ) ) {
720
+
721
+ if ( strrpos( $base, 'paged-' ) ) {
722
+ $base = substr_replace( $base, '', strrpos( $base, 'paged-' ), strlen( $base ) );
723
  }
724
 
725
+ // Remove query string from base URL since paginate_links() adds it automatically.
726
+ // This should also fix the WPML pagination issue that was added since 1.10.2.
727
+ if ( count( $_GET ) > 0 ) {
728
+ $base = strtok( $base, '?' );
729
  }
730
 
731
+ $base = untrailingslashit( $base );
732
+
733
+ } else {
734
+ $url_params = wp_parse_url( $base, PHP_URL_QUERY );
735
+
736
+ if ( empty( $url_params ) ) {
737
+ $base = trailingslashit( $base );
738
  }
739
+ }
740
 
741
+ return $base;
742
+ }
 
 
743
 
744
+ /**
745
+ * Build the custom pagination format.
746
+ *
747
+ * @param string $permalink_structure
748
+ * @param string $base
749
+ * @since 1.10.7
750
+ * @return string
751
+ */
752
+ static public function paged_format( $permalink_structure, $base ) {
753
+ if ( self::$loop_counter > 1 ) {
754
+ $page_prefix = 'paged-' . self::$loop_counter;
755
+ } else {
756
+ $page_prefix = empty( $permalink_structure ) ? 'paged' : 'page';
757
+ }
758
+
759
+ if ( ! empty( $permalink_structure ) ) {
760
+ $format = ! empty( $page_prefix ) ? '/' . $page_prefix . '/' : '/';
761
+ $format .= '%#%';
762
+ $format .= substr( $permalink_structure, -1 ) == '/' ? '/' : '';
763
+ } elseif ( empty( $permalink_structure ) || is_search() ) {
764
+ $parse_url = wp_parse_url( $base, PHP_URL_QUERY );
765
+ $format = empty( $parse_url ) ? '?' : '&';
766
+ $format .= $page_prefix . '=%#%';
767
+ }
768
+
769
+ return $format;
770
+ }
771
+
772
+ /**
773
+ * Returns the custom pagination request data.
774
+ *
775
+ * @since 1.10.7
776
+ * @return array|bool
777
+ */
778
+ static public function get_custom_paged() {
779
+ if ( ! empty( self::$custom_paged_data ) ) {
780
+ return self::$custom_paged_data;
781
+ }
782
+
783
+ if ( did_action( 'wp' ) ) {
784
+ global $wp;
785
+ $current_url = home_url( $wp->request );
786
+ } else {
787
+ $current_url = $_SERVER['REQUEST_URI'];
788
+ }
789
+
790
+ // Do a quick test if the current request URL contains the custom `paged-` var
791
+ if ( false === strpos( $current_url, 'paged-' ) ) {
792
+ return false;
793
+ }
794
+
795
+ // Check the current URL if it matches our custom pagination var.
796
+ $paged_matches = preg_match( '/([^.\/]*?)(?:\/)?([^.\/]*?)\/paged-([0-9]{1,})(?:\=|\/)([0-9]{1,})/', $current_url, $matches );
797
+
798
+ if ( $paged_matches ) {
799
+ self::$custom_paged_data = array(
800
+ 'parent_page' => $matches[1],
801
+ 'current_page' => $matches[2],
802
+ 'current_loop' => $matches[3],
803
+ 'paged' => $matches[4],
804
+ );
805
+ }
806
+
807
+ return self::$custom_paged_data;
808
+ }
809
+
810
+ /**
811
+ * Check to see if the posts loop is currently paginated.
812
+ *
813
+ * @since 1.10.7
814
+ * @return bool
815
+ */
816
+ static public function is_paginated_loop() {
817
+ $custom_paged = self::get_custom_paged();
818
+
819
+ if ( ! isset( $custom_paged['current_loop'] ) ) {
820
+ return false;
821
+ }
822
+
823
+ if ( $custom_paged['current_loop'] == self::$loop_counter ) {
824
+ return true;
825
  }
826
+
827
+ return false;
828
  }
829
 
830
  /**
833
  * @since 1.9.5
834
  * @return int
835
  */
836
+ static public function get_paged() {
 
837
  global $wp_the_query, $paged;
838
 
839
  // Check first for custom pagination from post module
840
+ $flpaged = $wp_the_query->get( 'flpaged' );
841
 
842
+ // In case the site is using default permalink structure and it has multiple paginations.
843
+ $permalink_structure = get_option( 'permalink_structure' );
844
+ $base = html_entity_decode( get_pagenum_link() );
845
+
846
+ if ( is_numeric( $flpaged ) && self::is_paginated_loop() ) {
847
  return $flpaged;
848
+ } elseif ( empty( $permalink_structure ) && strrpos( $base, 'paged-' ) && self::$loop_counter > 1 ) {
 
 
 
 
849
 
850
+ $flpaged = 0;
851
+ $url_parts = wp_parse_url( $base, PHP_URL_QUERY );
852
+ wp_parse_str( $url_parts, $url_params );
853
 
854
+ foreach ( $url_params as $paged_key => $paged_val ) {
855
+ $get_paged_loop = explode( '-', $paged_key );
856
+
857
+ if ( false === strpos( $paged_key, 'paged-' ) || ! isset( $get_paged_loop[1] ) ) {
858
+ continue;
859
+ }
860
+
861
+ if ( $get_paged_loop[1] == self::$loop_counter ) {
862
+ $flpaged = $paged_val;
863
+ break;
864
+ }
865
+ }
866
+
867
+ return $flpaged;
868
+ } elseif ( self::$loop_counter > 1 ) {
869
+ // If we have multiple paginations, make sure it won't affect the other loops.
870
+ return 0;
871
  }
872
 
873
  // Check the 'paged' query var.
877
  return $paged_qv;
878
  }
879
 
880
+ // Check the 'page' query var.
881
+ $page_qv = $wp_the_query->get( 'page' );
882
+
883
+ if ( is_numeric( $page_qv ) ) {
884
+ return $page_qv;
885
+ }
886
+
887
  // Check the $paged global?
888
  if ( is_numeric( $paged ) ) {
889
  return $paged;
899
  * @since 1.2.3
900
  * @return array
901
  */
902
+ static public function post_types() {
 
903
  $post_types = get_post_types(array(
904
  'public' => true,
905
+ 'show_ui' => true,
906
  ), 'objects');
907
 
908
+ unset( $post_types['attachment'] );
909
+ unset( $post_types['fl-builder-template'] );
910
+ unset( $post_types['fl-theme-layout'] );
911
 
912
  return $post_types;
913
  }
919
  * @param string $post_type The post type to get taxonomies for.
920
  * @return array
921
  */
922
+ static public function taxonomies( $post_type ) {
923
+ $taxonomies = get_object_taxonomies( $post_type, 'objects' );
 
924
  $data = array();
925
 
926
+ foreach ( $taxonomies as $tax_slug => $tax ) {
927
 
928
+ if ( ! $tax->public || ! $tax->show_ui ) {
929
  continue;
930
  }
931
 
932
+ $data[ $tax_slug ] = $tax;
933
  }
934
 
935
  return apply_filters( 'fl_builder_loop_taxonomies', $data, $taxonomies, $post_type );
942
  * @param string $format The date format to use.
943
  * @return void
944
  */
945
+ static public function post_date( $format = 'default' ) {
 
946
  if ( 'default' == $format ) {
947
  $format = get_option( 'date_format' );
948
  }
961
  * @param object $settings
962
  * @return void
963
  */
964
+ static public function render_match_select( $name, $value, $field, $settings ) {
 
965
  if ( ! isset( $field['matching'] ) || ! $field['matching'] ) {
966
  return;
967
  }
classes/class-fl-builder-model.php CHANGED
@@ -16,15 +16,15 @@ final class FLBuilderModel {
16
  * @var array $row_layouts
17
  */
18
  static public $row_layouts = array(
19
- '1-col' => array(100),
20
- '2-cols' => array(50, 50),
21
- '3-cols' => array(33.33, 33.33, 33.33),
22
- '4-cols' => array(25, 25, 25, 25),
23
- '5-cols' => array(20, 20, 20, 20, 20),
24
- '6-cols' => array(16.65, 16.65, 16.65, 16.65, 16.65, 16.65),
25
- 'left-sidebar' => array(33.33, 66.66),
26
- 'right-sidebar' => array(66.66, 33.33),
27
- 'left-right-sidebar' => array(25, 50, 25)
28
  );
29
 
30
  /**
@@ -173,22 +173,21 @@ final class FLBuilderModel {
173
  * @since 1.8
174
  * @return void
175
  */
176
- static public function init()
177
- {
178
  /* Admin AJAX */
179
- add_action('wp_ajax_fl_builder_disable', __CLASS__ . '::disable');
180
- add_action('wp_ajax_fl_builder_duplicate_wpml_layout', __CLASS__ . '::duplicate_wpml_layout');
181
 
182
  /* Actions */
183
- add_action('init', __CLASS__ . '::load_settings', 1);
184
- add_action('init', __CLASS__ . '::load_modules', 2);
185
- add_action('before_delete_post', __CLASS__ . '::delete_post');
186
- add_action('save_post', __CLASS__ . '::save_revision');
187
- add_action('save_post', __CLASS__ . '::set_node_template_default_type', 10, 3);
188
- add_action('wp_restore_post_revision', __CLASS__ . '::restore_revision', 10, 2);
189
 
190
  /* Filters */
191
- add_filter('heartbeat_received', __CLASS__ . '::lock_post', 10, 2);
192
 
193
  /* Core Templates */
194
  self::register_core_templates();
@@ -201,12 +200,10 @@ final class FLBuilderModel {
201
  * @param int $post_id The post id to get an edit url for.
202
  * @return string
203
  */
204
- static public function get_edit_url( $post_id = false )
205
- {
206
  if ( false === $post_id ) {
207
  global $post;
208
- }
209
- else {
210
  $post = get_post( $post_id );
211
  }
212
 
@@ -222,8 +219,7 @@ final class FLBuilderModel {
222
  * @param array $params An array of key/value params to add to the query string.
223
  * @return string
224
  */
225
- static public function get_upgrade_url( $params = array() )
226
- {
227
  return apply_filters( 'fl_builder_upgrade_url', self::get_store_url( '', $params ) );
228
  }
229
 
@@ -235,8 +231,7 @@ final class FLBuilderModel {
235
  * @param array $params An array of key/value params to add to the query string.
236
  * @return string
237
  */
238
- static public function get_store_url( $path = '', $params = array() )
239
- {
240
  $url = trailingslashit( FL_BUILDER_STORE_URL . $path ) . '?' . http_build_query( $params, '', '&' );
241
 
242
  return apply_filters( 'fl_builder_store_url', $url, $path );
@@ -249,13 +244,12 @@ final class FLBuilderModel {
249
  * @since 1.0
250
  * @return array
251
  */
252
- static public function get_post_data()
253
- {
254
- if(!self::$post_data) {
255
 
256
  self::$post_data = array();
257
 
258
- if(isset($_POST['fl_builder_data'])) {
259
 
260
  // Decode settings if our ModSecurity fix is enabled.
261
  if ( isset( $_POST['fl_builder_data']['settings'] ) ) {
@@ -267,14 +261,13 @@ final class FLBuilderModel {
267
 
268
  $data = FLBuilderUtils::json_decode_deep( wp_unslash( $_POST['fl_builder_data'] ) );
269
 
270
- foreach($data as $key => $val) {
271
- self::$post_data[$key] = $val;
272
  }
273
- }
274
- else if(isset($_POST)) {
275
 
276
- foreach($_POST as $key => $val) {
277
- self::$post_data[$key] = $val;
278
  }
279
  }
280
  }
@@ -290,10 +283,9 @@ final class FLBuilderModel {
290
  * @param mixed $value The value to update.
291
  * @return void
292
  */
293
- static public function update_post_data($key, $value)
294
- {
295
  $post_data = self::get_post_data();
296
- $post_data[$key] = $value;
297
  self::$post_data = $post_data;
298
  }
299
 
@@ -304,14 +296,12 @@ final class FLBuilderModel {
304
  * @since 1.0
305
  * @return array
306
  */
307
- static public function get_post_types()
308
- {
309
  $value = self::get_admin_settings_option( '_fl_builder_post_types', true );
310
 
311
  if ( ! $value ) {
312
  $value = array( 'page', 'fl-builder-template' );
313
- }
314
- else {
315
  $value[] = 'fl-builder-template';
316
  }
317
 
@@ -325,9 +315,8 @@ final class FLBuilderModel {
325
  * @since 1.0
326
  * @return array
327
  */
328
- static public function get_global_posts()
329
- {
330
- return apply_filters('fl_builder_global_posts', array());
331
  }
332
 
333
  /**
@@ -339,8 +328,7 @@ final class FLBuilderModel {
339
  * @param int $post_id
340
  * @return void
341
  */
342
- static public function set_post_id( $post_id )
343
- {
344
  array_unshift( self::$post_id, $post_id );
345
  }
346
 
@@ -353,8 +341,7 @@ final class FLBuilderModel {
353
  * @since 1.10
354
  * @return void
355
  */
356
- static public function reset_post_id()
357
- {
358
  array_shift( self::$post_id );
359
  }
360
 
@@ -365,8 +352,7 @@ final class FLBuilderModel {
365
  * @since 1.0
366
  * @return int|bool The post id or false.
367
  */
368
- static public function get_post_id()
369
- {
370
  global $wp_the_query;
371
  global $post;
372
 
@@ -374,21 +360,17 @@ final class FLBuilderModel {
374
 
375
  // Get a post ID from the internal $post_id array if not empty.
376
  if ( ! empty( self::$post_id ) ) {
377
- return self::$post_id[ 0 ];
378
- }
379
- // Get a post ID sent in an AJAX request.
380
- else if ( isset( $post_data['post_id'] ) ) {
381
  return $post_data['post_id'];
382
- }
383
- // Get a post ID from the main query.
384
- else if ( in_the_loop() && is_main_query() && isset( $wp_the_query->post ) ) {
385
  return $wp_the_query->post->ID;
386
- }
387
- // Get a post ID in a query outside of the main loop.
388
- else if ( isset( $post ) ) {
389
  return $post->ID;
390
- }
391
- // No post ID found.
392
  else {
393
  return false;
394
  }
@@ -401,8 +383,7 @@ final class FLBuilderModel {
401
  * @since 1.6.3
402
  * @return object
403
  */
404
- static public function get_post()
405
- {
406
  return get_post( self::get_post_id() );
407
  }
408
 
@@ -412,15 +393,12 @@ final class FLBuilderModel {
412
  * @since 1.0
413
  * @return bool
414
  */
415
- static public function is_ssl()
416
- {
417
  if ( is_ssl() ) {
418
  return true;
419
- }
420
- else if ( 0 === stripos( get_option( 'siteurl' ), 'https://' ) ) {
421
  return true;
422
- }
423
- else if ( isset( $_SERVER['HTTP_X_FORWARDED_PROTO'] ) && 'https' == $_SERVER['HTTP_X_FORWARDED_PROTO'] ) {
424
  return true;
425
  }
426
 
@@ -434,8 +412,7 @@ final class FLBuilderModel {
434
  * @since 1.0
435
  * @return bool
436
  */
437
- static public function is_post_editable()
438
- {
439
  global $wp_the_query;
440
 
441
  $editable = false;
@@ -461,13 +438,12 @@ final class FLBuilderModel {
461
  * @since 1.0
462
  * @return void
463
  */
464
- static public function lock_post($response, $data)
465
- {
466
- if(isset($data['fl_builder_post_lock'])) {
467
 
468
  require_once ABSPATH . 'wp-admin/includes/post.php';
469
 
470
- wp_set_post_lock($data['fl_builder_post_lock']['post_id']);
471
  }
472
  }
473
 
@@ -478,23 +454,20 @@ final class FLBuilderModel {
478
  * @since 1.0
479
  * @return bool
480
  */
481
- static public function is_builder_enabled()
482
- {
483
  $post_id = self::get_post_id();
484
 
485
- if(!is_admin() && post_password_required($post_id)) {
486
  return false;
487
- }
488
- else if(self::is_builder_active()) {
489
  return true;
490
- }
491
- else {
492
 
493
  $post_types = self::get_post_types();
494
- $post = get_post($post_id);
495
 
496
- if($post && in_array($post->post_type, $post_types)) {
497
- return get_post_meta($post->ID, '_fl_builder_enabled', true);
498
  }
499
  }
500
 
@@ -508,8 +481,7 @@ final class FLBuilderModel {
508
  * @since 1.0
509
  * @return bool
510
  */
511
- static public function is_builder_active()
512
- {
513
  global $wp_the_query;
514
  global $post;
515
 
@@ -518,11 +490,9 @@ final class FLBuilderModel {
518
 
519
  if ( null !== self::$active ) {
520
  return self::$active;
521
- }
522
- else if ( ! is_admin() && is_singular() && $query_id != $post_id ) {
523
  self::$active = false;
524
- }
525
- else if ( self::is_post_editable() && ! is_admin() && ! post_password_required() ) {
526
  $post_data = self::get_post_data();
527
  self::$active = isset( $_GET['fl_builder'] ) || isset( $post_data['fl_builder'] );
528
  }
@@ -537,8 +507,7 @@ final class FLBuilderModel {
537
  * @since 1.4.9
538
  * @return bool
539
  */
540
- static public function is_new_user()
541
- {
542
  if ( self::is_builder_active() ) {
543
 
544
  $current_user = wp_get_current_user();
@@ -561,8 +530,7 @@ final class FLBuilderModel {
561
  * @since 1.0
562
  * @return string
563
  */
564
- static public function get_node_status()
565
- {
566
  return self::is_builder_active() ? 'draft' : 'published';
567
  }
568
 
@@ -572,9 +540,8 @@ final class FLBuilderModel {
572
  * @since 1.0
573
  * @return void
574
  */
575
- static public function enable()
576
- {
577
- update_post_meta(self::get_post_id(), '_fl_builder_enabled', true);
578
  }
579
 
580
  /**
@@ -583,9 +550,8 @@ final class FLBuilderModel {
583
  * @since 1.0
584
  * @return void
585
  */
586
- static public function disable()
587
- {
588
- update_post_meta(self::get_post_id(), '_fl_builder_enabled', false);
589
  }
590
 
591
  /**
@@ -594,8 +560,7 @@ final class FLBuilderModel {
594
  * @since 1.0
595
  * @return void
596
  */
597
- static public function enable_editing()
598
- {
599
  global $wp_the_query;
600
 
601
  if ( self::is_post_editable() && is_object( $wp_the_query->post ) ) {
@@ -614,9 +579,8 @@ final class FLBuilderModel {
614
  $settings->text = wpautop( $post->post_content );
615
 
616
  self::add_module( 'rich-text', $settings, $col->node );
617
- }
618
- // Create a new draft?
619
- else if ( empty( $draft ) ) {
620
  self::update_layout_data( $published, 'draft', $post->ID );
621
  self::update_layout_settings( self::get_layout_settings( 'published' ), 'draft', $post->ID );
622
  }
@@ -640,13 +604,12 @@ final class FLBuilderModel {
640
  * @since 1.0
641
  * @return array
642
  */
643
- static public function get_upload_dir()
644
- {
645
  $wp_info = wp_upload_dir();
646
  $dir_name = basename( FL_BUILDER_DIR );
647
 
648
  // We use bb-plugin for the lite version as well.
649
- if ( $dir_name == 'beaver-builder-lite-version' ) {
650
  $dir_name = 'bb-plugin';
651
  }
652
 
@@ -658,7 +621,7 @@ final class FLBuilderModel {
658
  // Build the paths.
659
  $dir_info = array(
660
  'path' => $wp_info['basedir'] . '/' . $dir_name . '/',
661
- 'url' => $wp_info['baseurl'] . '/' . $dir_name . '/'
662
  );
663
 
664
  // Create the upload dir if it doesn't exist.
@@ -682,8 +645,7 @@ final class FLBuilderModel {
682
  * @param string $name The name of the cache directory to get paths for.
683
  * @return array
684
  */
685
- static public function get_cache_dir( $name = 'cache' )
686
- {
687
  $upload_info = self::get_upload_dir();
688
  $allowed = array( 'cache', 'icons' );
689
 
@@ -695,11 +657,11 @@ final class FLBuilderModel {
695
  // Build the paths.
696
  $dir_info = array(
697
  'path' => $upload_info['path'] . $name . '/',
698
- 'url' => $upload_info['url'] . $name . '/'
699
  );
700
 
701
  // Create the cache dir if it doesn't exist.
702
- if( ! file_exists( $dir_info['path'] ) ) {
703
 
704
  // Create the directory.
705
  mkdir( $dir_info['path'] );
@@ -720,16 +682,14 @@ final class FLBuilderModel {
720
  * @since 1.0
721
  * @return string
722
  */
723
- static public function get_asset_version()
724
- {
725
  $post_id = self::get_post_id();
726
  $active = self::is_builder_active();
727
 
728
- if($active) {
729
- return md5(uniqid());
730
- }
731
- else {
732
- return md5(get_post_modified_time('U', false, $post_id));
733
  }
734
  }
735
 
@@ -740,31 +700,28 @@ final class FLBuilderModel {
740
  * @since 1.0
741
  * @return array
742
  */
743
- static public function get_asset_info()
744
- {
745
  $post_data = self::get_post_data();
746
  $post_id = self::get_post_id();
747
  $cache_dir = self::get_cache_dir();
748
 
749
- if(isset($post_data['node_preview'])) {
750
  $suffix = '-layout-preview';
751
- }
752
- else if(self::is_builder_active()) {
753
  $suffix = '-layout-draft';
754
- }
755
- else {
756
  $suffix = '-layout';
757
  }
758
 
759
  $info = array(
760
  'css' => $cache_dir['path'] . $post_id . $suffix . '.css',
761
- 'css_url' => $cache_dir['url'] . $post_id . $suffix . '.css',
762
  'css_partial' => $cache_dir['path'] . $post_id . $suffix . '-partial.css',
763
- 'css_partial_url' => $cache_dir['url'] . $post_id . $suffix . '-partial.css',
764
  'js' => $cache_dir['path'] . $post_id . $suffix . '.js',
765
- 'js_url' => $cache_dir['url'] . $post_id . $suffix . '.js',
766
  'js_partial' => $cache_dir['path'] . $post_id . $suffix . '-partial.js',
767
- 'js_partial_url' => $cache_dir['url'] . $post_id . $suffix . '-partial.js'
768
  );
769
 
770
  return $info;
@@ -779,8 +736,7 @@ final class FLBuilderModel {
779
  * @param string $type The type of cache to delete. Either css or js.
780
  * @return void
781
  */
782
- static public function delete_asset_cache( $type = false )
783
- {
784
  $info = self::get_asset_info();
785
  $types = $type ? array( $type ) : array( 'css', 'css_partial', 'js', 'js_partial' );
786
 
@@ -801,8 +757,7 @@ final class FLBuilderModel {
801
  * @param int $post_id
802
  * @return void
803
  */
804
- static public function delete_all_asset_cache( $post_id = false )
805
- {
806
  $post_id = $post_id ? $post_id : self::get_post_id();
807
  $cache_dir = self::get_cache_dir();
808
 
@@ -820,7 +775,7 @@ final class FLBuilderModel {
820
  $cache_dir['path'] . $post_id . '-layout-preview.js',
821
  $cache_dir['path'] . $post_id . '-layout-partial.js',
822
  $cache_dir['path'] . $post_id . '-layout-draft-partial.js',
823
- $cache_dir['path'] . $post_id . '-layout-preview-partial.js'
824
  );
825
 
826
  foreach ( $paths as $path ) {
@@ -839,12 +794,11 @@ final class FLBuilderModel {
839
  * @param int $post_id
840
  * @return void
841
  */
842
- static public function delete_node_template_asset_cache( $post_id = false )
843
- {
844
  $posts = self::get_posts_with_global_node_template( $post_id );
845
 
846
  if ( ! empty( $posts ) ) {
847
- foreach( $posts as $post ) {
848
  self::delete_all_asset_cache( $post->ID );
849
  }
850
  }
@@ -856,8 +810,7 @@ final class FLBuilderModel {
856
  * @since 1.6.3
857
  * @return void
858
  */
859
- static public function delete_asset_cache_for_all_posts()
860
- {
861
  $cache_dir = self::get_cache_dir();
862
  $css = glob( $cache_dir['path'] . '*.css' );
863
  $js = glob( $cache_dir['path'] . '*.js' );
@@ -877,11 +830,10 @@ final class FLBuilderModel {
877
  * @since 1.0
878
  * @return string
879
  */
880
- static public function generate_node_id()
881
- {
882
  $node_id = uniqid();
883
 
884
- if($node_id == self::$last_generated_node_id) {
885
  return self::generate_node_id();
886
  }
887
 
@@ -897,24 +849,23 @@ final class FLBuilderModel {
897
  * @param array $data An array of node data.
898
  * @return array
899
  */
900
- static public function generate_new_node_ids($data)
901
- {
902
  $map = array();
903
  $nodes = array();
904
 
905
  // Map the new node ids to the old.
906
- foreach($data as $node_id => $node) {
907
- $map[$node_id] = self::generate_node_id();
908
  }
909
 
910
  // Replace the old node ids.
911
- foreach($data as $node_id => $node) {
912
 
913
- $nodes[$map[$node_id]] = $node;
914
- $nodes[$map[$node_id]]->node = $map[$node_id];
915
 
916
- if(!empty($node->parent) && isset($map[$node->parent])) {
917
- $nodes[$map[$node_id]]->parent = $map[$node->parent];
918
  }
919
  }
920
 
@@ -929,12 +880,10 @@ final class FLBuilderModel {
929
  * @param string $status The node status. Either draft or published.
930
  * @return object
931
  */
932
- static public function get_node( $node_id = null, $status = null )
933
- {
934
  if ( is_object( $node_id ) ) {
935
  $node = $node_id;
936
- }
937
- else {
938
  $data = self::get_layout_data( $status );
939
  $node = isset( $data[ $node_id ] ) ? $data[ $node_id ] : null;
940
  }
@@ -955,24 +904,21 @@ final class FLBuilderModel {
955
  * @param string $status The node status. Either draft or published.
956
  * @return array
957
  */
958
- static public function get_nodes( $type = null, $parent_id = null, $status = null )
959
- {
960
  $parent = is_object( $parent_id ) ? $parent_id : self::get_node( $parent_id );
961
  $nodes = array();
962
 
963
  // Get the layout data.
964
  if ( ! $parent ) {
965
  $data = self::get_layout_data( $status );
966
- }
967
- else {
968
  $data = self::get_child_nodes( $parent, $status );
969
  }
970
 
971
  // Return all nodes?
972
  if ( ! $type ) {
973
  $nodes = $data;
974
- }
975
- // Return nodes of a certain type.
976
  else {
977
 
978
  foreach ( $data as $node_id => $node ) {
@@ -1006,14 +952,12 @@ final class FLBuilderModel {
1006
  * @param string $status The node status. Either draft or published.
1007
  * @return object
1008
  */
1009
- static public function get_node_parent( $node_id = null, $status = null )
1010
- {
1011
  $parent = null;
1012
 
1013
  if ( is_object( $node_id ) ) {
1014
  $node = $node_id;
1015
- }
1016
- else {
1017
  $node = self::get_node( $node_id, $status );
1018
  }
1019
 
@@ -1039,8 +983,7 @@ final class FLBuilderModel {
1039
  * @param string $type The type of parent to return. Either "column", "column-group" or "row".
1040
  * @return object The parent node.
1041
  */
1042
- static public function get_node_parent_by_type( $node, $type = '' )
1043
- {
1044
  // Get node object if node ID set
1045
  if ( ! is_object( $node ) ) {
1046
  $node = self::get_node( $node );
@@ -1118,7 +1061,6 @@ final class FLBuilderModel {
1118
  if ( $break_while ) {
1119
  break; // From while
1120
  }
1121
-
1122
  } else {
1123
  break; // From while
1124
  }
@@ -1136,8 +1078,7 @@ final class FLBuilderModel {
1136
  * @param string $status The node status. Either draft or published.
1137
  * @return array
1138
  */
1139
- static public function get_child_nodes( $parent_id, $status = null )
1140
- {
1141
  $parent = is_object( $parent_id ) ? $parent_id : self::get_node( $parent_id );
1142
  $template_post_id = self::is_node_global( $parent );
1143
  $status = $template_post_id && ! self::is_post_node_template() ? 'published' : $status;
@@ -1161,8 +1102,7 @@ final class FLBuilderModel {
1161
  * @param string $parent_id The parent node id.
1162
  * @return array
1163
  */
1164
- static public function get_nested_nodes( $parent_id )
1165
- {
1166
  $children = self::get_child_nodes( $parent_id );
1167
 
1168
  foreach ( $children as $child_id => $child ) {
@@ -1194,8 +1134,7 @@ final class FLBuilderModel {
1194
  * @since 1.6.3
1195
  * @return array
1196
  */
1197
- static public function get_categorized_nodes()
1198
- {
1199
  $nodes = array(
1200
  'rows' => array(),
1201
  'groups' => array(),
@@ -1205,8 +1144,7 @@ final class FLBuilderModel {
1205
 
1206
  if ( self::is_post_user_template( 'module' ) ) {
1207
  $nodes['modules'] = self::get_all_modules();
1208
- }
1209
- else {
1210
  $rows = self::get_nodes( 'row' );
1211
 
1212
  foreach ( $rows as $row ) {
@@ -1233,8 +1171,7 @@ final class FLBuilderModel {
1233
  if ( $module ) {
1234
  $nodes['modules'][ $col_child->node ] = $module;
1235
  }
1236
- }
1237
- else if ( 'column-group' == $col_child->type ) {
1238
 
1239
  $nodes['groups'][ $col_child->node ] = $col_child;
1240
  $group_cols = self::get_nodes( 'column', $col_child );
@@ -1251,9 +1188,9 @@ final class FLBuilderModel {
1251
  }
1252
  }
1253
  }
1254
- }
1255
- }
1256
- }
1257
 
1258
  return $nodes;
1259
  }
@@ -1266,8 +1203,7 @@ final class FLBuilderModel {
1266
  * @param object $node A node object.
1267
  * @return object
1268
  */
1269
- static public function get_node_settings($node)
1270
- {
1271
  $post_data = self::get_post_data();
1272
 
1273
  // Get the node settings for a node template's root node?
@@ -1279,21 +1215,19 @@ final class FLBuilderModel {
1279
  }
1280
 
1281
  // Get either the preview settings or saved node settings merged with the defaults.
1282
- if(isset($post_data['node_preview']) && isset($post_data['node_id']) && $post_data['node_id'] == $node->node) {
1283
 
1284
- if(!isset($post_data['node_preview_processed_settings'])) {
1285
  $settings = $post_data['node_preview'];
1286
- $settings = (object)array_merge((array)$node->settings, (array)$settings);
1287
- $settings = self::process_node_settings($node, $settings);
1288
- self::update_post_data('node_preview_processed_settings', $settings);
1289
- }
1290
- else {
1291
  $settings = $post_data['node_preview_processed_settings'];
1292
  }
1293
- }
1294
- else {
1295
- $defaults = self::get_node_defaults($node);
1296
- $settings = (object)array_merge((array)$defaults, (array)$node->settings);
1297
 
1298
  if ( 'module' == $node->type ) {
1299
  $settings = self::merge_nested_module_defaults( $node->settings->type, $settings );
@@ -1312,16 +1246,15 @@ final class FLBuilderModel {
1312
  * @param object $new_settings The new node settings.
1313
  * @return object
1314
  */
1315
- static public function process_node_settings($node, $new_settings)
1316
- {
1317
- if($node->type == 'row') {
1318
- $new_settings = self::process_row_settings($node, $new_settings);
1319
  }
1320
- if($node->type == 'column') {
1321
- $new_settings = self::process_col_settings($node, $new_settings);
1322
  }
1323
- if($node->type == 'module') {
1324
- $new_settings = self::process_module_settings($node, $new_settings);
1325
  }
1326
 
1327
  return $new_settings;
@@ -1334,18 +1267,15 @@ final class FLBuilderModel {
1334
  * @param object $node A node object.
1335
  * @return object
1336
  */
1337
- static public function get_node_defaults($node)
1338
- {
1339
  $defaults = array();
1340
 
1341
- if($node->type == 'row') {
1342
  $defaults = self::get_row_defaults();
1343
- }
1344
- else if($node->type == 'column') {
1345
  $defaults = self::get_col_defaults();
1346
- }
1347
- else if($node->type == 'module') {
1348
- $defaults = self::get_module_defaults($node->settings->type);
1349
  }
1350
 
1351
  return $defaults;
@@ -1359,9 +1289,8 @@ final class FLBuilderModel {
1359
  * @param int $b The second position.
1360
  * @return int
1361
  */
1362
- static public function order_nodes($a, $b)
1363
- {
1364
- return (int)$a->position - (int)$b->position;
1365
  }
1366
 
1367
  /**
@@ -1372,9 +1301,8 @@ final class FLBuilderModel {
1372
  * @param string $parent_id The parent node id.
1373
  * @return int
1374
  */
1375
- static public function count_nodes($type = 'row', $parent_id = null)
1376
- {
1377
- return count(self::get_nodes($type, $parent_id));
1378
  }
1379
 
1380
  /**
@@ -1386,10 +1314,9 @@ final class FLBuilderModel {
1386
  * @param string $parent_id The parent node id.
1387
  * @return int
1388
  */
1389
- static public function next_node_position($type = 'row', $parent_id = null)
1390
- {
1391
- $nodes = self::get_nodes($type, $parent_id);
1392
- $last = array_pop($nodes);
1393
 
1394
  return $last ? $last->position + 1 : 0;
1395
  }
@@ -1401,13 +1328,12 @@ final class FLBuilderModel {
1401
  * @param string $node_id The ID of the node to delete.
1402
  * @return void
1403
  */
1404
- static public function delete_node( $node_id = null )
1405
- {
1406
  // Get the layout data.
1407
  $data = self::get_layout_data();
1408
 
1409
  // Return if the node doesn't exist.
1410
- if ( ! isset( $data[ $node_id] ) ) {
1411
  return;
1412
  }
1413
 
@@ -1446,8 +1372,7 @@ final class FLBuilderModel {
1446
  * @param object $data The data array to delete from.
1447
  * @return void
1448
  */
1449
- static public function delete_child_nodes_from_data( $parent = null, &$data )
1450
- {
1451
  $children = self::get_nodes( null, $parent );
1452
 
1453
  foreach ( $children as $child_id => $child ) {
@@ -1471,10 +1396,9 @@ final class FLBuilderModel {
1471
  * @param object $node A module node.
1472
  * @return void
1473
  */
1474
- static public function call_module_delete($node)
1475
- {
1476
- if($node->type == 'module' && isset(self::$modules[$node->settings->type])) {
1477
- $class = get_class(self::$modules[$node->settings->type]);
1478
  $instance = new $class();
1479
  $instance->settings = $node->settings;
1480
  $instance->delete();
@@ -1491,36 +1415,35 @@ final class FLBuilderModel {
1491
  * @param string $type The type of node to order.
1492
  * @return void
1493
  */
1494
- static public function reorder_node($node_id = null, $position = 0)
1495
- {
1496
  $data = self::get_layout_data();
1497
- $node = $data[$node_id];
1498
  $type = ! $node->parent ? $node->type : null;
1499
- $nodes = self::get_nodes($type, $node->parent);
1500
  $new_pos = 0;
1501
 
1502
  // Make sure node positions start at zero.
1503
- foreach($nodes as $node) {
1504
- $data[$node->node]->position = $new_pos;
1505
  $new_pos++;
1506
  }
1507
 
1508
  // Get the node and remove it from the array.
1509
- $node = $data[$node_id];
1510
- $removed = array_splice($nodes, $node->position, 1);
1511
  $new_pos = 0;
1512
 
1513
  // Reposition it in the array.
1514
- array_splice($nodes, $position, 0, $removed);
1515
 
1516
  // Update the position data.
1517
- foreach($nodes as $node) {
1518
- $data[$node->node]->position = $new_pos;
1519
  $new_pos++;
1520
  }
1521
 
1522
  // Update the layout data.
1523
- self::update_layout_data($data);
1524
  }
1525
 
1526
  /**
@@ -1532,12 +1455,11 @@ final class FLBuilderModel {
1532
  * @param int $position The position in the new parent.
1533
  * @return void
1534
  */
1535
- static public function move_node($node_id = null, $new_parent_id = null, $position = 0)
1536
- {
1537
  $data = self::get_layout_data();
1538
- $new_parent = self::get_node($new_parent_id);
1539
- $node = self::get_node($node_id);
1540
- $siblings = self::get_nodes(null, $node->parent);
1541
  $sibling_pos = 0;
1542
 
1543
  // Set the node's new parent.
@@ -1553,10 +1475,10 @@ final class FLBuilderModel {
1553
  }
1554
 
1555
  // Update the layout data.
1556
- self::update_layout_data($data);
1557
 
1558
  // Set the node's new order.
1559
- self::reorder_node($node_id, $position);
1560
  }
1561
 
1562
  /**
@@ -1567,33 +1489,32 @@ final class FLBuilderModel {
1567
  * @param int $position The position of the new row.
1568
  * @return object The new row object.
1569
  */
1570
- static public function add_row($cols = '1-col', $position = false)
1571
- {
1572
  $data = self::get_layout_data();
1573
  $settings = self::get_row_defaults();
1574
  $row_node_id = self::generate_node_id();
1575
 
1576
  // Add the row.
1577
- $data[$row_node_id] = new StdClass();
1578
- $data[$row_node_id]->node = $row_node_id;
1579
- $data[$row_node_id]->type = 'row';
1580
- $data[$row_node_id]->parent = null;
1581
- $data[$row_node_id]->position = self::next_node_position('row');
1582
- $data[$row_node_id]->settings = $settings;
1583
 
1584
  // Update the layout data.
1585
- self::update_layout_data($data);
1586
 
1587
  // Position the row.
1588
- if($position !== false) {
1589
- self::reorder_node($row_node_id, $position);
1590
  }
1591
 
1592
  // Add a column group.
1593
- self::add_col_group($row_node_id, $cols, 0);
1594
 
1595
  // Return the updated row.
1596
- return self::get_node($row_node_id);
1597
  }
1598
 
1599
  /**
@@ -1603,8 +1524,7 @@ final class FLBuilderModel {
1603
  * @param string $node_id Node ID of the row to copy.
1604
  * @return void
1605
  */
1606
- static public function copy_row( $node_id = null )
1607
- {
1608
  $layout_data = self::get_layout_data();
1609
  $row = self::get_node( $node_id );
1610
  $new_row_id = self::generate_node_id();
@@ -1641,8 +1561,7 @@ final class FLBuilderModel {
1641
 
1642
  if ( 'module' == $node->type ) {
1643
  $new_nodes[ $node->node ]->settings = self::clone_module_settings( $node->settings );
1644
- }
1645
- else if ( 'column-group' == $node->type ) {
1646
 
1647
  $nested_cols = self::get_nodes( 'column', $node );
1648
 
@@ -1660,14 +1579,14 @@ final class FLBuilderModel {
1660
  }
1661
  }
1662
  }
1663
- }
1664
 
1665
  // Generate new child ids.
1666
  $new_nodes = self::generate_new_node_ids( $new_nodes );
1667
 
1668
  // Set col group parent ids to the new row id and unset template data.
1669
  foreach ( $new_nodes as $child_node_id => $child ) {
1670
- if ( $child->type == 'column-group' ) {
1671
  if ( $child->parent == $row->node || ( isset( $row->template_node_id ) && $child->parent == $row->template_node_id ) ) {
1672
  $new_nodes[ $child_node_id ]->parent = $new_row_id;
1673
  }
@@ -1697,8 +1616,7 @@ final class FLBuilderModel {
1697
  * @since 1.0
1698
  * @return object
1699
  */
1700
- static public function get_row_defaults()
1701
- {
1702
  return self::get_settings_form_defaults( 'row' );
1703
  }
1704
 
@@ -1709,8 +1627,7 @@ final class FLBuilderModel {
1709
  * @since 1.9
1710
  * @return array
1711
  */
1712
- static public function get_row_spacing_placeholders()
1713
- {
1714
  $settings = FLBuilderModel::get_global_settings();
1715
  $placeholders = array();
1716
 
@@ -1725,11 +1642,9 @@ final class FLBuilderModel {
1725
  // Responsive row margins.
1726
  if ( '' != $settings->row_margins_responsive ) {
1727
  $placeholders['row_margins_responsive'] = $settings->row_margins_responsive;
1728
- }
1729
- else if ( $settings->auto_spacing ) {
1730
  $placeholders['row_margins_responsive'] = 0;
1731
- }
1732
- else {
1733
  $placeholders['row_margins_responsive'] = $placeholders['row_margins_medium'];
1734
  }
1735
 
@@ -1737,12 +1652,10 @@ final class FLBuilderModel {
1737
  if ( '' != $settings->row_padding_responsive ) {
1738
  $placeholders['row_padding_tb_responsive'] = $settings->row_padding_responsive;
1739
  $placeholders['row_padding_lr_responsive'] = $settings->row_padding_responsive;
1740
- }
1741
- else if ( $settings->auto_spacing ) {
1742
  $placeholders['row_padding_tb_responsive'] = $placeholders['row_padding_medium'];
1743
  $placeholders['row_padding_lr_responsive'] = 0;
1744
- }
1745
- else {
1746
  $placeholders['row_padding_tb_responsive'] = $placeholders['row_padding_medium'];
1747
  $placeholders['row_padding_lr_responsive'] = $placeholders['row_padding_medium'];
1748
  }
@@ -1758,20 +1671,18 @@ final class FLBuilderModel {
1758
  * @param object $new_settings The new settings object.
1759
  * @return object
1760
  */
1761
- static public function process_row_settings( $row, $new_settings )
1762
- {
1763
  // Cache background video data.
1764
- if ( $new_settings->bg_type == 'video' ) {
1765
 
1766
  // Video Fallback Photo
1767
  if ( ! empty( $new_settings->bg_video_fallback_src ) ) {
1768
  $fallback = $new_settings->bg_video_fallback_src;
1769
- }
1770
- else {
1771
  $fallback = '';
1772
  }
1773
 
1774
- if ( $new_settings->bg_video_source == 'wordpress' ) {
1775
  // Video MP4
1776
  $mp4 = FLBuilderPhoto::get_attachment_data( $new_settings->bg_video );
1777
 
@@ -1795,10 +1706,10 @@ final class FLBuilderModel {
1795
  }
1796
 
1797
  // Cache background slideshow data.
1798
- if($new_settings->bg_type == 'slideshow' && $new_settings->ss_source == 'wordpress') {
1799
 
1800
  // Make sure we have a photo data object.
1801
- if(!isset($row->settings->ss_photo_data)) {
1802
  $row->settings->ss_photo_data = new StdClass();
1803
  }
1804
 
@@ -1820,16 +1731,15 @@ final class FLBuilderModel {
1820
  * @param object $row A row node.
1821
  * @return object
1822
  */
1823
- static public function get_row_bg_data( $row )
1824
- {
1825
  $data = null;
1826
 
1827
  // Background Video
1828
- if ( $row->settings->bg_type == 'video' ) {
1829
 
1830
  if ( isset( $row->settings->bg_video_data ) ) {
1831
  $data = array();
1832
- $data[ 'mp4' ] = $row->settings->bg_video_data;
1833
  }
1834
  if ( isset( $row->settings->bg_video_webm_data ) ) {
1835
 
@@ -1837,12 +1747,10 @@ final class FLBuilderModel {
1837
  $data = array();
1838
  }
1839
 
1840
- $data[ 'webm' ] = $row->settings->bg_video_webm_data;
1841
  }
1842
- }
1843
-
1844
- // Background Slideshow
1845
- else if ( $row->settings->bg_type == 'slideshow' && isset( $row->settings->ss_photo_data ) ) {
1846
  $data = $row->settings->ss_photo_data;
1847
  }
1848
 
@@ -1856,10 +1764,9 @@ final class FLBuilderModel {
1856
  * @param object $row A row node.
1857
  * @return string
1858
  */
1859
- static public function get_row_slideshow_source($row)
1860
- {
1861
  // Make sure we have a photo data object.
1862
- if(!isset($row->settings->ss_photo_data)) {
1863
  $row->settings->ss_photo_data = new StdClass();
1864
  }
1865
 
@@ -1884,48 +1791,46 @@ final class FLBuilderModel {
1884
  * @param int $position The position of the new column group.
1885
  * @return object The new column group object.
1886
  */
1887
- static public function add_col_group($node_id = null, $cols = '1-col', $position = false)
1888
- {
1889
  $data = self::get_layout_data();
1890
  $group_node_id = self::generate_node_id();
1891
  $parent = self::get_node( $node_id );
1892
  $old_group = null;
1893
 
1894
  // Add the column group.
1895
- $data[$group_node_id] = new StdClass();
1896
- $data[$group_node_id]->node = $group_node_id;
1897
- $data[$group_node_id]->type = 'column-group';
1898
- $data[$group_node_id]->parent = $node_id;
1899
- $data[$group_node_id]->position = self::next_node_position(null, $node_id);
1900
- $data[$group_node_id]->settings = '';
1901
 
1902
  // Add node template data.
1903
  if ( self::is_node_global( $parent ) ) {
1904
- $data[$group_node_id]->template_id = $parent->template_id;
1905
- $data[$group_node_id]->template_node_id = $group_node_id;
1906
  }
1907
 
1908
  // Add new columns?
1909
  if ( isset( self::$row_layouts[ $cols ] ) ) {
1910
 
1911
- for($i = 0; $i < count(self::$row_layouts[$cols]); $i++) {
1912
 
1913
  $col_node_id = self::generate_node_id();
1914
- $data[$col_node_id] = new StdClass();
1915
- $data[$col_node_id]->node = $col_node_id;
1916
- $data[$col_node_id]->type = 'column';
1917
- $data[$col_node_id]->parent = $group_node_id;
1918
- $data[$col_node_id]->position = $i;
1919
- $data[$col_node_id]->settings = new StdClass();
1920
- $data[$col_node_id]->settings->size = self::$row_layouts[$cols][$i];
1921
 
1922
  if ( self::is_node_global( $parent ) ) {
1923
- $data[$col_node_id]->template_id = $parent->template_id;
1924
- $data[$col_node_id]->template_node_id = $col_node_id;
1925
  }
1926
  }
1927
- }
1928
- // Add an existing column.
1929
  else {
1930
 
1931
  $old_group = $data[ $cols ]->parent;
@@ -1953,25 +1858,24 @@ final class FLBuilderModel {
1953
  }
1954
 
1955
  // Update the layout data.
1956
- self::update_layout_data($data);
1957
 
1958
  // Delete an existing column's old group if empty or resize it.
1959
  if ( $old_group ) {
1960
  if ( 0 === count( self::get_nodes( 'column', $old_group ) ) ) {
1961
  self::delete_node( $old_group );
1962
- }
1963
- else {
1964
  self::reset_col_widths( $old_group );
1965
  }
1966
  }
1967
 
1968
  // Position the column group.
1969
- if($position !== false) {
1970
- self::reorder_node($group_node_id, $position);
1971
  }
1972
 
1973
  // Return the column group.
1974
- return self::get_node($group_node_id);
1975
  }
1976
 
1977
  /**
@@ -1982,8 +1886,7 @@ final class FLBuilderModel {
1982
  * @param object $new_settings The new settings object.
1983
  * @return object
1984
  */
1985
- static public function process_col_settings($col, $new_settings)
1986
- {
1987
  $post_data = self::get_post_data();
1988
 
1989
  // Don't process for preview nodes.
@@ -1992,7 +1895,7 @@ final class FLBuilderModel {
1992
  }
1993
 
1994
  // Resize sibling cols if needed.
1995
- $new_settings->size = self::resize_col($col->node, $new_settings->size);
1996
 
1997
  // Update other sibling vars as needed.
1998
  $equal_height = false;
@@ -2000,41 +1903,41 @@ final class FLBuilderModel {
2000
  $responsive_order = false;
2001
 
2002
  // Adjust sibling equal height?
2003
- if ( $col->settings->equal_height != $new_settings->equal_height ) {
2004
- $equal_height = $new_settings->equal_height;
2005
- }
2006
 
2007
- // Adjust sibling content alignment?
2008
- if ( $col->settings->content_alignment != $new_settings->content_alignment ) {
2009
- $content_alignment = $new_settings->content_alignment;
2010
- }
2011
 
2012
- // Adjust sibling responsive order?
2013
- if ( $col->settings->responsive_order != $new_settings->responsive_order ) {
2014
- $responsive_order = $new_settings->responsive_order;
2015
- }
2016
 
2017
- // Update the siblings?
2018
- if ( false !== $equal_height || false !== $content_alignment || false !== $responsive_order ) {
2019
 
2020
- $data = self::get_layout_data();
2021
- $cols = self::get_nodes( 'column', $col->parent );
2022
 
2023
  foreach ( $cols as $node_id => $node ) {
2024
 
2025
  if ( false !== $equal_height ) {
2026
- $data[ $node_id ]->settings->equal_height = $equal_height;
2027
  }
2028
  if ( false !== $content_alignment ) {
2029
- $data[ $node_id ]->settings->content_alignment = $content_alignment;
2030
- }
2031
  if ( false !== $responsive_order ) {
2032
- $data[ $node_id ]->settings->responsive_order = $responsive_order;
2033
  }
2034
- }
2035
 
2036
- self::update_layout_data( $data );
2037
- }
2038
 
2039
  return $new_settings;
2040
  }
@@ -2047,44 +1950,41 @@ final class FLBuilderModel {
2047
  * @param int $new_width New width of the remaining columns.
2048
  * @return void
2049
  */
2050
- static public function delete_col($node_id = null, $new_width = 100)
2051
- {
2052
- $col = self::get_node($node_id);
2053
 
2054
  // Delete the column.
2055
- self::delete_node($node_id);
2056
 
2057
  // Return if the node we just deleted was a group.
2058
- if('column-group' == $col->type) {
2059
  return;
2060
  }
2061
 
2062
  // Get the group
2063
- $group = self::get_node($col->parent);
2064
 
2065
  // Get the group children.
2066
- $cols = self::get_nodes('column', $group->node);
2067
 
2068
  // Delete the group if empty.
2069
- if(count($cols) === 0) {
2070
- self::delete_node($group->node);
2071
- }
2072
-
2073
- // Resize the remaining columns.
2074
  else {
2075
 
2076
  // Get the layout data.
2077
  $data = self::get_layout_data();
2078
 
2079
  // Loop through the columns.
2080
- foreach($cols as $col_id => $col) {
2081
 
2082
  // Set the new size.
2083
- $data[$col_id]->settings->size = round($new_width, 2);
2084
  }
2085
 
2086
  // Update the layout data.
2087
- self::update_layout_data($data);
2088
  }
2089
  }
2090
 
@@ -2096,8 +1996,7 @@ final class FLBuilderModel {
2096
  * @param int $position
2097
  * @return void
2098
  */
2099
- static public function reorder_col( $node_id, $position = 0 )
2100
- {
2101
  $col = self::get_node( $node_id );
2102
 
2103
  self::reorder_node( $node_id, $position );
@@ -2114,8 +2013,7 @@ final class FLBuilderModel {
2114
  * @param array $resize
2115
  * @return void
2116
  */
2117
- static public function move_col( $col_id, $group_id, $position, $resize = array() )
2118
- {
2119
  $col = self::get_node( $col_id );
2120
  $old_group = self::get_node( $col->parent );
2121
 
@@ -2124,8 +2022,7 @@ final class FLBuilderModel {
2124
  if ( 0 === count( self::get_nodes( 'column', $old_group ) ) ) {
2125
  self::delete_node( $old_group->node );
2126
  self::reset_col_widths( $group_id );
2127
- }
2128
- else {
2129
  self::reset_col_widths( $resize );
2130
  }
2131
  }
@@ -2138,42 +2035,39 @@ final class FLBuilderModel {
2138
  * @param int $new_width New width of the column.
2139
  * @return int The new width
2140
  */
2141
- static public function resize_col($node_id = null, $new_width = 100)
2142
- {
2143
  $data = self::get_layout_data();
2144
- $col = $data[$node_id];
2145
- $group = $data[$col->parent];
2146
- $cols = array_values(self::get_nodes('column', $group->node));
2147
  $pos = $col->position;
2148
  $siblings = array();
2149
  $siblings_width = 0;
2150
- $num_cols = count($cols);
2151
  $min_width = 8;
2152
  $max_width = 100 - $min_width;
2153
 
2154
  // Don't resize if only one column or width isn't a number.
2155
- if($num_cols == 1 || !is_numeric($new_width)) {
2156
  return $col->settings->size;
2157
  }
2158
 
2159
  // Find the sibling column to absorb this resize.
2160
- if($pos === 0) {
2161
  $sibling = $cols[1];
2162
- }
2163
- else if($pos == $num_cols - 1) {
2164
- $sibling = $cols[$num_cols - 2];
2165
- }
2166
- else {
2167
- $sibling = $cols[$pos + 1];
2168
  }
2169
 
2170
  // Find other siblings.
2171
- foreach($cols as $c) {
2172
 
2173
- if($col->node == $c->node) {
2174
  continue;
2175
  }
2176
- if($sibling->node == $c->node) {
2177
  continue;
2178
  }
2179
 
@@ -2183,23 +2077,23 @@ final class FLBuilderModel {
2183
  }
2184
 
2185
  // Make sure the new width isn't too small.
2186
- if($new_width < $min_width) {
2187
  $new_width = $min_width;
2188
  }
2189
 
2190
  // Make sure the new width isn't too big.
2191
- if($new_width > $max_width) {
2192
  $new_width = $max_width;
2193
  }
2194
 
2195
  // Save new sibling size.
2196
- $data[$sibling->node]->settings->size = round(100 - $siblings_width - $new_width, 2);
2197
 
2198
  // Save new column size.
2199
- $data[$col->node]->settings->size = $new_width;
2200
 
2201
  // Update the layout data.
2202
- self::update_layout_data($data);
2203
 
2204
  // Return the new size.
2205
  return $new_width;
@@ -2215,8 +2109,7 @@ final class FLBuilderModel {
2215
  * @param int $sibling_width New width of the sibling.
2216
  * @return void
2217
  */
2218
- static public function resize_cols( $col_id = null, $col_width = null, $sibling_id = null, $sibling_width = null )
2219
- {
2220
  $data = self::get_layout_data();
2221
 
2222
  // Save the column width.
@@ -2236,8 +2129,7 @@ final class FLBuilderModel {
2236
  * @param string|array $group_id Node ID of the group whose columns to reset or an array of group IDs.
2237
  * @return void
2238
  */
2239
- static public function reset_col_widths( $group_id = null )
2240
- {
2241
  if ( 'array' == gettype( $group_id ) ) {
2242
  foreach ( $group_id as $id ) {
2243
  self::reset_col_widths( $id );
@@ -2265,8 +2157,7 @@ final class FLBuilderModel {
2265
  * @param int $position The position of the new column.
2266
  * @return object The new column object.
2267
  */
2268
- static public function add_col($node_id = null, $position = false)
2269
- {
2270
  $group = self::get_node( $node_id );
2271
  $cols = self::get_nodes( 'column', $group );
2272
  $num_cols = count( $cols );
@@ -2305,8 +2196,7 @@ final class FLBuilderModel {
2305
  * @param boolean $nested Whether these columns are nested or not.
2306
  * @return object
2307
  */
2308
- static public function add_cols( $col_id, $insert = 'before', $type = '1-col', $nested = false )
2309
- {
2310
  $data = self::get_layout_data();
2311
  $col = self::get_node( $col_id );
2312
  $parent = self::get_node( $col->parent );
@@ -2322,27 +2212,23 @@ final class FLBuilderModel {
2322
  if ( $num_cols + $num_new_cols > $max_cols ) {
2323
  $num_new_cols = $num_new_cols - ( $num_cols + $num_new_cols - $max_cols );
2324
  $num_cols = $max_cols;
2325
- }
2326
- else {
2327
  $num_cols += $num_new_cols;
2328
  }
2329
 
2330
  // Get the new width.
2331
  if ( 6 === $num_cols ) {
2332
  $new_width = 16.65;
2333
- }
2334
- elseif ( 7 === $num_cols ) {
2335
  $new_width = 14.28;
2336
- }
2337
- else {
2338
  $new_width = round( 100 / $num_cols, 2 );
2339
  }
2340
 
2341
  // Get the new column position.
2342
  if ( 'before' == $insert ) {
2343
  $new_col_position = $col->position - 1 < 0 ? 0 : $col->position;
2344
- }
2345
- else {
2346
  $new_col_position = $col->position + 1;
2347
  }
2348
 
@@ -2380,12 +2266,10 @@ final class FLBuilderModel {
2380
  $data[ $sibling_col_id ]->position = $new_col_position;
2381
  $new_col_position++;
2382
  }
2383
- }
2384
- else if ( $reposition ) {
2385
  $data[ $sibling_col_id ]->position = $new_col_position;
2386
  $new_col_position++;
2387
- }
2388
- else {
2389
  $data[ $sibling_col_id ]->position = $position;
2390
  $position++;
2391
  }
@@ -2404,8 +2288,7 @@ final class FLBuilderModel {
2404
  * @since 1.0
2405
  * @return object
2406
  */
2407
- static public function get_col_defaults()
2408
- {
2409
  return self::get_settings_form_defaults( 'col' );
2410
  }
2411
 
@@ -2415,15 +2298,14 @@ final class FLBuilderModel {
2415
  * @since 1.0
2416
  * @return void
2417
  */
2418
- static public function load_modules()
2419
- {
2420
  $path = FL_BUILDER_DIR . 'modules/';
2421
- $dir = dir($path);
2422
  $module_path = '';
2423
 
2424
- while(false !== ($entry = $dir->read())) {
2425
 
2426
- if(!is_dir($path . $entry) || $entry == '.' || $entry == '..') {
2427
  continue;
2428
  }
2429
 
@@ -2434,17 +2316,13 @@ final class FLBuilderModel {
2434
  $builder_path = FL_BUILDER_DIR . 'modules/' . $module_path;
2435
 
2436
  // Check for the module class in a child theme.
2437
- if(is_child_theme() && file_exists($child_path)) {
2438
  require_once $child_path;
2439
- }
2440
-
2441
- // Check for the module class in a parent theme.
2442
- else if(file_exists($theme_path)) {
2443
  require_once $theme_path;
2444
- }
2445
-
2446
- // Check for the module class in the builder directory.
2447
- else if(file_exists($builder_path)) {
2448
  require_once $builder_path;
2449
  }
2450
  }
@@ -2458,9 +2336,8 @@ final class FLBuilderModel {
2458
  * @param array $form The module's settings form.
2459
  * @return void
2460
  */
2461
- static public function register_module($class, $form)
2462
- {
2463
- if(class_exists($class)) {
2464
 
2465
  // Create a new instance of the module.
2466
  $instance = new $class();
@@ -2475,11 +2352,11 @@ final class FLBuilderModel {
2475
  $instance->enabled = apply_filters( 'fl_builder_register_module', $instance->enabled, $instance );
2476
 
2477
  // Save the instance in the modules array.
2478
- self::$modules[$instance->slug] = $instance;
2479
 
2480
  // Add the form to the instance.
2481
- self::$modules[$instance->slug]->form = apply_filters( 'fl_builder_register_settings_form', $form, $instance->slug );
2482
- self::$modules[$instance->slug]->form['advanced'] = self::$settings_forms['module_advanced'];
2483
  }
2484
  }
2485
 
@@ -2492,8 +2369,7 @@ final class FLBuilderModel {
2492
  * @param array $config The alias config.
2493
  * @return void
2494
  */
2495
- static public function register_module_alias( $alias, $config )
2496
- {
2497
  if ( isset( self::$module_aliases[ $alias ] ) ) {
2498
  _doing_it_wrong( __CLASS__ . '::register_module_alias', sprintf( _x( 'The module alias %s already exists! Please namespace your module aliases to ensure compatibility with Beaver Builder.', '%s stands for the module alias key', 'fl-builder' ), $alias ), '1.10' );
2499
  return;
@@ -2518,8 +2394,7 @@ final class FLBuilderModel {
2518
  * @param string $alias The alias key.
2519
  * @return array|null
2520
  */
2521
- static public function get_module_alias_settings( $alias )
2522
- {
2523
  if ( isset( self::$module_aliases[ $alias ] ) ) {
2524
  return self::$module_aliases[ $alias ]->settings;
2525
  }
@@ -2535,8 +2410,7 @@ final class FLBuilderModel {
2535
  * @param array $type The module's type slug.
2536
  * @return void
2537
  */
2538
- static public function is_module_registered( $type )
2539
- {
2540
  return isset( self::$modules[ $type ] );
2541
  }
2542
 
@@ -2546,8 +2420,7 @@ final class FLBuilderModel {
2546
  * @since 1.0
2547
  * @return array
2548
  */
2549
- static public function get_enabled_modules()
2550
- {
2551
  $default = array_keys( self::$modules );
2552
  $default[] = 'all';
2553
  $setting = self::get_admin_settings_option( '_fl_builder_enabled_modules', true );
@@ -2570,8 +2443,7 @@ final class FLBuilderModel {
2570
  * @param bool $show_disabled Whether to include disabled modules in the result.
2571
  * @return array
2572
  */
2573
- static public function get_categorized_modules( $show_disabled = false )
2574
- {
2575
  $enabled_modules = self::get_enabled_modules();
2576
  $widgets = null;
2577
  $categories = array();
@@ -2582,10 +2454,10 @@ final class FLBuilderModel {
2582
  }
2583
 
2584
  // Get the core category keys.
2585
- $basic_key = __('Basic Modules', 'fl-builder');
2586
- $advanced_key = __('Advanced Modules', 'fl-builder');
2587
- $other_key = __('Other Modules', 'fl-builder');
2588
- $widgets_key = __('WordPress Widgets', 'fl-builder');
2589
 
2590
  // Build the default category arrays.
2591
  $categories[ $basic_key ] = array();
@@ -2593,27 +2465,23 @@ final class FLBuilderModel {
2593
  $categories[ $other_key ] = array();
2594
 
2595
  // Build the categories array.
2596
- foreach(self::$modules as $module) {
2597
 
2598
  if ( ! $module->enabled ) {
2599
  continue;
2600
- }
2601
- else if(!in_array($module->slug, $enabled_modules) && !$show_disabled) {
2602
  continue;
2603
- }
2604
- else if($module->slug == 'widget') {
2605
  $widgets = self::get_wp_widgets();
2606
- }
2607
- else if(isset($module->category)) {
2608
 
2609
- if(!isset($categories[$module->category])) {
2610
- $categories[$module->category] = array();
2611
  }
2612
 
2613
- $categories[$module->category][$module->name] = $module;
2614
- }
2615
- else {
2616
- $categories[$other_key][$module->name] = $module;
2617
  }
2618
  }
2619
 
@@ -2632,16 +2500,15 @@ final class FLBuilderModel {
2632
 
2633
  // Add widgets if we have them.
2634
  if ( $widgets ) {
2635
- $categories[$widgets_key] = $widgets;
2636
  }
2637
 
2638
  // Sort the modules.
2639
- foreach($categories as $title => $modules) {
2640
- if(count($categories[$title]) == 0) {
2641
- unset($categories[$title]);
2642
- }
2643
- else {
2644
- ksort($categories[$title]);
2645
  }
2646
  }
2647
 
@@ -2656,13 +2523,12 @@ final class FLBuilderModel {
2656
  * @param string $name The category name.
2657
  * @return string
2658
  */
2659
- static public function get_module_category_slug( $name )
2660
- {
2661
  // Get the core category keys.
2662
- $basic_key = __('Basic Modules', 'fl-builder');
2663
- $advanced_key = __('Advanced Modules', 'fl-builder');
2664
- $other_key = __('Other Modules', 'fl-builder');
2665
- $widgets_key = __('WordPress Widgets', 'fl-builder');
2666
 
2667
  if ( $name == $basic_key ) {
2668
  return 'basic';
@@ -2687,20 +2553,19 @@ final class FLBuilderModel {
2687
  * @param string|object $node_id A module node ID or object.
2688
  * @return object|bool The module or false if it doesn't exist.
2689
  */
2690
- static public function get_module( $node_id )
2691
- {
2692
  $module = is_object( $node_id ) ? $node_id : self::get_node( $node_id );
2693
 
2694
- if( self::is_module_registered( $module->settings->type ) ) {
2695
 
2696
- $class = get_class(self::$modules[$module->settings->type]);
2697
  $instance = new $class();
2698
  $instance->node = $module->node;
2699
  $instance->parent = $module->parent;
2700
  $instance->position = $module->position;
2701
  $instance->settings = $module->settings;
2702
  $instance->type = 'module';
2703
- $instance->form = self::$modules[$module->settings->type]->form;
2704
 
2705
  if ( isset( $module->template_id ) ) {
2706
  $instance->template_id = $module->template_id;
@@ -2724,32 +2589,31 @@ final class FLBuilderModel {
2724
  * @param string|object $col_id A column ID or object.
2725
  * @return array
2726
  */
2727
- static public function get_modules($col_id = null)
2728
- {
2729
  $col = is_object( $col_id ) ? $col_id : self::get_node( $col_id );
2730
- $modules = self::get_nodes('module', $col);
2731
  $instances = array();
2732
  $i = 0;
2733
 
2734
- foreach($modules as $module) {
2735
 
2736
  if ( self::is_module_registered( $module->settings->type ) ) {
2737
 
2738
- $class = get_class(self::$modules[$module->settings->type]);
2739
- $instances[$i] = new $class();
2740
- $instances[$i]->node = $module->node;
2741
- $instances[$i]->parent = $module->parent;
2742
- $instances[$i]->position = $module->position;
2743
- $instances[$i]->settings = $module->settings;
2744
- $instances[$i]->type = 'module';
2745
- $instances[$i]->form = self::$modules[$module->settings->type]->form;
2746
 
2747
  if ( isset( $module->template_id ) ) {
2748
- $instances[$i]->template_id = $module->template_id;
2749
- $instances[$i]->template_node_id = $module->template_node_id;
2750
  }
2751
  if ( isset( $module->template_root_node ) ) {
2752
- $instances[$i]->template_root_node = true;
2753
  }
2754
 
2755
  $i++;
@@ -2765,8 +2629,7 @@ final class FLBuilderModel {
2765
  * @since 1.0
2766
  * @return array
2767
  */
2768
- static public function get_all_modules()
2769
- {
2770
  return self::get_modules();
2771
  }
2772
 
@@ -2780,44 +2643,43 @@ final class FLBuilderModel {
2780
  * @param int $position The new module's position.
2781
  * @return object The new module object.
2782
  */
2783
- static public function add_module($type = null, $settings = array(), $parent_id = null, $position = false )
2784
- {
2785
  $data = self::get_layout_data();
2786
  $parent = self::get_node( $parent_id );
2787
  $module_node_id = self::generate_node_id();
2788
  $settings->type = $type;
2789
 
2790
  // Run module update method.
2791
- $class = get_class(self::$modules[$type]);
2792
  $instance = new $class();
2793
  $instance->node = $module_node_id;
2794
  $instance->settings = $settings;
2795
- $settings = $instance->update($settings);
2796
 
2797
  // Save the module.
2798
- $data[$module_node_id] = new StdClass();
2799
- $data[$module_node_id]->node = $module_node_id;
2800
- $data[$module_node_id]->type = 'module';
2801
- $data[$module_node_id]->parent = $parent_id;
2802
- $data[$module_node_id]->position = self::next_node_position('module', $parent_id);
2803
- $data[$module_node_id]->settings = $settings;
2804
 
2805
  // Add node template data.
2806
  if ( self::is_node_global( $parent ) ) {
2807
- $data[$module_node_id]->template_id = $parent->template_id;
2808
- $data[$module_node_id]->template_node_id = $module_node_id;
2809
  }
2810
 
2811
  // Update the layout data.
2812
- self::update_layout_data($data);
2813
 
2814
  // Position the module.
2815
- if($position !== false) {
2816
- self::reorder_node($module_node_id, $position);
2817
  }
2818
 
2819
  // Send back the inserted module.
2820
- return self::get_module($module_node_id);
2821
  }
2822
 
2823
  /**
@@ -2829,8 +2691,7 @@ final class FLBuilderModel {
2829
  * @param int $position The position of the parent.
2830
  * @return string|null The new parent ID or null if none exists.
2831
  */
2832
- static public function add_module_parent( $parent_id = null, $position = null )
2833
- {
2834
  $parent = ! $parent_id ? null : self::get_node( $parent_id );
2835
 
2836
  // Add a new row if we don't have a parent.
@@ -2841,18 +2702,14 @@ final class FLBuilderModel {
2841
  $cols = self::get_nodes( 'column', $col_group->node );
2842
  $parent = array_shift( $cols );
2843
  $parent_id = $parent->node;
2844
- }
2845
-
2846
- // Add a new column group if the parent is a row.
2847
- else if ( $parent->type == 'row' ) {
2848
  $col_group = self::add_col_group( $parent->node, '1-col', $position );
2849
  $cols = self::get_nodes( 'column', $col_group->node );
2850
  $parent = array_shift( $cols );
2851
  $parent_id = $parent->node;
2852
- }
2853
-
2854
- // Add a new column if the parent is a column group.
2855
- else if ( $parent->type == 'column-group' ) {
2856
  $parent = self::add_col( $parent->node, $position );
2857
  $parent_id = $parent->node;
2858
  }
@@ -2868,8 +2725,7 @@ final class FLBuilderModel {
2868
  * @param string|object $module_id The module's node ID. Can also be a module object.
2869
  * @return object The parent node.
2870
  */
2871
- static public function get_module_parent( $type, $module_id )
2872
- {
2873
  $module = is_object( $module_id ) ? $module_id : self::get_module( $module_id );
2874
  $nodes = self::get_categorized_nodes();
2875
 
@@ -2914,10 +2770,9 @@ final class FLBuilderModel {
2914
  * @return object The new module object.
2915
  * @return array $defaults Default settings for the module.
2916
  */
2917
- static public function add_default_module($parent_id = null, $type = null, $position = null, $defaults = null)
2918
- {
2919
- $parent = $parent_id == 0 ? null : self::get_node($parent_id);
2920
- $settings = self::get_module_defaults($type);
2921
  $module_node_id = self::generate_node_id();
2922
 
2923
  // Add a new parent if one is needed.
@@ -2929,41 +2784,41 @@ final class FLBuilderModel {
2929
 
2930
  // Merge default settings if present.
2931
  if ( $defaults ) {
2932
- $settings = ( object )array_merge( ( array )$settings, $defaults );
2933
  }
2934
 
2935
  // Run module update method.
2936
- $class = get_class(self::$modules[$type]);
2937
  $instance = new $class();
2938
  $instance->node = $module_node_id;
2939
  $instance->settings = $settings;
2940
- $settings = $instance->update($settings);
2941
 
2942
  // Save the module.
2943
  $data = self::get_layout_data();
2944
- $data[$module_node_id] = new StdClass();
2945
- $data[$module_node_id]->node = $module_node_id;
2946
- $data[$module_node_id]->type = 'module';
2947
- $data[$module_node_id]->parent = $parent_id;
2948
- $data[$module_node_id]->position = self::next_node_position('module', $parent_id);
2949
- $data[$module_node_id]->settings = $settings;
2950
 
2951
  // Add node template data.
2952
  if ( self::is_node_global( $parent ) ) {
2953
- $data[$module_node_id]->template_id = $parent->template_id;
2954
- $data[$module_node_id]->template_node_id = $module_node_id;
2955
  }
2956
 
2957
  // Update the layout data.
2958
- self::update_layout_data($data);
2959
 
2960
  // Position the module.
2961
- if(null !== $position) {
2962
- self::reorder_node($module_node_id, $position);
2963
  }
2964
 
2965
  // Send back the inserted module.
2966
- return self::get_module($module_node_id);
2967
  }
2968
 
2969
  /**
@@ -2973,8 +2828,7 @@ final class FLBuilderModel {
2973
  * @param string $node_id Node ID of the module to copy.
2974
  * @return object The new module object.
2975
  */
2976
- static public function copy_module( $node_id = null )
2977
- {
2978
  $module = self::get_module( $node_id );
2979
 
2980
  return self::add_module( $module->settings->type, $module->settings, $module->parent, $module->position + 1 );
@@ -2988,10 +2842,9 @@ final class FLBuilderModel {
2988
  * @param object $new_settings The new settings.
2989
  * @return object
2990
  */
2991
- static public function process_module_settings($module, $new_settings)
2992
- {
2993
  // Get a new node instance to work with.
2994
- $class = get_class(self::$modules[$module->settings->type]);
2995
  $instance = new $class();
2996
  $instance->node = $module->node;
2997
 
@@ -3001,7 +2854,7 @@ final class FLBuilderModel {
3001
 
3002
  // Run node update.
3003
  $instance->settings = $new_settings;
3004
- $new_settings = $instance->update($new_settings);
3005
 
3006
  return $new_settings;
3007
  }
@@ -3013,8 +2866,7 @@ final class FLBuilderModel {
3013
  * @param object $settings
3014
  * @return object
3015
  */
3016
- static public function clone_module_settings( $settings )
3017
- {
3018
  $new_settings = new stdClass;
3019
 
3020
  foreach ( $settings as $key => $val ) {
@@ -3031,11 +2883,10 @@ final class FLBuilderModel {
3031
  * @param string $type The type of module.
3032
  * @return object
3033
  */
3034
- static public function get_module_defaults($type)
3035
- {
3036
  $defaults = new StdClass();
3037
 
3038
- if(isset(self::$modules[$type]->form)) {
3039
  $defaults = self::get_settings_form_defaults( $type );
3040
  $defaults->type = $type;
3041
  }
@@ -3051,41 +2902,8 @@ final class FLBuilderModel {
3051
  * @param object $settings The module settings object.
3052
  * @return object
3053
  */
3054
- static public function merge_nested_module_defaults( $type, $settings )
3055
- {
3056
- // Make sure the module form exists.
3057
- if ( isset( self::$modules[ $type ] ) ) {
3058
-
3059
- // Get the fields.
3060
- $fields = self::get_settings_form_fields( self::$modules[ $type ]->form );
3061
-
3062
- // Loop through the settings.
3063
- foreach ( $settings as $key => $val ) {
3064
-
3065
- // Make sure this field is a nested form.
3066
- if ( ! isset( $fields[ $key ]['form'] ) ) {
3067
- continue;
3068
- }
3069
-
3070
- // Get the nested form defaults.
3071
- $nested_defaults = self::get_settings_form_defaults( $fields[ $key ]['form'] );
3072
-
3073
- // Merge the defaults.
3074
- if ( is_array( $val ) ) {
3075
- foreach ( $val as $nested_key => $nested_val ) {
3076
- $settings->{ $key }[ $nested_key ] = ( object )array_merge( ( array )$nested_defaults, ( array )$nested_val );
3077
- }
3078
- }
3079
- else if ( ! empty( $settings->{ $key } ) ) {
3080
- $settings->{ $key } = ( object )array_merge( ( array )$nested_defaults, ( array )$settings->{ $key } );
3081
- }
3082
- else {
3083
- $settings->{ $key } = ( object )$nested_defaults;
3084
- }
3085
- }
3086
- }
3087
-
3088
- return $settings;
3089
  }
3090
 
3091
  /**
@@ -3094,8 +2912,7 @@ final class FLBuilderModel {
3094
  * @since 1.0
3095
  * @return array
3096
  */
3097
- static public function get_wp_widgets()
3098
- {
3099
  global $wp_widget_factory;
3100
 
3101
  $widgets = array();
@@ -3127,17 +2944,16 @@ final class FLBuilderModel {
3127
  * @since 1.0
3128
  * @return array
3129
  */
3130
- static public function get_wp_sidebars()
3131
- {
3132
  global $wp_registered_sidebars;
3133
 
3134
  $sidebars = array();
3135
 
3136
- foreach($wp_registered_sidebars as $sidebar) {
3137
- $sidebars[$sidebar['name']] = $sidebar;
3138
  }
3139
 
3140
- ksort($sidebars);
3141
 
3142
  return $sidebars;
3143
  }
@@ -3148,8 +2964,7 @@ final class FLBuilderModel {
3148
  * @since 1.0
3149
  * @return void
3150
  */
3151
- static public function load_settings()
3152
- {
3153
  require_once FL_BUILDER_DIR . 'includes/global-settings.php';
3154
  require_once FL_BUILDER_DIR . 'includes/layout-settings.php';
3155
  require_once FL_BUILDER_DIR . 'includes/row-settings.php';
@@ -3165,9 +2980,8 @@ final class FLBuilderModel {
3165
  * @param array $form The form data.
3166
  * @return void
3167
  */
3168
- static public function register_settings_form($id, $form)
3169
- {
3170
- self::$settings_forms[$id] = apply_filters( 'fl_builder_register_settings_form', $form, $id );
3171
  }
3172
 
3173
  /**
@@ -3177,8 +2991,7 @@ final class FLBuilderModel {
3177
  * @param string $id The form id.
3178
  * @return array
3179
  */
3180
- static public function get_settings_form( $id )
3181
- {
3182
  return isset( self::$settings_forms[ $id ] ) ? self::$settings_forms[ $id ] : false;
3183
  }
3184
 
@@ -3189,8 +3002,7 @@ final class FLBuilderModel {
3189
  * @param array $form The form data array.
3190
  * @return array
3191
  */
3192
- static public function get_settings_form_fields($form)
3193
- {
3194
  $fields = array();
3195
 
3196
  foreach ( $form as $tab ) {
@@ -3215,8 +3027,7 @@ final class FLBuilderModel {
3215
  * @param string $type The type of form.
3216
  * @return object
3217
  */
3218
- static public function get_settings_form_defaults( $type )
3219
- {
3220
  // Check to see if the defaults are cached first.
3221
  if ( isset( self::$settings_form_defaults[ $type ] ) ) {
3222
  return self::$settings_form_defaults[ $type ];
@@ -3229,13 +3040,11 @@ final class FLBuilderModel {
3229
  if ( isset( self::$settings_forms[ $type ] ) ) {
3230
  $form_type = $type;
3231
  $tabs = self::$settings_forms[ $type ]['tabs'];
3232
- }
3233
- // If it's not a registered form, it must be a module form.
3234
- else if ( isset( self::$modules[ $type ] ) ) {
3235
  $form_type = $type . '-module';
3236
  $tabs = self::$modules[ $type ]->form;
3237
- }
3238
- // The form can't be found.
3239
  else {
3240
  return $defaults;
3241
  }
@@ -3244,18 +3053,17 @@ final class FLBuilderModel {
3244
  $fields = self::get_settings_form_fields( $tabs );
3245
 
3246
  // Loop through the fields and get the defaults.
3247
- foreach($fields as $name => $field) {
3248
 
3249
- $default = isset($field['default']) ? $field['default'] : '';
3250
- $is_multiple = isset($field['multiple']) && $field['multiple'] === true;
3251
- $supports_multiple = $field['type'] != 'editor' && $field['type'] != 'photo';
3252
- $responsive = isset($field['responsive']) && $field['responsive'] ? $field['responsive'] : false;
3253
  $responsive_name = '';
3254
 
3255
- if($is_multiple && $supports_multiple) {
3256
- $defaults->$name = array($default);
3257
- }
3258
- else if ( $responsive ) {
3259
 
3260
  foreach ( array( 'default', 'medium', 'responsive' ) as $device ) {
3261
 
@@ -3263,16 +3071,13 @@ final class FLBuilderModel {
3263
 
3264
  if ( is_array( $responsive ) && isset( $responsive['default'] ) && isset( $responsive['default'][ $device ] ) ) {
3265
  $defaults->{ $responsive_name } = $responsive['default'][ $device ];
3266
- }
3267
- else if( 'default' == $device ) {
3268
  $defaults->$name = $default;
3269
- }
3270
- else {
3271
  $defaults->{ $responsive_name } = '';
3272
  }
3273
  }
3274
- }
3275
- else {
3276
  $defaults->$name = $default;
3277
  }
3278
  }
@@ -3283,6 +3088,52 @@ final class FLBuilderModel {
3283
  return self::$settings_form_defaults[ $type ];
3284
  }
3285
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3286
  /**
3287
  * Save the settings for a node.
3288
  *
@@ -3291,21 +3142,20 @@ final class FLBuilderModel {
3291
  * @param object $settings The settings to save.
3292
  * @return void
3293
  */
3294
- static public function save_settings($node_id = null, $settings = null)
3295
- {
3296
- $node = self::get_node($node_id);
3297
- $new_settings = (object)array_merge((array)$node->settings, (array)$settings);
3298
  $template_post_id = self::is_node_global( $node );
3299
 
3300
  // Process the settings.
3301
- $new_settings = self::process_node_settings($node, $new_settings);
3302
 
3303
  // Save the settings to the node.
3304
  $data = self::get_layout_data();
3305
- $data[$node_id]->settings = $new_settings;
3306
 
3307
  // Update the layout data.
3308
- self::update_layout_data($data);
3309
 
3310
  // Save settings for a global node template?
3311
  if ( $template_post_id && ! self::is_post_node_template() ) {
@@ -3338,19 +3188,16 @@ final class FLBuilderModel {
3338
  * @param mixed $data The data to slash.
3339
  * @return mixed The slashed data.
3340
  */
3341
- static public function slash_settings( $data )
3342
- {
3343
  if ( is_array( $data ) ) {
3344
  foreach ( $data as $key => $val ) {
3345
  $data[ $key ] = self::slash_settings( $val );
3346
  }
3347
- }
3348
- else if ( is_object( $data ) ) {
3349
  foreach ( $data as $key => $val ) {
3350
  $data->$key = self::slash_settings( $val );
3351
  }
3352
- }
3353
- else if ( is_string( $data ) ) {
3354
  $data = wp_slash( $data );
3355
  }
3356
 
@@ -3365,10 +3212,9 @@ final class FLBuilderModel {
3365
  * @param array $defaults The defaults to merge in.
3366
  * @return void
3367
  */
3368
- static public function default_settings(&$settings, $defaults)
3369
- {
3370
- foreach($defaults as $name => $value) {
3371
- if(!isset($settings->$name)) {
3372
  $settings->$name = $value;
3373
  }
3374
  }
@@ -3380,18 +3226,18 @@ final class FLBuilderModel {
3380
  * @since 1.0
3381
  * @return object
3382
  */
3383
- static public function get_global_settings()
3384
- {
3385
  if ( null === self::$global_settings ) {
3386
- $settings = get_option('_fl_builder_settings');
3387
  $defaults = self::get_settings_form_defaults( 'global' );
3388
 
3389
- if ( !$settings ) {
3390
  $settings = new StdClass();
3391
  }
3392
 
3393
  // Merge in defaults and cache settings
3394
- self::$global_settings = (object) array_merge((array) $defaults, (array) $settings);
 
3395
  }
3396
 
3397
  return self::$global_settings;
@@ -3404,15 +3250,14 @@ final class FLBuilderModel {
3404
  * @param array $settings The new global settings.
3405
  * @return object
3406
  */
3407
- static public function save_global_settings($settings = array())
3408
- {
3409
  $old_settings = self::get_global_settings();
3410
- $new_settings = (object)array_merge((array)$old_settings, (array)$settings);
3411
 
3412
  self::delete_asset_cache_for_all_posts();
3413
  self::$global_settings = null;
3414
 
3415
- update_option('_fl_builder_settings', $settings);
3416
 
3417
  return self::get_global_settings();
3418
  }
@@ -3423,12 +3268,11 @@ final class FLBuilderModel {
3423
  * @since 1.0
3424
  * @return int The new post ID.
3425
  */
3426
- static public function duplicate_post()
3427
- {
3428
  global $wpdb;
3429
 
3430
  $post_id = self::get_post_id();
3431
- $post = get_post($post_id);
3432
  $current_user = wp_get_current_user();
3433
  $template_id = false;
3434
 
@@ -3446,55 +3290,54 @@ final class FLBuilderModel {
3446
  'post_title' => sprintf( _x( 'Copy of %s', '%s stands for post/page title.', 'fl-builder' ), $post->post_title ),
3447
  'post_type' => $post->post_type,
3448
  'to_ping' => $post->to_ping,
3449
- 'menu_order' => $post->menu_order
3450
  );
3451
 
3452
  // Get the new post id.
3453
- $new_post_id = wp_insert_post($data);
3454
 
3455
  // Duplicate post meta.
3456
  $post_meta = $wpdb->get_results( $wpdb->prepare( "SELECT meta_key, meta_value FROM {$wpdb->postmeta} WHERE post_id = %d", $post_id ) );
3457
 
3458
- if(count($post_meta) !== 0) {
3459
 
3460
  $sql = "INSERT INTO {$wpdb->postmeta} (post_id, meta_key, meta_value) ";
3461
 
3462
- foreach($post_meta as $meta_info) {
3463
  $meta_key = $meta_info->meta_key;
3464
 
3465
- if ( $meta_key == '_fl_builder_template_id' ) {
3466
  $meta_value = self::generate_node_id();
3467
- }
3468
- else {
3469
- $meta_value = addslashes($meta_info->meta_value);
3470
  }
3471
 
3472
  $sql_select[] = "SELECT {$new_post_id}, '{$meta_key}', '{$meta_value}'";
3473
  }
3474
 
3475
- $sql .= implode(" UNION ALL ", $sql_select);
3476
  // @codingStandardsIgnoreStart
3477
  $wpdb->query($sql);
3478
  // @codingStandardsIgnoreEnd
3479
  }
3480
 
3481
  // Duplicate post terms.
3482
- $taxonomies = get_object_taxonomies($post->post_type);
3483
 
3484
- foreach($taxonomies as $taxonomy) {
3485
 
3486
- $post_terms = wp_get_object_terms($post_id, $taxonomy);
3487
 
3488
- for($i = 0; $i < count($post_terms); $i++) {
3489
- wp_set_object_terms($new_post_id, $post_terms[$i]->slug, $taxonomy, true);
3490
  }
3491
  }
3492
 
3493
  // Get the duplicated layout data.
3494
- $data = self::get_layout_data('published', $new_post_id);
3495
 
3496
  // Generate new node ids.
3497
- $data = self::generate_new_node_ids($data);
3498
 
3499
  // Update template ID and template node ID
3500
  $template_id = get_post_meta( $new_post_id, '_fl_builder_template_id', true );
@@ -3506,10 +3349,10 @@ final class FLBuilderModel {
3506
  }
3507
 
3508
  // Save the duplicated layout data.
3509
- self::update_layout_data($data, 'published', $new_post_id);
3510
 
3511
  // Also update draft data
3512
- self::update_layout_data($data, 'draft', $new_post_id);
3513
 
3514
  // Return the new post id.
3515
  return $new_post_id;
@@ -3522,8 +3365,7 @@ final class FLBuilderModel {
3522
  * @param int $post_id The post ID to delete data and cache for.
3523
  * @return void
3524
  */
3525
- static public function delete_post( $post_id )
3526
- {
3527
  // If this is a global template, unlink it from other posts.
3528
  self::unlink_global_node_template_from_all_posts( $post_id );
3529
 
@@ -3542,19 +3384,18 @@ final class FLBuilderModel {
3542
  * @param int $post_id
3543
  * @return void
3544
  */
3545
- static public function save_revision($post_id)
3546
- {
3547
- $parent_id = wp_is_post_revision($post_id);
3548
 
3549
- if($parent_id) {
3550
 
3551
- $parent = get_post($parent_id);
3552
- $data = self::get_layout_data('published', $parent->ID);
3553
- $settings = self::get_layout_settings('published', $parent->ID);
3554
 
3555
- if(!empty($data)) {
3556
- self::update_layout_data($data, 'published', $post_id);
3557
- self::update_layout_settings($settings, 'published', $post_id);
3558
  }
3559
  }
3560
  }
@@ -3567,27 +3408,25 @@ final class FLBuilderModel {
3567
  * @param int $revision_id
3568
  * @return void
3569
  */
3570
- static public function restore_revision($post_id, $revision_id)
3571
- {
3572
- $post = get_post($post_id);
3573
- $revision = get_post($revision_id);
3574
 
3575
- if($revision) {
3576
 
3577
- $data = self::get_layout_data('published', $revision->ID);
3578
- $settings = self::get_layout_settings('published', $revision->ID);
3579
 
3580
- if(!empty($data)) {
3581
- self::update_layout_data($data, 'published', $post_id);
3582
- self::update_layout_data($data, 'draft', $post_id);
3583
- self::update_layout_settings($settings, 'published', $post_id);
3584
- self::update_layout_settings($settings, 'draft', $post_id);
3585
- }
3586
- else {
3587
- self::delete_layout_data('published', $post_id);
3588
- self::delete_layout_data('draft', $post_id);
3589
- self::delete_layout_settings('published', $post_id);
3590
- self::delete_layout_settings('draft', $post_id);
3591
  }
3592
 
3593
  self::delete_all_asset_cache( $post_id );
@@ -3603,40 +3442,38 @@ final class FLBuilderModel {
3603
  * @param int $post_id The ID of the post to get data for.
3604
  * @return array
3605
  */
3606
- static public function get_layout_data($status = null, $post_id = null)
3607
- {
3608
- $post_id = !$post_id ? self::get_post_id() : $post_id;
3609
- $status = !$status ? self::get_node_status() : $status;
3610
 
3611
  // Get published data?
3612
- if($status == 'published') {
3613
- if(isset(self::$published_layout_data[$post_id])) {
3614
- $data = self::$published_layout_data[$post_id];
3615
- }
3616
- else {
3617
- $data = get_metadata('post', $post_id, '_fl_builder_data', true);
3618
- self::$published_layout_data[$post_id] = self::clean_layout_data( $data );
3619
- }
3620
- }
3621
- // Get draft data?
3622
- else if($status == 'draft') {
3623
- if(isset(self::$draft_layout_data[$post_id])) {
3624
- $data = self::$draft_layout_data[$post_id];
3625
  }
3626
- else {
3627
- $data = get_metadata('post', $post_id, '_fl_builder_draft', true);
3628
- self::$draft_layout_data[$post_id] = self::clean_layout_data( $data );
 
 
 
 
3629
  }
3630
  }
3631
 
3632
  // Make sure we have an array.
3633
- if(empty($data)) {
3634
  $data = array();
3635
  }
3636
 
3637
  // Clone the layout data to ensure the cache remains intact.
3638
- foreach($data as $node_id => $node) {
3639
- $data[$node_id] = clone $node;
 
 
3640
  }
3641
 
3642
  // Return the data.
@@ -3653,10 +3490,9 @@ final class FLBuilderModel {
3653
  * @param int $post_id The ID of the post to update.
3654
  * @return void
3655
  */
3656
- static public function update_layout_data($data, $status = null, $post_id = null)
3657
- {
3658
- $post_id = !$post_id ? self::get_post_id() : $post_id;
3659
- $status = !$status ? self::get_node_status() : $status;
3660
  $key = 'published' == $status ? '_fl_builder_data' : '_fl_builder_draft';
3661
  $raw_data = get_metadata( 'post', $post_id, $key );
3662
  $data = self::slash_settings( self::clean_layout_data( $data ) );
@@ -3664,17 +3500,15 @@ final class FLBuilderModel {
3664
  // Update the data.
3665
  if ( 0 === count( $raw_data ) ) {
3666
  add_metadata( 'post', $post_id, $key, $data );
3667
- }
3668
- else {
3669
  update_metadata( 'post', $post_id, $key, $data );
3670
  }
3671
 
3672
  // Cache the data.
3673
- if($status == 'published') {
3674
- self::$published_layout_data[$post_id] = $data;
3675
- }
3676
- else if($status == 'draft') {
3677
- self::$draft_layout_data[$post_id] = $data;
3678
  }
3679
  }
3680
 
@@ -3686,26 +3520,25 @@ final class FLBuilderModel {
3686
  * @param int $post_id The ID of the post to delete data.
3687
  * @return void
3688
  */
3689
- static public function delete_layout_data($status = null, $post_id = null)
3690
- {
3691
  // Make sure we have a status to delete.
3692
- if(!$status) {
3693
  return;
3694
  }
3695
 
3696
  // Get the post id.
3697
- $post_id = !$post_id ? self::get_post_id() : $post_id;
3698
 
3699
  // Get the data to delete.
3700
- $data = self::get_layout_data($status, $post_id);
3701
 
3702
  // Delete the nodes.
3703
- foreach($data as $node) {
3704
- self::call_module_delete($node);
3705
  }
3706
 
3707
  // Update the layout data.
3708
- self::update_layout_data(array(), $status, $post_id);
3709
  }
3710
 
3711
  /**
@@ -3718,8 +3551,7 @@ final class FLBuilderModel {
3718
  * @param array $data An array of layout data.
3719
  * @return array
3720
  */
3721
- static public function clean_layout_data( $data = array() )
3722
- {
3723
  $cleaned = array();
3724
 
3725
  if ( is_array( $data ) ) {
@@ -3735,8 +3567,7 @@ final class FLBuilderModel {
3735
  $cleaned[ $node->node ]->parent = $node->parent;
3736
  $cleaned[ $node->node ]->position = $node->position;
3737
  $cleaned[ $node->node ]->settings = $node->settings;
3738
- }
3739
- else {
3740
  $cleaned[ $node->node ] = $node;
3741
  }
3742
  }
@@ -3754,8 +3585,7 @@ final class FLBuilderModel {
3754
  * @param int $post_id The ID of the post to get settings for.
3755
  * @return object
3756
  */
3757
- static public function get_layout_settings( $status = null, $post_id = null )
3758
- {
3759
  $status = ! $status ? self::get_node_status() : $status;
3760
  $post_id = ! $post_id ? self::get_post_id() : $post_id;
3761
  $key = 'published' == $status ? '_fl_builder_data_settings' : '_fl_builder_draft_settings';
@@ -3766,7 +3596,7 @@ final class FLBuilderModel {
3766
  $settings = new StdClass();
3767
  }
3768
 
3769
- $settings = (object)array_merge( (array)$defaults, (array)$settings );
3770
 
3771
  return apply_filters( 'fl_builder_layout_settings', $settings, $status, $post_id );
3772
  }
@@ -3780,19 +3610,17 @@ final class FLBuilderModel {
3780
  * @param int $post_id The ID of the post to update.
3781
  * @return object
3782
  */
3783
- static public function update_layout_settings( $settings = array(), $status = null, $post_id = null )
3784
- {
3785
  $status = ! $status ? self::get_node_status() : $status;
3786
  $post_id = ! $post_id ? self::get_post_id() : $post_id;
3787
  $key = 'published' == $status ? '_fl_builder_data_settings' : '_fl_builder_draft_settings';
3788
  $raw_settings = get_metadata( 'post', $post_id, $key );
3789
  $old_settings = self::get_layout_settings( $status, $post_id );
3790
- $new_settings = (object)array_merge( (array)$old_settings, (array)$settings );
3791
 
3792
  if ( 0 === count( $raw_settings ) ) {
3793
  add_metadata( 'post', $post_id, $key, self::slash_settings( $new_settings ) );
3794
- }
3795
- else {
3796
  update_metadata( 'post', $post_id, $key, self::slash_settings( $new_settings ) );
3797
  }
3798
 
@@ -3808,8 +3636,7 @@ final class FLBuilderModel {
3808
  * @param int $post_id The ID of the post to update.
3809
  * @return object
3810
  */
3811
- static public function save_layout_settings( $settings = array(), $status = null, $post_id = null )
3812
- {
3813
  return self::update_layout_settings( $settings, $status, $post_id );
3814
  }
3815
 
@@ -3821,8 +3648,7 @@ final class FLBuilderModel {
3821
  * @param int $post_id The ID of a post whose settings to delete.
3822
  * @return void
3823
  */
3824
- static public function delete_layout_settings( $status = null, $post_id = null )
3825
- {
3826
  $status = ! $status ? self::get_node_status() : $status;
3827
  $post_id = ! $post_id ? self::get_post_id() : $post_id;
3828
  $key = 'published' == $status ? '_fl_builder_data_settings' : '_fl_builder_draft_settings';
@@ -3838,19 +3664,16 @@ final class FLBuilderModel {
3838
  * @param object $merge_settings The layout settings to merge.
3839
  * @return object
3840
  */
3841
- static public function merge_layout_settings( $settings, $merge_settings )
3842
- {
3843
  $keys = array( 'css', 'js' );
3844
 
3845
  foreach ( $keys as $key ) {
3846
 
3847
  if ( empty( $merge_settings->{$key} ) ) {
3848
  continue;
3849
- }
3850
- else if ( strstr( $settings->{$key}, $merge_settings->{$key} ) ) {
3851
  continue;
3852
- }
3853
- else {
3854
 
3855
  if ( ! empty( $settings->{$key} ) ) {
3856
  $settings->{$key} .= "\n";
@@ -3870,23 +3693,22 @@ final class FLBuilderModel {
3870
  * @since 1.0
3871
  * @return void
3872
  */
3873
- static public function clear_draft_layout()
3874
- {
3875
  $post_id = self::get_post_id();
3876
- $data = self::get_layout_data('published', $post_id);
3877
- $settings = self::get_layout_settings('published', $post_id);
3878
 
3879
  // Delete the old draft layout.
3880
- self::delete_layout_data('draft');
3881
 
3882
  // Save the new draft layout.
3883
- self::update_layout_data($data, 'draft', $post_id);
3884
 
3885
  // Save the new draft layout settings.
3886
- self::update_layout_settings($settings, 'draft', $post_id);
3887
 
3888
  // Clear the asset cache.
3889
- self::delete_all_asset_cache($post_id);
3890
  }
3891
 
3892
  /**
@@ -3896,44 +3718,42 @@ final class FLBuilderModel {
3896
  * @param bool $publish Whether to publish the parent post or not.
3897
  * @return void
3898
  */
3899
- static public function save_layout( $publish = true )
3900
- {
3901
  $editor_content = FLBuilder::render_editor_content();
3902
  $post_id = self::get_post_id();
3903
- $data = self::get_layout_data('draft', $post_id);
3904
- $settings = self::get_layout_settings('draft', $post_id);
3905
 
3906
  // Fire the before action.
3907
  do_action( 'fl_builder_before_save_layout', $post_id, $publish, $data, $settings );
3908
 
3909
  // Delete the old published layout.
3910
- self::delete_layout_data('published', $post_id);
3911
- self::delete_layout_settings('published', $post_id);
3912
 
3913
  // Save the new published layout.
3914
- self::update_layout_data($data, 'published', $post_id);
3915
- self::update_layout_settings($settings, 'published', $post_id);
3916
 
3917
  // Clear the asset cache.
3918
- self::delete_all_asset_cache($post_id);
3919
- self::delete_node_template_asset_cache($post_id);
3920
 
3921
  // Enable the builder to take over the post content.
3922
  self::enable();
3923
 
3924
  // Get the post status.
3925
- $post_status = get_post_status($post_id);
3926
 
3927
  // Publish the post?
3928
  if ( $publish ) {
3929
 
3930
- $is_draft = strstr($post_status, 'draft');
3931
- $is_pending = strstr($post_status, 'pending');
3932
 
3933
  if ( current_user_can( 'publish_posts' ) ) {
3934
  $post_status = $is_draft || $is_pending ? 'publish' : $post_status;
3935
- }
3936
- else if( $is_draft ) {
3937
  $post_status = 'pending';
3938
  }
3939
  }
@@ -3942,7 +3762,7 @@ final class FLBuilderModel {
3942
  wp_update_post(array(
3943
  'ID' => self::get_post_id(),
3944
  'post_status' => $post_status,
3945
- 'post_content' => $editor_content
3946
  ));
3947
 
3948
  // Fire the after action.
@@ -3959,8 +3779,7 @@ final class FLBuilderModel {
3959
  * @since 1.6.1
3960
  * @return void
3961
  */
3962
- static public function save_draft()
3963
- {
3964
  $post_id = self::get_post_id();
3965
  $post_status = get_post_status( $post_id );
3966
 
@@ -3978,30 +3797,29 @@ final class FLBuilderModel {
3978
  * @param int $new_post_id
3979
  * @return array
3980
  */
3981
- static public function duplicate_wpml_layout($original_post_id = null, $new_post_id = null)
3982
- {
3983
  $post_data = self::get_post_data();
3984
- $original_post_id = isset($post_data['original_post_id']) ? $post_data['original_post_id'] : $original_post_id;
3985
- $new_post_id = isset($post_data['post_id']) ? $post_data['post_id'] : $new_post_id;
3986
- $enabled = get_post_meta($original_post_id, '_fl_builder_enabled', true);
3987
- $published = self::get_layout_data('published', $original_post_id);
3988
- $draft = self::get_layout_data('draft', $original_post_id);
3989
 
3990
  $response = array(
3991
  'enabled' => false,
3992
- 'has_layout' => false
3993
  );
3994
 
3995
- if(!empty($enabled)) {
3996
- update_post_meta($new_post_id, '_fl_builder_enabled', true);
3997
  $response['enabled'] = true;
3998
  }
3999
- if(!empty($published)) {
4000
- self::update_layout_data($published, 'published', $new_post_id);
4001
  $response['has_layout'] = true;
4002
  }
4003
- if(!empty($draft)) {
4004
- self::update_layout_data($draft, 'draft', $new_post_id);
4005
  $response['has_layout'] = true;
4006
  }
4007
 
@@ -4014,8 +3832,7 @@ final class FLBuilderModel {
4014
  * @since 1.1.3
4015
  * @return string
4016
  */
4017
- static public function get_enabled_templates()
4018
- {
4019
  $value = self::get_admin_settings_option( '_fl_builder_enabled_templates', true );
4020
 
4021
  return ! $value ? 'enabled' : $value;
@@ -4028,19 +3845,16 @@ final class FLBuilderModel {
4028
  * @param string $type The type of user template to check for.
4029
  * @return bool
4030
  */
4031
- static public function is_post_user_template( $type = null )
4032
- {
4033
  $post = FLBuilderModel::get_post();
4034
 
4035
  if ( ! $post ) {
4036
  return false;
4037
- }
4038
- else if ( 'fl-builder-template' == $post->post_type ) {
4039
 
4040
  if ( null === $type ) {
4041
  return true;
4042
- }
4043
- else {
4044
 
4045
  $saved_type = self::get_user_template_type( $post->ID );
4046
 
@@ -4059,15 +3873,14 @@ final class FLBuilderModel {
4059
  * @since 1.1.3
4060
  * @return void
4061
  */
4062
- static public function save_user_template( $settings = array() )
4063
- {
4064
  // Save the user template post.
4065
  $post_id = wp_insert_post(array(
4066
  'post_title' => $settings['name'],
4067
  'post_type' => 'fl-builder-template',
4068
  'post_status' => 'publish',
4069
  'ping_status' => 'closed',
4070
- 'comment_status' => 'closed'
4071
  ));
4072
 
4073
  // Set the template type.
@@ -4078,14 +3891,14 @@ final class FLBuilderModel {
4078
  $settings = self::get_layout_settings();
4079
 
4080
  // Generate new node ids.
4081
- $data = self::generate_new_node_ids($data);
4082
 
4083
  // Save the template layout data and settings.
4084
- self::update_layout_data($data, 'published', $post_id);
4085
- self::update_layout_settings($settings, 'published', $post_id);
4086
 
4087
  // Enable the builder for this template.
4088
- update_post_meta($post_id, '_fl_builder_enabled', true);
4089
 
4090
  // Allow extensions to hook into saving a user template.
4091
  do_action( 'fl_builder_after_save_user_template', $post_id );
@@ -4099,13 +3912,12 @@ final class FLBuilderModel {
4099
  * @param string $type The type of user template to return.
4100
  * @return array
4101
  */
4102
- static public function get_user_templates( $type = 'layout' )
4103
- {
4104
  $categorized = array(
4105
  'uncategorized' => array(
4106
  'name' => _x( 'Uncategorized', 'Default user template category.', 'fl-builder' ),
4107
- 'templates' => array()
4108
- )
4109
  );
4110
 
4111
  $posts = get_posts( array(
@@ -4117,21 +3929,20 @@ final class FLBuilderModel {
4117
  array(
4118
  'taxonomy' => 'fl-builder-template-type',
4119
  'field' => 'slug',
4120
- 'terms' => $type
4121
- )
4122
- )
4123
  ) );
4124
 
4125
  $templates = array();
4126
 
4127
  // Loop through templates posts and build the templates array.
4128
- foreach( $posts as $post ) {
4129
 
4130
  if ( has_post_thumbnail( $post->ID ) ) {
4131
  $image_data = wp_get_attachment_image_src( get_post_thumbnail_id( $post->ID ), 'medium' );
4132
  $image = $image_data[0];
4133
- }
4134
- else {
4135
  $image = FL_BUILDER_URL . 'img/templates/blank.jpg';
4136
  }
4137
 
@@ -4139,7 +3950,7 @@ final class FLBuilderModel {
4139
  'id' => $post->ID,
4140
  'name' => $post->post_title,
4141
  'image' => $image,
4142
- 'type' => 'user'
4143
  );
4144
  }
4145
 
@@ -4150,15 +3961,14 @@ final class FLBuilderModel {
4150
 
4151
  if ( 0 === count( $cats ) || is_wp_error( $cats ) ) {
4152
  $categorized['uncategorized']['templates'][] = $template;
4153
- }
4154
- else {
4155
 
4156
  foreach ( $cats as $cat ) {
4157
 
4158
  if ( ! isset( $categorized[ $cat->slug ] ) ) {
4159
  $categorized[ $cat->slug ] = array(
4160
  'name' => $cat->name,
4161
- 'templates' => array()
4162
  );
4163
  }
4164
 
@@ -4177,7 +3987,7 @@ final class FLBuilderModel {
4177
 
4178
  return array(
4179
  'templates' => $templates,
4180
- 'categorized' => $categorized
4181
  );
4182
  }
4183
 
@@ -4188,8 +3998,7 @@ final class FLBuilderModel {
4188
  * @param int $template_id The post ID of the template.
4189
  * @return string
4190
  */
4191
- static public function get_user_template_type( $template_id = null )
4192
- {
4193
  if ( $template_id && isset( self::$node_template_types[ $template_id ] ) ) {
4194
  return self::$node_template_types[ $template_id ];
4195
  }
@@ -4198,8 +4007,7 @@ final class FLBuilderModel {
4198
 
4199
  if ( 'fl-builder-template' != $post->post_type ) {
4200
  return '';
4201
- }
4202
- else {
4203
 
4204
  $terms = wp_get_post_terms( $post->ID, 'fl-builder-template-type' );
4205
 
@@ -4218,10 +4026,9 @@ final class FLBuilderModel {
4218
  * @param int $template_id The post ID of the template to delete.
4219
  * @return void
4220
  */
4221
- static public function delete_user_template($template_id = null)
4222
- {
4223
- if(isset($template_id)) {
4224
- wp_delete_post($template_id, true);
4225
  }
4226
  }
4227
 
@@ -4233,63 +4040,62 @@ final class FLBuilderModel {
4233
  * @param bool $append Whether to append the new template or replacing the existing layout.
4234
  * @return void
4235
  */
4236
- static public function apply_user_template($template = null, $append = false)
4237
- {
4238
- if($template) {
4239
 
4240
  // Delete existing nodes and settings?
4241
- if(!$append) {
4242
- self::delete_layout_data('draft');
4243
- self::delete_layout_settings('draft');
4244
  }
4245
 
4246
  // Insert new nodes if this is not a blank template.
4247
- if($template != 'blank') {
4248
 
4249
  // Get the template data if $template is not an object.
4250
  if ( ! is_object( $template ) ) {
4251
  $template_id = $template;
4252
  $template = new StdClass();
4253
- $template->nodes = self::get_layout_data('published', $template_id);
4254
- $template->settings = self::get_layout_settings('published', $template_id);
4255
  }
4256
 
4257
  // Get new ids for the template nodes.
4258
- $template->nodes = self::generate_new_node_ids($template->nodes);
4259
 
4260
  // Get the existing layout data and settings.
4261
  $layout_data = self::get_layout_data();
4262
  $layout_settings = self::get_layout_settings();
4263
 
4264
  // Reposition rows if we are appending.
4265
- if($append) {
4266
 
4267
- $row_position = self::next_node_position('row');
4268
 
4269
- foreach($template->nodes as $node_id => $node) {
4270
 
4271
- if($node->type == 'row') {
4272
- $template->nodes[$node_id]->position += $row_position;
4273
  }
4274
  }
4275
  }
4276
 
4277
  // Merge the layout data and settings.
4278
- $data = array_merge($layout_data, $template->nodes);
4279
  $settings = self::merge_layout_settings( $layout_settings, $template->settings );
4280
 
4281
  // Update the layout data and settings.
4282
- self::update_layout_data($data);
4283
  self::update_layout_settings( $settings );
4284
 
4285
  // Delete old asset cache.
4286
  self::delete_asset_cache();
4287
 
4288
  return array(
4289
- 'layout_css' => $settings->css
4290
  );
4291
- }
4292
- }
4293
  }
4294
 
4295
  /**
@@ -4298,8 +4104,7 @@ final class FLBuilderModel {
4298
  * @since 1.6.3
4299
  * @return bool
4300
  */
4301
- static public function node_templates_enabled()
4302
- {
4303
  $enabled_templates = self::get_enabled_templates();
4304
 
4305
  if ( true === FL_BUILDER_LITE ) {
@@ -4319,15 +4124,13 @@ final class FLBuilderModel {
4319
  * @param int $post_id If supplied, this post will be checked instead.
4320
  * @return bool
4321
  */
4322
- static public function is_post_node_template( $post_id = false )
4323
- {
4324
  $post_id = $post_id ? $post_id : self::get_post_id();
4325
  $post = get_post( $post_id );
4326
 
4327
  if ( ! $post ) {
4328
  return false;
4329
- }
4330
- else if ( 'fl-builder-template' == $post->post_type ) {
4331
 
4332
  $saved_type = self::get_user_template_type( $post->ID );
4333
 
@@ -4346,8 +4149,7 @@ final class FLBuilderModel {
4346
  * @param int $post_id If supplied, this post will be checked instead.
4347
  * @return bool
4348
  */
4349
- static public function is_post_global_node_template( $post_id = false )
4350
- {
4351
  $post_id = $post_id ? $post_id : self::get_post_id();
4352
 
4353
  if ( ! self::is_post_node_template( $post_id ) ) {
@@ -4370,8 +4172,7 @@ final class FLBuilderModel {
4370
  * @param object $node The node object to check.
4371
  * @return bool|int
4372
  */
4373
- static public function is_node_global( $node )
4374
- {
4375
  if ( ! isset( $node->template_id ) ) {
4376
  return false;
4377
  }
@@ -4386,43 +4187,38 @@ final class FLBuilderModel {
4386
  * @param object $node The type of object to check
4387
  * @return bool
4388
  */
4389
- static public function is_node_visible( $node )
4390
- {
4391
  global $wp_the_query;
4392
 
4393
  $is_visible = true;
4394
 
4395
- if ( self::is_builder_active() && $wp_the_query->post->ID == self::get_post_id() ) {
4396
  return $is_visible;
4397
  }
4398
 
4399
  if ( isset( $node->settings->visibility_display ) && ('' != $node->settings->visibility_display) ) {
4400
 
4401
  // For logged out users
4402
- if ( $node->settings->visibility_display == 'logged_out' && ! is_user_logged_in() ) {
4403
  $is_visible = true;
4404
- }
4405
- // For logged in users
4406
- else if ( $node->settings->visibility_display == 'logged_in' && is_user_logged_in() ) {
4407
  $is_visible = true;
4408
 
4409
  // User capability setting
4410
- if ( isset($node->settings->visibility_user_capability) && ! empty($node->settings->visibility_user_capability) ) {
4411
- if (self::current_user_has_capability( trim( $node->settings->visibility_user_capability ) )) {
4412
  $is_visible = true;
4413
- }
4414
- else {
4415
  $is_visible = false;
4416
  }
4417
  }
4418
- }
4419
- // Never
4420
- else if ( $node->settings->visibility_display == 0 ) {
4421
  $is_visible = false;
4422
  } else {
4423
  $is_visible = false;
4424
  }
4425
-
4426
  }
4427
 
4428
  return apply_filters( 'fl_builder_is_node_visible', $is_visible, $node );
@@ -4435,8 +4231,7 @@ final class FLBuilderModel {
4435
  * @param object $node The node object to check.
4436
  * @return bool|int
4437
  */
4438
- static public function is_node_template_root( $node )
4439
- {
4440
  return self::is_node_global( $node ) && isset( $node->template_root_node );
4441
  }
4442
 
@@ -4447,8 +4242,7 @@ final class FLBuilderModel {
4447
  * @param string $type The type of node template to get.
4448
  * @return array
4449
  */
4450
- static public function get_node_templates( $type = '' )
4451
- {
4452
  $posts = get_posts( array(
4453
  'post_type' => 'fl-builder-template',
4454
  'orderby' => 'title',
@@ -4458,9 +4252,9 @@ final class FLBuilderModel {
4458
  array(
4459
  'taxonomy' => 'fl-builder-template-type',
4460
  'field' => 'slug',
4461
- 'terms' => $type
4462
- )
4463
- )
4464
  ) );
4465
 
4466
  $templates = array();
@@ -4471,7 +4265,7 @@ final class FLBuilderModel {
4471
  'id' => get_post_meta( $post->ID, '_fl_builder_template_id', true ),
4472
  'global' => get_post_meta( $post->ID, '_fl_builder_template_global', true ),
4473
  'link' => add_query_arg( 'fl_builder', '', get_permalink( $post->ID ) ),
4474
- 'name' => $post->post_title
4475
  );
4476
  }
4477
 
@@ -4486,8 +4280,7 @@ final class FLBuilderModel {
4486
  * @param array $nodes The node template data.
4487
  * @return object
4488
  */
4489
- static public function get_node_template_root( $type = '', $nodes = array() )
4490
- {
4491
  foreach ( $nodes as $node ) {
4492
  if ( $type == $node->type ) {
4493
  return $node;
@@ -4504,12 +4297,10 @@ final class FLBuilderModel {
4504
  * @param string $template_id The node template ID as stored in the template's post meta.
4505
  * @return int
4506
  */
4507
- static public function get_node_template_post_id( $template_id )
4508
- {
4509
  if ( isset( self::$node_template_post_ids[ $template_id ] ) ) {
4510
  return self::$node_template_post_ids[ $template_id ];
4511
- }
4512
- else {
4513
 
4514
  $posts = get_posts( array(
4515
  'post_type' => 'fl-builder-template',
@@ -4517,16 +4308,16 @@ final class FLBuilderModel {
4517
  'posts_per_page' => '-1',
4518
  'post_status' => 'any',
4519
  'meta_key' => '_fl_builder_template_id',
4520
- 'meta_value' => $template_id
4521
  ) );
4522
 
4523
  if ( 0 === count( $posts ) ) {
4524
  return false;
4525
  }
4526
 
4527
- self::$node_template_post_ids[ $template_id ] = $posts[ 0 ]->ID;
4528
 
4529
- return $posts[ 0 ]->ID;
4530
  }
4531
  }
4532
 
@@ -4537,8 +4328,7 @@ final class FLBuilderModel {
4537
  * @param string $template_id The node template ID as stored in the template's post meta.
4538
  * @return string
4539
  */
4540
- static public function get_node_template_edit_url( $template_id )
4541
- {
4542
  return self::get_edit_url( self::get_node_template_post_id( $template_id ) );
4543
  }
4544
 
@@ -4550,8 +4340,7 @@ final class FLBuilderModel {
4550
  * @param int $post_id The post ID of the global node template.
4551
  * @return array
4552
  */
4553
- static public function get_posts_with_global_node_template( $post_id = false )
4554
- {
4555
  $posts = array();
4556
 
4557
  if ( self::is_post_global_node_template( $post_id ) ) {
@@ -4564,17 +4353,17 @@ final class FLBuilderModel {
4564
  array(
4565
  'key' => '_fl_builder_data',
4566
  'value' => $template_id,
4567
- 'compare' => 'LIKE'
4568
  ),
4569
  array(
4570
  'key' => '_fl_builder_draft',
4571
  'value' => $template_id,
4572
- 'compare' => 'LIKE'
4573
  )
4574
  ),
4575
  'post_type' => 'any',
4576
  'post_status' => 'any',
4577
- 'post__not_in' => array( $post_id )
4578
  ) );
4579
 
4580
  $posts = $query->posts;
@@ -4591,8 +4380,7 @@ final class FLBuilderModel {
4591
  * @param string $settings The settings for this template.
4592
  * @return void
4593
  */
4594
- static public function save_node_template( $template_node_id, $settings )
4595
- {
4596
  $root_node = self::get_node( $template_node_id );
4597
  $nodes = self::get_nested_nodes( $template_node_id );
4598
  $template_id = self::generate_node_id();
@@ -4605,7 +4393,7 @@ final class FLBuilderModel {
4605
  'post_type' => 'fl-builder-template',
4606
  'post_status' => 'publish',
4607
  'ping_status' => 'closed',
4608
- 'comment_status' => 'closed'
4609
  ) );
4610
 
4611
  // Set the template type.
@@ -4633,13 +4421,11 @@ final class FLBuilderModel {
4633
 
4634
  if ( $node_id == $root_node->node ) {
4635
  $nodes[ $node_id ]->template_root_node = true;
4636
- }
4637
- else if ( isset( $nodes[ $node_id ]->template_root_node ) ) {
4638
  unset( $nodes[ $node_id ]->template_root_node );
4639
  }
4640
  }
4641
- }
4642
- // We need to remove the template ID and template node ID for standard templates.
4643
  else {
4644
 
4645
  foreach ( $nodes as $node_id => $node ) {
@@ -4688,7 +4474,7 @@ final class FLBuilderModel {
4688
  'link' => add_query_arg( 'fl_builder', '', get_permalink( $post_id ) ),
4689
  'name' => $settings['name'],
4690
  'type' => $root_node->type,
4691
- 'layout' => $settings['global'] ? FLBuilderAJAXLayout::render( $root_node->node, $template_node_id ) : null
4692
  );
4693
  }
4694
 
@@ -4701,8 +4487,7 @@ final class FLBuilderModel {
4701
  * @param bool $update Whether this is a new post or an update.
4702
  * @return void
4703
  */
4704
- static public function set_node_template_default_type( $post_id, $post, $update )
4705
- {
4706
  global $pagenow;
4707
 
4708
  if ( 'admin.php' == $pagenow && isset( $_GET['import'] ) ) {
@@ -4732,8 +4517,7 @@ final class FLBuilderModel {
4732
  * @param string $template_id The ID of node template to delete.
4733
  * @return void
4734
  */
4735
- static public function delete_node_template( $template_id )
4736
- {
4737
  // Make sure we have a template ID.
4738
  if ( ! isset( $template_id ) ) {
4739
  return;
@@ -4761,8 +4545,7 @@ final class FLBuilderModel {
4761
  * @param int $template_post_id The post ID of the template to unlink.
4762
  * @return void
4763
  */
4764
- static public function unlink_global_node_template_from_all_posts( $template_post_id )
4765
- {
4766
  if ( self::is_post_global_node_template( $template_post_id ) ) {
4767
 
4768
  $posts = self::get_posts_with_global_node_template( $template_post_id );
@@ -4789,8 +4572,7 @@ final class FLBuilderModel {
4789
  * @param string $template_id The ID of the template to unlink from the layout data.
4790
  * @return void
4791
  */
4792
- static public function unlink_global_node_template_from_post( $status, $post_id, $template_post_id, $template_id )
4793
- {
4794
  $template_data = self::get_layout_data( $status, $template_post_id );
4795
  $layout_data = self::get_layout_data( $status, $post_id );
4796
  $update = false;
@@ -4850,8 +4632,7 @@ final class FLBuilderModel {
4850
  * @param int $template_post_id The post ID of the template to delete.
4851
  * @return void
4852
  */
4853
- static public function delete_global_node_template_from_all_posts( $template_post_id )
4854
- {
4855
  if ( self::is_post_global_node_template( $template_post_id ) ) {
4856
 
4857
  $posts = self::get_posts_with_global_node_template( $template_post_id );
@@ -4875,8 +4656,7 @@ final class FLBuilderModel {
4875
  * @param string $template_id The ID of the template to delete from the layout data.
4876
  * @return void
4877
  */
4878
- static public function delete_global_node_template_from_post( $status, $post_id, $template_id )
4879
- {
4880
  $layout_data = self::get_layout_data( $status, $post_id );
4881
  $update = false;
4882
 
@@ -4929,9 +4709,8 @@ final class FLBuilderModel {
4929
  * @param object $template Optional. Template data to use instead of pulling it with the template ID.
4930
  * @return void
4931
  */
4932
- static public function apply_node_template( $template_id = null, $parent_id = null, $position = 0, $template = null )
4933
- {
4934
- $parent = $parent_id == 0 ? null : self::get_node( $parent_id );
4935
  $template_post_id = self::get_node_template_post_id( $template_id );
4936
 
4937
  // Allow extensions to hook into applying a node template.
@@ -4940,7 +4719,7 @@ final class FLBuilderModel {
4940
  'parent_id' => $parent_id,
4941
  'position' => $position,
4942
  'template' => $template,
4943
- 'template_post_id' => $template_post_id
4944
  ) );
4945
 
4946
  // Return if we got an override from the filter.
@@ -4954,8 +4733,7 @@ final class FLBuilderModel {
4954
  $template_settings = $template->settings;
4955
  $type = $template->type;
4956
  $global = $template->global;
4957
- }
4958
- // Get the template data.
4959
  else {
4960
  $template_data = self::get_layout_data( 'published', $template_post_id );
4961
  $template_settings = self::get_layout_settings( 'published', $template_post_id );
@@ -4985,8 +4763,7 @@ final class FLBuilderModel {
4985
  // Only merge the root node for global templates.
4986
  if ( $global ) {
4987
  $layout_data[ $root_node->node ] = $template_data[ $root_node->node ];
4988
- }
4989
- // Merge all template data and settings for standard templates.
4990
  else {
4991
 
4992
  // Merge template data.
@@ -5017,8 +4794,7 @@ final class FLBuilderModel {
5017
  // Return the root node.
5018
  if ( 'module' == $root_node->type ) {
5019
  return self::get_module( $root_node->node );
5020
- }
5021
- else {
5022
  return $root_node;
5023
  }
5024
  }
@@ -5030,8 +4806,7 @@ final class FLBuilderModel {
5030
  * @param sting $path The directory path to the template data file.
5031
  * @return void
5032
  */
5033
- static public function register_templates( $path = false )
5034
- {
5035
  if ( $path && file_exists( $path ) ) {
5036
  self::$templates[] = $path;
5037
  }
@@ -5043,8 +4818,7 @@ final class FLBuilderModel {
5043
  * @since 1.10.3
5044
  * @return void
5045
  */
5046
- static private function register_core_templates()
5047
- {
5048
  $templates = glob( FL_BUILDER_DIR . 'data/*' );
5049
 
5050
  // glob() will return false on error so cast as an array() just in case.
@@ -5069,13 +4843,12 @@ final class FLBuilderModel {
5069
  * @param string $type The type of template to apply.
5070
  * @return void
5071
  */
5072
- static public function apply_template($index = 0, $append = false, $type = 'layout')
5073
- {
5074
  // Allow extensions to hook into applying a template.
5075
  $override = apply_filters( 'fl_builder_override_apply_template', false, array(
5076
  'index' => $index,
5077
  'append' => $append,
5078
- 'type' => $type
5079
  ) );
5080
 
5081
  // Return if we have an override from the filter.
@@ -5096,41 +4869,40 @@ final class FLBuilderModel {
5096
  * @param string $type The type of template to apply.
5097
  * @return void
5098
  */
5099
- static public function apply_core_template($index = 0, $append = false, $type = 'layout')
5100
- {
5101
- $template = self::get_template($index, $type);
5102
- $row_position = self::next_node_position('row');
5103
 
5104
  // Delete existing nodes and settings?
5105
- if(!$append) {
5106
- self::delete_layout_data('draft');
5107
- self::delete_layout_settings('draft');
5108
  }
5109
 
5110
  // Only move forward if we have template nodes.
5111
- if(isset($template->nodes)) {
5112
 
5113
  // Get new ids for the template nodes.
5114
- $template->nodes = self::generate_new_node_ids($template->nodes);
5115
 
5116
  // Get the existing layout data and settings.
5117
  $layout_data = self::get_layout_data();
5118
  $layout_settings = self::get_layout_settings();
5119
 
5120
  // Reposition rows?
5121
- if($append) {
5122
 
5123
- foreach($template->nodes as $node_id => $node) {
5124
 
5125
- if($node->type == 'row') {
5126
- $template->nodes[$node_id]->position += $row_position;
5127
  }
5128
  }
5129
  }
5130
 
5131
  // Merge and update the layout data.
5132
- $data = array_merge($layout_data, $template->nodes);
5133
- self::update_layout_data($data);
5134
 
5135
  // Merge and update the layout settings.
5136
  if ( isset( $template->settings ) ) {
@@ -5151,8 +4923,7 @@ final class FLBuilderModel {
5151
  * @param string $type The type of template to get. Currently either layout, row or module.
5152
  * @return object
5153
  */
5154
- static public function get_template( $index, $type = 'layout' )
5155
- {
5156
  $templates = self::get_templates( $type );
5157
  $template = isset( $templates[ $index ] ) ? $templates[ $index ] : false;
5158
 
@@ -5171,8 +4942,7 @@ final class FLBuilderModel {
5171
  * @param bool $cached
5172
  * @return array
5173
  */
5174
- static public function get_templates( $type = 'layout', $cached = true )
5175
- {
5176
  // Pull from dat files if cached is false or we don't have saved data.
5177
  if ( ! $cached || ! self::$template_data ) {
5178
 
@@ -5190,8 +4960,7 @@ final class FLBuilderModel {
5190
  ob_start();
5191
  include $path;
5192
  $unserialized = unserialize( ob_get_clean() );
5193
- }
5194
- else {
5195
  $unserialized = fl_maybe_fix_unserialize( file_get_contents( $path ) );
5196
  }
5197
 
@@ -5216,8 +4985,8 @@ final class FLBuilderModel {
5216
 
5217
  self::$template_data[ $template_type ] = array_merge( self::$template_data[ $template_type ], $template_data );
5218
  }
5219
- }
5220
- }
5221
 
5222
  $templates = isset( self::$template_data[ $type ] ) ? self::$template_data[ $type ] : array();
5223
 
@@ -5230,8 +4999,7 @@ final class FLBuilderModel {
5230
  * @since 1.8
5231
  * @return bool
5232
  */
5233
- static public function has_templates()
5234
- {
5235
  return apply_filters( 'fl_builder_has_templates', ( count( self::get_templates() ) > 0 ) );
5236
  }
5237
 
@@ -5244,19 +5012,18 @@ final class FLBuilderModel {
5244
  * @param string $type Either layout, row or module
5245
  * @return array
5246
  */
5247
- static public function get_template_selector_data( $type = 'layout' )
5248
- {
5249
  $type = apply_filters( 'fl_builder_template_selector_data_type', $type );
5250
  $categorized = array();
5251
  $templates = array();
5252
  $core_categories = array(
5253
  'general' => __( 'General', 'fl-builder' ),
5254
  'landing' => __( 'Landing Pages', 'fl-builder' ),
5255
- 'company' => __( 'Content Pages', 'fl-builder' )
5256
  );
5257
 
5258
  // Build the the templates array.
5259
- foreach( self::get_templates( $type ) as $key => $template ) {
5260
 
5261
  if ( 'module' == $type ) {
5262
 
@@ -5270,8 +5037,7 @@ final class FLBuilderModel {
5270
 
5271
  if ( strstr( $template->image, '://' ) || strstr( $template->image, ';base64,' ) ) {
5272
  $image = $template->image;
5273
- }
5274
- else {
5275
  $image = FL_BUILDER_URL . 'img/templates/' . ( empty( $template->image ) ? 'blank.jpg' : $template->image );
5276
  }
5277
 
@@ -5280,7 +5046,7 @@ final class FLBuilderModel {
5280
  'name' => $template->name,
5281
  'image' => $image,
5282
  'category' => isset( $template->category ) ? $template->category : $template->categories,
5283
- 'type' => 'core'
5284
  );
5285
 
5286
  $template_data = apply_filters( 'fl_builder_template_selector_data', $template_data, $template );
@@ -5289,7 +5055,7 @@ final class FLBuilderModel {
5289
  }
5290
 
5291
  // Build the categorized templates array.
5292
- foreach( $templates as $template ) {
5293
 
5294
  if ( ! isset( $template['category'] ) ) {
5295
  continue;
@@ -5302,19 +5068,18 @@ final class FLBuilderModel {
5302
  if ( ! isset( $categorized[ $cat_key ] ) ) {
5303
  $categorized[ $cat_key ] = array(
5304
  'name' => $cat_label,
5305
- 'templates' => array()
5306
  );
5307
  }
5308
 
5309
  $categorized[ $cat_key ]['templates'][] = $template;
5310
  }
5311
- }
5312
- else {
5313
 
5314
  if ( ! isset( $categorized[ $template['category'] ] ) ) {
5315
  $categorized[ $template['category'] ] = array(
5316
  'name' => $core_categories[ $template['category'] ],
5317
- 'templates' => array()
5318
  );
5319
  }
5320
 
@@ -5325,7 +5090,7 @@ final class FLBuilderModel {
5325
  // Return both the templates and categorized templates array.
5326
  return apply_filters( 'fl_builder_template_selector_data', array(
5327
  'templates' => $templates,
5328
- 'categorized' => $categorized
5329
  ), $type );
5330
  }
5331
 
@@ -5335,8 +5100,7 @@ final class FLBuilderModel {
5335
  * @since 1.8
5336
  * @return array
5337
  */
5338
- static public function get_template_selector_filter_data()
5339
- {
5340
  $templates = self::get_template_selector_data();
5341
  $data = array();
5342
 
@@ -5353,8 +5117,7 @@ final class FLBuilderModel {
5353
  * @since 1.8
5354
  * @return array
5355
  */
5356
- static public function get_row_templates_data()
5357
- {
5358
  return apply_filters( 'fl_builder_row_templates_data', self::get_template_selector_data( 'row' ) );
5359
  }
5360
 
@@ -5364,8 +5127,7 @@ final class FLBuilderModel {
5364
  * @since 1.8
5365
  * @return array
5366
  */
5367
- static public function get_module_templates_data()
5368
- {
5369
  return apply_filters( 'fl_builder_module_templates_data', self::get_template_selector_data( 'module' ) );
5370
  }
5371
 
@@ -5375,8 +5137,7 @@ final class FLBuilderModel {
5375
  * @since 1.6.4
5376
  * @return object
5377
  */
5378
- static public function get_color_presets()
5379
- {
5380
  $settings = get_option( '_fl_builder_color_presets', array() );
5381
 
5382
  return apply_filters( 'fl_builder_color_presets', $settings );
@@ -5389,8 +5150,7 @@ final class FLBuilderModel {
5389
  * @param array $presets The new color presets collection.
5390
  * @return object
5391
  */
5392
- static public function save_color_presets( $presets = array() )
5393
- {
5394
  return update_option( '_fl_builder_color_presets', $presets );
5395
  }
5396
 
@@ -5400,8 +5160,7 @@ final class FLBuilderModel {
5400
  * @since 1.3.1
5401
  * @return string
5402
  */
5403
- static public function get_branding()
5404
- {
5405
  if ( class_exists( 'FLBuilderWhiteLabel' ) ) {
5406
  return FLBuilderWhiteLabel::get_branding();
5407
  }
@@ -5415,8 +5174,7 @@ final class FLBuilderModel {
5415
  * @since 1.3.7
5416
  * @return string
5417
  */
5418
- static public function get_branding_icon()
5419
- {
5420
  if ( class_exists( 'FLBuilderWhiteLabel' ) ) {
5421
  return FLBuilderWhiteLabel::get_branding_icon();
5422
  }
@@ -5430,8 +5188,7 @@ final class FLBuilderModel {
5430
  * @since 1.4.6
5431
  * @return array
5432
  */
5433
- static public function get_enabled_icons()
5434
- {
5435
  $value = self::get_admin_settings_option( '_fl_builder_enabled_icons', true );
5436
 
5437
  return ! $value ? array( 'font-awesome', 'foundation-icons', 'dashicons' ) : $value;
@@ -5443,21 +5200,19 @@ final class FLBuilderModel {
5443
  * @param string $cap The capability to evaluate if it's single or multiple (comma separated) value
5444
  * @return bool
5445
  */
5446
- static public function current_user_has_capability( $cap )
5447
- {
5448
  if ( strstr( $cap, ',' ) ) {
5449
 
5450
  $parts = explode( ',', $cap );
5451
 
5452
- foreach( $parts as $part ) {
5453
  if ( current_user_can( trim( $part ) ) ) {
5454
  return true;
5455
  }
5456
  }
5457
 
5458
  return false;
5459
- }
5460
- else {
5461
  return current_user_can( $cap );
5462
  }
5463
  }
@@ -5468,17 +5223,24 @@ final class FLBuilderModel {
5468
  * @since 1.4.9
5469
  * @return array
5470
  */
5471
- static public function get_help_button_defaults()
5472
- {
5473
  $defaults = array(
5474
  'enabled' => true,
5475
  'tour' => true,
5476
  'video' => true,
5477
  'video_embed' => '<iframe src="https://player.vimeo.com/video/124230072?autoplay=1" width="420" height="315" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>',
5478
  'knowledge_base' => true,
5479
- 'knowledge_base_url' => self::get_store_url( 'knowledge-base', array( 'utm_medium' => ( true === FL_BUILDER_LITE ? 'bb-lite' : 'bb-pro' ), 'utm_source' => 'builder-ui', 'utm_campaign' => 'kb-help-button' ) ),
 
 
 
 
5480
  'forums' => true,
5481
- 'forums_url' => self::get_store_url( 'knowledge-base', array( 'utm_medium' => ( true === FL_BUILDER_LITE ? 'bb-lite' : 'bb-pro' ), 'utm_source' => 'builder-ui', 'utm_campaign' => 'forums-help-button' ) )
 
 
 
 
5482
  );
5483
 
5484
  return $defaults;
@@ -5490,8 +5252,7 @@ final class FLBuilderModel {
5490
  * @since 1.4.9
5491
  * @return array
5492
  */
5493
- static public function get_help_button_settings()
5494
- {
5495
  if ( class_exists( 'FLBuilderWhiteLabel' ) ) {
5496
  return FLBuilderWhiteLabel::get_help_button_settings();
5497
  }
@@ -5505,8 +5266,7 @@ final class FLBuilderModel {
5505
  * @since 1.5.4
5506
  * @return array
5507
  */
5508
- static public function get_services()
5509
- {
5510
  return get_option( '_fl_builder_services', array() );
5511
  }
5512
 
@@ -5519,8 +5279,7 @@ final class FLBuilderModel {
5519
  * @param array $data The account data.
5520
  * @return void
5521
  */
5522
- static public function update_services( $service, $account, $data )
5523
- {
5524
  $services = self::get_services();
5525
  $account = sanitize_text_field( $account );
5526
 
@@ -5541,8 +5300,7 @@ final class FLBuilderModel {
5541
  * @param string $account The account name.
5542
  * @return void
5543
  */
5544
- static public function delete_service_account( $service, $account )
5545
- {
5546
  $services = self::get_services();
5547
 
5548
  if ( isset( $services[ $service ][ $account ] ) ) {
@@ -5564,22 +5322,18 @@ final class FLBuilderModel {
5564
  * @param bool $network_override Whether to allow the network admin setting to be overridden on subsites.
5565
  * @return mixed
5566
  */
5567
- static public function get_admin_settings_option( $key, $network_override = true )
5568
- {
5569
  // Get the site-wide option if we're in the network admin.
5570
  if ( is_network_admin() ) {
5571
  $value = get_site_option( $key );
5572
- }
5573
- // Get the site-wide option if network overrides aren't allowed.
5574
- else if ( ! $network_override && class_exists( 'FLBuilderMultisiteSettings' ) ) {
5575
  $value = get_site_option( $key );
5576
- }
5577
- // Network overrides are allowed. Return the subsite option if it exists.
5578
- else if ( class_exists( 'FLBuilderMultisiteSettings' ) ) {
5579
  $value = get_option( $key );
5580
  $value = false === $value ? get_site_option( $key ) : $value;
5581
- }
5582
- // This must be a single site install. Get the single site option.
5583
  else {
5584
  $value = get_option( $key );
5585
  }
@@ -5596,17 +5350,14 @@ final class FLBuilderModel {
5596
  * @param bool $network_override Whether to allow the network admin setting to be overridden on subsites.
5597
  * @return mixed
5598
  */
5599
- static public function update_admin_settings_option( $key, $value, $network_override = true )
5600
- {
5601
  // Update the site-wide option since we're in the network admin.
5602
  if ( is_network_admin() ) {
5603
  update_site_option( $key, $value );
5604
- }
5605
- // Delete the option if network overrides are allowed and the override checkbox isn't checked.
5606
- else if ( $network_override && FLBuilderAdminSettings::multisite_support() && ! isset( $_POST['fl-override-ms'] ) ) {
5607
  delete_option( $key );
5608
- }
5609
- // Update the option for single install or subsite.
5610
  else {
5611
  update_option( $key, $value );
5612
  }
@@ -5618,8 +5369,7 @@ final class FLBuilderModel {
5618
  * @since 1.0
5619
  * @return string
5620
  */
5621
- static public function plugin_basename()
5622
- {
5623
  return plugin_basename( FL_BUILDER_DIR . 'fl-builder.php' );
5624
  }
5625
 
@@ -5631,28 +5381,27 @@ final class FLBuilderModel {
5631
  * @since 1.0
5632
  * @return void
5633
  */
5634
- static public function uninstall_database()
5635
- {
5636
- if(current_user_can('delete_plugins')) {
5637
 
5638
  // Delete builder options.
5639
- delete_option('_fl_builder_settings');
5640
- delete_option('_fl_builder_enabled_modules');
5641
- delete_option('_fl_builder_enabled_templates');
5642
- delete_option('_fl_builder_templates_override');
5643
- delete_option('_fl_builder_templates_override_rows');
5644
- delete_option('_fl_builder_templates_override_modules');
5645
- delete_option('_fl_builder_post_types');
5646
- delete_option('_fl_builder_enabled_icons');
5647
- delete_option('_fl_builder_branding');
5648
- delete_option('_fl_builder_branding_icon');
5649
- delete_option('_fl_builder_theme_branding');
5650
- delete_option('_fl_builder_user_access');
5651
- delete_option('_fl_builder_help_button');
5652
- delete_option('_fl_builder_color_presets');
5653
 
5654
  // Delete builder user meta.
5655
- delete_metadata('user', 0, '_fl_builder_launched', 1, true);
5656
 
5657
  // Delete uploaded files and folders.
5658
  $upload_dir = self::get_upload_dir();
@@ -5660,25 +5409,24 @@ final class FLBuilderModel {
5660
  $filesystem->rmdir( $upload_dir['path'], true );
5661
 
5662
  // Deactivate and delete the plugin.
5663
- if (!function_exists('deactivate_plugins')) {
5664
- require_once(ABSPATH . 'wp-admin/includes/plugin.php');
5665
  }
5666
- deactivate_plugins(array(self::plugin_basename()), false, is_network_admin());
5667
- delete_plugins(array(self::plugin_basename()));
5668
 
5669
  // Redirect to the plugins page.
5670
- wp_redirect(admin_url('plugins.php?deleted=true&plugin_status=all&paged=1&s='));
5671
 
5672
  exit;
5673
- }
5674
  }
5675
 
5676
  /**
5677
  * @since 1.6.4.3
5678
  * @deprecated 1.8
5679
  */
5680
- static public function get_theme_branding()
5681
- {
5682
  _deprecated_function( __METHOD__, '1.8', 'FLBuilderWhiteLabel::get_theme_branding()' );
5683
 
5684
  if ( class_exists( 'FLBuilderWhiteLabel' ) ) {
@@ -5690,8 +5438,7 @@ final class FLBuilderModel {
5690
  * @since 1.0
5691
  * @deprecated 1.8
5692
  */
5693
- static public function save_templates( $templates = array() )
5694
- {
5695
  _deprecated_function( __METHOD__, '1.8', 'FLBuilderCoreTemplatesAdmin::save_templates()' );
5696
 
5697
  if ( class_exists( 'FLBuilderCoreTemplatesAdmin' ) ) {
@@ -5703,8 +5450,7 @@ final class FLBuilderModel {
5703
  * @since 1.0
5704
  * @deprecated 1.8
5705
  */
5706
- static public function save_template( $settings )
5707
- {
5708
  _deprecated_function( __METHOD__, '1.8', 'FLBuilderCoreTemplatesAdmin::save_template()' );
5709
 
5710
  if ( class_exists( 'FLBuilderCoreTemplatesAdmin' ) ) {
@@ -5716,8 +5462,7 @@ final class FLBuilderModel {
5716
  * @since 1.0
5717
  * @deprecated 1.8
5718
  */
5719
- static public function update_template( $old_index, $settings )
5720
- {
5721
  _deprecated_function( __METHOD__, '1.8', 'FLBuilderCoreTemplatesAdmin::update_template()' );
5722
 
5723
  if ( class_exists( 'FLBuilderCoreTemplatesAdmin' ) ) {
@@ -5729,8 +5474,7 @@ final class FLBuilderModel {
5729
  * @since 1.0
5730
  * @deprecated 1.8
5731
  */
5732
- static public function delete_template( $index )
5733
- {
5734
  _deprecated_function( __METHOD__, '1.8', 'FLBuilderCoreTemplatesAdmin::delete_template()' );
5735
 
5736
  if ( class_exists( 'FLBuilderCoreTemplatesAdmin' ) ) {
@@ -5742,8 +5486,7 @@ final class FLBuilderModel {
5742
  * @since 1.3.9
5743
  * @deprecated 1.10
5744
  */
5745
- static public function get_editing_capability()
5746
- {
5747
  _deprecated_function( __METHOD__, '1.10' );
5748
 
5749
  return 'edit_posts';
@@ -5753,8 +5496,7 @@ final class FLBuilderModel {
5753
  * @since 1.7
5754
  * @deprecated 1.10
5755
  */
5756
- static public function current_user_has_editing_capability()
5757
- {
5758
  _deprecated_function( __METHOD__, '1.10', 'FLBuilderUserAccess::current_user_can()' );
5759
 
5760
  return FLBuilderUserAccess::current_user_can( 'unrestricted_editing' );
@@ -5764,8 +5506,7 @@ final class FLBuilderModel {
5764
  * @since 1.6.3
5765
  * @deprecated 1.10
5766
  */
5767
- static public function get_global_templates_editing_capability()
5768
- {
5769
  _deprecated_function( __METHOD__, '1.10', 'FLBuilderUserAccess::current_user_can' );
5770
 
5771
  return 'edit_posts';
@@ -5775,8 +5516,7 @@ final class FLBuilderModel {
5775
  * @since 1.5.7
5776
  * @deprecated 1.10
5777
  */
5778
- static public function user_templates_admin_enabled()
5779
- {
5780
  _deprecated_function( __METHOD__, '1.10', 'FLBuilderUserAccess::current_user_can( "builder_admin" )' );
5781
 
5782
  return FLBuilderUserAccess::current_user_can( 'builder_admin' );
16
  * @var array $row_layouts
17
  */
18
  static public $row_layouts = array(
19
+ '1-col' => array( 100 ),
20
+ '2-cols' => array( 50, 50 ),
21
+ '3-cols' => array( 33.33, 33.33, 33.33 ),
22
+ '4-cols' => array( 25, 25, 25, 25 ),
23
+ '5-cols' => array( 20, 20, 20, 20, 20 ),
24
+ '6-cols' => array( 16.65, 16.65, 16.65, 16.65, 16.65, 16.65 ),
25
+ 'left-sidebar' => array( 33.33, 66.66 ),
26
+ 'right-sidebar' => array( 66.66, 33.33 ),
27
+ 'left-right-sidebar' => array( 25, 50, 25 ),
28
  );
29
 
30
  /**
173
  * @since 1.8
174
  * @return void
175
  */
176
+ static public function init() {
 
177
  /* Admin AJAX */
178
+ add_action( 'wp_ajax_fl_builder_disable', __CLASS__ . '::disable' );
179
+ add_action( 'wp_ajax_fl_builder_duplicate_wpml_layout', __CLASS__ . '::duplicate_wpml_layout' );
180
 
181
  /* Actions */
182
+ add_action( 'init', __CLASS__ . '::load_settings', 1 );
183
+ add_action( 'init', __CLASS__ . '::load_modules', 2 );
184
+ add_action( 'before_delete_post', __CLASS__ . '::delete_post' );
185
+ add_action( 'save_post', __CLASS__ . '::save_revision' );
186
+ add_action( 'save_post', __CLASS__ . '::set_node_template_default_type', 10, 3 );
187
+ add_action( 'wp_restore_post_revision', __CLASS__ . '::restore_revision', 10, 2 );
188
 
189
  /* Filters */
190
+ add_filter( 'heartbeat_received', __CLASS__ . '::lock_post', 10, 2 );
191
 
192
  /* Core Templates */
193
  self::register_core_templates();
200
  * @param int $post_id The post id to get an edit url for.
201
  * @return string
202
  */
203
+ static public function get_edit_url( $post_id = false ) {
 
204
  if ( false === $post_id ) {
205
  global $post;
206
+ } else {
 
207
  $post = get_post( $post_id );
208
  }
209
 
219
  * @param array $params An array of key/value params to add to the query string.
220
  * @return string
221
  */
222
+ static public function get_upgrade_url( $params = array() ) {
 
223
  return apply_filters( 'fl_builder_upgrade_url', self::get_store_url( '', $params ) );
224
  }
225
 
231
  * @param array $params An array of key/value params to add to the query string.
232
  * @return string
233
  */
234
+ static public function get_store_url( $path = '', $params = array() ) {
 
235
  $url = trailingslashit( FL_BUILDER_STORE_URL . $path ) . '?' . http_build_query( $params, '', '&' );
236
 
237
  return apply_filters( 'fl_builder_store_url', $url, $path );
244
  * @since 1.0
245
  * @return array
246
  */
247
+ static public function get_post_data() {
248
+ if ( ! self::$post_data ) {
 
249
 
250
  self::$post_data = array();
251
 
252
+ if ( isset( $_POST['fl_builder_data'] ) ) {
253
 
254
  // Decode settings if our ModSecurity fix is enabled.
255
  if ( isset( $_POST['fl_builder_data']['settings'] ) ) {
261
 
262
  $data = FLBuilderUtils::json_decode_deep( wp_unslash( $_POST['fl_builder_data'] ) );
263
 
264
+ foreach ( $data as $key => $val ) {
265
+ self::$post_data[ $key ] = $val;
266
  }
267
+ } elseif ( isset( $_POST ) ) {
 
268
 
269
+ foreach ( $_POST as $key => $val ) {
270
+ self::$post_data[ $key ] = $val;
271
  }
272
  }
273
  }
283
  * @param mixed $value The value to update.
284
  * @return void
285
  */
286
+ static public function update_post_data( $key, $value ) {
 
287
  $post_data = self::get_post_data();
288
+ $post_data[ $key ] = $value;
289
  self::$post_data = $post_data;
290
  }
291
 
296
  * @since 1.0
297
  * @return array
298
  */
299
+ static public function get_post_types() {
 
300
  $value = self::get_admin_settings_option( '_fl_builder_post_types', true );
301
 
302
  if ( ! $value ) {
303
  $value = array( 'page', 'fl-builder-template' );
304
+ } else {
 
305
  $value[] = 'fl-builder-template';
306
  }
307
 
315
  * @since 1.0
316
  * @return array
317
  */
318
+ static public function get_global_posts() {
319
+ return apply_filters( 'fl_builder_global_posts', array() );
 
320
  }
321
 
322
  /**
328
  * @param int $post_id
329
  * @return void
330
  */
331
+ static public function set_post_id( $post_id ) {
 
332
  array_unshift( self::$post_id, $post_id );
333
  }
334
 
341
  * @since 1.10
342
  * @return void
343
  */
344
+ static public function reset_post_id() {
 
345
  array_shift( self::$post_id );
346
  }
347
 
352
  * @since 1.0
353
  * @return int|bool The post id or false.
354
  */
355
+ static public function get_post_id() {
 
356
  global $wp_the_query;
357
  global $post;
358
 
360
 
361
  // Get a post ID from the internal $post_id array if not empty.
362
  if ( ! empty( self::$post_id ) ) {
363
+ return self::$post_id[0];
364
+ } // End if().
365
+ elseif ( isset( $post_data['post_id'] ) ) {
 
366
  return $post_data['post_id'];
367
+ } // Get a post ID from the main query.
368
+ elseif ( in_the_loop() && is_main_query() && isset( $wp_the_query->post ) ) {
 
369
  return $wp_the_query->post->ID;
370
+ } // Get a post ID in a query outside of the main loop.
371
+ elseif ( isset( $post ) ) {
 
372
  return $post->ID;
373
+ } // No post ID found.
 
374
  else {
375
  return false;
376
  }
383
  * @since 1.6.3
384
  * @return object
385
  */
386
+ static public function get_post() {
 
387
  return get_post( self::get_post_id() );
388
  }
389
 
393
  * @since 1.0
394
  * @return bool
395
  */
396
+ static public function is_ssl() {
 
397
  if ( is_ssl() ) {
398
  return true;
399
+ } elseif ( 0 === stripos( get_option( 'siteurl' ), 'https://' ) ) {
 
400
  return true;
401
+ } elseif ( isset( $_SERVER['HTTP_X_FORWARDED_PROTO'] ) && 'https' == $_SERVER['HTTP_X_FORWARDED_PROTO'] ) {
 
402
  return true;
403
  }
404
 
412
  * @since 1.0
413
  * @return bool
414
  */
415
+ static public function is_post_editable() {
 
416
  global $wp_the_query;
417
 
418
  $editable = false;
438
  * @since 1.0
439
  * @return void
440
  */
441
+ static public function lock_post( $response, $data ) {
442
+ if ( isset( $data['fl_builder_post_lock'] ) ) {
 
443
 
444
  require_once ABSPATH . 'wp-admin/includes/post.php';
445
 
446
+ wp_set_post_lock( $data['fl_builder_post_lock']['post_id'] );
447
  }
448
  }
449
 
454
  * @since 1.0
455
  * @return bool
456
  */
457
+ static public function is_builder_enabled() {
 
458
  $post_id = self::get_post_id();
459
 
460
+ if ( ! is_admin() && post_password_required( $post_id ) ) {
461
  return false;
462
+ } elseif ( self::is_builder_active() ) {
 
463
  return true;
464
+ } else {
 
465
 
466
  $post_types = self::get_post_types();
467
+ $post = get_post( $post_id );
468
 
469
+ if ( $post && in_array( $post->post_type, $post_types ) ) {
470
+ return get_post_meta( $post->ID, '_fl_builder_enabled', true );
471
  }
472
  }
473
 
481
  * @since 1.0
482
  * @return bool
483
  */
484
+ static public function is_builder_active() {
 
485
  global $wp_the_query;
486
  global $post;
487
 
490
 
491
  if ( null !== self::$active ) {
492
  return self::$active;
493
+ } elseif ( ! is_admin() && is_singular() && $query_id != $post_id ) {
 
494
  self::$active = false;
495
+ } elseif ( self::is_post_editable() && ! is_admin() && ! post_password_required() ) {
 
496
  $post_data = self::get_post_data();
497
  self::$active = isset( $_GET['fl_builder'] ) || isset( $post_data['fl_builder'] );
498
  }
507
  * @since 1.4.9
508
  * @return bool
509
  */
510
+ static public function is_new_user() {
 
511
  if ( self::is_builder_active() ) {
512
 
513
  $current_user = wp_get_current_user();
530
  * @since 1.0
531
  * @return string
532
  */
533
+ static public function get_node_status() {
 
534
  return self::is_builder_active() ? 'draft' : 'published';
535
  }
536
 
540
  * @since 1.0
541
  * @return void
542
  */
543
+ static public function enable() {
544
+ update_post_meta( self::get_post_id(), '_fl_builder_enabled', true );
 
545
  }
546
 
547
  /**
550
  * @since 1.0
551
  * @return void
552
  */
553
+ static public function disable() {
554
+ update_post_meta( self::get_post_id(), '_fl_builder_enabled', false );
 
555
  }
556
 
557
  /**
560
  * @since 1.0
561
  * @return void
562
  */
563
+ static public function enable_editing() {
 
564
  global $wp_the_query;
565
 
566
  if ( self::is_post_editable() && is_object( $wp_the_query->post ) ) {
579
  $settings->text = wpautop( $post->post_content );
580
 
581
  self::add_module( 'rich-text', $settings, $col->node );
582
+ } // End if().
583
+ elseif ( empty( $draft ) ) {
 
584
  self::update_layout_data( $published, 'draft', $post->ID );
585
  self::update_layout_settings( self::get_layout_settings( 'published' ), 'draft', $post->ID );
586
  }
604
  * @since 1.0
605
  * @return array
606
  */
607
+ static public function get_upload_dir() {
 
608
  $wp_info = wp_upload_dir();
609
  $dir_name = basename( FL_BUILDER_DIR );
610
 
611
  // We use bb-plugin for the lite version as well.
612
+ if ( 'beaver-builder-lite-version' == $dir_name ) {
613
  $dir_name = 'bb-plugin';
614
  }
615
 
621
  // Build the paths.
622
  $dir_info = array(
623
  'path' => $wp_info['basedir'] . '/' . $dir_name . '/',
624
+ 'url' => $wp_info['baseurl'] . '/' . $dir_name . '/',
625
  );
626
 
627
  // Create the upload dir if it doesn't exist.
645
  * @param string $name The name of the cache directory to get paths for.
646
  * @return array
647
  */
648
+ static public function get_cache_dir( $name = 'cache' ) {
 
649
  $upload_info = self::get_upload_dir();
650
  $allowed = array( 'cache', 'icons' );
651
 
657
  // Build the paths.
658
  $dir_info = array(
659
  'path' => $upload_info['path'] . $name . '/',
660
+ 'url' => $upload_info['url'] . $name . '/',
661
  );
662
 
663
  // Create the cache dir if it doesn't exist.
664
+ if ( ! file_exists( $dir_info['path'] ) ) {
665
 
666
  // Create the directory.
667
  mkdir( $dir_info['path'] );
682
  * @since 1.0
683
  * @return string
684
  */
685
+ static public function get_asset_version() {
 
686
  $post_id = self::get_post_id();
687
  $active = self::is_builder_active();
688
 
689
+ if ( $active ) {
690
+ return md5( uniqid() );
691
+ } else {
692
+ return md5( get_post_modified_time( 'U', false, $post_id ) );
 
693
  }
694
  }
695
 
700
  * @since 1.0
701
  * @return array
702
  */
703
+ static public function get_asset_info() {
 
704
  $post_data = self::get_post_data();
705
  $post_id = self::get_post_id();
706
  $cache_dir = self::get_cache_dir();
707
 
708
+ if ( isset( $post_data['node_preview'] ) ) {
709
  $suffix = '-layout-preview';
710
+ } elseif ( self::is_builder_active() ) {
 
711
  $suffix = '-layout-draft';
712
+ } else {
 
713
  $suffix = '-layout';
714
  }
715
 
716
  $info = array(
717
  'css' => $cache_dir['path'] . $post_id . $suffix . '.css',
718
+ 'css_url' => $cache_dir['url'] . $post_id . $suffix . '.css',
719
  'css_partial' => $cache_dir['path'] . $post_id . $suffix . '-partial.css',
720
+ 'css_partial_url' => $cache_dir['url'] . $post_id . $suffix . '-partial.css',
721
  'js' => $cache_dir['path'] . $post_id . $suffix . '.js',
722
+ 'js_url' => $cache_dir['url'] . $post_id . $suffix . '.js',
723
  'js_partial' => $cache_dir['path'] . $post_id . $suffix . '-partial.js',
724
+ 'js_partial_url' => $cache_dir['url'] . $post_id . $suffix . '-partial.js',
725
  );
726
 
727
  return $info;
736
  * @param string $type The type of cache to delete. Either css or js.
737
  * @return void
738
  */
739
+ static public function delete_asset_cache( $type = false ) {
 
740
  $info = self::get_asset_info();
741
  $types = $type ? array( $type ) : array( 'css', 'css_partial', 'js', 'js_partial' );
742
 
757
  * @param int $post_id
758
  * @return void
759
  */
760
+ static public function delete_all_asset_cache( $post_id = false ) {
 
761
  $post_id = $post_id ? $post_id : self::get_post_id();
762
  $cache_dir = self::get_cache_dir();
763
 
775
  $cache_dir['path'] . $post_id . '-layout-preview.js',
776
  $cache_dir['path'] . $post_id . '-layout-partial.js',
777
  $cache_dir['path'] . $post_id . '-layout-draft-partial.js',
778
+ $cache_dir['path'] . $post_id . '-layout-preview-partial.js',
779
  );
780
 
781
  foreach ( $paths as $path ) {
794
  * @param int $post_id
795
  * @return void
796
  */
797
+ static public function delete_node_template_asset_cache( $post_id = false ) {
 
798
  $posts = self::get_posts_with_global_node_template( $post_id );
799
 
800
  if ( ! empty( $posts ) ) {
801
+ foreach ( $posts as $post ) {
802
  self::delete_all_asset_cache( $post->ID );
803
  }
804
  }
810
  * @since 1.6.3
811
  * @return void
812
  */
813
+ static public function delete_asset_cache_for_all_posts() {
 
814
  $cache_dir = self::get_cache_dir();
815
  $css = glob( $cache_dir['path'] . '*.css' );
816
  $js = glob( $cache_dir['path'] . '*.js' );
830
  * @since 1.0
831
  * @return string
832
  */
833
+ static public function generate_node_id() {
 
834
  $node_id = uniqid();
835
 
836
+ if ( $node_id == self::$last_generated_node_id ) {
837
  return self::generate_node_id();
838
  }
839
 
849
  * @param array $data An array of node data.
850
  * @return array
851
  */
852
+ static public function generate_new_node_ids( $data ) {
 
853
  $map = array();
854
  $nodes = array();
855
 
856
  // Map the new node ids to the old.
857
+ foreach ( $data as $node_id => $node ) {
858
+ $map[ $node_id ] = self::generate_node_id();
859
  }
860
 
861
  // Replace the old node ids.
862
+ foreach ( $data as $node_id => $node ) {
863
 
864
+ $nodes[ $map[ $node_id ] ] = $node;
865
+ $nodes[ $map[ $node_id ] ]->node = $map[ $node_id ];
866
 
867
+ if ( ! empty( $node->parent ) && isset( $map[ $node->parent ] ) ) {
868
+ $nodes[ $map[ $node_id ] ]->parent = $map[ $node->parent ];
869
  }
870
  }
871
 
880
  * @param string $status The node status. Either draft or published.
881
  * @return object
882
  */
883
+ static public function get_node( $node_id = null, $status = null ) {
 
884
  if ( is_object( $node_id ) ) {
885
  $node = $node_id;
886
+ } else {
 
887
  $data = self::get_layout_data( $status );
888
  $node = isset( $data[ $node_id ] ) ? $data[ $node_id ] : null;
889
  }
904
  * @param string $status The node status. Either draft or published.
905
  * @return array
906
  */
907
+ static public function get_nodes( $type = null, $parent_id = null, $status = null ) {
 
908
  $parent = is_object( $parent_id ) ? $parent_id : self::get_node( $parent_id );
909
  $nodes = array();
910
 
911
  // Get the layout data.
912
  if ( ! $parent ) {
913
  $data = self::get_layout_data( $status );
914
+ } else {
 
915
  $data = self::get_child_nodes( $parent, $status );
916
  }
917
 
918
  // Return all nodes?
919
  if ( ! $type ) {
920
  $nodes = $data;
921
+ } // End if().
 
922
  else {
923
 
924
  foreach ( $data as $node_id => $node ) {
952
  * @param string $status The node status. Either draft or published.
953
  * @return object
954
  */
955
+ static public function get_node_parent( $node_id = null, $status = null ) {
 
956
  $parent = null;
957
 
958
  if ( is_object( $node_id ) ) {
959
  $node = $node_id;
960
+ } else {
 
961
  $node = self::get_node( $node_id, $status );
962
  }
963
 
983
  * @param string $type The type of parent to return. Either "column", "column-group" or "row".
984
  * @return object The parent node.
985
  */
986
+ static public function get_node_parent_by_type( $node, $type = '' ) {
 
987
  // Get node object if node ID set
988
  if ( ! is_object( $node ) ) {
989
  $node = self::get_node( $node );
1061
  if ( $break_while ) {
1062
  break; // From while
1063
  }
 
1064
  } else {
1065
  break; // From while
1066
  }
1078
  * @param string $status The node status. Either draft or published.
1079
  * @return array
1080
  */
1081
+ static public function get_child_nodes( $parent_id, $status = null ) {
 
1082
  $parent = is_object( $parent_id ) ? $parent_id : self::get_node( $parent_id );
1083
  $template_post_id = self::is_node_global( $parent );
1084
  $status = $template_post_id && ! self::is_post_node_template() ? 'published' : $status;
1102
  * @param string $parent_id The parent node id.
1103
  * @return array
1104
  */
1105
+ static public function get_nested_nodes( $parent_id ) {
 
1106
  $children = self::get_child_nodes( $parent_id );
1107
 
1108
  foreach ( $children as $child_id => $child ) {
1134
  * @since 1.6.3
1135
  * @return array
1136
  */
1137
+ static public function get_categorized_nodes() {
 
1138
  $nodes = array(
1139
  'rows' => array(),
1140
  'groups' => array(),
1144
 
1145
  if ( self::is_post_user_template( 'module' ) ) {
1146
  $nodes['modules'] = self::get_all_modules();
1147
+ } else {
 
1148
  $rows = self::get_nodes( 'row' );
1149
 
1150
  foreach ( $rows as $row ) {
1171
  if ( $module ) {
1172
  $nodes['modules'][ $col_child->node ] = $module;
1173
  }
1174
+ } elseif ( 'column-group' == $col_child->type ) {
 
1175
 
1176
  $nodes['groups'][ $col_child->node ] = $col_child;
1177
  $group_cols = self::get_nodes( 'column', $col_child );
1188
  }
1189
  }
1190
  }
1191
+ }// End foreach().
1192
+ }// End foreach().
1193
+ }// End if().
1194
 
1195
  return $nodes;
1196
  }
1203
  * @param object $node A node object.
1204
  * @return object
1205
  */
1206
+ static public function get_node_settings( $node ) {
 
1207
  $post_data = self::get_post_data();
1208
 
1209
  // Get the node settings for a node template's root node?
1215
  }
1216
 
1217
  // Get either the preview settings or saved node settings merged with the defaults.
1218
+ if ( isset( $post_data['node_preview'] ) && isset( $post_data['node_id'] ) && $post_data['node_id'] == $node->node ) {
1219
 
1220
+ if ( ! isset( $post_data['node_preview_processed_settings'] ) ) {
1221
  $settings = $post_data['node_preview'];
1222
+ $settings = (object) array_merge( (array) $node->settings, (array) $settings );
1223
+ $settings = self::process_node_settings( $node, $settings );
1224
+ self::update_post_data( 'node_preview_processed_settings', $settings );
1225
+ } else {
 
1226
  $settings = $post_data['node_preview_processed_settings'];
1227
  }
1228
+ } else {
1229
+ $defaults = self::get_node_defaults( $node );
1230
+ $settings = (object) array_merge( (array) $defaults, (array) $node->settings );
 
1231
 
1232
  if ( 'module' == $node->type ) {
1233
  $settings = self::merge_nested_module_defaults( $node->settings->type, $settings );
1246
  * @param object $new_settings The new node settings.
1247
  * @return object
1248
  */
1249
+ static public function process_node_settings( $node, $new_settings ) {
1250
+ if ( 'row' == $node->type ) {
1251
+ $new_settings = self::process_row_settings( $node, $new_settings );
 
1252
  }
1253
+ if ( 'column' == $node->type ) {
1254
+ $new_settings = self::process_col_settings( $node, $new_settings );
1255
  }
1256
+ if ( 'module' == $node->type ) {
1257
+ $new_settings = self::process_module_settings( $node, $new_settings );
1258
  }
1259
 
1260
  return $new_settings;
1267
  * @param object $node A node object.
1268
  * @return object
1269
  */
1270
+ static public function get_node_defaults( $node ) {
 
1271
  $defaults = array();
1272
 
1273
+ if ( 'row' == $node->type ) {
1274
  $defaults = self::get_row_defaults();
1275
+ } elseif ( 'column' == $node->type ) {
 
1276
  $defaults = self::get_col_defaults();
1277
+ } elseif ( 'module' == $node->type ) {
1278
+ $defaults = self::get_module_defaults( $node->settings->type );
 
1279
  }
1280
 
1281
  return $defaults;
1289
  * @param int $b The second position.
1290
  * @return int
1291
  */
1292
+ static public function order_nodes( $a, $b ) {
1293
+ return (int) $a->position - (int) $b->position;
 
1294
  }
1295
 
1296
  /**
1301
  * @param string $parent_id The parent node id.
1302
  * @return int
1303
  */
1304
+ static public function count_nodes( $type = 'row', $parent_id = null ) {
1305
+ return count( self::get_nodes( $type, $parent_id ) );
 
1306
  }
1307
 
1308
  /**
1314
  * @param string $parent_id The parent node id.
1315
  * @return int
1316
  */
1317
+ static public function next_node_position( $type = 'row', $parent_id = null ) {
1318
+ $nodes = self::get_nodes( $type, $parent_id );
1319
+ $last = array_pop( $nodes );
 
1320
 
1321
  return $last ? $last->position + 1 : 0;
1322
  }
1328
  * @param string $node_id The ID of the node to delete.
1329
  * @return void
1330
  */
1331
+ static public function delete_node( $node_id = null ) {
 
1332
  // Get the layout data.
1333
  $data = self::get_layout_data();
1334
 
1335
  // Return if the node doesn't exist.
1336
+ if ( ! isset( $data[ $node_id ] ) ) {
1337
  return;
1338
  }
1339
 
1372
  * @param object $data The data array to delete from.
1373
  * @return void
1374
  */
1375
+ static public function delete_child_nodes_from_data( $parent = null, &$data ) {
 
1376
  $children = self::get_nodes( null, $parent );
1377
 
1378
  foreach ( $children as $child_id => $child ) {
1396
  * @param object $node A module node.
1397
  * @return void
1398
  */
1399
+ static public function call_module_delete( $node ) {
1400
+ if ( 'module' == $node->type && isset( self::$modules[ $node->settings->type ] ) ) {
1401
+ $class = get_class( self::$modules[ $node->settings->type ] );
 
1402
  $instance = new $class();
1403
  $instance->settings = $node->settings;
1404
  $instance->delete();
1415
  * @param string $type The type of node to order.
1416
  * @return void
1417
  */
1418
+ static public function reorder_node( $node_id = null, $position = 0 ) {
 
1419
  $data = self::get_layout_data();
1420
+ $node = $data[ $node_id ];
1421
  $type = ! $node->parent ? $node->type : null;
1422
+ $nodes = self::get_nodes( $type, $node->parent );
1423
  $new_pos = 0;
1424
 
1425
  // Make sure node positions start at zero.
1426
+ foreach ( $nodes as $node ) {
1427
+ $data[ $node->node ]->position = $new_pos;
1428
  $new_pos++;
1429
  }
1430
 
1431
  // Get the node and remove it from the array.
1432
+ $node = $data[ $node_id ];
1433
+ $removed = array_splice( $nodes, $node->position, 1 );
1434
  $new_pos = 0;
1435
 
1436
  // Reposition it in the array.
1437
+ array_splice( $nodes, $position, 0, $removed );
1438
 
1439
  // Update the position data.
1440
+ foreach ( $nodes as $node ) {
1441
+ $data[ $node->node ]->position = $new_pos;
1442
  $new_pos++;
1443
  }
1444
 
1445
  // Update the layout data.
1446
+ self::update_layout_data( $data );
1447
  }
1448
 
1449
  /**
1455
  * @param int $position The position in the new parent.
1456
  * @return void
1457
  */
1458
+ static public function move_node( $node_id = null, $new_parent_id = null, $position = 0 ) {
 
1459
  $data = self::get_layout_data();
1460
+ $new_parent = self::get_node( $new_parent_id );
1461
+ $node = self::get_node( $node_id );
1462
+ $siblings = self::get_nodes( null, $node->parent );
1463
  $sibling_pos = 0;
1464
 
1465
  // Set the node's new parent.
1475
  }
1476
 
1477
  // Update the layout data.
1478
+ self::update_layout_data( $data );
1479
 
1480
  // Set the node's new order.
1481
+ self::reorder_node( $node_id, $position );
1482
  }
1483
 
1484
  /**
1489
  * @param int $position The position of the new row.
1490
  * @return object The new row object.
1491
  */
1492
+ static public function add_row( $cols = '1-col', $position = false ) {
 
1493
  $data = self::get_layout_data();
1494
  $settings = self::get_row_defaults();
1495
  $row_node_id = self::generate_node_id();
1496
 
1497
  // Add the row.
1498
+ $data[ $row_node_id ] = new StdClass();
1499
+ $data[ $row_node_id ]->node = $row_node_id;
1500
+ $data[ $row_node_id ]->type = 'row';
1501
+ $data[ $row_node_id ]->parent = null;
1502
+ $data[ $row_node_id ]->position = self::next_node_position( 'row' );
1503
+ $data[ $row_node_id ]->settings = $settings;
1504
 
1505
  // Update the layout data.
1506
+ self::update_layout_data( $data );
1507
 
1508
  // Position the row.
1509
+ if ( false !== $position ) {
1510
+ self::reorder_node( $row_node_id, $position );
1511
  }
1512
 
1513
  // Add a column group.
1514
+ self::add_col_group( $row_node_id, $cols, 0 );
1515
 
1516
  // Return the updated row.
1517
+ return self::get_node( $row_node_id );
1518
  }
1519
 
1520
  /**
1524
  * @param string $node_id Node ID of the row to copy.
1525
  * @return void
1526
  */
1527
+ static public function copy_row( $node_id = null ) {
 
1528
  $layout_data = self::get_layout_data();
1529
  $row = self::get_node( $node_id );
1530
  $new_row_id = self::generate_node_id();
1561
 
1562
  if ( 'module' == $node->type ) {
1563
  $new_nodes[ $node->node ]->settings = self::clone_module_settings( $node->settings );
1564
+ } elseif ( 'column-group' == $node->type ) {
 
1565
 
1566
  $nested_cols = self::get_nodes( 'column', $node );
1567
 
1579
  }
1580
  }
1581
  }
1582
+ }// End foreach().
1583
 
1584
  // Generate new child ids.
1585
  $new_nodes = self::generate_new_node_ids( $new_nodes );
1586
 
1587
  // Set col group parent ids to the new row id and unset template data.
1588
  foreach ( $new_nodes as $child_node_id => $child ) {
1589
+ if ( 'column-group' == $child->type ) {
1590
  if ( $child->parent == $row->node || ( isset( $row->template_node_id ) && $child->parent == $row->template_node_id ) ) {
1591
  $new_nodes[ $child_node_id ]->parent = $new_row_id;
1592
  }
1616
  * @since 1.0
1617
  * @return object
1618
  */
1619
+ static public function get_row_defaults() {
 
1620
  return self::get_settings_form_defaults( 'row' );
1621
  }
1622
 
1627
  * @since 1.9
1628
  * @return array
1629
  */
1630
+ static public function get_row_spacing_placeholders() {
 
1631
  $settings = FLBuilderModel::get_global_settings();
1632
  $placeholders = array();
1633
 
1642
  // Responsive row margins.
1643
  if ( '' != $settings->row_margins_responsive ) {
1644
  $placeholders['row_margins_responsive'] = $settings->row_margins_responsive;
1645
+ } elseif ( $settings->auto_spacing ) {
 
1646
  $placeholders['row_margins_responsive'] = 0;
1647
+ } else {
 
1648
  $placeholders['row_margins_responsive'] = $placeholders['row_margins_medium'];
1649
  }
1650
 
1652
  if ( '' != $settings->row_padding_responsive ) {
1653
  $placeholders['row_padding_tb_responsive'] = $settings->row_padding_responsive;
1654
  $placeholders['row_padding_lr_responsive'] = $settings->row_padding_responsive;
1655
+ } elseif ( $settings->auto_spacing ) {
 
1656
  $placeholders['row_padding_tb_responsive'] = $placeholders['row_padding_medium'];
1657
  $placeholders['row_padding_lr_responsive'] = 0;
1658
+ } else {
 
1659
  $placeholders['row_padding_tb_responsive'] = $placeholders['row_padding_medium'];
1660
  $placeholders['row_padding_lr_responsive'] = $placeholders['row_padding_medium'];
1661
  }
1671
  * @param object $new_settings The new settings object.
1672
  * @return object
1673
  */
1674
+ static public function process_row_settings( $row, $new_settings ) {
 
1675
  // Cache background video data.
1676
+ if ( 'video' == $new_settings->bg_type ) {
1677
 
1678
  // Video Fallback Photo
1679
  if ( ! empty( $new_settings->bg_video_fallback_src ) ) {
1680
  $fallback = $new_settings->bg_video_fallback_src;
1681
+ } else {
 
1682
  $fallback = '';
1683
  }
1684
 
1685
+ if ( 'wordpress' == $new_settings->bg_video_source ) {
1686
  // Video MP4
1687
  $mp4 = FLBuilderPhoto::get_attachment_data( $new_settings->bg_video );
1688
 
1706
  }
1707
 
1708
  // Cache background slideshow data.
1709
+ if ( 'slideshow' == $new_settings->bg_type && 'wordpress' == $new_settings->ss_source ) {
1710
 
1711
  // Make sure we have a photo data object.
1712
+ if ( ! isset( $row->settings->ss_photo_data ) ) {
1713
  $row->settings->ss_photo_data = new StdClass();
1714
  }
1715
 
1731
  * @param object $row A row node.
1732
  * @return object
1733
  */
1734
+ static public function get_row_bg_data( $row ) {
 
1735
  $data = null;
1736
 
1737
  // Background Video
1738
+ if ( 'video' == $row->settings->bg_type ) {
1739
 
1740
  if ( isset( $row->settings->bg_video_data ) ) {
1741
  $data = array();
1742
+ $data['mp4'] = $row->settings->bg_video_data;
1743
  }
1744
  if ( isset( $row->settings->bg_video_webm_data ) ) {
1745
 
1747
  $data = array();
1748
  }
1749
 
1750
+ $data['webm'] = $row->settings->bg_video_webm_data;
1751
  }
1752
+ } // End if().
1753
+ elseif ( 'slideshow' == $row->settings->bg_type && isset( $row->settings->ss_photo_data ) ) {
 
 
1754
  $data = $row->settings->ss_photo_data;
1755
  }
1756
 
1764
  * @param object $row A row node.
1765
  * @return string
1766
  */
1767
+ static public function get_row_slideshow_source( $row ) {
 
1768
  // Make sure we have a photo data object.
1769
+ if ( ! isset( $row->settings->ss_photo_data ) ) {
1770
  $row->settings->ss_photo_data = new StdClass();
1771
  }
1772
 
1791
  * @param int $position The position of the new column group.
1792
  * @return object The new column group object.
1793
  */
1794
+ static public function add_col_group( $node_id = null, $cols = '1-col', $position = false ) {
 
1795
  $data = self::get_layout_data();
1796
  $group_node_id = self::generate_node_id();
1797
  $parent = self::get_node( $node_id );
1798
  $old_group = null;
1799
 
1800
  // Add the column group.
1801
+ $data[ $group_node_id ] = new StdClass();
1802
+ $data[ $group_node_id ]->node = $group_node_id;
1803
+ $data[ $group_node_id ]->type = 'column-group';
1804
+ $data[ $group_node_id ]->parent = $node_id;
1805
+ $data[ $group_node_id ]->position = self::next_node_position( null, $node_id );
1806
+ $data[ $group_node_id ]->settings = '';
1807
 
1808
  // Add node template data.
1809
  if ( self::is_node_global( $parent ) ) {
1810
+ $data[ $group_node_id ]->template_id = $parent->template_id;
1811
+ $data[ $group_node_id ]->template_node_id = $group_node_id;
1812
  }
1813
 
1814
  // Add new columns?
1815
  if ( isset( self::$row_layouts[ $cols ] ) ) {
1816
 
1817
+ for ( $i = 0; $i < count( self::$row_layouts[ $cols ] ); $i++ ) {
1818
 
1819
  $col_node_id = self::generate_node_id();
1820
+ $data[ $col_node_id ] = new StdClass();
1821
+ $data[ $col_node_id ]->node = $col_node_id;
1822
+ $data[ $col_node_id ]->type = 'column';
1823
+ $data[ $col_node_id ]->parent = $group_node_id;
1824
+ $data[ $col_node_id ]->position = $i;
1825
+ $data[ $col_node_id ]->settings = new StdClass();
1826
+ $data[ $col_node_id ]->settings->size = self::$row_layouts[ $cols ][ $i ];
1827
 
1828
  if ( self::is_node_global( $parent ) ) {
1829
+ $data[ $col_node_id ]->template_id = $parent->template_id;
1830
+ $data[ $col_node_id ]->template_node_id = $col_node_id;
1831
  }
1832
  }
1833
+ } // End if().
 
1834
  else {
1835
 
1836
  $old_group = $data[ $cols ]->parent;
1858
  }
1859
 
1860
  // Update the layout data.
1861
+ self::update_layout_data( $data );
1862
 
1863
  // Delete an existing column's old group if empty or resize it.
1864
  if ( $old_group ) {
1865
  if ( 0 === count( self::get_nodes( 'column', $old_group ) ) ) {
1866
  self::delete_node( $old_group );
1867
+ } else {
 
1868
  self::reset_col_widths( $old_group );
1869
  }
1870
  }
1871
 
1872
  // Position the column group.
1873
+ if ( false !== $position ) {
1874
+ self::reorder_node( $group_node_id, $position );
1875
  }
1876
 
1877
  // Return the column group.
1878
+ return self::get_node( $group_node_id );
1879
  }
1880
 
1881
  /**
1886
  * @param object $new_settings The new settings object.
1887
  * @return object
1888
  */
1889
+ static public function process_col_settings( $col, $new_settings ) {
 
1890
  $post_data = self::get_post_data();
1891
 
1892
  // Don't process for preview nodes.
1895
  }
1896
 
1897
  // Resize sibling cols if needed.
1898
+ $new_settings->size = self::resize_col( $col->node, $new_settings->size );
1899
 
1900
  // Update other sibling vars as needed.
1901
  $equal_height = false;
1903
  $responsive_order = false;
1904
 
1905
  // Adjust sibling equal height?
1906
+ if ( $col->settings->equal_height != $new_settings->equal_height ) {
1907
+ $equal_height = $new_settings->equal_height;
1908
+ }
1909
 
1910
+ // Adjust sibling content alignment?
1911
+ if ( $col->settings->content_alignment != $new_settings->content_alignment ) {
1912
+ $content_alignment = $new_settings->content_alignment;
1913
+ }
1914
 
1915
+ // Adjust sibling responsive order?
1916
+ if ( $col->settings->responsive_order != $new_settings->responsive_order ) {
1917
+ $responsive_order = $new_settings->responsive_order;
1918
+ }
1919
 
1920
+ // Update the siblings?
1921
+ if ( false !== $equal_height || false !== $content_alignment || false !== $responsive_order ) {
1922
 
1923
+ $data = self::get_layout_data();
1924
+ $cols = self::get_nodes( 'column', $col->parent );
1925
 
1926
  foreach ( $cols as $node_id => $node ) {
1927
 
1928
  if ( false !== $equal_height ) {
1929
+ $data[ $node_id ]->settings->equal_height = $equal_height;
1930
  }
1931
  if ( false !== $content_alignment ) {
1932
+ $data[ $node_id ]->settings->content_alignment = $content_alignment;
1933
+ }
1934
  if ( false !== $responsive_order ) {
1935
+ $data[ $node_id ]->settings->responsive_order = $responsive_order;
1936
  }
1937
+ }
1938
 
1939
+ self::update_layout_data( $data );
1940
+ }
1941
 
1942
  return $new_settings;
1943
  }
1950
  * @param int $new_width New width of the remaining columns.
1951
  * @return void
1952
  */
1953
+ static public function delete_col( $node_id = null, $new_width = 100 ) {
1954
+ $col = self::get_node( $node_id );
 
1955
 
1956
  // Delete the column.
1957
+ self::delete_node( $node_id );
1958
 
1959
  // Return if the node we just deleted was a group.
1960
+ if ( 'column-group' == $col->type ) {
1961
  return;
1962
  }
1963
 
1964
  // Get the group
1965
+ $group = self::get_node( $col->parent );
1966
 
1967
  // Get the group children.
1968
+ $cols = self::get_nodes( 'column', $group->node );
1969
 
1970
  // Delete the group if empty.
1971
+ if ( count( $cols ) === 0 ) {
1972
+ self::delete_node( $group->node );
1973
+ } // End if().
 
 
1974
  else {
1975
 
1976
  // Get the layout data.
1977
  $data = self::get_layout_data();
1978
 
1979
  // Loop through the columns.
1980
+ foreach ( $cols as $col_id => $col ) {
1981
 
1982
  // Set the new size.
1983
+ $data[ $col_id ]->settings->size = round( $new_width, 2 );
1984
  }
1985
 
1986
  // Update the layout data.
1987
+ self::update_layout_data( $data );
1988
  }
1989
  }
1990
 
1996
  * @param int $position
1997
  * @return void
1998
  */
1999
+ static public function reorder_col( $node_id, $position = 0 ) {
 
2000
  $col = self::get_node( $node_id );
2001
 
2002
  self::reorder_node( $node_id, $position );
2013
  * @param array $resize
2014
  * @return void
2015
  */
2016
+ static public function move_col( $col_id, $group_id, $position, $resize = array() ) {
 
2017
  $col = self::get_node( $col_id );
2018
  $old_group = self::get_node( $col->parent );
2019
 
2022
  if ( 0 === count( self::get_nodes( 'column', $old_group ) ) ) {
2023
  self::delete_node( $old_group->node );
2024
  self::reset_col_widths( $group_id );
2025
+ } else {
 
2026
  self::reset_col_widths( $resize );
2027
  }
2028
  }
2035
  * @param int $new_width New width of the column.
2036
  * @return int The new width
2037
  */
2038
+ static public function resize_col( $node_id = null, $new_width = 100 ) {
 
2039
  $data = self::get_layout_data();
2040
+ $col = $data[ $node_id ];
2041
+ $group = $data[ $col->parent ];
2042
+ $cols = array_values( self::get_nodes( 'column', $group->node ) );
2043
  $pos = $col->position;
2044
  $siblings = array();
2045
  $siblings_width = 0;
2046
+ $num_cols = count( $cols );
2047
  $min_width = 8;
2048
  $max_width = 100 - $min_width;
2049
 
2050
  // Don't resize if only one column or width isn't a number.
2051
+ if ( 1 == $num_cols || ! is_numeric( $new_width ) ) {
2052
  return $col->settings->size;
2053
  }
2054
 
2055
  // Find the sibling column to absorb this resize.
2056
+ if ( 0 === $pos ) {
2057
  $sibling = $cols[1];
2058
+ } elseif ( $pos == $num_cols - 1 ) {
2059
+ $sibling = $cols[ $num_cols - 2 ];
2060
+ } else {
2061
+ $sibling = $cols[ $pos + 1 ];
 
 
2062
  }
2063
 
2064
  // Find other siblings.
2065
+ foreach ( $cols as $c ) {
2066
 
2067
+ if ( $col->node == $c->node ) {
2068
  continue;
2069
  }
2070
+ if ( $sibling->node == $c->node ) {
2071
  continue;
2072
  }
2073
 
2077
  }
2078
 
2079
  // Make sure the new width isn't too small.
2080
+ if ( $new_width < $min_width ) {
2081
  $new_width = $min_width;
2082
  }
2083
 
2084
  // Make sure the new width isn't too big.
2085
+ if ( $new_width > $max_width ) {
2086
  $new_width = $max_width;
2087
  }
2088
 
2089
  // Save new sibling size.
2090
+ $data[ $sibling->node ]->settings->size = round( 100 - $siblings_width - $new_width, 2 );
2091
 
2092
  // Save new column size.
2093
+ $data[ $col->node ]->settings->size = $new_width;
2094
 
2095
  // Update the layout data.
2096
+ self::update_layout_data( $data );
2097
 
2098
  // Return the new size.
2099
  return $new_width;
2109
  * @param int $sibling_width New width of the sibling.
2110
  * @return void
2111
  */
2112
+ static public function resize_cols( $col_id = null, $col_width = null, $sibling_id = null, $sibling_width = null ) {
 
2113
  $data = self::get_layout_data();
2114
 
2115
  // Save the column width.
2129
  * @param string|array $group_id Node ID of the group whose columns to reset or an array of group IDs.
2130
  * @return void
2131
  */
2132
+ static public function reset_col_widths( $group_id = null ) {
 
2133
  if ( 'array' == gettype( $group_id ) ) {
2134
  foreach ( $group_id as $id ) {
2135
  self::reset_col_widths( $id );
2157
  * @param int $position The position of the new column.
2158
  * @return object The new column object.
2159
  */
2160
+ static public function add_col( $node_id = null, $position = false ) {
 
2161
  $group = self::get_node( $node_id );
2162
  $cols = self::get_nodes( 'column', $group );
2163
  $num_cols = count( $cols );
2196
  * @param boolean $nested Whether these columns are nested or not.
2197
  * @return object
2198
  */
2199
+ static public function add_cols( $col_id, $insert = 'before', $type = '1-col', $nested = false ) {
 
2200
  $data = self::get_layout_data();
2201
  $col = self::get_node( $col_id );
2202
  $parent = self::get_node( $col->parent );
2212
  if ( $num_cols + $num_new_cols > $max_cols ) {
2213
  $num_new_cols = $num_new_cols - ( $num_cols + $num_new_cols - $max_cols );
2214
  $num_cols = $max_cols;
2215
+ } else {
 
2216
  $num_cols += $num_new_cols;
2217
  }
2218
 
2219
  // Get the new width.
2220
  if ( 6 === $num_cols ) {
2221
  $new_width = 16.65;
2222
+ } elseif ( 7 === $num_cols ) {
 
2223
  $new_width = 14.28;
2224
+ } else {
 
2225
  $new_width = round( 100 / $num_cols, 2 );
2226
  }
2227
 
2228
  // Get the new column position.
2229
  if ( 'before' == $insert ) {
2230
  $new_col_position = $col->position - 1 < 0 ? 0 : $col->position;
2231
+ } else {
 
2232
  $new_col_position = $col->position + 1;
2233
  }
2234
 
2266
  $data[ $sibling_col_id ]->position = $new_col_position;
2267
  $new_col_position++;
2268
  }
2269
+ } elseif ( $reposition ) {
 
2270
  $data[ $sibling_col_id ]->position = $new_col_position;
2271
  $new_col_position++;
2272
+ } else {
 
2273
  $data[ $sibling_col_id ]->position = $position;
2274
  $position++;
2275
  }
2288
  * @since 1.0
2289
  * @return object
2290
  */
2291
+ static public function get_col_defaults() {
 
2292
  return self::get_settings_form_defaults( 'col' );
2293
  }
2294
 
2298
  * @since 1.0
2299
  * @return void
2300
  */
2301
+ static public function load_modules() {
 
2302
  $path = FL_BUILDER_DIR . 'modules/';
2303
+ $dir = dir( $path );
2304
  $module_path = '';
2305
 
2306
+ while ( false !== ($entry = $dir->read()) ) { // @codingStandardsIgnoreLine
2307
 
2308
+ if ( ! is_dir( $path . $entry ) || '.' == $entry || '..' == $entry ) {
2309
  continue;
2310
  }
2311
 
2316
  $builder_path = FL_BUILDER_DIR . 'modules/' . $module_path;
2317
 
2318
  // Check for the module class in a child theme.
2319
+ if ( is_child_theme() && file_exists( $child_path ) ) {
2320
  require_once $child_path;
2321
+ } // End if().
2322
+ elseif ( file_exists( $theme_path ) ) {
 
 
2323
  require_once $theme_path;
2324
+ } // Check for the module class in the builder directory.
2325
+ elseif ( file_exists( $builder_path ) ) {
 
 
2326
  require_once $builder_path;
2327
  }
2328
  }
2336
  * @param array $form The module's settings form.
2337
  * @return void
2338
  */
2339
+ static public function register_module( $class, $form ) {
2340
+ if ( class_exists( $class ) ) {
 
2341
 
2342
  // Create a new instance of the module.
2343
  $instance = new $class();
2352
  $instance->enabled = apply_filters( 'fl_builder_register_module', $instance->enabled, $instance );
2353
 
2354
  // Save the instance in the modules array.
2355
+ self::$modules[ $instance->slug ] = $instance;
2356
 
2357
  // Add the form to the instance.
2358
+ self::$modules[ $instance->slug ]->form = apply_filters( 'fl_builder_register_settings_form', $form, $instance->slug );
2359
+ self::$modules[ $instance->slug ]->form['advanced'] = self::$settings_forms['module_advanced'];
2360
  }
2361
  }
2362
 
2369
  * @param array $config The alias config.
2370
  * @return void
2371
  */
2372
+ static public function register_module_alias( $alias, $config ) {
 
2373
  if ( isset( self::$module_aliases[ $alias ] ) ) {
2374
  _doing_it_wrong( __CLASS__ . '::register_module_alias', sprintf( _x( 'The module alias %s already exists! Please namespace your module aliases to ensure compatibility with Beaver Builder.', '%s stands for the module alias key', 'fl-builder' ), $alias ), '1.10' );
2375
  return;
2394
  * @param string $alias The alias key.
2395
  * @return array|null
2396
  */
2397
+ static public function get_module_alias_settings( $alias ) {
 
2398
  if ( isset( self::$module_aliases[ $alias ] ) ) {
2399
  return self::$module_aliases[ $alias ]->settings;
2400
  }
2410
  * @param array $type The module's type slug.
2411
  * @return void
2412
  */
2413
+ static public function is_module_registered( $type ) {
 
2414
  return isset( self::$modules[ $type ] );
2415
  }
2416
 
2420
  * @since 1.0
2421
  * @return array
2422
  */
2423
+ static public function get_enabled_modules() {
 
2424
  $default = array_keys( self::$modules );
2425
  $default[] = 'all';
2426
  $setting = self::get_admin_settings_option( '_fl_builder_enabled_modules', true );
2443
  * @param bool $show_disabled Whether to include disabled modules in the result.
2444
  * @return array
2445
  */
2446
+ static public function get_categorized_modules( $show_disabled = false ) {
 
2447
  $enabled_modules = self::get_enabled_modules();
2448
  $widgets = null;
2449
  $categories = array();
2454
  }
2455
 
2456
  // Get the core category keys.
2457
+ $basic_key = __( 'Basic Modules', 'fl-builder' );
2458
+ $advanced_key = __( 'Advanced Modules', 'fl-builder' );
2459
+ $other_key = __( 'Other Modules', 'fl-builder' );
2460
+ $widgets_key = __( 'WordPress Widgets', 'fl-builder' );
2461
 
2462
  // Build the default category arrays.
2463
  $categories[ $basic_key ] = array();
2465
  $categories[ $other_key ] = array();
2466
 
2467
  // Build the categories array.
2468
+ foreach ( self::$modules as $module ) {
2469
 
2470
  if ( ! $module->enabled ) {
2471
  continue;
2472
+ } elseif ( ! in_array( $module->slug, $enabled_modules ) && ! $show_disabled ) {
 
2473
  continue;
2474
+ } elseif ( 'widget' == $module->slug ) {
 
2475
  $widgets = self::get_wp_widgets();
2476
+ } elseif ( isset( $module->category ) ) {
 
2477
 
2478
+ if ( ! isset( $categories[ $module->category ] ) ) {
2479
+ $categories[ $module->category ] = array();
2480
  }
2481
 
2482
+ $categories[ $module->category ][ $module->name ] = $module;
2483
+ } else {
2484
+ $categories[ $other_key ][ $module->name ] = $module;
 
2485
  }
2486
  }
2487
 
2500
 
2501
  // Add widgets if we have them.
2502
  if ( $widgets ) {
2503
+ $categories[ $widgets_key ] = $widgets;
2504
  }
2505
 
2506
  // Sort the modules.
2507
+ foreach ( $categories as $title => $modules ) {
2508
+ if ( count( $categories[ $title ] ) == 0 ) {
2509
+ unset( $categories[ $title ] );
2510
+ } else {
2511
+ ksort( $categories[ $title ] );
 
2512
  }
2513
  }
2514
 
2523
  * @param string $name The category name.
2524
  * @return string
2525
  */
2526
+ static public function get_module_category_slug( $name ) {
 
2527
  // Get the core category keys.
2528
+ $basic_key = __( 'Basic Modules', 'fl-builder' );
2529
+ $advanced_key = __( 'Advanced Modules', 'fl-builder' );
2530
+ $other_key = __( 'Other Modules', 'fl-builder' );
2531
+ $widgets_key = __( 'WordPress Widgets', 'fl-builder' );
2532
 
2533
  if ( $name == $basic_key ) {
2534
  return 'basic';
2553
  * @param string|object $node_id A module node ID or object.
2554
  * @return object|bool The module or false if it doesn't exist.
2555
  */
2556
+ static public function get_module( $node_id ) {
 
2557
  $module = is_object( $node_id ) ? $node_id : self::get_node( $node_id );
2558
 
2559
+ if ( self::is_module_registered( $module->settings->type ) ) {
2560
 
2561
+ $class = get_class( self::$modules[ $module->settings->type ] );
2562
  $instance = new $class();
2563
  $instance->node = $module->node;
2564
  $instance->parent = $module->parent;
2565
  $instance->position = $module->position;
2566
  $instance->settings = $module->settings;
2567
  $instance->type = 'module';
2568
+ $instance->form = self::$modules[ $module->settings->type ]->form;
2569
 
2570
  if ( isset( $module->template_id ) ) {
2571
  $instance->template_id = $module->template_id;
2589
  * @param string|object $col_id A column ID or object.
2590
  * @return array
2591
  */
2592
+ static public function get_modules( $col_id = null ) {
 
2593
  $col = is_object( $col_id ) ? $col_id : self::get_node( $col_id );
2594
+ $modules = self::get_nodes( 'module', $col );
2595
  $instances = array();
2596
  $i = 0;
2597
 
2598
+ foreach ( $modules as $module ) {
2599
 
2600
  if ( self::is_module_registered( $module->settings->type ) ) {
2601
 
2602
+ $class = get_class( self::$modules[ $module->settings->type ] );
2603
+ $instances[ $i ] = new $class();
2604
+ $instances[ $i ]->node = $module->node;
2605
+ $instances[ $i ]->parent = $module->parent;
2606
+ $instances[ $i ]->position = $module->position;
2607
+ $instances[ $i ]->settings = $module->settings;
2608
+ $instances[ $i ]->type = 'module';
2609
+ $instances[ $i ]->form = self::$modules[ $module->settings->type ]->form;
2610
 
2611
  if ( isset( $module->template_id ) ) {
2612
+ $instances[ $i ]->template_id = $module->template_id;
2613
+ $instances[ $i ]->template_node_id = $module->template_node_id;
2614
  }
2615
  if ( isset( $module->template_root_node ) ) {
2616
+ $instances[ $i ]->template_root_node = true;
2617
  }
2618
 
2619
  $i++;
2629
  * @since 1.0
2630
  * @return array
2631
  */
2632
+ static public function get_all_modules() {
 
2633
  return self::get_modules();
2634
  }
2635
 
2643
  * @param int $position The new module's position.
2644
  * @return object The new module object.
2645
  */
2646
+ static public function add_module( $type = null, $settings = array(), $parent_id = null, $position = false ) {
 
2647
  $data = self::get_layout_data();
2648
  $parent = self::get_node( $parent_id );
2649
  $module_node_id = self::generate_node_id();
2650
  $settings->type = $type;
2651
 
2652
  // Run module update method.
2653
+ $class = get_class( self::$modules[ $type ] );
2654
  $instance = new $class();
2655
  $instance->node = $module_node_id;
2656
  $instance->settings = $settings;
2657
+ $settings = $instance->update( $settings );
2658
 
2659
  // Save the module.
2660
+ $data[ $module_node_id ] = new StdClass();
2661
+ $data[ $module_node_id ]->node = $module_node_id;
2662
+ $data[ $module_node_id ]->type = 'module';
2663
+ $data[ $module_node_id ]->parent = $parent_id;
2664
+ $data[ $module_node_id ]->position = self::next_node_position( 'module', $parent_id );
2665
+ $data[ $module_node_id ]->settings = $settings;
2666
 
2667
  // Add node template data.
2668
  if ( self::is_node_global( $parent ) ) {
2669
+ $data[ $module_node_id ]->template_id = $parent->template_id;
2670
+ $data[ $module_node_id ]->template_node_id = $module_node_id;
2671
  }
2672
 
2673
  // Update the layout data.
2674
+ self::update_layout_data( $data );
2675
 
2676
  // Position the module.
2677
+ if ( false !== $position ) {
2678
+ self::reorder_node( $module_node_id, $position );
2679
  }
2680
 
2681
  // Send back the inserted module.
2682
+ return self::get_module( $module_node_id );
2683
  }
2684
 
2685
  /**
2691
  * @param int $position The position of the parent.
2692
  * @return string|null The new parent ID or null if none exists.
2693
  */
2694
+ static public function add_module_parent( $parent_id = null, $position = null ) {
 
2695
  $parent = ! $parent_id ? null : self::get_node( $parent_id );
2696
 
2697
  // Add a new row if we don't have a parent.
2702
  $cols = self::get_nodes( 'column', $col_group->node );
2703
  $parent = array_shift( $cols );
2704
  $parent_id = $parent->node;
2705
+ } // End if().
2706
+ elseif ( 'row' == $parent->type ) {
 
 
2707
  $col_group = self::add_col_group( $parent->node, '1-col', $position );
2708
  $cols = self::get_nodes( 'column', $col_group->node );
2709
  $parent = array_shift( $cols );
2710
  $parent_id = $parent->node;
2711
+ } // Add a new column if the parent is a column group.
2712
+ elseif ( 'column-group' == $parent->type ) {
 
 
2713
  $parent = self::add_col( $parent->node, $position );
2714
  $parent_id = $parent->node;
2715
  }
2725
  * @param string|object $module_id The module's node ID. Can also be a module object.
2726
  * @return object The parent node.
2727
  */
2728
+ static public function get_module_parent( $type, $module_id ) {
 
2729
  $module = is_object( $module_id ) ? $module_id : self::get_module( $module_id );
2730
  $nodes = self::get_categorized_nodes();
2731
 
2770
  * @return object The new module object.
2771
  * @return array $defaults Default settings for the module.
2772
  */
2773
+ static public function add_default_module( $parent_id = null, $type = null, $position = null, $defaults = null ) {
2774
+ $parent = 0 == $parent_id ? null : self::get_node( $parent_id );
2775
+ $settings = self::get_module_defaults( $type );
 
2776
  $module_node_id = self::generate_node_id();
2777
 
2778
  // Add a new parent if one is needed.
2784
 
2785
  // Merge default settings if present.
2786
  if ( $defaults ) {
2787
+ $settings = (object) array_merge( (array) $settings, $defaults );
2788
  }
2789
 
2790
  // Run module update method.
2791
+ $class = get_class( self::$modules[ $type ] );
2792
  $instance = new $class();
2793
  $instance->node = $module_node_id;
2794
  $instance->settings = $settings;
2795
+ $settings = $instance->update( $settings );
2796
 
2797
  // Save the module.
2798
  $data = self::get_layout_data();
2799
+ $data[ $module_node_id ] = new StdClass();
2800
+ $data[ $module_node_id ]->node = $module_node_id;
2801
+ $data[ $module_node_id ]->type = 'module';
2802
+ $data[ $module_node_id ]->parent = $parent_id;
2803
+ $data[ $module_node_id ]->position = self::next_node_position( 'module', $parent_id );
2804
+ $data[ $module_node_id ]->settings = $settings;
2805
 
2806
  // Add node template data.
2807
  if ( self::is_node_global( $parent ) ) {
2808
+ $data[ $module_node_id ]->template_id = $parent->template_id;
2809
+ $data[ $module_node_id ]->template_node_id = $module_node_id;
2810
  }
2811
 
2812
  // Update the layout data.
2813
+ self::update_layout_data( $data );
2814
 
2815
  // Position the module.
2816
+ if ( null !== $position ) {
2817
+ self::reorder_node( $module_node_id, $position );
2818
  }
2819
 
2820
  // Send back the inserted module.
2821
+ return self::get_module( $module_node_id );
2822
  }
2823
 
2824
  /**
2828
  * @param string $node_id Node ID of the module to copy.
2829
  * @return object The new module object.
2830
  */
2831
+ static public function copy_module( $node_id = null ) {
 
2832
  $module = self::get_module( $node_id );
2833
 
2834
  return self::add_module( $module->settings->type, $module->settings, $module->parent, $module->position + 1 );
2842
  * @param object $new_settings The new settings.
2843
  * @return object
2844
  */
2845
+ static public function process_module_settings( $module, $new_settings ) {
 
2846
  // Get a new node instance to work with.
2847
+ $class = get_class( self::$modules[ $module->settings->type ] );
2848
  $instance = new $class();
2849
  $instance->node = $module->node;
2850
 
2854
 
2855
  // Run node update.
2856
  $instance->settings = $new_settings;
2857
+ $new_settings = $instance->update( $new_settings );
2858
 
2859
  return $new_settings;
2860
  }
2866
  * @param object $settings
2867
  * @return object
2868
  */
2869
+ static public function clone_module_settings( $settings ) {
 
2870
  $new_settings = new stdClass;
2871
 
2872
  foreach ( $settings as $key => $val ) {
2883
  * @param string $type The type of module.
2884
  * @return object
2885
  */
2886
+ static public function get_module_defaults( $type ) {
 
2887
  $defaults = new StdClass();
2888
 
2889
+ if ( isset( self::$modules[ $type ]->form ) ) {
2890
  $defaults = self::get_settings_form_defaults( $type );
2891
  $defaults->type = $type;
2892
  }
2902
  * @param object $settings The module settings object.
2903
  * @return object
2904
  */
2905
+ static public function merge_nested_module_defaults( $type, $settings ) {
2906
+ return self::merge_nested_form_defaults( 'module', $type, $settings );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2907
  }
2908
 
2909
  /**
2912
  * @since 1.0
2913
  * @return array
2914
  */
2915
+ static public function get_wp_widgets() {
 
2916
  global $wp_widget_factory;
2917
 
2918
  $widgets = array();
2944
  * @since 1.0
2945
  * @return array
2946
  */
2947
+ static public function get_wp_sidebars() {
 
2948
  global $wp_registered_sidebars;
2949
 
2950
  $sidebars = array();
2951
 
2952
+ foreach ( $wp_registered_sidebars as $sidebar ) {
2953
+ $sidebars[ $sidebar['name'] ] = $sidebar;
2954
  }
2955
 
2956
+ ksort( $sidebars );
2957
 
2958
  return $sidebars;
2959
  }
2964
  * @since 1.0
2965
  * @return void
2966
  */
2967
+ static public function load_settings() {
 
2968
  require_once FL_BUILDER_DIR . 'includes/global-settings.php';
2969
  require_once FL_BUILDER_DIR . 'includes/layout-settings.php';
2970
  require_once FL_BUILDER_DIR . 'includes/row-settings.php';
2980
  * @param array $form The form data.
2981
  * @return void
2982
  */
2983
+ static public function register_settings_form( $id, $form ) {
2984
+ self::$settings_forms[ $id ] = apply_filters( 'fl_builder_register_settings_form', $form, $id );
 
2985
  }
2986
 
2987
  /**
2991
  * @param string $id The form id.
2992
  * @return array
2993
  */
2994
+ static public function get_settings_form( $id ) {
 
2995
  return isset( self::$settings_forms[ $id ] ) ? self::$settings_forms[ $id ] : false;
2996
  }
2997
 
3002
  * @param array $form The form data array.
3003
  * @return array
3004
  */
3005
+ static public function get_settings_form_fields( $form ) {
 
3006
  $fields = array();
3007
 
3008
  foreach ( $form as $tab ) {
3027
  * @param string $type The type of form.
3028
  * @return object
3029
  */
3030
+ static public function get_settings_form_defaults( $type ) {
 
3031
  // Check to see if the defaults are cached first.
3032
  if ( isset( self::$settings_form_defaults[ $type ] ) ) {
3033
  return self::$settings_form_defaults[ $type ];
3040
  if ( isset( self::$settings_forms[ $type ] ) ) {
3041
  $form_type = $type;
3042
  $tabs = self::$settings_forms[ $type ]['tabs'];
3043
+ } // End if().
3044
+ elseif ( isset( self::$modules[ $type ] ) ) {
 
3045
  $form_type = $type . '-module';
3046
  $tabs = self::$modules[ $type ]->form;
3047
+ } // The form can't be found.
 
3048
  else {
3049
  return $defaults;
3050
  }
3053
  $fields = self::get_settings_form_fields( $tabs );
3054
 
3055
  // Loop through the fields and get the defaults.
3056
+ foreach ( $fields as $name => $field ) {
3057
 
3058
+ $default = isset( $field['default'] ) ? $field['default'] : '';
3059
+ $is_multiple = isset( $field['multiple'] ) && true === $field['multiple'];
3060
+ $supports_multiple = 'editor' != $field['type'] && 'photo' != $field['type'];
3061
+ $responsive = isset( $field['responsive'] ) && $field['responsive'] ? $field['responsive'] : false;
3062
  $responsive_name = '';
3063
 
3064
+ if ( $is_multiple && $supports_multiple ) {
3065
+ $defaults->$name = array( $default );
3066
+ } elseif ( $responsive ) {
 
3067
 
3068
  foreach ( array( 'default', 'medium', 'responsive' ) as $device ) {
3069
 
3071
 
3072
  if ( is_array( $responsive ) && isset( $responsive['default'] ) && isset( $responsive['default'][ $device ] ) ) {
3073
  $defaults->{ $responsive_name } = $responsive['default'][ $device ];
3074
+ } elseif ( 'default' == $device ) {
 
3075
  $defaults->$name = $default;
3076
+ } else {
 
3077
  $defaults->{ $responsive_name } = '';
3078
  }
3079
  }
3080
+ } else {
 
3081
  $defaults->$name = $default;
3082
  }
3083
  }
3088
  return self::$settings_form_defaults[ $type ];
3089
  }
3090
 
3091
+ /**
3092
+ * Merges the default settings for nested forms.
3093
+ *
3094
+ * @since 1.10.8
3095
+ * @param string $type The type of form.
3096
+ * @param string $form The form ID.
3097
+ * @param object $settings The module settings object.
3098
+ * @return object
3099
+ */
3100
+ static public function merge_nested_form_defaults( $type, $form, $settings ) {
3101
+
3102
+ // Get the fields.
3103
+ if ( 'module' === $type && isset( self::$modules[ $form ] ) ) {
3104
+ $fields = self::get_settings_form_fields( self::$modules[ $form ]->form );
3105
+ } elseif ( isset( self::$settings_forms[ $form ] ) ) {
3106
+ $fields = self::get_settings_form_fields( self::$settings_forms[ $form ]['tabs'] );
3107
+ } else {
3108
+ return $settings;
3109
+ }
3110
+
3111
+ // Loop through the settings.
3112
+ foreach ( $settings as $key => $val ) {
3113
+
3114
+ // Make sure this field is a nested form.
3115
+ if ( ! isset( $fields[ $key ]['form'] ) ) {
3116
+ continue;
3117
+ }
3118
+
3119
+ // Get the nested form defaults.
3120
+ $nested_defaults = self::get_settings_form_defaults( $fields[ $key ]['form'] );
3121
+
3122
+ // Merge the defaults.
3123
+ if ( is_array( $val ) ) {
3124
+ foreach ( $val as $nested_key => $nested_val ) {
3125
+ $settings->{ $key }[ $nested_key ] = (object) array_merge( (array) $nested_defaults, (array) $nested_val );
3126
+ }
3127
+ } elseif ( ! empty( $settings->{ $key } ) ) {
3128
+ $settings->{ $key } = (object) array_merge( (array) $nested_defaults, (array) $settings->{ $key } );
3129
+ } else {
3130
+ $settings->{ $key } = (object) $nested_defaults;
3131
+ }
3132
+ }
3133
+
3134
+ return $settings;
3135
+ }
3136
+
3137
  /**
3138
  * Save the settings for a node.
3139
  *
3142
  * @param object $settings The settings to save.
3143
  * @return void
3144
  */
3145
+ static public function save_settings( $node_id = null, $settings = null ) {
3146
+ $node = self::get_node( $node_id );
3147
+ $new_settings = (object) array_merge( (array) $node->settings, (array) $settings );
 
3148
  $template_post_id = self::is_node_global( $node );
3149
 
3150
  // Process the settings.
3151
+ $new_settings = self::process_node_settings( $node, $new_settings );
3152
 
3153
  // Save the settings to the node.
3154
  $data = self::get_layout_data();
3155
+ $data[ $node_id ]->settings = $new_settings;
3156
 
3157
  // Update the layout data.
3158
+ self::update_layout_data( $data );
3159
 
3160
  // Save settings for a global node template?
3161
  if ( $template_post_id && ! self::is_post_node_template() ) {
3188
  * @param mixed $data The data to slash.
3189
  * @return mixed The slashed data.
3190
  */
3191
+ static public function slash_settings( $data ) {
 
3192
  if ( is_array( $data ) ) {
3193
  foreach ( $data as $key => $val ) {
3194
  $data[ $key ] = self::slash_settings( $val );
3195
  }
3196
+ } elseif ( is_object( $data ) ) {
 
3197
  foreach ( $data as $key => $val ) {
3198
  $data->$key = self::slash_settings( $val );
3199
  }
3200
+ } elseif ( is_string( $data ) ) {
 
3201
  $data = wp_slash( $data );
3202
  }
3203
 
3212
  * @param array $defaults The defaults to merge in.
3213
  * @return void
3214
  */
3215
+ static public function default_settings( &$settings, $defaults ) {
3216
+ foreach ( $defaults as $name => $value ) {
3217
+ if ( ! isset( $settings->$name ) ) {
 
3218
  $settings->$name = $value;
3219
  }
3220
  }
3226
  * @since 1.0
3227
  * @return object
3228
  */
3229
+ static public function get_global_settings() {
 
3230
  if ( null === self::$global_settings ) {
3231
+ $settings = get_option( '_fl_builder_settings' );
3232
  $defaults = self::get_settings_form_defaults( 'global' );
3233
 
3234
+ if ( ! $settings ) {
3235
  $settings = new StdClass();
3236
  }
3237
 
3238
  // Merge in defaults and cache settings
3239
+ self::$global_settings = (object) array_merge( (array) $defaults, (array) $settings );
3240
+ self::$global_settings = self::merge_nested_form_defaults( 'general', 'global', self::$global_settings );
3241
  }
3242
 
3243
  return self::$global_settings;
3250
  * @param array $settings The new global settings.
3251
  * @return object
3252
  */
3253
+ static public function save_global_settings( $settings = array() ) {
 
3254
  $old_settings = self::get_global_settings();
3255
+ $new_settings = (object) array_merge( (array) $old_settings, (array) $settings );
3256
 
3257
  self::delete_asset_cache_for_all_posts();
3258
  self::$global_settings = null;
3259
 
3260
+ update_option( '_fl_builder_settings', $new_settings );
3261
 
3262
  return self::get_global_settings();
3263
  }
3268
  * @since 1.0
3269
  * @return int The new post ID.
3270
  */
3271
+ static public function duplicate_post() {
 
3272
  global $wpdb;
3273
 
3274
  $post_id = self::get_post_id();
3275
+ $post = get_post( $post_id );
3276
  $current_user = wp_get_current_user();
3277
  $template_id = false;
3278
 
3290
  'post_title' => sprintf( _x( 'Copy of %s', '%s stands for post/page title.', 'fl-builder' ), $post->post_title ),
3291
  'post_type' => $post->post_type,
3292
  'to_ping' => $post->to_ping,
3293
+ 'menu_order' => $post->menu_order,
3294
  );
3295
 
3296
  // Get the new post id.
3297
+ $new_post_id = wp_insert_post( $data );
3298
 
3299
  // Duplicate post meta.
3300
  $post_meta = $wpdb->get_results( $wpdb->prepare( "SELECT meta_key, meta_value FROM {$wpdb->postmeta} WHERE post_id = %d", $post_id ) );
3301
 
3302
+ if ( count( $post_meta ) !== 0 ) {
3303
 
3304
  $sql = "INSERT INTO {$wpdb->postmeta} (post_id, meta_key, meta_value) ";
3305
 
3306
+ foreach ( $post_meta as $meta_info ) {
3307
  $meta_key = $meta_info->meta_key;
3308
 
3309
+ if ( '_fl_builder_template_id' == $meta_key ) {
3310
  $meta_value = self::generate_node_id();
3311
+ } else {
3312
+ $meta_value = addslashes( $meta_info->meta_value );
 
3313
  }
3314
 
3315
  $sql_select[] = "SELECT {$new_post_id}, '{$meta_key}', '{$meta_value}'";
3316
  }
3317
 
3318
+ $sql .= implode( ' UNION ALL ', $sql_select );
3319
  // @codingStandardsIgnoreStart
3320
  $wpdb->query($sql);
3321
  // @codingStandardsIgnoreEnd
3322
  }
3323
 
3324
  // Duplicate post terms.
3325
+ $taxonomies = get_object_taxonomies( $post->post_type );
3326
 
3327
+ foreach ( $taxonomies as $taxonomy ) {
3328
 
3329
+ $post_terms = wp_get_object_terms( $post_id, $taxonomy );
3330
 
3331
+ for ( $i = 0; $i < count( $post_terms ); $i++ ) {
3332
+ wp_set_object_terms( $new_post_id, $post_terms[ $i ]->slug, $taxonomy, true );
3333
  }
3334
  }
3335
 
3336
  // Get the duplicated layout data.
3337
+ $data = self::get_layout_data( 'published', $new_post_id );
3338
 
3339
  // Generate new node ids.
3340
+ $data = self::generate_new_node_ids( $data );
3341
 
3342
  // Update template ID and template node ID
3343
  $template_id = get_post_meta( $new_post_id, '_fl_builder_template_id', true );
3349
  }
3350
 
3351
  // Save the duplicated layout data.
3352
+ self::update_layout_data( $data, 'published', $new_post_id );
3353
 
3354
  // Also update draft data
3355
+ self::update_layout_data( $data, 'draft', $new_post_id );
3356
 
3357
  // Return the new post id.
3358
  return $new_post_id;
3365
  * @param int $post_id The post ID to delete data and cache for.
3366
  * @return void
3367
  */
3368
+ static public function delete_post( $post_id ) {
 
3369
  // If this is a global template, unlink it from other posts.
3370
  self::unlink_global_node_template_from_all_posts( $post_id );
3371
 
3384
  * @param int $post_id
3385
  * @return void
3386
  */
3387
+ static public function save_revision( $post_id ) {
3388
+ $parent_id = wp_is_post_revision( $post_id );
 
3389
 
3390
+ if ( $parent_id ) {
3391
 
3392
+ $parent = get_post( $parent_id );
3393
+ $data = self::get_layout_data( 'published', $parent->ID );
3394
+ $settings = self::get_layout_settings( 'published', $parent->ID );
3395
 
3396
+ if ( ! empty( $data ) ) {
3397
+ self::update_layout_data( $data, 'published', $post_id );
3398
+ self::update_layout_settings( $settings, 'published', $post_id );
3399
  }
3400
  }
3401
  }
3408
  * @param int $revision_id
3409
  * @return void
3410
  */
3411
+ static public function restore_revision( $post_id, $revision_id ) {
3412
+ $post = get_post( $post_id );
3413
+ $revision = get_post( $revision_id );
 
3414
 
3415
+ if ( $revision ) {
3416
 
3417
+ $data = self::get_layout_data( 'published', $revision->ID );
3418
+ $settings = self::get_layout_settings( 'published', $revision->ID );
3419
 
3420
+ if ( ! empty( $data ) ) {
3421
+ self::update_layout_data( $data, 'published', $post_id );
3422
+ self::update_layout_data( $data, 'draft', $post_id );
3423
+ self::update_layout_settings( $settings, 'published', $post_id );
3424
+ self::update_layout_settings( $settings, 'draft', $post_id );
3425
+ } else {
3426
+ self::delete_layout_data( 'published', $post_id );
3427
+ self::delete_layout_data( 'draft', $post_id );
3428
+ self::delete_layout_settings( 'published', $post_id );
3429
+ self::delete_layout_settings( 'draft', $post_id );
 
3430
  }
3431
 
3432
  self::delete_all_asset_cache( $post_id );
3442
  * @param int $post_id The ID of the post to get data for.
3443
  * @return array
3444
  */
3445
+ static public function get_layout_data( $status = null, $post_id = null ) {
3446
+ $post_id = ! $post_id ? self::get_post_id() : $post_id;
3447
+ $status = ! $status ? self::get_node_status() : $status;
 
3448
 
3449
  // Get published data?
3450
+ if ( 'published' == $status ) {
3451
+ if ( isset( self::$published_layout_data[ $post_id ] ) ) {
3452
+ $data = self::$published_layout_data[ $post_id ];
3453
+ } else {
3454
+ $data = get_metadata( 'post', $post_id, '_fl_builder_data', true );
3455
+ self::$published_layout_data[ $post_id ] = self::clean_layout_data( $data );
 
 
 
 
 
 
 
3456
  }
3457
+ } // End if().
3458
+ elseif ( 'draft' == $status ) {
3459
+ if ( isset( self::$draft_layout_data[ $post_id ] ) ) {
3460
+ $data = self::$draft_layout_data[ $post_id ];
3461
+ } else {
3462
+ $data = get_metadata( 'post', $post_id, '_fl_builder_draft', true );
3463
+ self::$draft_layout_data[ $post_id ] = self::clean_layout_data( $data );
3464
  }
3465
  }
3466
 
3467
  // Make sure we have an array.
3468
+ if ( empty( $data ) ) {
3469
  $data = array();
3470
  }
3471
 
3472
  // Clone the layout data to ensure the cache remains intact.
3473
+ foreach ( $data as $node_id => $node ) {
3474
+ if ( is_object( $node ) ) {
3475
+ $data[ $node_id ] = clone $node;
3476
+ }
3477
  }
3478
 
3479
  // Return the data.
3490
  * @param int $post_id The ID of the post to update.
3491
  * @return void
3492
  */
3493
+ static public function update_layout_data( $data, $status = null, $post_id = null ) {
3494
+ $post_id = ! $post_id ? self::get_post_id() : $post_id;
3495
+ $status = ! $status ? self::get_node_status() : $status;
 
3496
  $key = 'published' == $status ? '_fl_builder_data' : '_fl_builder_draft';
3497
  $raw_data = get_metadata( 'post', $post_id, $key );
3498
  $data = self::slash_settings( self::clean_layout_data( $data ) );
3500
  // Update the data.
3501
  if ( 0 === count( $raw_data ) ) {
3502
  add_metadata( 'post', $post_id, $key, $data );
3503
+ } else {
 
3504
  update_metadata( 'post', $post_id, $key, $data );
3505
  }
3506
 
3507
  // Cache the data.
3508
+ if ( 'published' == $status ) {
3509
+ self::$published_layout_data[ $post_id ] = $data;
3510
+ } elseif ( 'draft' == $status ) {
3511
+ self::$draft_layout_data[ $post_id ] = $data;
 
3512
  }
3513
  }
3514
 
3520
  * @param int $post_id The ID of the post to delete data.
3521
  * @return void
3522
  */
3523
+ static public function delete_layout_data( $status = null, $post_id = null ) {
 
3524
  // Make sure we have a status to delete.
3525
+ if ( ! $status ) {
3526
  return;
3527
  }
3528
 
3529
  // Get the post id.
3530
+ $post_id = ! $post_id ? self::get_post_id() : $post_id;
3531
 
3532
  // Get the data to delete.
3533
+ $data = self::get_layout_data( $status, $post_id );
3534
 
3535
  // Delete the nodes.
3536
+ foreach ( $data as $node ) {
3537
+ self::call_module_delete( $node );
3538
  }
3539
 
3540
  // Update the layout data.
3541
+ self::update_layout_data( array(), $status, $post_id );
3542
  }
3543
 
3544
  /**
3551
  * @param array $data An array of layout data.
3552
  * @return array
3553
  */
3554
+ static public function clean_layout_data( $data = array() ) {
 
3555
  $cleaned = array();
3556
 
3557
  if ( is_array( $data ) ) {
3567
  $cleaned[ $node->node ]->parent = $node->parent;
3568
  $cleaned[ $node->node ]->position = $node->position;
3569
  $cleaned[ $node->node ]->settings = $node->settings;
3570
+ } else {
 
3571
  $cleaned[ $node->node ] = $node;
3572
  }
3573
  }
3585
  * @param int $post_id The ID of the post to get settings for.
3586
  * @return object
3587
  */
3588
+ static public function get_layout_settings( $status = null, $post_id = null ) {
 
3589
  $status = ! $status ? self::get_node_status() : $status;
3590
  $post_id = ! $post_id ? self::get_post_id() : $post_id;
3591
  $key = 'published' == $status ? '_fl_builder_data_settings' : '_fl_builder_draft_settings';
3596
  $settings = new StdClass();
3597
  }
3598
 
3599
+ $settings = (object) array_merge( (array) $defaults, (array) $settings );
3600
 
3601
  return apply_filters( 'fl_builder_layout_settings', $settings, $status, $post_id );
3602
  }
3610
  * @param int $post_id The ID of the post to update.
3611
  * @return object
3612
  */
3613
+ static public function update_layout_settings( $settings = array(), $status = null, $post_id = null ) {
 
3614
  $status = ! $status ? self::get_node_status() : $status;
3615
  $post_id = ! $post_id ? self::get_post_id() : $post_id;
3616
  $key = 'published' == $status ? '_fl_builder_data_settings' : '_fl_builder_draft_settings';
3617
  $raw_settings = get_metadata( 'post', $post_id, $key );
3618
  $old_settings = self::get_layout_settings( $status, $post_id );
3619
+ $new_settings = (object) array_merge( (array) $old_settings, (array) $settings );
3620
 
3621
  if ( 0 === count( $raw_settings ) ) {
3622
  add_metadata( 'post', $post_id, $key, self::slash_settings( $new_settings ) );
3623
+ } else {
 
3624
  update_metadata( 'post', $post_id, $key, self::slash_settings( $new_settings ) );
3625
  }
3626
 
3636
  * @param int $post_id The ID of the post to update.
3637
  * @return object
3638
  */
3639
+ static public function save_layout_settings( $settings = array(), $status = null, $post_id = null ) {
 
3640
  return self::update_layout_settings( $settings, $status, $post_id );
3641
  }
3642
 
3648
  * @param int $post_id The ID of a post whose settings to delete.
3649
  * @return void
3650
  */
3651
+ static public function delete_layout_settings( $status = null, $post_id = null ) {
 
3652
  $status = ! $status ? self::get_node_status() : $status;
3653
  $post_id = ! $post_id ? self::get_post_id() : $post_id;
3654
  $key = 'published' == $status ? '_fl_builder_data_settings' : '_fl_builder_draft_settings';
3664
  * @param object $merge_settings The layout settings to merge.
3665
  * @return object
3666
  */
3667
+ static public function merge_layout_settings( $settings, $merge_settings ) {
 
3668
  $keys = array( 'css', 'js' );
3669
 
3670
  foreach ( $keys as $key ) {
3671
 
3672
  if ( empty( $merge_settings->{$key} ) ) {
3673
  continue;
3674
+ } elseif ( strstr( $settings->{$key}, $merge_settings->{$key} ) ) {
 
3675
  continue;
3676
+ } else {
 
3677
 
3678
  if ( ! empty( $settings->{$key} ) ) {
3679
  $settings->{$key} .= "\n";
3693
  * @since 1.0
3694
  * @return void
3695
  */
3696
+ static public function clear_draft_layout() {
 
3697
  $post_id = self::get_post_id();
3698
+ $data = self::get_layout_data( 'published', $post_id );
3699
+ $settings = self::get_layout_settings( 'published', $post_id );
3700
 
3701
  // Delete the old draft layout.
3702
+ self::delete_layout_data( 'draft' );
3703
 
3704
  // Save the new draft layout.
3705
+ self::update_layout_data( $data, 'draft', $post_id );
3706
 
3707
  // Save the new draft layout settings.
3708
+ self::update_layout_settings( $settings, 'draft', $post_id );
3709
 
3710
  // Clear the asset cache.
3711
+ self::delete_all_asset_cache( $post_id );
3712
  }
3713
 
3714
  /**
3718
  * @param bool $publish Whether to publish the parent post or not.
3719
  * @return void
3720
  */
3721
+ static public function save_layout( $publish = true ) {
 
3722
  $editor_content = FLBuilder::render_editor_content();
3723
  $post_id = self::get_post_id();
3724
+ $data = self::get_layout_data( 'draft', $post_id );
3725
+ $settings = self::get_layout_settings( 'draft', $post_id );
3726
 
3727
  // Fire the before action.
3728
  do_action( 'fl_builder_before_save_layout', $post_id, $publish, $data, $settings );
3729
 
3730
  // Delete the old published layout.
3731
+ self::delete_layout_data( 'published', $post_id );
3732
+ self::delete_layout_settings( 'published', $post_id );
3733
 
3734
  // Save the new published layout.
3735
+ self::update_layout_data( $data, 'published', $post_id );
3736
+ self::update_layout_settings( $settings, 'published', $post_id );
3737
 
3738
  // Clear the asset cache.
3739
+ self::delete_all_asset_cache( $post_id );
3740
+ self::delete_node_template_asset_cache( $post_id );
3741
 
3742
  // Enable the builder to take over the post content.
3743
  self::enable();
3744
 
3745
  // Get the post status.
3746
+ $post_status = get_post_status( $post_id );
3747
 
3748
  // Publish the post?
3749
  if ( $publish ) {
3750
 
3751
+ $is_draft = strstr( $post_status, 'draft' );
3752
+ $is_pending = strstr( $post_status, 'pending' );
3753
 
3754
  if ( current_user_can( 'publish_posts' ) ) {
3755
  $post_status = $is_draft || $is_pending ? 'publish' : $post_status;
3756
+ } elseif ( $is_draft ) {
 
3757
  $post_status = 'pending';
3758
  }
3759
  }
3762
  wp_update_post(array(
3763
  'ID' => self::get_post_id(),
3764
  'post_status' => $post_status,
3765
+ 'post_content' => $editor_content,
3766
  ));
3767
 
3768
  // Fire the after action.
3779
  * @since 1.6.1
3780
  * @return void
3781
  */
3782
+ static public function save_draft() {
 
3783
  $post_id = self::get_post_id();
3784
  $post_status = get_post_status( $post_id );
3785
 
3797
  * @param int $new_post_id
3798
  * @return array
3799
  */
3800
+ static public function duplicate_wpml_layout( $original_post_id = null, $new_post_id = null ) {
 
3801
  $post_data = self::get_post_data();
3802
+ $original_post_id = isset( $post_data['original_post_id'] ) ? $post_data['original_post_id'] : $original_post_id;
3803
+ $new_post_id = isset( $post_data['post_id'] ) ? $post_data['post_id'] : $new_post_id;
3804
+ $enabled = get_post_meta( $original_post_id, '_fl_builder_enabled', true );
3805
+ $published = self::get_layout_data( 'published', $original_post_id );
3806
+ $draft = self::get_layout_data( 'draft', $original_post_id );
3807
 
3808
  $response = array(
3809
  'enabled' => false,
3810
+ 'has_layout' => false,
3811
  );
3812
 
3813
+ if ( ! empty( $enabled ) ) {
3814
+ update_post_meta( $new_post_id, '_fl_builder_enabled', true );
3815
  $response['enabled'] = true;
3816
  }
3817
+ if ( ! empty( $published ) ) {
3818
+ self::update_layout_data( $published, 'published', $new_post_id );
3819
  $response['has_layout'] = true;
3820
  }
3821
+ if ( ! empty( $draft ) ) {
3822
+ self::update_layout_data( $draft, 'draft', $new_post_id );
3823
  $response['has_layout'] = true;
3824
  }
3825
 
3832
  * @since 1.1.3
3833
  * @return string
3834
  */
3835
+ static public function get_enabled_templates() {
 
3836
  $value = self::get_admin_settings_option( '_fl_builder_enabled_templates', true );
3837
 
3838
  return ! $value ? 'enabled' : $value;
3845
  * @param string $type The type of user template to check for.
3846
  * @return bool
3847
  */
3848
+ static public function is_post_user_template( $type = null ) {
 
3849
  $post = FLBuilderModel::get_post();
3850
 
3851
  if ( ! $post ) {
3852
  return false;
3853
+ } elseif ( 'fl-builder-template' == $post->post_type ) {
 
3854
 
3855
  if ( null === $type ) {
3856
  return true;
3857
+ } else {
 
3858
 
3859
  $saved_type = self::get_user_template_type( $post->ID );
3860
 
3873
  * @since 1.1.3
3874
  * @return void
3875
  */
3876
+ static public function save_user_template( $settings = array() ) {
 
3877
  // Save the user template post.
3878
  $post_id = wp_insert_post(array(
3879
  'post_title' => $settings['name'],
3880
  'post_type' => 'fl-builder-template',
3881
  'post_status' => 'publish',
3882
  'ping_status' => 'closed',
3883
+ 'comment_status' => 'closed',
3884
  ));
3885
 
3886
  // Set the template type.
3891
  $settings = self::get_layout_settings();
3892
 
3893
  // Generate new node ids.
3894
+ $data = self::generate_new_node_ids( $data );
3895
 
3896
  // Save the template layout data and settings.
3897
+ self::update_layout_data( $data, 'published', $post_id );
3898
+ self::update_layout_settings( $settings, 'published', $post_id );
3899
 
3900
  // Enable the builder for this template.
3901
+ update_post_meta( $post_id, '_fl_builder_enabled', true );
3902
 
3903
  // Allow extensions to hook into saving a user template.
3904
  do_action( 'fl_builder_after_save_user_template', $post_id );
3912
  * @param string $type The type of user template to return.
3913
  * @return array
3914
  */
3915
+ static public function get_user_templates( $type = 'layout' ) {
 
3916
  $categorized = array(
3917
  'uncategorized' => array(
3918
  'name' => _x( 'Uncategorized', 'Default user template category.', 'fl-builder' ),
3919
+ 'templates' => array(),
3920
+ ),
3921
  );
3922
 
3923
  $posts = get_posts( array(
3929
  array(
3930
  'taxonomy' => 'fl-builder-template-type',
3931
  'field' => 'slug',
3932
+ 'terms' => $type,
3933
+ ),
3934
+ ),
3935
  ) );
3936
 
3937
  $templates = array();
3938
 
3939
  // Loop through templates posts and build the templates array.
3940
+ foreach ( $posts as $post ) {
3941
 
3942
  if ( has_post_thumbnail( $post->ID ) ) {
3943
  $image_data = wp_get_attachment_image_src( get_post_thumbnail_id( $post->ID ), 'medium' );
3944
  $image = $image_data[0];
3945
+ } else {
 
3946
  $image = FL_BUILDER_URL . 'img/templates/blank.jpg';
3947
  }
3948
 
3950
  'id' => $post->ID,
3951
  'name' => $post->post_title,
3952
  'image' => $image,
3953
+ 'type' => 'user',
3954
  );
3955
  }
3956
 
3961
 
3962
  if ( 0 === count( $cats ) || is_wp_error( $cats ) ) {
3963
  $categorized['uncategorized']['templates'][] = $template;
3964
+ } else {
 
3965
 
3966
  foreach ( $cats as $cat ) {
3967
 
3968
  if ( ! isset( $categorized[ $cat->slug ] ) ) {
3969
  $categorized[ $cat->slug ] = array(
3970
  'name' => $cat->name,
3971
+ 'templates' => array(),
3972
  );
3973
  }
3974
 
3987
 
3988
  return array(
3989
  'templates' => $templates,
3990
+ 'categorized' => $categorized,
3991
  );
3992
  }
3993
 
3998
  * @param int $template_id The post ID of the template.
3999
  * @return string
4000
  */
4001
+ static public function get_user_template_type( $template_id = null ) {
 
4002
  if ( $template_id && isset( self::$node_template_types[ $template_id ] ) ) {
4003
  return self::$node_template_types[ $template_id ];
4004
  }
4007
 
4008
  if ( 'fl-builder-template' != $post->post_type ) {
4009
  return '';
4010
+ } else {
 
4011
 
4012
  $terms = wp_get_post_terms( $post->ID, 'fl-builder-template-type' );
4013
 
4026
  * @param int $template_id The post ID of the template to delete.
4027
  * @return void
4028
  */
4029
+ static public function delete_user_template( $template_id = null ) {
4030
+ if ( isset( $template_id ) ) {
4031
+ wp_delete_post( $template_id, true );
 
4032
  }
4033
  }
4034
 
4040
  * @param bool $append Whether to append the new template or replacing the existing layout.
4041
  * @return void
4042
  */
4043
+ static public function apply_user_template( $template = null, $append = false ) {
4044
+ if ( $template ) {
 
4045
 
4046
  // Delete existing nodes and settings?
4047
+ if ( ! $append ) {
4048
+ self::delete_layout_data( 'draft' );
4049
+ self::delete_layout_settings( 'draft' );
4050
  }
4051
 
4052
  // Insert new nodes if this is not a blank template.
4053
+ if ( 'blank' != $template ) {
4054
 
4055
  // Get the template data if $template is not an object.
4056
  if ( ! is_object( $template ) ) {
4057
  $template_id = $template;
4058
  $template = new StdClass();
4059
+ $template->nodes = self::get_layout_data( 'published', $template_id );
4060
+ $template->settings = self::get_layout_settings( 'published', $template_id );
4061
  }
4062
 
4063
  // Get new ids for the template nodes.
4064
+ $template->nodes = self::generate_new_node_ids( $template->nodes );
4065
 
4066
  // Get the existing layout data and settings.
4067
  $layout_data = self::get_layout_data();
4068
  $layout_settings = self::get_layout_settings();
4069
 
4070
  // Reposition rows if we are appending.
4071
+ if ( $append ) {
4072
 
4073
+ $row_position = self::next_node_position( 'row' );
4074
 
4075
+ foreach ( $template->nodes as $node_id => $node ) {
4076
 
4077
+ if ( 'row' == $node->type ) {
4078
+ $template->nodes[ $node_id ]->position += $row_position;
4079
  }
4080
  }
4081
  }
4082
 
4083
  // Merge the layout data and settings.
4084
+ $data = array_merge( $layout_data, $template->nodes );
4085
  $settings = self::merge_layout_settings( $layout_settings, $template->settings );
4086
 
4087
  // Update the layout data and settings.
4088
+ self::update_layout_data( $data );
4089
  self::update_layout_settings( $settings );
4090
 
4091
  // Delete old asset cache.
4092
  self::delete_asset_cache();
4093
 
4094
  return array(
4095
+ 'layout_css' => $settings->css,
4096
  );
4097
+ }// End if().
4098
+ }// End if().
4099
  }
4100
 
4101
  /**
4104
  * @since 1.6.3
4105
  * @return bool
4106
  */
4107
+ static public function node_templates_enabled() {
 
4108
  $enabled_templates = self::get_enabled_templates();
4109
 
4110
  if ( true === FL_BUILDER_LITE ) {
4124
  * @param int $post_id If supplied, this post will be checked instead.
4125
  * @return bool
4126
  */
4127
+ static public function is_post_node_template( $post_id = false ) {
 
4128
  $post_id = $post_id ? $post_id : self::get_post_id();
4129
  $post = get_post( $post_id );
4130
 
4131
  if ( ! $post ) {
4132
  return false;
4133
+ } elseif ( 'fl-builder-template' == $post->post_type ) {
 
4134
 
4135
  $saved_type = self::get_user_template_type( $post->ID );
4136
 
4149
  * @param int $post_id If supplied, this post will be checked instead.
4150
  * @return bool
4151
  */
4152
+ static public function is_post_global_node_template( $post_id = false ) {
 
4153
  $post_id = $post_id ? $post_id : self::get_post_id();
4154
 
4155
  if ( ! self::is_post_node_template( $post_id ) ) {
4172
  * @param object $node The node object to check.
4173
  * @return bool|int
4174
  */
4175
+ static public function is_node_global( $node ) {
 
4176
  if ( ! isset( $node->template_id ) ) {
4177
  return false;
4178
  }
4187
  * @param object $node The type of object to check
4188
  * @return bool
4189
  */
4190
+ static public function is_node_visible( $node ) {
 
4191
  global $wp_the_query;
4192
 
4193
  $is_visible = true;
4194
 
4195
+ if ( self::is_builder_active() && self::get_post_id() == $wp_the_query->post->ID ) {
4196
  return $is_visible;
4197
  }
4198
 
4199
  if ( isset( $node->settings->visibility_display ) && ('' != $node->settings->visibility_display) ) {
4200
 
4201
  // For logged out users
4202
+ if ( 'logged_out' == $node->settings->visibility_display && ! is_user_logged_in() ) {
4203
  $is_visible = true;
4204
+ } // End if().
4205
+ elseif ( 'logged_in' == $node->settings->visibility_display && is_user_logged_in() ) {
 
4206
  $is_visible = true;
4207
 
4208
  // User capability setting
4209
+ if ( isset( $node->settings->visibility_user_capability ) && ! empty( $node->settings->visibility_user_capability ) ) {
4210
+ if ( self::current_user_has_capability( trim( $node->settings->visibility_user_capability ) ) ) {
4211
  $is_visible = true;
4212
+ } else {
 
4213
  $is_visible = false;
4214
  }
4215
  }
4216
+ } // Never
4217
+ elseif ( 0 == $node->settings->visibility_display ) {
 
4218
  $is_visible = false;
4219
  } else {
4220
  $is_visible = false;
4221
  }
 
4222
  }
4223
 
4224
  return apply_filters( 'fl_builder_is_node_visible', $is_visible, $node );
4231
  * @param object $node The node object to check.
4232
  * @return bool|int
4233
  */
4234
+ static public function is_node_template_root( $node ) {
 
4235
  return self::is_node_global( $node ) && isset( $node->template_root_node );
4236
  }
4237
 
4242
  * @param string $type The type of node template to get.
4243
  * @return array
4244
  */
4245
+ static public function get_node_templates( $type = '' ) {
 
4246
  $posts = get_posts( array(
4247
  'post_type' => 'fl-builder-template',
4248
  'orderby' => 'title',
4252
  array(
4253
  'taxonomy' => 'fl-builder-template-type',
4254
  'field' => 'slug',
4255
+ 'terms' => $type,
4256
+ ),
4257
+ ),
4258
  ) );
4259
 
4260
  $templates = array();
4265
  'id' => get_post_meta( $post->ID, '_fl_builder_template_id', true ),
4266
  'global' => get_post_meta( $post->ID, '_fl_builder_template_global', true ),
4267
  'link' => add_query_arg( 'fl_builder', '', get_permalink( $post->ID ) ),
4268
+ 'name' => $post->post_title,
4269
  );
4270
  }
4271
 
4280
  * @param array $nodes The node template data.
4281
  * @return object
4282
  */
4283
+ static public function get_node_template_root( $type = '', $nodes = array() ) {
 
4284
  foreach ( $nodes as $node ) {
4285
  if ( $type == $node->type ) {
4286
  return $node;
4297
  * @param string $template_id The node template ID as stored in the template's post meta.
4298
  * @return int
4299
  */
4300
+ static public function get_node_template_post_id( $template_id ) {
 
4301
  if ( isset( self::$node_template_post_ids[ $template_id ] ) ) {
4302
  return self::$node_template_post_ids[ $template_id ];
4303
+ } else {
 
4304
 
4305
  $posts = get_posts( array(
4306
  'post_type' => 'fl-builder-template',
4308
  'posts_per_page' => '-1',
4309
  'post_status' => 'any',
4310
  'meta_key' => '_fl_builder_template_id',
4311
+ 'meta_value' => $template_id,
4312
  ) );
4313
 
4314
  if ( 0 === count( $posts ) ) {
4315
  return false;
4316
  }
4317
 
4318
+ self::$node_template_post_ids[ $template_id ] = $posts[0]->ID;
4319
 
4320
+ return $posts[0]->ID;
4321
  }
4322
  }
4323
 
4328
  * @param string $template_id The node template ID as stored in the template's post meta.
4329
  * @return string
4330
  */
4331
+ static public function get_node_template_edit_url( $template_id ) {
 
4332
  return self::get_edit_url( self::get_node_template_post_id( $template_id ) );
4333
  }
4334
 
4340
  * @param int $post_id The post ID of the global node template.
4341
  * @return array
4342
  */
4343
+ static public function get_posts_with_global_node_template( $post_id = false ) {
 
4344
  $posts = array();
4345
 
4346
  if ( self::is_post_global_node_template( $post_id ) ) {
4353
  array(
4354
  'key' => '_fl_builder_data',
4355
  'value' => $template_id,
4356
+ 'compare' => 'LIKE',
4357
  ),
4358
  array(
4359
  'key' => '_fl_builder_draft',
4360
  'value' => $template_id,
4361
+ 'compare' => 'LIKE',
4362
  )
4363
  ),
4364
  'post_type' => 'any',
4365
  'post_status' => 'any',
4366
+ 'post__not_in' => array( $post_id ),
4367
  ) );
4368
 
4369
  $posts = $query->posts;
4380
  * @param string $settings The settings for this template.
4381
  * @return void
4382
  */
4383
+ static public function save_node_template( $template_node_id, $settings ) {
 
4384
  $root_node = self::get_node( $template_node_id );
4385
  $nodes = self::get_nested_nodes( $template_node_id );
4386
  $template_id = self::generate_node_id();
4393
  'post_type' => 'fl-builder-template',
4394
  'post_status' => 'publish',
4395
  'ping_status' => 'closed',
4396
+ 'comment_status' => 'closed',
4397
  ) );
4398
 
4399
  // Set the template type.
4421
 
4422
  if ( $node_id == $root_node->node ) {
4423
  $nodes[ $node_id ]->template_root_node = true;
4424
+ } elseif ( isset( $nodes[ $node_id ]->template_root_node ) ) {
 
4425
  unset( $nodes[ $node_id ]->template_root_node );
4426
  }
4427
  }
4428
+ } // End if().
 
4429
  else {
4430
 
4431
  foreach ( $nodes as $node_id => $node ) {
4474
  'link' => add_query_arg( 'fl_builder', '', get_permalink( $post_id ) ),
4475
  'name' => $settings['name'],
4476
  'type' => $root_node->type,
4477
+ 'layout' => $settings['global'] ? FLBuilderAJAXLayout::render( $root_node->node, $template_node_id ) : null,
4478
  );
4479
  }
4480
 
4487
  * @param bool $update Whether this is a new post or an update.
4488
  * @return void
4489
  */
4490
+ static public function set_node_template_default_type( $post_id, $post, $update ) {
 
4491
  global $pagenow;
4492
 
4493
  if ( 'admin.php' == $pagenow && isset( $_GET['import'] ) ) {
4517
  * @param string $template_id The ID of node template to delete.
4518
  * @return void
4519
  */
4520
+ static public function delete_node_template( $template_id ) {
 
4521
  // Make sure we have a template ID.
4522
  if ( ! isset( $template_id ) ) {
4523
  return;
4545
  * @param int $template_post_id The post ID of the template to unlink.
4546
  * @return void
4547
  */
4548
+ static public function unlink_global_node_template_from_all_posts( $template_post_id ) {
 
4549
  if ( self::is_post_global_node_template( $template_post_id ) ) {
4550
 
4551
  $posts = self::get_posts_with_global_node_template( $template_post_id );
4572
  * @param string $template_id The ID of the template to unlink from the layout data.
4573
  * @return void
4574
  */
4575
+ static public function unlink_global_node_template_from_post( $status, $post_id, $template_post_id, $template_id ) {
 
4576
  $template_data = self::get_layout_data( $status, $template_post_id );
4577
  $layout_data = self::get_layout_data( $status, $post_id );
4578
  $update = false;
4632
  * @param int $template_post_id The post ID of the template to delete.
4633
  * @return void
4634
  */
4635
+ static public function delete_global_node_template_from_all_posts( $template_post_id ) {
 
4636
  if ( self::is_post_global_node_template( $template_post_id ) ) {
4637
 
4638
  $posts = self::get_posts_with_global_node_template( $template_post_id );
4656
  * @param string $template_id The ID of the template to delete from the layout data.
4657
  * @return void
4658
  */
4659
+ static public function delete_global_node_template_from_post( $status, $post_id, $template_id ) {
 
4660
  $layout_data = self::get_layout_data( $status, $post_id );
4661
  $update = false;
4662
 
4709
  * @param object $template Optional. Template data to use instead of pulling it with the template ID.
4710
  * @return void
4711
  */
4712
+ static public function apply_node_template( $template_id = null, $parent_id = null, $position = 0, $template = null ) {
4713
+ $parent = 0 == $parent_id ? null : self::get_node( $parent_id );
 
4714
  $template_post_id = self::get_node_template_post_id( $template_id );
4715
 
4716
  // Allow extensions to hook into applying a node template.
4719
  'parent_id' => $parent_id,
4720
  'position' => $position,
4721
  'template' => $template,
4722
+ 'template_post_id' => $template_post_id,
4723
  ) );
4724
 
4725
  // Return if we got an override from the filter.
4733
  $template_settings = $template->settings;
4734
  $type = $template->type;
4735
  $global = $template->global;
4736
+ } // End if().
 
4737
  else {
4738
  $template_data = self::get_layout_data( 'published', $template_post_id );
4739
  $template_settings = self::get_layout_settings( 'published', $template_post_id );
4763
  // Only merge the root node for global templates.
4764
  if ( $global ) {
4765
  $layout_data[ $root_node->node ] = $template_data[ $root_node->node ];
4766
+ } // End if().
 
4767
  else {
4768
 
4769
  // Merge template data.
4794
  // Return the root node.
4795
  if ( 'module' == $root_node->type ) {
4796
  return self::get_module( $root_node->node );
4797
+ } else {
 
4798
  return $root_node;
4799
  }
4800
  }
4806
  * @param sting $path The directory path to the template data file.
4807
  * @return void
4808
  */
4809
+ static public function register_templates( $path = false ) {
 
4810
  if ( $path && file_exists( $path ) ) {
4811
  self::$templates[] = $path;
4812
  }
4818
  * @since 1.10.3
4819
  * @return void
4820
  */
4821
+ static private function register_core_templates() {
 
4822
  $templates = glob( FL_BUILDER_DIR . 'data/*' );
4823
 
4824
  // glob() will return false on error so cast as an array() just in case.
4843
  * @param string $type The type of template to apply.
4844
  * @return void
4845
  */
4846
+ static public function apply_template( $index = 0, $append = false, $type = 'layout' ) {
 
4847
  // Allow extensions to hook into applying a template.
4848
  $override = apply_filters( 'fl_builder_override_apply_template', false, array(
4849
  'index' => $index,
4850
  'append' => $append,
4851
+ 'type' => $type,
4852
  ) );
4853
 
4854
  // Return if we have an override from the filter.
4869
  * @param string $type The type of template to apply.
4870
  * @return void
4871
  */
4872
+ static public function apply_core_template( $index = 0, $append = false, $type = 'layout' ) {
4873
+ $template = self::get_template( $index, $type );
4874
+ $row_position = self::next_node_position( 'row' );
 
4875
 
4876
  // Delete existing nodes and settings?
4877
+ if ( ! $append ) {
4878
+ self::delete_layout_data( 'draft' );
4879
+ self::delete_layout_settings( 'draft' );
4880
  }
4881
 
4882
  // Only move forward if we have template nodes.
4883
+ if ( isset( $template->nodes ) ) {
4884
 
4885
  // Get new ids for the template nodes.
4886
+ $template->nodes = self::generate_new_node_ids( $template->nodes );
4887
 
4888
  // Get the existing layout data and settings.
4889
  $layout_data = self::get_layout_data();
4890
  $layout_settings = self::get_layout_settings();
4891
 
4892
  // Reposition rows?
4893
+ if ( $append ) {
4894
 
4895
+ foreach ( $template->nodes as $node_id => $node ) {
4896
 
4897
+ if ( 'row' == $node->type ) {
4898
+ $template->nodes[ $node_id ]->position += $row_position;
4899
  }
4900
  }
4901
  }
4902
 
4903
  // Merge and update the layout data.
4904
+ $data = array_merge( $layout_data, $template->nodes );
4905
+ self::update_layout_data( $data );
4906
 
4907
  // Merge and update the layout settings.
4908
  if ( isset( $template->settings ) ) {
4923
  * @param string $type The type of template to get. Currently either layout, row or module.
4924
  * @return object
4925
  */
4926
+ static public function get_template( $index, $type = 'layout' ) {
 
4927
  $templates = self::get_templates( $type );
4928
  $template = isset( $templates[ $index ] ) ? $templates[ $index ] : false;
4929
 
4942
  * @param bool $cached
4943
  * @return array
4944
  */
4945
+ static public function get_templates( $type = 'layout', $cached = true ) {
 
4946
  // Pull from dat files if cached is false or we don't have saved data.
4947
  if ( ! $cached || ! self::$template_data ) {
4948
 
4960
  ob_start();
4961
  include $path;
4962
  $unserialized = unserialize( ob_get_clean() );
4963
+ } else {
 
4964
  $unserialized = fl_maybe_fix_unserialize( file_get_contents( $path ) );
4965
  }
4966
 
4985
 
4986
  self::$template_data[ $template_type ] = array_merge( self::$template_data[ $template_type ], $template_data );
4987
  }
4988
+ }// End foreach().
4989
+ }// End if().
4990
 
4991
  $templates = isset( self::$template_data[ $type ] ) ? self::$template_data[ $type ] : array();
4992
 
4999
  * @since 1.8
5000
  * @return bool
5001
  */
5002
+ static public function has_templates() {
 
5003
  return apply_filters( 'fl_builder_has_templates', ( count( self::get_templates() ) > 0 ) );
5004
  }
5005
 
5012
  * @param string $type Either layout, row or module
5013
  * @return array
5014
  */
5015
+ static public function get_template_selector_data( $type = 'layout' ) {
 
5016
  $type = apply_filters( 'fl_builder_template_selector_data_type', $type );
5017
  $categorized = array();
5018
  $templates = array();
5019
  $core_categories = array(
5020
  'general' => __( 'General', 'fl-builder' ),
5021
  'landing' => __( 'Landing Pages', 'fl-builder' ),
5022
+ 'company' => __( 'Content Pages', 'fl-builder' ),
5023
  );
5024
 
5025
  // Build the the templates array.
5026
+ foreach ( self::get_templates( $type ) as $key => $template ) {
5027
 
5028
  if ( 'module' == $type ) {
5029
 
5037
 
5038
  if ( strstr( $template->image, '://' ) || strstr( $template->image, ';base64,' ) ) {
5039
  $image = $template->image;
5040
+ } else {
 
5041
  $image = FL_BUILDER_URL . 'img/templates/' . ( empty( $template->image ) ? 'blank.jpg' : $template->image );
5042
  }
5043
 
5046
  'name' => $template->name,
5047
  'image' => $image,
5048
  'category' => isset( $template->category ) ? $template->category : $template->categories,
5049
+ 'type' => 'core',
5050
  );
5051
 
5052
  $template_data = apply_filters( 'fl_builder_template_selector_data', $template_data, $template );
5055
  }
5056
 
5057
  // Build the categorized templates array.
5058
+ foreach ( $templates as $template ) {
5059
 
5060
  if ( ! isset( $template['category'] ) ) {
5061
  continue;
5068
  if ( ! isset( $categorized[ $cat_key ] ) ) {
5069
  $categorized[ $cat_key ] = array(
5070
  'name' => $cat_label,
5071
+ 'templates' => array(),
5072
  );
5073
  }
5074
 
5075
  $categorized[ $cat_key ]['templates'][] = $template;
5076
  }
5077
+ } else {
 
5078
 
5079
  if ( ! isset( $categorized[ $template['category'] ] ) ) {
5080
  $categorized[ $template['category'] ] = array(
5081
  'name' => $core_categories[ $template['category'] ],
5082
+ 'templates' => array(),
5083
  );
5084
  }
5085
 
5090
  // Return both the templates and categorized templates array.
5091
  return apply_filters( 'fl_builder_template_selector_data', array(
5092
  'templates' => $templates,
5093
+ 'categorized' => $categorized,
5094
  ), $type );
5095
  }
5096
 
5100
  * @since 1.8
5101
  * @return array
5102
  */
5103
+ static public function get_template_selector_filter_data() {
 
5104
  $templates = self::get_template_selector_data();
5105
  $data = array();
5106
 
5117
  * @since 1.8
5118
  * @return array
5119
  */
5120
+ static public function get_row_templates_data() {
 
5121
  return apply_filters( 'fl_builder_row_templates_data', self::get_template_selector_data( 'row' ) );
5122
  }
5123
 
5127
  * @since 1.8
5128
  * @return array
5129
  */
5130
+ static public function get_module_templates_data() {
 
5131
  return apply_filters( 'fl_builder_module_templates_data', self::get_template_selector_data( 'module' ) );
5132
  }
5133
 
5137
  * @since 1.6.4
5138
  * @return object
5139
  */
5140
+ static public function get_color_presets() {
 
5141
  $settings = get_option( '_fl_builder_color_presets', array() );
5142
 
5143
  return apply_filters( 'fl_builder_color_presets', $settings );
5150
  * @param array $presets The new color presets collection.
5151
  * @return object
5152
  */
5153
+ static public function save_color_presets( $presets = array() ) {
 
5154
  return update_option( '_fl_builder_color_presets', $presets );
5155
  }
5156
 
5160
  * @since 1.3.1
5161
  * @return string
5162
  */
5163
+ static public function get_branding() {
 
5164
  if ( class_exists( 'FLBuilderWhiteLabel' ) ) {
5165
  return FLBuilderWhiteLabel::get_branding();
5166
  }
5174
  * @since 1.3.7
5175
  * @return string
5176
  */
5177
+ static public function get_branding_icon() {
 
5178
  if ( class_exists( 'FLBuilderWhiteLabel' ) ) {
5179
  return FLBuilderWhiteLabel::get_branding_icon();
5180
  }
5188
  * @since 1.4.6
5189
  * @return array
5190
  */
5191
+ static public function get_enabled_icons() {
 
5192
  $value = self::get_admin_settings_option( '_fl_builder_enabled_icons', true );
5193
 
5194
  return ! $value ? array( 'font-awesome', 'foundation-icons', 'dashicons' ) : $value;
5200
  * @param string $cap The capability to evaluate if it's single or multiple (comma separated) value
5201
  * @return bool
5202
  */
5203
+ static public function current_user_has_capability( $cap ) {
 
5204
  if ( strstr( $cap, ',' ) ) {
5205
 
5206
  $parts = explode( ',', $cap );
5207
 
5208
+ foreach ( $parts as $part ) {
5209
  if ( current_user_can( trim( $part ) ) ) {
5210
  return true;
5211
  }
5212
  }
5213
 
5214
  return false;
5215
+ } else {
 
5216
  return current_user_can( $cap );
5217
  }
5218
  }
5223
  * @since 1.4.9
5224
  * @return array
5225
  */
5226
+ static public function get_help_button_defaults() {
 
5227
  $defaults = array(
5228
  'enabled' => true,
5229
  'tour' => true,
5230
  'video' => true,
5231
  'video_embed' => '<iframe src="https://player.vimeo.com/video/124230072?autoplay=1" width="420" height="315" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>',
5232
  'knowledge_base' => true,
5233
+ 'knowledge_base_url' => self::get_store_url( 'knowledge-base', array(
5234
+ 'utm_medium' => ( true === FL_BUILDER_LITE ? 'bb-lite' : 'bb-pro' ),
5235
+ 'utm_source' => 'builder-ui',
5236
+ 'utm_campaign' => 'kb-help-button',
5237
+ ) ),
5238
  'forums' => true,
5239
+ 'forums_url' => self::get_store_url( 'knowledge-base', array(
5240
+ 'utm_medium' => ( true === FL_BUILDER_LITE ? 'bb-lite' : 'bb-pro' ),
5241
+ 'utm_source' => 'builder-ui',
5242
+ 'utm_campaign' => 'forums-help-button',
5243
+ ) ),
5244
  );
5245
 
5246
  return $defaults;
5252
  * @since 1.4.9
5253
  * @return array
5254
  */
5255
+ static public function get_help_button_settings() {
 
5256
  if ( class_exists( 'FLBuilderWhiteLabel' ) ) {
5257
  return FLBuilderWhiteLabel::get_help_button_settings();
5258
  }
5266
  * @since 1.5.4
5267
  * @return array
5268
  */
5269
+ static public function get_services() {
 
5270
  return get_option( '_fl_builder_services', array() );
5271
  }
5272
 
5279
  * @param array $data The account data.
5280
  * @return void
5281
  */
5282
+ static public function update_services( $service, $account, $data ) {
 
5283
  $services = self::get_services();
5284
  $account = sanitize_text_field( $account );
5285
 
5300
  * @param string $account The account name.
5301
  * @return void
5302
  */
5303
+ static public function delete_service_account( $service, $account ) {
 
5304
  $services = self::get_services();
5305
 
5306
  if ( isset( $services[ $service ][ $account ] ) ) {
5322
  * @param bool $network_override Whether to allow the network admin setting to be overridden on subsites.
5323
  * @return mixed
5324
  */
5325
+ static public function get_admin_settings_option( $key, $network_override = true ) {
 
5326
  // Get the site-wide option if we're in the network admin.
5327
  if ( is_network_admin() ) {
5328
  $value = get_site_option( $key );
5329
+ } // End if().
5330
+ elseif ( ! $network_override && class_exists( 'FLBuilderMultisiteSettings' ) ) {
 
5331
  $value = get_site_option( $key );
5332
+ } // Network overrides are allowed. Return the subsite option if it exists.
5333
+ elseif ( class_exists( 'FLBuilderMultisiteSettings' ) ) {
 
5334
  $value = get_option( $key );
5335
  $value = false === $value ? get_site_option( $key ) : $value;
5336
+ } // This must be a single site install. Get the single site option.
 
5337
  else {
5338
  $value = get_option( $key );
5339
  }
5350
  * @param bool $network_override Whether to allow the network admin setting to be overridden on subsites.
5351
  * @return mixed
5352
  */
5353
+ static public function update_admin_settings_option( $key, $value, $network_override = true ) {
 
5354
  // Update the site-wide option since we're in the network admin.
5355
  if ( is_network_admin() ) {
5356
  update_site_option( $key, $value );
5357
+ } // End if().
5358
+ elseif ( $network_override && FLBuilderAdminSettings::multisite_support() && ! isset( $_POST['fl-override-ms'] ) ) {
 
5359
  delete_option( $key );
5360
+ } // Update the option for single install or subsite.
 
5361
  else {
5362
  update_option( $key, $value );
5363
  }
5369
  * @since 1.0
5370
  * @return string
5371
  */
5372
+ static public function plugin_basename() {
 
5373
  return plugin_basename( FL_BUILDER_DIR . 'fl-builder.php' );
5374
  }
5375
 
5381
  * @since 1.0
5382
  * @return void
5383
  */
5384
+ static public function uninstall_database() {
5385
+ if ( current_user_can( 'delete_plugins' ) ) {
 
5386
 
5387
  // Delete builder options.
5388
+ delete_option( '_fl_builder_settings' );
5389
+ delete_option( '_fl_builder_enabled_modules' );
5390
+ delete_option( '_fl_builder_enabled_templates' );
5391
+ delete_option( '_fl_builder_templates_override' );
5392
+ delete_option( '_fl_builder_templates_override_rows' );
5393
+ delete_option( '_fl_builder_templates_override_modules' );
5394
+ delete_option( '_fl_builder_post_types' );
5395
+ delete_option( '_fl_builder_enabled_icons' );
5396
+ delete_option( '_fl_builder_branding' );
5397
+ delete_option( '_fl_builder_branding_icon' );
5398
+ delete_option( '_fl_builder_theme_branding' );
5399
+ delete_option( '_fl_builder_user_access' );
5400
+ delete_option( '_fl_builder_help_button' );
5401
+ delete_option( '_fl_builder_color_presets' );
5402
 
5403
  // Delete builder user meta.
5404
+ delete_metadata( 'user', 0, '_fl_builder_launched', 1, true );
5405
 
5406
  // Delete uploaded files and folders.
5407
  $upload_dir = self::get_upload_dir();
5409
  $filesystem->rmdir( $upload_dir['path'], true );
5410
 
5411
  // Deactivate and delete the plugin.
5412
+ if ( ! function_exists( 'deactivate_plugins' ) ) {
5413
+ require_once( ABSPATH . 'wp-admin/includes/plugin.php' );
5414
  }
5415
+ deactivate_plugins( array( self::plugin_basename() ), false, is_network_admin() );
5416
+ delete_plugins( array( self::plugin_basename() ) );
5417
 
5418
  // Redirect to the plugins page.
5419
+ wp_redirect( admin_url( 'plugins.php?deleted=true&plugin_status=all&paged=1&s=' ) );
5420
 
5421
  exit;
5422
+ }// End if().
5423
  }
5424
 
5425
  /**
5426
  * @since 1.6.4.3
5427
  * @deprecated 1.8
5428
  */
5429
+ static public function get_theme_branding() {
 
5430
  _deprecated_function( __METHOD__, '1.8', 'FLBuilderWhiteLabel::get_theme_branding()' );
5431
 
5432
  if ( class_exists( 'FLBuilderWhiteLabel' ) ) {
5438
  * @since 1.0
5439
  * @deprecated 1.8
5440
  */
5441
+ static public function save_templates( $templates = array() ) {
 
5442
  _deprecated_function( __METHOD__, '1.8', 'FLBuilderCoreTemplatesAdmin::save_templates()' );
5443
 
5444
  if ( class_exists( 'FLBuilderCoreTemplatesAdmin' ) ) {
5450
  * @since 1.0
5451
  * @deprecated 1.8
5452
  */
5453
+ static public function save_template( $settings ) {
 
5454
  _deprecated_function( __METHOD__, '1.8', 'FLBuilderCoreTemplatesAdmin::save_template()' );
5455
 
5456
  if ( class_exists( 'FLBuilderCoreTemplatesAdmin' ) ) {
5462
  * @since 1.0
5463
  * @deprecated 1.8
5464
  */
5465
+ static public function update_template( $old_index, $settings ) {
 
5466
  _deprecated_function( __METHOD__, '1.8', 'FLBuilderCoreTemplatesAdmin::update_template()' );
5467
 
5468
  if ( class_exists( 'FLBuilderCoreTemplatesAdmin' ) ) {
5474
  * @since 1.0
5475
  * @deprecated 1.8
5476
  */
5477
+ static public function delete_template( $index ) {
 
5478
  _deprecated_function( __METHOD__, '1.8', 'FLBuilderCoreTemplatesAdmin::delete_template()' );
5479
 
5480
  if ( class_exists( 'FLBuilderCoreTemplatesAdmin' ) ) {
5486
  * @since 1.3.9
5487
  * @deprecated 1.10
5488
  */
5489
+ static public function get_editing_capability() {
 
5490
  _deprecated_function( __METHOD__, '1.10' );
5491
 
5492
  return 'edit_posts';
5496
  * @since 1.7
5497
  * @deprecated 1.10
5498
  */
5499
+ static public function current_user_has_editing_capability() {
 
5500
  _deprecated_function( __METHOD__, '1.10', 'FLBuilderUserAccess::current_user_can()' );
5501
 
5502
  return FLBuilderUserAccess::current_user_can( 'unrestricted_editing' );
5506
  * @since 1.6.3
5507
  * @deprecated 1.10
5508
  */
5509
+ static public function get_global_templates_editing_capability() {
 
5510
  _deprecated_function( __METHOD__, '1.10', 'FLBuilderUserAccess::current_user_can' );
5511
 
5512
  return 'edit_posts';
5516
  * @since 1.5.7
5517
  * @deprecated 1.10
5518
  */
5519
+ static public function user_templates_admin_enabled() {
 
5520
  _deprecated_function( __METHOD__, '1.10', 'FLBuilderUserAccess::current_user_can( "builder_admin" )' );
5521
 
5522
  return FLBuilderUserAccess::current_user_can( 'builder_admin' );
classes/class-fl-builder-module.php CHANGED
@@ -6,97 +6,97 @@
6
  * @since 1.0
7
  */
8
  class FLBuilderModule {
9
-
10
- /**
11
- * A unique ID for the module.
12
  *
13
  * @since 1.0
14
  * @var string $node
15
  */
16
  public $node;
17
-
18
- /**
19
- * A unique ID for the module's parent.
20
  *
21
  * @since 1.0
22
  * @var int $parent
23
  */
24
  public $parent;
25
-
26
- /**
27
- * The sort order for this module.
28
  *
29
  * @since 1.0
30
  * @var int $position
31
  */
32
  public $position;
33
-
34
- /**
35
  * A display name for the module.
36
  *
37
  * @since 1.0
38
  * @var string $name
39
  */
40
  public $name;
41
-
42
- /**
43
  * A description to display for the module.
44
  *
45
  * @since 1.0
46
  * @var string $description
47
  */
48
  public $description;
49
-
50
- /**
51
  * The category this module belongs to.
52
  *
53
  * @since 1.0
54
  * @var string $category
55
  */
56
  public $category;
57
-
58
- /**
59
  * Must be the module's folder name.
60
  *
61
  * @since 1.0
62
  * @var string $slug
63
  */
64
  public $slug;
65
-
66
- /**
67
- * The module's directory path.
68
  *
69
  * @since 1.0
70
  * @var string $dir
71
  */
72
  public $dir;
73
-
74
- /**
75
- * The module's directory url.
76
  *
77
  * @since 1.0
78
  * @var string $url
79
  */
80
  public $url;
81
-
82
- /**
83
  * An array of form settings.
84
  *
85
  * @since 1.0
86
  * @var array $form
87
  */
88
  public $form = array();
89
-
90
- /**
91
- * Whether this module is enabled on the
92
  * frontend or not.
93
  *
94
  * @since 1.0
95
  * @var boolean $enabled
96
  */
97
  public $enabled = true;
98
-
99
- /**
100
  * Whether this module's content should
101
  * be exported to the WP editor or not.
102
  *
@@ -104,8 +104,8 @@ class FLBuilderModule {
104
  * @var boolean $editor_export
105
  */
106
  public $editor_export = true;
107
-
108
- /**
109
  * Whether partial refresh should be enabled
110
  * for this module or not.
111
  *
@@ -113,24 +113,24 @@ class FLBuilderModule {
113
  * @var boolean $partial_refresh
114
  */
115
  public $partial_refresh = false;
116
-
117
- /**
118
  * The module settings object.
119
  *
120
  * @since 1.0
121
  * @var object $settings
122
  */
123
  public $settings;
124
-
125
- /**
126
  * Additional CSS to enqueue.
127
  *
128
  * @since 1.0
129
  * @var array $css
130
  */
131
  public $css = array();
132
-
133
- /**
134
  * Additional JS to enqueue.
135
  *
136
  * @since 1.0
@@ -138,32 +138,31 @@ class FLBuilderModule {
138
  */
139
  public $js = array();
140
 
141
- /**
142
- * Module constructor.
143
- *
144
  * @since 1.0
145
  */
146
- public function __construct( $params )
147
- {
148
- $class_info = new ReflectionClass($this);
149
  $class_path = $class_info->getFileName();
150
- $dir_path = dirname($class_path);
151
- $this->slug = basename($class_path, '.php');
152
- $this->enabled = isset($params['enabled']) ? $params['enabled'] : true;
153
- $this->editor_export = isset($params['editor_export']) ? $params['editor_export'] : true;
154
- $this->partial_refresh = isset($params['partial_refresh']) ? $params['partial_refresh'] : false;
155
-
156
  $details = apply_filters( 'fl_builder_module_details', array(
157
  'name' => $params['name'],
158
  'description' => $params['description'],
159
- 'category' => $params['category']
160
  ), $this->slug );
161
-
162
  $this->name = $details['name'];
163
  $this->description = $details['description'];
164
  $this->category = $details['category'];
165
-
166
- // We need to normalize the paths here since path comparisons
167
  // break on Windows because they use backslashes.
168
  $abspath = str_replace( '\\', '/', ABSPATH );
169
  $fl_builder_dir = str_replace( '\\', '/', FL_BUILDER_DIR );
@@ -172,34 +171,30 @@ class FLBuilderModule {
172
  $stylesheet_directory_uri = str_replace( '\\', '/', get_stylesheet_directory_uri() );
173
  $template_directory = str_replace( '\\', '/', get_template_directory() );
174
  $template_directory_uri = str_replace( '\\', '/', get_template_directory_uri() );
175
-
176
  // Find the right paths.
177
- if(is_child_theme() && stristr($dir_path, $stylesheet_directory)) {
178
- $this->url = trailingslashit(str_replace($stylesheet_directory, $stylesheet_directory_uri, $dir_path));
179
- $this->dir = trailingslashit($dir_path);
180
- }
181
- else if(stristr($dir_path, $template_directory)) {
182
- $this->url = trailingslashit(str_replace($template_directory, $template_directory_uri, $dir_path));
183
- $this->dir = trailingslashit($dir_path);
184
- }
185
- else if(isset($params['url']) && isset($params['dir'])) {
186
- $this->url = trailingslashit($params['url']);
187
- $this->dir = trailingslashit($params['dir']);
188
- }
189
- else if(!stristr($dir_path, $fl_builder_dir)) {
190
- $this->url = trailingslashit(str_replace(trailingslashit($abspath), trailingslashit(home_url()), $dir_path));
191
- $this->dir = trailingslashit($dir_path);
192
- }
193
- else {
194
- $this->url = trailingslashit(FL_BUILDER_URL . 'modules/' . $this->slug);
195
- $this->dir = trailingslashit(FL_BUILDER_DIR . 'modules/' . $this->slug);
196
  }
197
  }
198
 
199
- /**
200
- * Used to enqueue additional frontend styles. Do not enqueue
201
- * frontend.css or frontend.responsive.css as those will be
202
- * enqueued automatically. Params are the same as those used in
203
  * WordPress' wp_enqueue_style function.
204
  *
205
  * @since 1.0
@@ -209,15 +204,14 @@ class FLBuilderModule {
209
  * @param string $ver
210
  * @param string $media
211
  * @return void
212
- */
213
- public function add_css($handle, $src = null, $deps = null, $ver = null, $media = null)
214
- {
215
- $this->css[$handle] = array($src, $deps, $ver, $media);
216
  }
217
 
218
- /**
219
  * Used to enqueue additional frontend scripts. Do not enqueue
220
- * frontend.js as that will be enqueued automatically. Params
221
  * are the same as those used in WordPress' wp_enqueue_script function.
222
  *
223
  * @since 1.0
@@ -227,86 +221,79 @@ class FLBuilderModule {
227
  * @param string $ver
228
  * @param bool $in_footer
229
  * @return void
230
- */
231
- public function add_js($handle, $src = null, $deps = null, $ver = null, $in_footer = null)
232
- {
233
- $this->js[$handle] = array($src, $deps, $ver, $in_footer);
234
  }
235
 
236
- /**
237
  * Enqueues the needed styles for any icon fields
238
  * in this module.
239
  *
240
  * @since 1.4.6
241
  * @return void
242
- */
243
- public function enqueue_icon_styles()
244
- {
245
  FLBuilderIcons::enqueue_styles_for_module( $this );
246
  }
247
 
248
- /**
249
  * Enqueues the needed styles for any font fields
250
  * in this module.
251
  *
252
  * @since 1.6.3
253
  * @return void
254
- */
255
- public function enqueue_font_styles()
256
- {
257
  FLBuilderFonts::add_fonts_for_module( $this );
258
  }
259
 
260
- /**
261
  * Should be overridden by subclasses to enqueue
262
  * additional css/js using the add_css and add_js methods.
263
  *
264
  * @since 1.0
265
  * @return void
266
- */
267
- public function enqueue_scripts()
268
- {
269
 
270
  }
271
 
272
- /**
273
  * Should be overridden by subclasses to
274
- * work with settings data before it is saved.
275
  *
276
  * @since 1.0
277
  * @param object A settings object that is going to be saved.
278
  * @return object
279
- */
280
- public function update($settings)
281
- {
282
  return $settings;
283
  }
284
 
285
- /**
286
- * Should be overridden by subclasses to work with a module before
287
  * it is deleted. Please note, this method is called when a module
288
  * is updated and when it's actually removed from the page and should
289
- * be used for things like clearing photo cache from the builder's
290
- * cache directory. If only need to run logic when a module is
291
  * actually removed from the page, use the remove method instead.
292
  *
293
  * @since 1.0
294
  * @return void
295
- */
296
- public function delete()
297
- {
298
 
299
  }
300
 
301
  /**
302
- * Should be overridden by subclasses to work with a module when
303
  * it is actually removed from the page.
304
  *
305
  * @since 1.0
306
  * @return void
307
  */
308
- public function remove()
309
- {
310
 
311
  }
312
- }
6
  * @since 1.0
7
  */
8
  class FLBuilderModule {
9
+
10
+ /**
11
+ * A unique ID for the module.
12
  *
13
  * @since 1.0
14
  * @var string $node
15
  */
16
  public $node;
17
+
18
+ /**
19
+ * A unique ID for the module's parent.
20
  *
21
  * @since 1.0
22
  * @var int $parent
23
  */
24
  public $parent;
25
+
26
+ /**
27
+ * The sort order for this module.
28
  *
29
  * @since 1.0
30
  * @var int $position
31
  */
32
  public $position;
33
+
34
+ /**
35
  * A display name for the module.
36
  *
37
  * @since 1.0
38
  * @var string $name
39
  */
40
  public $name;
41
+
42
+ /**
43
  * A description to display for the module.
44
  *
45
  * @since 1.0
46
  * @var string $description
47
  */
48
  public $description;
49
+
50
+ /**
51
  * The category this module belongs to.
52
  *
53
  * @since 1.0
54
  * @var string $category
55
  */
56
  public $category;
57
+
58
+ /**
59
  * Must be the module's folder name.
60
  *
61
  * @since 1.0
62
  * @var string $slug
63
  */
64
  public $slug;
65
+
66
+ /**
67
+ * The module's directory path.
68
  *
69
  * @since 1.0
70
  * @var string $dir
71
  */
72
  public $dir;
73
+
74
+ /**
75
+ * The module's directory url.
76
  *
77
  * @since 1.0
78
  * @var string $url
79
  */
80
  public $url;
81
+
82
+ /**
83
  * An array of form settings.
84
  *
85
  * @since 1.0
86
  * @var array $form
87
  */
88
  public $form = array();
89
+
90
+ /**
91
+ * Whether this module is enabled on the
92
  * frontend or not.
93
  *
94
  * @since 1.0
95
  * @var boolean $enabled
96
  */
97
  public $enabled = true;
98
+
99
+ /**
100
  * Whether this module's content should
101
  * be exported to the WP editor or not.
102
  *
104
  * @var boolean $editor_export
105
  */
106
  public $editor_export = true;
107
+
108
+ /**
109
  * Whether partial refresh should be enabled
110
  * for this module or not.
111
  *
113
  * @var boolean $partial_refresh
114
  */
115
  public $partial_refresh = false;
116
+
117
+ /**
118
  * The module settings object.
119
  *
120
  * @since 1.0
121
  * @var object $settings
122
  */
123
  public $settings;
124
+
125
+ /**
126
  * Additional CSS to enqueue.
127
  *
128
  * @since 1.0
129
  * @var array $css
130
  */
131
  public $css = array();
132
+
133
+ /**
134
  * Additional JS to enqueue.
135
  *
136
  * @since 1.0
138
  */
139
  public $js = array();
140
 
141
+ /**
142
+ * Module constructor.
143
+ *
144
  * @since 1.0
145
  */
146
+ public function __construct( $params ) {
147
+ $class_info = new ReflectionClass( $this );
 
148
  $class_path = $class_info->getFileName();
149
+ $dir_path = dirname( $class_path );
150
+ $this->slug = basename( $class_path, '.php' );
151
+ $this->enabled = isset( $params['enabled'] ) ? $params['enabled'] : true;
152
+ $this->editor_export = isset( $params['editor_export'] ) ? $params['editor_export'] : true;
153
+ $this->partial_refresh = isset( $params['partial_refresh'] ) ? $params['partial_refresh'] : false;
154
+
155
  $details = apply_filters( 'fl_builder_module_details', array(
156
  'name' => $params['name'],
157
  'description' => $params['description'],
158
+ 'category' => $params['category'],
159
  ), $this->slug );
160
+
161
  $this->name = $details['name'];
162
  $this->description = $details['description'];
163
  $this->category = $details['category'];
164
+
165
+ // We need to normalize the paths here since path comparisons
166
  // break on Windows because they use backslashes.
167
  $abspath = str_replace( '\\', '/', ABSPATH );
168
  $fl_builder_dir = str_replace( '\\', '/', FL_BUILDER_DIR );
171
  $stylesheet_directory_uri = str_replace( '\\', '/', get_stylesheet_directory_uri() );
172
  $template_directory = str_replace( '\\', '/', get_template_directory() );
173
  $template_directory_uri = str_replace( '\\', '/', get_template_directory_uri() );
174
+
175
  // Find the right paths.
176
+ if ( is_child_theme() && stristr( $dir_path, $stylesheet_directory ) ) {
177
+ $this->url = trailingslashit( str_replace( $stylesheet_directory, $stylesheet_directory_uri, $dir_path ) );
178
+ $this->dir = trailingslashit( $dir_path );
179
+ } elseif ( stristr( $dir_path, $template_directory ) ) {
180
+ $this->url = trailingslashit( str_replace( $template_directory, $template_directory_uri, $dir_path ) );
181
+ $this->dir = trailingslashit( $dir_path );
182
+ } elseif ( isset( $params['url'] ) && isset( $params['dir'] ) ) {
183
+ $this->url = trailingslashit( $params['url'] );
184
+ $this->dir = trailingslashit( $params['dir'] );
185
+ } elseif ( ! stristr( $dir_path, $fl_builder_dir ) ) {
186
+ $this->url = trailingslashit( str_replace( trailingslashit( $abspath ), trailingslashit( home_url() ), $dir_path ) );
187
+ $this->dir = trailingslashit( $dir_path );
188
+ } else {
189
+ $this->url = trailingslashit( FL_BUILDER_URL . 'modules/' . $this->slug );
190
+ $this->dir = trailingslashit( FL_BUILDER_DIR . 'modules/' . $this->slug );
 
 
 
 
191
  }
192
  }
193
 
194
+ /**
195
+ * Used to enqueue additional frontend styles. Do not enqueue
196
+ * frontend.css or frontend.responsive.css as those will be
197
+ * enqueued automatically. Params are the same as those used in
198
  * WordPress' wp_enqueue_style function.
199
  *
200
  * @since 1.0
204
  * @param string $ver
205
  * @param string $media
206
  * @return void
207
+ */
208
+ public function add_css( $handle, $src = null, $deps = null, $ver = null, $media = null ) {
209
+ $this->css[ $handle ] = array( $src, $deps, $ver, $media );
 
210
  }
211
 
212
+ /**
213
  * Used to enqueue additional frontend scripts. Do not enqueue
214
+ * frontend.js as that will be enqueued automatically. Params
215
  * are the same as those used in WordPress' wp_enqueue_script function.
216
  *
217
  * @since 1.0
221
  * @param string $ver
222
  * @param bool $in_footer
223
  * @return void
224
+ */
225
+ public function add_js( $handle, $src = null, $deps = null, $ver = null, $in_footer = null ) {
226
+ $this->js[ $handle ] = array( $src, $deps, $ver, $in_footer );
 
227
  }
228
 
229
+ /**
230
  * Enqueues the needed styles for any icon fields
231
  * in this module.
232
  *
233
  * @since 1.4.6
234
  * @return void
235
+ */
236
+ public function enqueue_icon_styles() {
 
237
  FLBuilderIcons::enqueue_styles_for_module( $this );
238
  }
239
 
240
+ /**
241
  * Enqueues the needed styles for any font fields
242
  * in this module.
243
  *
244
  * @since 1.6.3
245
  * @return void
246
+ */
247
+ public function enqueue_font_styles() {
 
248
  FLBuilderFonts::add_fonts_for_module( $this );
249
  }
250
 
251
+ /**
252
  * Should be overridden by subclasses to enqueue
253
  * additional css/js using the add_css and add_js methods.
254
  *
255
  * @since 1.0
256
  * @return void
257
+ */
258
+ public function enqueue_scripts() {
 
259
 
260
  }
261
 
262
+ /**
263
  * Should be overridden by subclasses to
264
+ * work with settings data before it is saved.
265
  *
266
  * @since 1.0
267
  * @param object A settings object that is going to be saved.
268
  * @return object
269
+ */
270
+ public function update( $settings ) {
 
271
  return $settings;
272
  }
273
 
274
+ /**
275
+ * Should be overridden by subclasses to work with a module before
276
  * it is deleted. Please note, this method is called when a module
277
  * is updated and when it's actually removed from the page and should
278
+ * be used for things like clearing photo cache from the builder's
279
+ * cache directory. If only need to run logic when a module is
280
  * actually removed from the page, use the remove method instead.
281
  *
282
  * @since 1.0
283
  * @return void
284
+ */
285
+ public function delete() {
 
286
 
287
  }
288
 
289
  /**
290
+ * Should be overridden by subclasses to work with a module when
291
  * it is actually removed from the page.
292
  *
293
  * @since 1.0
294
  * @return void
295
  */
296
+ public function remove() {
 
297
 
298
  }
299
+ }
classes/class-fl-builder-photo.php CHANGED
@@ -8,35 +8,33 @@
8
  final class FLBuilderPhoto {
9
 
10
  /**
11
- * Returns an array of data for sizes that are
12
  * defined for WordPress images.
13
  *
14
  * @since 1.0
15
  * @return array
16
  */
17
- static public function sizes()
18
- {
19
  global $_wp_additional_image_sizes;
20
 
21
  $sizes = array();
22
 
23
- foreach(get_intermediate_image_sizes() as $size) {
24
-
25
  // Hidden size added in 4.4 for responsive images. We don't need it.
26
  if ( 'medium_large' == $size ) {
27
  continue;
28
  }
29
 
30
- $sizes[$size] = array(0, 0);
31
 
32
- if(in_array($size, array('thumbnail', 'medium', 'large'))) {
33
- $sizes[$size][0] = get_option($size . '_size_w');
34
- $sizes[$size][1] = get_option($size . '_size_h');
35
- }
36
- else if(isset($_wp_additional_image_sizes) && isset($_wp_additional_image_sizes[$size])) {
37
- $sizes[$size] = array(
38
- $_wp_additional_image_sizes[$size]['width'],
39
- $_wp_additional_image_sizes[$size]['height']
40
  );
41
  }
42
  }
@@ -52,12 +50,11 @@ final class FLBuilderPhoto {
52
  * @param string $id The attachment id.
53
  * @return object
54
  */
55
- static public function get_attachment_data($id)
56
- {
57
- $data = wp_prepare_attachment_for_js($id);
58
 
59
- if(gettype($data) == 'array') {
60
- return json_decode(json_encode($data));
61
  }
62
 
63
  return $data;
@@ -70,18 +67,14 @@ final class FLBuilderPhoto {
70
  * @param object $photo An object with photo data.
71
  * @return void
72
  */
73
- static public function get_thumb($photo)
74
- {
75
  if ( empty( $photo ) ) {
76
  echo FL_BUILDER_URL . 'img/spacer.png';
77
- }
78
- else if ( ! isset( $photo->sizes ) ) {
79
  echo $photo->url;
80
- }
81
- else if ( ! empty( $photo->sizes->thumbnail ) ) {
82
  echo $photo->sizes->thumbnail->url;
83
- }
84
- else {
85
  echo $photo->sizes->full->url;
86
  }
87
  }
@@ -94,34 +87,32 @@ final class FLBuilderPhoto {
94
  * @param object $photo An object with photo data.
95
  * @return void
96
  */
97
- static public function get_src_options($selected, $photo)
98
- {
99
  if ( ! isset( $photo->sizes ) ) {
100
- echo '<option value="' . $photo->url . '" selected="selected">' . _x( 'Full Size', 'Image size.', 'fl-builder' ) . '</option>';
101
- }
102
- else {
103
-
104
  $titles = array(
105
  'full' => _x( 'Full Size', 'Image size.', 'fl-builder' ),
106
  'large' => _x( 'Large', 'Image size.', 'fl-builder' ),
107
  'medium' => _x( 'Medium', 'Image size.', 'fl-builder' ),
108
- 'thumbnail' => _x( 'Thumbnail', 'Image size.', 'fl-builder' )
109
  );
110
-
111
- // Check the selected value without the protocol so we get a match if
112
  // a site has switched to HTTPS since selecting this photo (#641).
113
  $selected = str_replace( array( 'http://', 'https://' ), '', $selected );
114
-
115
- foreach($photo->sizes as $key => $val) {
116
-
117
- if(!isset($titles[$key])) {
118
- $titles[$key] = ucwords(str_replace(array('_', '-'), ' ', $key));
119
  }
120
-
121
  $check = str_replace( array( 'http://', 'https://' ), '', $val->url );
122
-
123
- echo '<option value="' . $val->url . '" ' . selected($selected, $check) . '>' . $titles[$key] . ' - ' . $val->width . ' x ' . $val->height . '</option>';
124
  }
125
  }
126
  }
127
- }
8
  final class FLBuilderPhoto {
9
 
10
  /**
11
+ * Returns an array of data for sizes that are
12
  * defined for WordPress images.
13
  *
14
  * @since 1.0
15
  * @return array
16
  */
17
+ static public function sizes() {
 
18
  global $_wp_additional_image_sizes;
19
 
20
  $sizes = array();
21
 
22
+ foreach ( get_intermediate_image_sizes() as $size ) {
23
+
24
  // Hidden size added in 4.4 for responsive images. We don't need it.
25
  if ( 'medium_large' == $size ) {
26
  continue;
27
  }
28
 
29
+ $sizes[ $size ] = array( 0, 0 );
30
 
31
+ if ( in_array( $size, array( 'thumbnail', 'medium', 'large' ) ) ) {
32
+ $sizes[ $size ][0] = get_option( $size . '_size_w' );
33
+ $sizes[ $size ][1] = get_option( $size . '_size_h' );
34
+ } elseif ( isset( $_wp_additional_image_sizes ) && isset( $_wp_additional_image_sizes[ $size ] ) ) {
35
+ $sizes[ $size ] = array(
36
+ $_wp_additional_image_sizes[ $size ]['width'],
37
+ $_wp_additional_image_sizes[ $size ]['height'],
 
38
  );
39
  }
40
  }
50
  * @param string $id The attachment id.
51
  * @return object
52
  */
53
+ static public function get_attachment_data( $id ) {
54
+ $data = wp_prepare_attachment_for_js( $id );
 
55
 
56
+ if ( gettype( $data ) == 'array' ) {
57
+ return json_decode( json_encode( $data ) );
58
  }
59
 
60
  return $data;
67
  * @param object $photo An object with photo data.
68
  * @return void
69
  */
70
+ static public function get_thumb( $photo ) {
 
71
  if ( empty( $photo ) ) {
72
  echo FL_BUILDER_URL . 'img/spacer.png';
73
+ } elseif ( ! isset( $photo->sizes ) ) {
 
74
  echo $photo->url;
75
+ } elseif ( ! empty( $photo->sizes->thumbnail ) ) {
 
76
  echo $photo->sizes->thumbnail->url;
77
+ } else {
 
78
  echo $photo->sizes->full->url;
79
  }
80
  }
87
  * @param object $photo An object with photo data.
88
  * @return void
89
  */
90
+ static public function get_src_options( $selected, $photo ) {
 
91
  if ( ! isset( $photo->sizes ) ) {
92
+ echo '<option value="' . $photo->url . '" selected="selected">' . _x( 'Full Size', 'Image size.', 'fl-builder' ) . '</option>';
93
+ } else {
94
+
 
95
  $titles = array(
96
  'full' => _x( 'Full Size', 'Image size.', 'fl-builder' ),
97
  'large' => _x( 'Large', 'Image size.', 'fl-builder' ),
98
  'medium' => _x( 'Medium', 'Image size.', 'fl-builder' ),
99
+ 'thumbnail' => _x( 'Thumbnail', 'Image size.', 'fl-builder' ),
100
  );
101
+
102
+ // Check the selected value without the protocol so we get a match if
103
  // a site has switched to HTTPS since selecting this photo (#641).
104
  $selected = str_replace( array( 'http://', 'https://' ), '', $selected );
105
+
106
+ foreach ( $photo->sizes as $key => $val ) {
107
+
108
+ if ( ! isset( $titles[ $key ] ) ) {
109
+ $titles[ $key ] = ucwords( str_replace( array( '_', '-' ), ' ', $key ) );
110
  }
111
+
112
  $check = str_replace( array( 'http://', 'https://' ), '', $val->url );
113
+
114
+ echo '<option value="' . $val->url . '" ' . selected( $selected, $check ) . '>' . $titles[ $key ] . ' - ' . $val->width . ' x ' . $val->height . '</option>';
115
  }
116
  }
117
  }
118
+ }
classes/class-fl-builder-service-activecampaign.php CHANGED
@@ -12,14 +12,14 @@ final class FLBuilderServiceActiveCampaign extends FLBuilderService {
12
  *
13
  * @since 1.6.0
14
  * @var string $id
15
- */
16
  public $id = 'activecampaign';
17
 
18
  /**
19
  * @since 1.6.0
20
  * @var object $api_instance
21
  * @access private
22
- */
23
  private $api_instance = null;
24
 
25
  /**
@@ -29,21 +29,20 @@ final class FLBuilderServiceActiveCampaign extends FLBuilderService {
29
  * @param string $api_url A valid API url.
30
  * @param string $api_key A valid API key.
31
  * @return object The API instance.
32
- */
33
- public function get_api( $api_url, $api_key )
34
- {
35
  if ( $this->api_instance ) {
36
  return $this->api_instance;
37
  }
38
  if ( ! class_exists( 'ActiveCampaign' ) ) {
39
  require_once FL_BUILDER_DIR . 'includes/vendor/activecampaign/ActiveCampaign.class.php';
40
  }
41
-
42
  $this->api_instance = new ActiveCampaign( $api_url, $api_key );
43
-
44
  return $this->api_instance;
45
  }
46
-
47
  /**
48
  * Test the API connection.
49
  *
@@ -56,38 +55,34 @@ final class FLBuilderServiceActiveCampaign extends FLBuilderService {
56
  * @type bool|string $error The error message or false if no error.
57
  * @type array $data An array of data used to make the connection.
58
  * }
59
- */
60
- public function connect( $fields = array() )
61
- {
62
- $response = array(
63
  'error' => false,
64
- 'data' => array()
65
  );
66
-
67
  // Make sure we have an API url.
68
  if ( ! isset( $fields['api_url'] ) || empty( $fields['api_url'] ) ) {
69
  $response['error'] = __( 'Error: You must provide an API URL.', 'fl-builder' );
70
- }
71
- // Make sure we have an API key.
72
- else if ( ! isset( $fields['api_key'] ) || empty( $fields['api_key'] ) ) {
73
  $response['error'] = __( 'Error: You must provide an API key.', 'fl-builder' );
74
- }
75
- // Try to connect and store the connection data.
76
  else {
77
-
78
  $api = $this->get_api( $fields['api_url'], $fields['api_key'] );
79
-
80
  if ( ! (int) $api->credentials_test() ) {
81
  $response['error'] = __( 'Error: Please check your API URL and API key.', 'fl-builder' );
82
- }
83
- else {
84
- $response['data'] = array(
85
  'api_url' => $fields['api_url'],
86
- 'api_key' => $fields['api_key']
87
  );
88
  }
89
  }
90
-
91
  return $response;
92
  }
93
 
@@ -96,11 +91,10 @@ final class FLBuilderServiceActiveCampaign extends FLBuilderService {
96
  *
97
  * @since 1.6.0
98
  * @return string The connection settings markup.
99
- */
100
- public function render_connect_settings()
101
- {
102
  ob_start();
103
-
104
  FLBuilder::render_settings_field( 'api_url', array(
105
  'row_class' => 'fl-builder-service-connect-row',
106
  'class' => 'fl-builder-service-connect-input',
@@ -108,10 +102,10 @@ final class FLBuilderServiceActiveCampaign extends FLBuilderService {
108
  'label' => __( 'API URL', 'fl-builder' ),
109
  'help' => __( 'Your API url can be found in your ActiveCampaign account under My Settings > Developer > API.', 'fl-builder' ),
110
  'preview' => array(
111
- 'type' => 'none'
112
- )
113
  ));
114
-
115
  FLBuilder::render_settings_field( 'api_key', array(
116
  'row_class' => 'fl-builder-service-connect-row',
117
  'class' => 'fl-builder-service-connect-input',
@@ -119,15 +113,15 @@ final class FLBuilderServiceActiveCampaign extends FLBuilderService {
119
  'label' => __( 'API Key', 'fl-builder' ),
120
  'help' => __( 'Your API key can be found in your ActiveCampaign account under My Settings > Developer > API.', 'fl-builder' ),
121
  'preview' => array(
122
- 'type' => 'none'
123
- )
124
- ));
125
-
126
  return ob_get_clean();
127
  }
128
 
129
  /**
130
- * Render the markup for service specific fields.
131
  *
132
  * @since 1.6.0
133
  * @param string $account The name of the saved account.
@@ -136,52 +130,50 @@ final class FLBuilderServiceActiveCampaign extends FLBuilderService {
136
  * @type bool|string $error The error message or false if no error.
137
  * @type string $html The field markup.
138
  * }
139
- */
140
- public function render_fields( $account, $settings )
141
- {
142
  $post_data = FLBuilderModel::get_post_data();
143
  $account_data = $this->get_account_data( $account );
144
  $api = $this->get_api( $account_data['api_url'], $account_data['api_key'] );
145
- $response = array(
146
- 'error' => false,
147
- 'html' => ''
148
  );
149
 
150
- if ( !isset($post_data['list_type']) ) {
151
  $response['html'] = $this->render_list_type_field( $settings );
152
  }
153
 
154
  $lists = $api->api( 'list/list?ids=all' );
155
  $render_type_html = $this->render_list_field( $lists, $settings );
156
 
157
- if ( isset($post_data['list_type']) || isset($settings->list_type) ) {
158
- $list_type = isset($post_data['list_type']) ? $post_data['list_type'] : $settings->list_type;
159
 
160
- if ( !empty($list_type) && $list_type == 'form' ) {
161
  $forms = $api->api( 'form/getforms' );
162
  $render_type_html = $this->render_form_field( $forms, $settings );
163
  }
164
  }
165
-
166
  $response['html'] .= $render_type_html;
167
 
168
- if ( !isset($post_data['list_type']) ) {
169
  $response['html'] .= $this->render_tags_field( $settings );
170
  }
171
-
172
  return $response;
173
  }
174
 
175
  /**
176
- * Render markup for the list type.
177
  *
178
  * @since 1.8.3
179
  * @param object $settings Saved module settings.
180
  * @return string The markup for the list field.
181
  * @access private
182
- */
183
- private function render_list_type_field( $settings )
184
- {
185
  ob_start();
186
  FLBuilder::render_settings_field( 'list_type', array(
187
  'row_class' => 'fl-builder-service-field-row',
@@ -190,12 +182,12 @@ final class FLBuilderServiceActiveCampaign extends FLBuilderService {
190
  'label' => _x( 'Type', 'Select the list type.', 'fl-builder' ),
191
  'default' => 'list',
192
  'options' => array(
193
- 'list' => __('List', 'fl-builder'),
194
- 'form' => __('Form', 'fl-builder')
195
  ),
196
  'preview' => array(
197
- 'type' => 'none'
198
- )
199
  ), $settings);
200
  return ob_get_clean();
201
  }
@@ -208,12 +200,13 @@ final class FLBuilderServiceActiveCampaign extends FLBuilderService {
208
  * @param object $settings Saved module settings.
209
  * @return string The markup for the form field.
210
  * @access private
211
- */
212
- private function render_form_field( $forms, $settings )
213
- {
214
  ob_start();
215
- $options = array( '' => __( 'Choose...', 'fl-builder' ) );
216
-
 
 
217
  foreach ( (array) $forms as $form ) {
218
  if ( is_object( $form ) && isset( $form->id ) ) {
219
  $options[ $form->id ] = $form->name;
@@ -226,27 +219,28 @@ final class FLBuilderServiceActiveCampaign extends FLBuilderService {
226
  'label' => _x( 'Form', 'Select a form a ActiveCampaign.', 'fl-builder' ),
227
  'options' => $options,
228
  'preview' => array(
229
- 'type' => 'none'
230
- )
231
  ), $settings);
232
  return ob_get_clean();
233
  }
234
 
235
  /**
236
- * Render markup for the list field.
237
  *
238
  * @since 1.6.0
239
  * @param array $lists List data from the API.
240
  * @param object $settings Saved module settings.
241
  * @return string The markup for the list field.
242
  * @access private
243
- */
244
- private function render_list_field( $lists, $settings )
245
- {
246
  ob_start();
247
 
248
- $options = array( '' => __( 'Choose...', 'fl-builder' ) );
249
-
 
 
250
  foreach ( (array) $lists as $list ) {
251
  if ( is_object( $list ) && isset( $list->id ) ) {
252
  $options[ $list->id ] = $list->name;
@@ -260,23 +254,22 @@ final class FLBuilderServiceActiveCampaign extends FLBuilderService {
260
  'label' => _x( 'List', 'An email list from ActiveCampaign.', 'fl-builder' ),
261
  'options' => $options,
262
  'preview' => array(
263
- 'type' => 'none'
264
- )
265
  ), $settings);
266
 
267
  return ob_get_clean();
268
  }
269
 
270
  /**
271
- * Render markup for the tags field.
272
  *
273
  * @since 1.8.8
274
  * @param object $settings Saved module settings.
275
  * @return string The markup for the tags field.
276
  * @access private
277
  */
278
- private function render_tags_field( $settings )
279
- {
280
  ob_start();
281
 
282
  FLBuilder::render_settings_field( 'tags', array(
@@ -287,14 +280,14 @@ final class FLBuilderServiceActiveCampaign extends FLBuilderService {
287
  'label' => _x( 'Tags', 'A comma separated list of tags.', 'fl-builder' ),
288
  'help' => __( 'A comma separated list of tags.', 'fl-builder' ),
289
  'preview' => array(
290
- 'type' => 'none'
291
- )
292
  ),$settings);
293
 
294
  return ob_get_clean();
295
  }
296
 
297
- /**
298
  * Subscribe an email address to ActiveCampaign.
299
  *
300
  * @since 1.6.0
@@ -305,34 +298,33 @@ final class FLBuilderServiceActiveCampaign extends FLBuilderService {
305
  * @return array {
306
  * @type bool|string $error The error message or false if no error.
307
  * }
308
- */
309
- public function subscribe( $settings, $email, $name = false )
310
- {
311
  $account_data = $this->get_account_data( $settings->service_account );
312
- $response = array( 'error' => false );
313
-
 
 
314
  if ( ! $account_data ) {
315
  $response['error'] = __( 'There was an error subscribing to ActiveCampaign. The account is no longer connected.', 'fl-builder' );
316
- }
317
- else {
318
-
319
  $api = $this->get_api( $account_data['api_url'], $account_data['api_key'] );
320
-
321
  $data['email'] = $email;
322
- if ( isset($settings->list_type) && $settings->list_type == 'form' ) {
323
  $data['form'] = $settings->form_id;
324
- }
325
- else {
326
  $data['p'] = array( $settings->list_id );
327
  $data['status'] = 1;
328
  $data['instantresponders'] = array( 1 );
329
  }
330
-
331
  // Name
332
  if ( $name ) {
333
-
334
  $names = explode( ' ', $name );
335
-
336
  if ( isset( $names[0] ) ) {
337
  $data['first_name'] = $names[0];
338
  }
@@ -342,24 +334,23 @@ final class FLBuilderServiceActiveCampaign extends FLBuilderService {
342
  }
343
 
344
  // Tags
345
- if ( isset($settings->tags) && !empty($settings->tags) ) {
346
  $data['tags'] = $settings->tags;
347
  }
348
-
349
  // Subscribe
350
  $result = $api->api( 'contact/sync', $data );
351
-
352
  if ( ! $result->success && isset( $result->error ) ) {
353
-
354
  if ( stristr( $result->error, 'access' ) ) {
355
  $response['error'] = __( 'Error: Invalid API data.', 'fl-builder' );
356
- }
357
- else {
358
  $response['error'] = $result->error;
359
  }
360
  }
361
- }
362
-
363
  return $response;
364
  }
365
- }
12
  *
13
  * @since 1.6.0
14
  * @var string $id
15
+ */
16
  public $id = 'activecampaign';
17
 
18
  /**
19
  * @since 1.6.0
20
  * @var object $api_instance
21
  * @access private
22
+ */
23
  private $api_instance = null;
24
 
25
  /**
29
  * @param string $api_url A valid API url.
30
  * @param string $api_key A valid API key.
31
  * @return object The API instance.
32
+ */
33
+ public function get_api( $api_url, $api_key ) {
 
34
  if ( $this->api_instance ) {
35
  return $this->api_instance;
36
  }
37
  if ( ! class_exists( 'ActiveCampaign' ) ) {
38
  require_once FL_BUILDER_DIR . 'includes/vendor/activecampaign/ActiveCampaign.class.php';
39
  }
40
+
41
  $this->api_instance = new ActiveCampaign( $api_url, $api_key );
42
+
43
  return $this->api_instance;
44
  }
45
+
46
  /**
47
  * Test the API connection.
48
  *
55
  * @type bool|string $error The error message or false if no error.
56
  * @type array $data An array of data used to make the connection.
57
  * }
58
+ */
59
+ public function connect( $fields = array() ) {
60
+ $response = array(
 
61
  'error' => false,
62
+ 'data' => array(),
63
  );
64
+
65
  // Make sure we have an API url.
66
  if ( ! isset( $fields['api_url'] ) || empty( $fields['api_url'] ) ) {
67
  $response['error'] = __( 'Error: You must provide an API URL.', 'fl-builder' );
68
+ } // End if().
69
+ elseif ( ! isset( $fields['api_key'] ) || empty( $fields['api_key'] ) ) {
 
70
  $response['error'] = __( 'Error: You must provide an API key.', 'fl-builder' );
71
+ } // Try to connect and store the connection data.
 
72
  else {
73
+
74
  $api = $this->get_api( $fields['api_url'], $fields['api_key'] );
75
+
76
  if ( ! (int) $api->credentials_test() ) {
77
  $response['error'] = __( 'Error: Please check your API URL and API key.', 'fl-builder' );
78
+ } else {
79
+ $response['data'] = array(
 
80
  'api_url' => $fields['api_url'],
81
+ 'api_key' => $fields['api_key'],
82
  );
83
  }
84
  }
85
+
86
  return $response;
87
  }
88
 
91
  *
92
  * @since 1.6.0
93
  * @return string The connection settings markup.
94
+ */
95
+ public function render_connect_settings() {
 
96
  ob_start();
97
+
98
  FLBuilder::render_settings_field( 'api_url', array(
99
  'row_class' => 'fl-builder-service-connect-row',
100
  'class' => 'fl-builder-service-connect-input',
102
  'label' => __( 'API URL', 'fl-builder' ),
103
  'help' => __( 'Your API url can be found in your ActiveCampaign account under My Settings > Developer > API.', 'fl-builder' ),
104
  'preview' => array(
105
+ 'type' => 'none',
106
+ ),
107
  ));
108
+
109
  FLBuilder::render_settings_field( 'api_key', array(
110
  'row_class' => 'fl-builder-service-connect-row',
111
  'class' => 'fl-builder-service-connect-input',
113
  'label' => __( 'API Key', 'fl-builder' ),
114
  'help' => __( 'Your API key can be found in your ActiveCampaign account under My Settings > Developer > API.', 'fl-builder' ),
115
  'preview' => array(
116
+ 'type' => 'none',
117
+ ),
118
+ ));
119
+
120
  return ob_get_clean();
121
  }
122
 
123
  /**
124
+ * Render the markup for service specific fields.
125
  *
126
  * @since 1.6.0
127
  * @param string $account The name of the saved account.
130
  * @type bool|string $error The error message or false if no error.
131
  * @type string $html The field markup.
132
  * }
133
+ */
134
+ public function render_fields( $account, $settings ) {
 
135
  $post_data = FLBuilderModel::get_post_data();
136
  $account_data = $this->get_account_data( $account );
137
  $api = $this->get_api( $account_data['api_url'], $account_data['api_key'] );
138
+ $response = array(
139
+ 'error' => false,
140
+ 'html' => '',
141
  );
142
 
143
+ if ( ! isset( $post_data['list_type'] ) ) {
144
  $response['html'] = $this->render_list_type_field( $settings );
145
  }
146
 
147
  $lists = $api->api( 'list/list?ids=all' );
148
  $render_type_html = $this->render_list_field( $lists, $settings );
149
 
150
+ if ( isset( $post_data['list_type'] ) || isset( $settings->list_type ) ) {
151
+ $list_type = isset( $post_data['list_type'] ) ? $post_data['list_type'] : $settings->list_type;
152
 
153
+ if ( ! empty( $list_type ) && 'form' == $list_type ) {
154
  $forms = $api->api( 'form/getforms' );
155
  $render_type_html = $this->render_form_field( $forms, $settings );
156
  }
157
  }
158
+
159
  $response['html'] .= $render_type_html;
160
 
161
+ if ( ! isset( $post_data['list_type'] ) ) {
162
  $response['html'] .= $this->render_tags_field( $settings );
163
  }
164
+
165
  return $response;
166
  }
167
 
168
  /**
169
+ * Render markup for the list type.
170
  *
171
  * @since 1.8.3
172
  * @param object $settings Saved module settings.
173
  * @return string The markup for the list field.
174
  * @access private
175
+ */
176
+ private function render_list_type_field( $settings ) {
 
177
  ob_start();
178
  FLBuilder::render_settings_field( 'list_type', array(
179
  'row_class' => 'fl-builder-service-field-row',
182
  'label' => _x( 'Type', 'Select the list type.', 'fl-builder' ),
183
  'default' => 'list',
184
  'options' => array(
185
+ 'list' => __( 'List', 'fl-builder' ),
186
+ 'form' => __( 'Form', 'fl-builder' ),
187
  ),
188
  'preview' => array(
189
+ 'type' => 'none',
190
+ ),
191
  ), $settings);
192
  return ob_get_clean();
193
  }
200
  * @param object $settings Saved module settings.
201
  * @return string The markup for the form field.
202
  * @access private
203
+ */
204
+ private function render_form_field( $forms, $settings ) {
 
205
  ob_start();
206
+ $options = array(
207
+ '' => __( 'Choose...', 'fl-builder' ),
208
+ );
209
+
210
  foreach ( (array) $forms as $form ) {
211
  if ( is_object( $form ) && isset( $form->id ) ) {
212
  $options[ $form->id ] = $form->name;
219
  'label' => _x( 'Form', 'Select a form a ActiveCampaign.', 'fl-builder' ),
220
  'options' => $options,
221
  'preview' => array(
222
+ 'type' => 'none',
223
+ ),
224
  ), $settings);
225
  return ob_get_clean();
226
  }
227
 
228
  /**
229
+ * Render markup for the list field.
230
  *
231
  * @since 1.6.0
232
  * @param array $lists List data from the API.
233
  * @param object $settings Saved module settings.
234
  * @return string The markup for the list field.
235
  * @access private
236
+ */
237
+ private function render_list_field( $lists, $settings ) {
 
238
  ob_start();
239
 
240
+ $options = array(
241
+ '' => __( 'Choose...', 'fl-builder' ),
242
+ );
243
+
244
  foreach ( (array) $lists as $list ) {
245
  if ( is_object( $list ) && isset( $list->id ) ) {
246
  $options[ $list->id ] = $list->name;
254
  'label' => _x( 'List', 'An email list from ActiveCampaign.', 'fl-builder' ),
255
  'options' => $options,
256
  'preview' => array(
257
+ 'type' => 'none',
258
+ ),
259
  ), $settings);
260
 
261
  return ob_get_clean();
262
  }
263
 
264
  /**
265
+ * Render markup for the tags field.
266
  *
267
  * @since 1.8.8
268
  * @param object $settings Saved module settings.
269
  * @return string The markup for the tags field.
270
  * @access private
271
  */
272
+ private function render_tags_field( $settings ) {
 
273
  ob_start();
274
 
275
  FLBuilder::render_settings_field( 'tags', array(
280
  'label' => _x( 'Tags', 'A comma separated list of tags.', 'fl-builder' ),
281
  'help' => __( 'A comma separated list of tags.', 'fl-builder' ),
282
  'preview' => array(
283
+ 'type' => 'none',
284
+ ),
285
  ),$settings);
286
 
287
  return ob_get_clean();
288
  }
289
 
290
+ /**
291
  * Subscribe an email address to ActiveCampaign.
292
  *
293
  * @since 1.6.0
298
  * @return array {
299
  * @type bool|string $error The error message or false if no error.
300
  * }
301
+ */
302
+ public function subscribe( $settings, $email, $name = false ) {
 
303
  $account_data = $this->get_account_data( $settings->service_account );
304
+ $response = array(
305
+ 'error' => false,
306
+ );
307
+
308
  if ( ! $account_data ) {
309
  $response['error'] = __( 'There was an error subscribing to ActiveCampaign. The account is no longer connected.', 'fl-builder' );
310
+ } else {
311
+
 
312
  $api = $this->get_api( $account_data['api_url'], $account_data['api_key'] );
313
+
314
  $data['email'] = $email;
315
+ if ( isset( $settings->list_type ) && 'form' == $settings->list_type ) {
316
  $data['form'] = $settings->form_id;
317
+ } else {
 
318
  $data['p'] = array( $settings->list_id );
319
  $data['status'] = 1;
320
  $data['instantresponders'] = array( 1 );
321
  }
322
+
323
  // Name
324
  if ( $name ) {
325
+
326
  $names = explode( ' ', $name );
327
+
328
  if ( isset( $names[0] ) ) {
329
  $data['first_name'] = $names[0];
330
  }
334
  }
335
 
336
  // Tags
337
+ if ( isset( $settings->tags ) && ! empty( $settings->tags ) ) {
338
  $data['tags'] = $settings->tags;
339
  }
340
+
341
  // Subscribe
342
  $result = $api->api( 'contact/sync', $data );
343
+
344
  if ( ! $result->success && isset( $result->error ) ) {
345
+
346
  if ( stristr( $result->error, 'access' ) ) {
347
  $response['error'] = __( 'Error: Invalid API data.', 'fl-builder' );
348
+ } else {
 
349
  $response['error'] = $result->error;
350
  }
351
  }
352
+ }// End if().
353
+
354
  return $response;
355
  }
356
+ }
classes/class-fl-builder-service-aweber.php CHANGED
@@ -12,14 +12,14 @@ final class FLBuilderServiceAWeber extends FLBuilderService {
12
  *
13
  * @since 1.5.4
14
  * @var string $id
15
- */
16
  public $id = 'aweber';
17
 
18
  /**
19
  * @since 1.5.4
20
  * @var object $api_instance
21
  * @access private
22
- */
23
  private $api_instance = null;
24
 
25
  /**
@@ -28,26 +28,25 @@ final class FLBuilderServiceAWeber extends FLBuilderService {
28
  * @since 1.5.4
29
  * @param string $auth_code A valid authorization code.
30
  * @return object The API instance.
31
- */
32
- public function get_api( $auth_code )
33
- {
34
  if ( $this->api_instance ) {
35
  return $this->api_instance;
36
  }
37
  if ( ! class_exists( 'AWeberAPI' ) ) {
38
  require_once FL_BUILDER_DIR . 'includes/vendor/aweber/aweber_api.php';
39
  }
40
-
41
  list( $auth_key, $auth_token, $req_key, $req_token, $oauth ) = explode( '|', $auth_code );
42
 
43
  $this->api_instance = new AWeberAPI( $auth_key, $auth_token );
44
  $this->api_instance->user->requestToken = $req_key;
45
  $this->api_instance->user->tokenSecret = $req_token;
46
  $this->api_instance->user->verifier = $oauth;
47
-
48
  return $this->api_instance;
49
  }
50
-
51
  /**
52
  * Test the API connection.
53
  *
@@ -59,54 +58,49 @@ final class FLBuilderServiceAWeber extends FLBuilderService {
59
  * @type bool|string $error The error message or false if no error.
60
  * @type array $data An array of data used to make the connection.
61
  * }
62
- */
63
- public function connect( $fields = array() )
64
- {
65
- $response = array(
66
  'error' => false,
67
- 'data' => array()
68
  );
69
-
70
  // Make sure we have an authorization code.
71
  if ( ! isset( $fields['auth_code'] ) || empty( $fields['auth_code'] ) ) {
72
  $response['error'] = __( 'Error: You must provide an Authorization Code.', 'fl-builder' );
73
- }
74
- // Make sure we have a valid authorization code.
75
- else if ( 6 != count( explode( '|', $fields['auth_code'] ) ) ) {
76
  $response['error'] = __( 'Error: Please enter a valid Authorization Code.', 'fl-builder' );
77
- }
78
- // Try to connect and store the connection data.
79
  else {
80
-
81
  $api = $this->get_api( $fields['auth_code'] );
82
-
83
  // Get an access token from the API.
84
  try {
85
  list( $access_token, $access_token_secret ) = $api->getAccessToken();
86
- }
87
- catch ( AWeberException $e ) {
88
  $response['error'] = $e->getMessage();
89
  }
90
-
91
  // Make sure we can get the account.
92
  try {
93
  $account = $api->getAccount();
94
- }
95
- catch ( AWeberException $e ) {
96
  $response['error'] = $e->getMessage();
97
  }
98
-
99
  // Build the response data.
100
  if ( ! $response['error'] ) {
101
-
102
  $response['data'] = array(
103
  'auth_code' => $fields['auth_code'],
104
  'access_token' => $access_token,
105
- 'access_secret' => $access_token_secret
106
  );
107
  }
108
  }
109
-
110
  return $response;
111
  }
112
 
@@ -115,11 +109,10 @@ final class FLBuilderServiceAWeber extends FLBuilderService {
115
  *
116
  * @since 1.5.4
117
  * @return string The connection settings markup.
118
- */
119
- public function render_connect_settings()
120
- {
121
  ob_start();
122
-
123
  FLBuilder::render_settings_field( 'auth_code', array(
124
  'row_class' => 'fl-builder-service-connect-row',
125
  'class' => 'fl-builder-service-connect-input',
@@ -127,15 +120,15 @@ final class FLBuilderServiceAWeber extends FLBuilderService {
127
  'label' => __( 'Authorization Code', 'fl-builder' ),
128
  'description' => sprintf( __( 'Please register this website with AWeber to get your Authorization Code. <a%s>Register Now</a>', 'fl-builder' ), ' href="https://auth.aweber.com/1.0/oauth/authorize_app/baa1f131" target="_blank"' ),
129
  'preview' => array(
130
- 'type' => 'none'
131
- )
132
- ));
133
-
134
  return ob_get_clean();
135
  }
136
 
137
  /**
138
- * Render the markup for service specific fields.
139
  *
140
  * @since 1.5.4
141
  * @param string $account The name of the saved account.
@@ -144,14 +137,13 @@ final class FLBuilderServiceAWeber extends FLBuilderService {
144
  * @type bool|string $error The error message or false if no error.
145
  * @type string $html The field markup.
146
  * }
147
- */
148
- public function render_fields( $account, $settings )
149
- {
150
  $account_data = $this->get_account_data( $account );
151
  $api = $this->get_api( $account_data['auth_code'] );
152
- $response = array(
153
- 'error' => false,
154
- 'html' => ''
155
  );
156
 
157
  try {
@@ -159,33 +151,33 @@ final class FLBuilderServiceAWeber extends FLBuilderService {
159
  $lists = $account->loadFromUrl( '/accounts/' . $account->id . '/lists' );
160
  $response['html'] = $this->render_list_field( $lists, $settings );
161
  $response['html'] .= $this->render_tags_field( $settings );
162
- }
163
- catch ( AWeberException $e ) {
164
  $response['error'] = $e->getMessage();
165
  }
166
-
167
  return $response;
168
  }
169
 
170
  /**
171
- * Render markup for the list field.
172
  *
173
  * @since 1.5.4
174
  * @param array $lists List data from the API.
175
  * @param object $settings Saved module settings.
176
  * @return string The markup for the list field.
177
  * @access private
178
- */
179
- private function render_list_field( $lists, $settings )
180
- {
181
  ob_start();
182
-
183
- $options = array( '' => __( 'Choose...', 'fl-builder' ) );
184
-
 
 
185
  foreach ( $lists->data['entries'] as $list ) {
186
  $options[ $list['id'] ] = $list['name'];
187
  }
188
-
189
  FLBuilder::render_settings_field( 'list_id', array(
190
  'row_class' => 'fl-builder-service-field-row',
191
  'class' => 'fl-builder-service-list-select',
@@ -193,23 +185,22 @@ final class FLBuilderServiceAWeber extends FLBuilderService {
193
  'label' => _x( 'List', 'An email list from a third party provider.', 'fl-builder' ),
194
  'options' => $options,
195
  'preview' => array(
196
- 'type' => 'none'
197
- )
198
- ), $settings);
199
-
200
  return ob_get_clean();
201
  }
202
 
203
  /**
204
- * Render markup for the tags field.
205
  *
206
  * @since 1.8.8
207
  * @param object $settings Saved module settings.
208
  * @return string The markup for the tags field.
209
  * @access private
210
  */
211
- private function render_tags_field( $settings )
212
- {
213
  ob_start();
214
 
215
  FLBuilder::render_settings_field( 'tags', array(
@@ -219,14 +210,14 @@ final class FLBuilderServiceAWeber extends FLBuilderService {
219
  'label' => _x( 'Tags', 'A comma separated list of tags.', 'fl-builder' ),
220
  'help' => __( 'A comma separated list of tags.', 'fl-builder' ),
221
  'preview' => array(
222
- 'type' => 'none'
223
- )
224
  ),$settings);
225
 
226
  return ob_get_clean();
227
  }
228
 
229
- /**
230
  * Subscribe an email address to AWeber.
231
  *
232
  * @since 1.5.4
@@ -236,51 +227,51 @@ final class FLBuilderServiceAWeber extends FLBuilderService {
236
  * @return array {
237
  * @type bool|string $error The error message or false if no error.
238
  * }
239
- */
240
- public function subscribe( $settings, $email, $name = false )
241
- {
242
  $account_data = $this->get_account_data( $settings->service_account );
243
- $response = array( 'error' => false );
244
-
 
 
245
  if ( ! $account_data ) {
246
  $response['error'] = __( 'There was an error subscribing to AWeber. The account is no longer connected.', 'fl-builder' );
247
- }
248
- else {
249
-
250
  $api = $this->get_api( $account_data['auth_code'] );
251
- $data = array(
252
  'ws.op' => 'create',
253
  'email' => $email,
254
  );
255
-
256
  if ( isset( $settings->tags ) ) {
257
  $data['tags'] = array( $settings->tags );
258
  }
259
-
260
  if ( $name ) {
261
  $data['name'] = $name;
262
  }
263
-
264
  try {
265
  $account = $api->getAccount( $account_data['access_token'], $account_data['access_secret'] );
266
  $url = '/accounts/' . $account->id . '/lists/' . $settings->list_id . '/subscribers';
267
- $result = $api->adapter->request( 'POST', $url, $data, array( 'return' => 'headers' ) );
 
 
268
 
269
  if ( is_array( $result ) && isset( $result['Status-Code'] ) && 201 == $result['Status-Code'] ) {
270
  return $response;
271
- }
272
- else {
273
  $response['error'] = __( 'There was an error connecting to AWeber. Please try again.', 'fl-builder' );
274
  }
275
- }
276
- catch ( AWeberAPIException $e ) {
277
  $response['error'] = sprintf(
278
  __( 'There was an error subscribing to AWeber. %s', 'fl-builder' ),
279
  $e->getMessage()
280
  );
281
  }
282
- }
283
-
284
  return $response;
285
  }
286
- }
12
  *
13
  * @since 1.5.4
14
  * @var string $id
15
+ */
16
  public $id = 'aweber';
17
 
18
  /**
19
  * @since 1.5.4
20
  * @var object $api_instance
21
  * @access private
22
+ */
23
  private $api_instance = null;
24
 
25
  /**
28
  * @since 1.5.4
29
  * @param string $auth_code A valid authorization code.
30
  * @return object The API instance.
31
+ */
32
+ public function get_api( $auth_code ) {
 
33
  if ( $this->api_instance ) {
34
  return $this->api_instance;
35
  }
36
  if ( ! class_exists( 'AWeberAPI' ) ) {
37
  require_once FL_BUILDER_DIR . 'includes/vendor/aweber/aweber_api.php';
38
  }
39
+
40
  list( $auth_key, $auth_token, $req_key, $req_token, $oauth ) = explode( '|', $auth_code );
41
 
42
  $this->api_instance = new AWeberAPI( $auth_key, $auth_token );
43
  $this->api_instance->user->requestToken = $req_key;
44
  $this->api_instance->user->tokenSecret = $req_token;
45
  $this->api_instance->user->verifier = $oauth;
46
+
47
  return $this->api_instance;
48
  }
49
+
50
  /**
51
  * Test the API connection.
52
  *
58
  * @type bool|string $error The error message or false if no error.
59
  * @type array $data An array of data used to make the connection.
60
  * }
61
+ */
62
+ public function connect( $fields = array() ) {
63
+ $response = array(
 
64
  'error' => false,
65
+ 'data' => array(),
66
  );
67
+
68
  // Make sure we have an authorization code.
69
  if ( ! isset( $fields['auth_code'] ) || empty( $fields['auth_code'] ) ) {
70
  $response['error'] = __( 'Error: You must provide an Authorization Code.', 'fl-builder' );
71
+ } // End if().
72
+ elseif ( 6 != count( explode( '|', $fields['auth_code'] ) ) ) {
 
73
  $response['error'] = __( 'Error: Please enter a valid Authorization Code.', 'fl-builder' );
74
+ } // Try to connect and store the connection data.
 
75
  else {
76
+
77
  $api = $this->get_api( $fields['auth_code'] );
78
+
79
  // Get an access token from the API.
80
  try {
81
  list( $access_token, $access_token_secret ) = $api->getAccessToken();
82
+ } catch ( AWeberException $e ) {
 
83
  $response['error'] = $e->getMessage();
84
  }
85
+
86
  // Make sure we can get the account.
87
  try {
88
  $account = $api->getAccount();
89
+ } catch ( AWeberException $e ) {
 
90
  $response['error'] = $e->getMessage();
91
  }
92
+
93
  // Build the response data.
94
  if ( ! $response['error'] ) {
95
+
96
  $response['data'] = array(
97
  'auth_code' => $fields['auth_code'],
98
  'access_token' => $access_token,
99
+ 'access_secret' => $access_token_secret,
100
  );
101
  }
102
  }
103
+
104
  return $response;
105
  }
106
 
109
  *
110
  * @since 1.5.4
111
  * @return string The connection settings markup.
112
+ */
113
+ public function render_connect_settings() {
 
114
  ob_start();
115
+
116
  FLBuilder::render_settings_field( 'auth_code', array(
117
  'row_class' => 'fl-builder-service-connect-row',
118
  'class' => 'fl-builder-service-connect-input',
120
  'label' => __( 'Authorization Code', 'fl-builder' ),
121
  'description' => sprintf( __( 'Please register this website with AWeber to get your Authorization Code. <a%s>Register Now</a>', 'fl-builder' ), ' href="https://auth.aweber.com/1.0/oauth/authorize_app/baa1f131" target="_blank"' ),
122
  'preview' => array(
123
+ 'type' => 'none',
124
+ ),
125
+ ));
126
+
127
  return ob_get_clean();
128
  }
129
 
130
  /**
131
+ * Render the markup for service specific fields.
132
  *
133
  * @since 1.5.4
134
  * @param string $account The name of the saved account.
137
  * @type bool|string $error The error message or false if no error.
138
  * @type string $html The field markup.
139
  * }
140
+ */
141
+ public function render_fields( $account, $settings ) {
 
142
  $account_data = $this->get_account_data( $account );
143
  $api = $this->get_api( $account_data['auth_code'] );
144
+ $response = array(
145
+ 'error' => false,
146
+ 'html' => '',
147
  );
148
 
149
  try {
151
  $lists = $account->loadFromUrl( '/accounts/' . $account->id . '/lists' );
152
  $response['html'] = $this->render_list_field( $lists, $settings );
153
  $response['html'] .= $this->render_tags_field( $settings );
154
+ } catch ( AWeberException $e ) {
 
155
  $response['error'] = $e->getMessage();
156
  }
157
+
158
  return $response;
159
  }
160
 
161
  /**
162
+ * Render markup for the list field.
163
  *
164
  * @since 1.5.4
165
  * @param array $lists List data from the API.
166
  * @param object $settings Saved module settings.
167
  * @return string The markup for the list field.
168
  * @access private
169
+ */
170
+ private function render_list_field( $lists, $settings ) {
 
171
  ob_start();
172
+
173
+ $options = array(
174
+ '' => __( 'Choose...', 'fl-builder' ),
175
+ );
176
+
177
  foreach ( $lists->data['entries'] as $list ) {
178
  $options[ $list['id'] ] = $list['name'];
179
  }
180
+
181
  FLBuilder::render_settings_field( 'list_id', array(
182
  'row_class' => 'fl-builder-service-field-row',
183
  'class' => 'fl-builder-service-list-select',
185
  'label' => _x( 'List', 'An email list from a third party provider.', 'fl-builder' ),
186
  'options' => $options,
187
  'preview' => array(
188
+ 'type' => 'none',
189
+ ),
190
+ ), $settings);
191
+
192
  return ob_get_clean();
193
  }
194
 
195
  /**
196
+ * Render markup for the tags field.
197
  *
198
  * @since 1.8.8
199
  * @param object $settings Saved module settings.
200
  * @return string The markup for the tags field.
201
  * @access private
202
  */
203
+ private function render_tags_field( $settings ) {
 
204
  ob_start();
205
 
206
  FLBuilder::render_settings_field( 'tags', array(
210
  'label' => _x( 'Tags', 'A comma separated list of tags.', 'fl-builder' ),
211
  'help' => __( 'A comma separated list of tags.', 'fl-builder' ),
212
  'preview' => array(
213
+ 'type' => 'none',
214
+ ),
215
  ),$settings);
216
 
217
  return ob_get_clean();
218
  }
219
 
220
+ /**
221
  * Subscribe an email address to AWeber.
222
  *
223
  * @since 1.5.4
227
  * @return array {
228
  * @type bool|string $error The error message or false if no error.
229
  * }
230
+ */
231
+ public function subscribe( $settings, $email, $name = false ) {
 
232
  $account_data = $this->get_account_data( $settings->service_account );
233
+ $response = array(
234
+ 'error' => false,
235
+ );
236
+
237
  if ( ! $account_data ) {
238
  $response['error'] = __( 'There was an error subscribing to AWeber. The account is no longer connected.', 'fl-builder' );
239
+ } else {
240
+
 
241
  $api = $this->get_api( $account_data['auth_code'] );
242
+ $data = array(
243
  'ws.op' => 'create',
244
  'email' => $email,
245
  );
246
+
247
  if ( isset( $settings->tags ) ) {
248
  $data['tags'] = array( $settings->tags );
249
  }
250
+
251
  if ( $name ) {
252
  $data['name'] = $name;
253
  }
254
+
255
  try {
256
  $account = $api->getAccount( $account_data['access_token'], $account_data['access_secret'] );
257
  $url = '/accounts/' . $account->id . '/lists/' . $settings->list_id . '/subscribers';
258
+ $result = $api->adapter->request( 'POST', $url, $data, array(
259
+ 'return' => 'headers',
260
+ ) );
261
 
262
  if ( is_array( $result ) && isset( $result['Status-Code'] ) && 201 == $result['Status-Code'] ) {
263
  return $response;
264
+ } else {
 
265
  $response['error'] = __( 'There was an error connecting to AWeber. Please try again.', 'fl-builder' );
266
  }
267
+ } catch ( AWeberAPIException $e ) {
 
268
  $response['error'] = sprintf(
269
  __( 'There was an error subscribing to AWeber. %s', 'fl-builder' ),
270
  $e->getMessage()
271
  );
272
  }
273
+ }// End if().
274
+
275
  return $response;
276
  }
277
+ }
classes/class-fl-builder-service-campaign-monitor.php CHANGED
@@ -12,7 +12,7 @@ final class FLBuilderServiceCampaignMonitor extends FLBuilderService {
12
  *
13
  * @since 1.5.4
14
  * @var string $id
15
- */
16
  public $id = 'campaign-monitor';
17
 
18
  /**
@@ -20,9 +20,8 @@ final class FLBuilderServiceCampaignMonitor extends FLBuilderService {
20
  *
21
  * @since 1.5.4
22
  * @return void
23
- */
24
- public function __construct()
25
- {
26
  if ( ! class_exists( 'CS_REST_General' ) ) {
27
  require_once FL_BUILDER_DIR . 'includes/vendor/campaign-monitor/csrest_general.php';
28
  require_once FL_BUILDER_DIR . 'includes/vendor/campaign-monitor/csrest_clients.php';
@@ -30,7 +29,7 @@ final class FLBuilderServiceCampaignMonitor extends FLBuilderService {
30
  require_once FL_BUILDER_DIR . 'includes/vendor/campaign-monitor/csrest_subscribers.php';
31
  }
32
  }
33
-
34
  /**
35
  * Test the API connection.
36
  *
@@ -42,32 +41,33 @@ final class FLBuilderServiceCampaignMonitor extends FLBuilderService {
42
  * @type bool|string $error The error message or false if no error.
43
  * @type array $data An array of data used to make the connection.
44
  * }
45
- */
46
- public function connect( $fields = array() )
47
- {
48
- $response = array(
49
  'error' => false,
50
- 'data' => array()
51
  );
52
-
53
  // Make sure we have an API key.
54
  if ( ! isset( $fields['api_key'] ) || empty( $fields['api_key'] ) ) {
55
  $response['error'] = __( 'Error: You must provide an API key.', 'fl-builder' );
56
- }
57
- // Try to connect and store the connection data.
58
  else {
59
-
60
- $api = new CS_REST_General( array( 'api_key' => $fields['api_key'] ) );
 
 
61
  $result = $api->get_clients();
62
-
63
  if ( $result->was_successful() ) {
64
- $response['data'] = array( 'api_key' => $fields['api_key'] );
65
- }
66
- else {
 
67
  $response['error'] = __( 'Error: Please check your API key.', 'fl-builder' );
68
  }
69
  }
70
-
71
  return $response;
72
  }
73
 
@@ -76,11 +76,10 @@ final class FLBuilderServiceCampaignMonitor extends FLBuilderService {
76
  *
77
  * @since 1.5.4
78
  * @return string The connection settings markup.
79
- */
80
- public function render_connect_settings()
81
- {
82
  ob_start();
83
-
84
  FLBuilder::render_settings_field( 'api_key', array(
85
  'row_class' => 'fl-builder-service-connect-row',
86
  'class' => 'fl-builder-service-connect-input',
@@ -88,15 +87,15 @@ final class FLBuilderServiceCampaignMonitor extends FLBuilderService {
88
  'label' => __( 'API Key', 'fl-builder' ),
89
  'help' => __( 'Your API key can be found in your Campaign Monitor account under Account Settings > API Key.', 'fl-builder' ),
90
  'preview' => array(
91
- 'type' => 'none'
92
- )
93
- ));
94
-
95
  return ob_get_clean();
96
  }
97
 
98
  /**
99
- * Render the markup for service specific fields.
100
  *
101
  * @since 1.5.4
102
  * @param string $account The name of the saved account.
@@ -105,52 +104,52 @@ final class FLBuilderServiceCampaignMonitor extends FLBuilderService {
105
  * @type bool|string $error The error message or false if no error.
106
  * @type string $html The field markup.
107
  * }
108
- */
109
- public function render_fields( $account, $settings )
110
- {
111
  $post_data = FLBuilderModel::get_post_data();
112
  $account_data = $this->get_account_data( $account );
113
  $api = new CS_REST_General( $account_data );
114
  $result = $api->get_clients();
115
- $response = array(
116
- 'error' => false,
117
- 'html' => ''
118
  );
119
-
120
  if ( $result->was_successful() ) {
121
-
122
  if ( ! isset( $post_data['client'] ) ) {
123
  $response['html'] .= $this->render_client_field( $result, $settings );
124
  }
125
 
126
  $response['html'] .= $this->render_list_field( $account_data, $settings );
127
- }
128
- else {
129
  $response['error'] = __( 'Error: Please check your API key.', 'fl-builder' );
130
  }
131
-
132
  return $response;
133
  }
134
 
135
  /**
136
- * Render markup for the client field.
137
  *
138
  * @since 1.5.4
139
  * @param array $clients Client data from the API.
140
  * @param object $settings Saved module settings.
141
  * @return string The markup for the list field.
142
  * @access private
143
- */
144
- private function render_client_field( $clients, $settings )
145
- {
146
  ob_start();
147
-
148
- $options = array( '' => __( 'Choose...', 'fl-builder' ) );
149
-
 
 
150
  foreach ( $clients->response as $client ) {
 
151
  $options[ $client->ClientID ] = $client->Name;
152
  }
153
-
154
  FLBuilder::render_settings_field( 'client_id', array(
155
  'row_class' => 'fl-builder-service-field-row',
156
  'class' => 'fl-builder-campaign-monitor-client-select',
@@ -158,50 +157,50 @@ final class FLBuilderServiceCampaignMonitor extends FLBuilderService {
158
  'label' => _x( 'Client', 'A client account in Campaign Monitor.', 'fl-builder' ),
159
  'options' => $options,
160
  'preview' => array(
161
- 'type' => 'none'
162
- )
163
- ), $settings);
164
-
165
  return ob_get_clean();
166
  }
167
 
168
  /**
169
- * Render markup for the list field.
170
  *
171
  * @since 1.5.4
172
  * @param array $account_data Saved account data.
173
  * @param object $settings Saved module settings.
174
  * @return string The markup for the list field.
175
  * @access private
176
- */
177
- private function render_list_field( $account_data, $settings )
178
- {
179
  $post_data = FLBuilderModel::get_post_data();
180
-
181
  // Get the client ID. Return an empty string if we don't have one yet.
182
  if ( isset( $post_data['client'] ) ) {
183
  $client_id = $post_data['client'];
184
- }
185
- else if ( isset( $settings->client_id ) ) {
186
  $client_id = $settings->client_id;
187
- }
188
- else {
189
  return '';
190
  }
191
-
192
  // Get the list data.
193
  $api = new CS_REST_Clients( $client_id, $account_data );
194
  $lists = $api->get_lists();
195
-
196
  // Render the list field.
197
  ob_start();
198
-
199
- $options = array( '' => __( 'Choose...', 'fl-builder' ) );
200
-
 
 
201
  foreach ( $lists->response as $list ) {
 
202
  $options[ $list->ListID ] = $list->Name;
203
  }
204
-
205
  FLBuilder::render_settings_field( 'list_id', array(
206
  'row_class' => 'fl-builder-service-field-row',
207
  'class' => 'fl-builder-service-list-select',
@@ -209,14 +208,14 @@ final class FLBuilderServiceCampaignMonitor extends FLBuilderService {
209
  'label' => _x( 'List', 'An email list from a third party provider.', 'fl-builder' ),
210
  'options' => $options,
211
  'preview' => array(
212
- 'type' => 'none'
213
- )
214
- ), $settings);
215
-
216
  return ob_get_clean();
217
  }
218
 
219
- /**
220
  * Subscribe an email address to Campaign Monitor.
221
  *
222
  * @since 1.5.4
@@ -226,34 +225,34 @@ final class FLBuilderServiceCampaignMonitor extends FLBuilderService {
226
  * @return array {
227
  * @type bool|string $error The error message or false if no error.
228
  * }
229
- */
230
- public function subscribe( $settings, $email, $name = false )
231
- {
232
  $account_data = $this->get_account_data( $settings->service_account );
233
- $response = array( 'error' => false );
234
-
 
 
235
  if ( ! $account_data ) {
236
  $response['error'] = __( 'There was an error subscribing to Campaign Monitor. The account is no longer connected.', 'fl-builder' );
237
- }
238
- else {
239
-
240
  $api = new CS_Rest_Subscribers( $settings->list_id, $account_data );
241
  $data = array(
242
  'EmailAddress' => $email,
243
- 'Resubscribe' => true
244
  );
245
-
246
  if ( $name ) {
247
  $data['Name'] = $name;
248
  }
249
-
250
  $result = $api->add( $data );
251
-
252
  if ( ! $result->was_successful() ) {
253
  $response['error'] = __( 'There was an error subscribing to Campaign Monitor.', 'fl-builder' );
254
  }
255
  }
256
-
257
  return $response;
258
  }
259
- }
12
  *
13
  * @since 1.5.4
14
  * @var string $id
15
+ */
16
  public $id = 'campaign-monitor';
17
 
18
  /**
20
  *
21
  * @since 1.5.4
22
  * @return void
23
+ */
24
+ public function __construct() {
 
25
  if ( ! class_exists( 'CS_REST_General' ) ) {
26
  require_once FL_BUILDER_DIR . 'includes/vendor/campaign-monitor/csrest_general.php';
27
  require_once FL_BUILDER_DIR . 'includes/vendor/campaign-monitor/csrest_clients.php';
29