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
  require_once FL_BUILDER_DIR . 'includes/vendor/campaign-monitor/csrest_subscribers.php';
30
  }
31
  }
32
+
33
  /**
34
  * Test the API connection.
35
  *
41
  * @type bool|string $error The error message or false if no error.
42
  * @type array $data An array of data used to make the connection.
43
  * }
44
+ */
45
+ public function connect( $fields = array() ) {
46
+ $response = array(
 
47
  'error' => false,
48
+ 'data' => array(),
49
  );
50
+
51
  // Make sure we have an API key.
52
  if ( ! isset( $fields['api_key'] ) || empty( $fields['api_key'] ) ) {
53
  $response['error'] = __( 'Error: You must provide an API key.', 'fl-builder' );
54
+ } // End if().
 
55
  else {
56
+
57
+ $api = new CS_REST_General( array(
58
+ 'api_key' => $fields['api_key'],
59
+ ) );
60
  $result = $api->get_clients();
61
+
62
  if ( $result->was_successful() ) {
63
+ $response['data'] = array(
64
+ '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
  *
77
  * @since 1.5.4
78
  * @return string The connection settings markup.
79
+ */
80
+ public function render_connect_settings() {
 
81
  ob_start();
82
+
83
  FLBuilder::render_settings_field( 'api_key', array(
84
  'row_class' => 'fl-builder-service-connect-row',
85
  'class' => 'fl-builder-service-connect-input',
87
  'label' => __( 'API Key', 'fl-builder' ),
88
  'help' => __( 'Your API key can be found in your Campaign Monitor account under Account Settings > API Key.', 'fl-builder' ),
89
  'preview' => array(
90
+ 'type' => 'none',
91
+ ),
92
+ ));
93
+
94
  return ob_get_clean();
95
  }
96
 
97
  /**
98
+ * Render the markup for service specific fields.
99
  *
100
  * @since 1.5.4
101
  * @param string $account The name of the saved account.
104
  * @type bool|string $error The error message or false if no error.
105
  * @type string $html The field markup.
106
  * }
107
+ */
108
+ public function render_fields( $account, $settings ) {
 
109
  $post_data = FLBuilderModel::get_post_data();
110
  $account_data = $this->get_account_data( $account );
111
  $api = new CS_REST_General( $account_data );
112
  $result = $api->get_clients();
113
+ $response = array(
114
+ 'error' => false,
115
+ 'html' => '',
116
  );
117
+
118
  if ( $result->was_successful() ) {
119
+
120
  if ( ! isset( $post_data['client'] ) ) {
121
  $response['html'] .= $this->render_client_field( $result, $settings );
122
  }
123
 
124
  $response['html'] .= $this->render_list_field( $account_data, $settings );
125
+ } else {
 
126
  $response['error'] = __( 'Error: Please check your API key.', 'fl-builder' );
127
  }
128
+
129
  return $response;
130
  }
131
 
132
  /**
133
+ * Render markup for the client field.
134
  *
135
  * @since 1.5.4
136
  * @param array $clients Client data from the API.
137
  * @param object $settings Saved module settings.
138
  * @return string The markup for the list field.
139
  * @access private
140
+ */
141
+ private function render_client_field( $clients, $settings ) {
 
142
  ob_start();
143
+
144
+ $options = array(
145
+ '' => __( 'Choose...', 'fl-builder' ),
146
+ );
147
+
148
  foreach ( $clients->response as $client ) {
149
+ // @codingStandardsIgnoreLine
150
  $options[ $client->ClientID ] = $client->Name;
151
  }
152
+
153
  FLBuilder::render_settings_field( 'client_id', array(
154
  'row_class' => 'fl-builder-service-field-row',
155
  'class' => 'fl-builder-campaign-monitor-client-select',
157
  'label' => _x( 'Client', 'A client account in Campaign Monitor.', 'fl-builder' ),
158
  'options' => $options,
159
  'preview' => array(
160
+ 'type' => 'none',
161
+ ),
162
+ ), $settings);
163
+
164
  return ob_get_clean();
165
  }
166
 
167
  /**
168
+ * Render markup for the list field.
169
  *
170
  * @since 1.5.4
171
  * @param array $account_data Saved account data.
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_field( $account_data, $settings ) {
 
177
  $post_data = FLBuilderModel::get_post_data();
178
+
179
  // Get the client ID. Return an empty string if we don't have one yet.
180
  if ( isset( $post_data['client'] ) ) {
181
  $client_id = $post_data['client'];
182
+ } elseif ( isset( $settings->client_id ) ) {
 
183
  $client_id = $settings->client_id;
184
+ } else {
 
185
  return '';
186
  }
187
+
188
  // Get the list data.
189
  $api = new CS_REST_Clients( $client_id, $account_data );
190
  $lists = $api->get_lists();
191
+
192
  // Render the list field.
193
  ob_start();
194
+
195
+ $options = array(
196
+ '' => __( 'Choose...', 'fl-builder' ),
197
+ );
198
+
199
  foreach ( $lists->response as $list ) {
200
+ // @codingStandardsIgnoreLine
201
  $options[ $list->ListID ] = $list->Name;
202
  }
203
+
204
  FLBuilder::render_settings_field( 'list_id', array(
205
  'row_class' => 'fl-builder-service-field-row',
206
  'class' => 'fl-builder-service-list-select',
208
  'label' => _x( 'List', 'An email list from a third party provider.', 'fl-builder' ),
209
  'options' => $options,
210
  'preview' => array(
211
+ 'type' => 'none',
212
+ ),
213
+ ), $settings);
214
+
215
  return ob_get_clean();
216
  }
217
 
218
+ /**
219
  * Subscribe an email address to Campaign Monitor.
220
  *
221
  * @since 1.5.4
225
  * @return array {
226
  * @type bool|string $error The error message or false if no error.
227
  * }
228
+ */
229
+ public function subscribe( $settings, $email, $name = false ) {
 
230
  $account_data = $this->get_account_data( $settings->service_account );
231
+ $response = array(
232
+ 'error' => false,
233
+ );
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
+ } else {
238
+
 
239
  $api = new CS_Rest_Subscribers( $settings->list_id, $account_data );
240
  $data = array(
241
  'EmailAddress' => $email,
242
+ 'Resubscribe' => true,
243
  );
244
+
245
  if ( $name ) {
246
  $data['Name'] = $name;
247
  }
248
+
249
  $result = $api->add( $data );
250
+
251
  if ( ! $result->was_successful() ) {
252
  $response['error'] = __( 'There was an error subscribing to Campaign Monitor.', 'fl-builder' );
253
  }
254
  }
255
+
256
  return $response;
257
  }
258
+ }
classes/class-fl-builder-service-campayn.php CHANGED
@@ -12,7 +12,7 @@ final class FLBuilderServiceCampayn extends FLBuilderService {
12
  *
13
  * @since 1.5.4
14
  * @var string $id
15
- */
16
  public $id = 'campayn';
17
 
18
  /**
@@ -21,17 +21,17 @@ final class FLBuilderServiceCampayn extends FLBuilderService {
21
  * @since 1.5.8
22
  * @access private
23
  * @var string $api_protocol
24
- */
25
- private $api_protocol = 'http';
26
 
27
- /**
28
  * The API version
29
  *
30
  * @since 1.5.8
31
  * @access private
32
  * @var string $api_version
33
- */
34
- private $api_version = 1;
35
 
36
  /**
37
  * Request data from the thir party API.
@@ -42,41 +42,38 @@ final class FLBuilderServiceCampayn extends FLBuilderService {
42
  * @param string $endpoint Method to request available from this service.
43
  * @param array $params Data to be passed to API
44
  * @return array|object The API response.
45
- */
46
- private function get_api_response( $base_url, $api_key, $endpoint, $params = array() )
47
- {
48
  // Exclude http:// from the user's input
49
- $request_uri = $this->api_protocol .'://'. preg_replace('#^https?://#', '', $base_url) .'/api/v' .$this->api_version . $endpoint;
50
 
51
  $params['timeout'] = 60;
52
- $params['body'] = isset($params['data']) && $params['data'] ? json_encode($params['data']) : '';
53
- $params['headers'] = array('Authorization' => 'TRUEREST apikey='. $api_key);
54
- $response = wp_remote_get( $request_uri, $params );
55
- $response_code = wp_remote_retrieve_response_code( $response );
 
 
56
  $response_message = wp_remote_retrieve_response_message( $response );
57
- $get_response = json_decode(wp_remote_retrieve_body( $response ), true);
58
 
59
- if ( is_wp_error($response) || (200 != $response_code) ) {
60
 
61
  if ( is_wp_error( $response ) ) {
62
  $data['error'] = $response->get_error_message();
63
- }
64
- else {
65
- $data['error'] = isset($get_response['msg']) ? $get_response['msg'] : $response_code .' - '. $response_message;
66
  }
67
-
68
- }
69
- else {
70
- if ($get_response) {
71
  $data = $get_response;
72
- }
73
- else {
74
  $data = $response;
75
- }
76
  }
77
  return $data;
78
  }
79
-
80
  /**
81
  * Test the API connection.
82
  *
@@ -89,35 +86,34 @@ final class FLBuilderServiceCampayn extends FLBuilderService {
89
  * @type bool|string $error The error message or false if no error.
90
  * @type array $data An array of data used to make the connection.
91
  * }
92
- */
93
- public function connect( $fields = array() )
94
- {
95
- $response = array(
96
  'error' => false,
97
- 'data' => array()
98
  );
99
-
100
  // Make sure we have the Host.
101
  if ( ! isset( $fields['api_host'] ) || empty( $fields['api_host'] ) ) {
102
  $response['error'] = __( 'Error: You must provide a Host.', 'fl-builder' );
103
- }
104
- // Make sure we have an API key.
105
- else if ( ! isset( $fields['api_key'] ) || empty( $fields['api_key'] ) ) {
106
  $response['error'] = __( 'Error: You must provide an API key.', 'fl-builder' );
107
- }
108
- // Try to connect and store the connection data.
109
  else {
110
 
111
  $result = $this->get_api_response( $fields['api_host'], $fields['api_key'], '/lists.json' );
112
-
113
- if (!isset($result['error'])) {
114
- $response['data'] = array( 'api_host' => $fields['api_host'], 'api_key' => $fields['api_key'] );
115
- }
116
- else {
117
- $response['error'] = sprintf(__( 'Error: Could not connect to Campayn. %s', 'fl-builder' ), $result['error']);
118
- }
 
 
119
  }
120
-
121
  return $response;
122
  }
123
 
@@ -126,11 +122,10 @@ final class FLBuilderServiceCampayn extends FLBuilderService {
126
  *
127
  * @since 1.5.4
128
  * @return string The connection settings markup.
129
- */
130
- public function render_connect_settings()
131
- {
132
  ob_start();
133
-
134
  FLBuilder::render_settings_field( 'api_host', array(
135
  'row_class' => 'fl-builder-service-connect-row',
136
  'class' => 'fl-builder-service-connect-input',
@@ -138,8 +133,8 @@ final class FLBuilderServiceCampayn extends FLBuilderService {
138
  'label' => __( 'Host', 'fl-builder' ),
139
  'help' => __( 'The host you chose when you signed up for your account. Check your welcome email if you forgot it. Please enter it without the initial http:// (for example: demo.campayn.com).', 'fl-builder' ),
140
  'preview' => array(
141
- 'type' => 'none'
142
- )
143
  ));
144
 
145
  FLBuilder::render_settings_field( 'api_key', array(
@@ -149,15 +144,15 @@ final class FLBuilderServiceCampayn extends FLBuilderService {
149
  'label' => __( 'API Key', 'fl-builder' ),
150
  'help' => __( 'Your API key can be found in your Campayn account under Settings > API Key.', 'fl-builder' ),
151
  'preview' => array(
152
- 'type' => 'none'
153
- )
154
- ));
155
-
156
  return ob_get_clean();
157
  }
158
 
159
  /**
160
- * Render the markup for service specific fields.
161
  *
162
  * @since 1.5.4
163
  * @param string $account The name of the saved account.
@@ -166,46 +161,45 @@ final class FLBuilderServiceCampayn extends FLBuilderService {
166
  * @type bool|string $error The error message or false if no error.
167
  * @type string $html The field markup.
168
  * }
169
- */
170
- public function render_fields( $account, $settings )
171
- {
172
  $account_data = $this->get_account_data( $account );
173
  $results = $this->get_api_response( $account_data['api_host'], $account_data['api_key'], '/lists.json' );
174
 
175
- $response = array(
176
- 'error' => false,
177
- 'html' => ''
178
  );
179
 
180
- if ( isset($results['error']) ) {
181
- $response['error'] = sprintf(__( 'Error: Please check your API key. %s', 'fl-builder' ), $results['error']);
182
- }
183
- else {
184
  $response['html'] = $this->render_list_field( $results, $settings );
185
  }
186
-
187
  return $response;
188
  }
189
 
190
  /**
191
- * Render markup for the list field.
192
  *
193
  * @since 1.5.4
194
  * @param array $lists List data from the API.
195
  * @param object $settings Saved module settings.
196
  * @return string The markup for the list field.
197
  * @access private
198
- */
199
- private function render_list_field( $lists, $settings )
200
- {
201
  ob_start();
202
-
203
- $options = array( '' => __( 'Choose...', 'fl-builder' ) );
204
-
 
 
205
  foreach ( $lists as $list ) {
206
  $options[ $list['id'] ] = $list['list_name'];
207
  }
208
-
209
  FLBuilder::render_settings_field( 'list_id', array(
210
  'row_class' => 'fl-builder-service-field-row',
211
  'class' => 'fl-builder-service-list-select',
@@ -213,14 +207,14 @@ final class FLBuilderServiceCampayn extends FLBuilderService {
213
  'label' => _x( 'List', 'An email list from third party provider.', 'fl-builder' ),
214
  'options' => $options,
215
  'preview' => array(
216
- 'type' => 'none'
217
- )
218
- ), $settings);
219
-
220
  return ob_get_clean();
221
  }
222
 
223
- /**
224
  * Subscribe an email address to Campayn.
225
  *
226
  * @since 1.5.4
@@ -230,26 +224,28 @@ final class FLBuilderServiceCampayn extends FLBuilderService {
230
  * @return array {
231
  * @type bool|string $error The error message or false if no error.
232
  * }
233
- */
234
- public function subscribe( $settings, $email, $name = '' )
235
- {
236
  $account_data = $this->get_account_data( $settings->service_account );
237
- $response = array( 'error' => false );
 
 
238
  $contact_id = null;
239
-
240
  if ( ! $account_data ) {
241
  $response['error'] = __( 'There was an error subscribing to Campayn. The account is no longer connected.', 'fl-builder' );
242
- }
243
- else {
244
-
245
  // Build data array
246
- $data = array('email' => $email);
 
 
247
 
248
  // Add the name to the data array if we have one.
249
  if ( $name ) {
250
-
251
  $names = explode( ' ', $name );
252
-
253
  if ( isset( $names[0] ) ) {
254
  $data['first_name'] = $names[0];
255
  }
@@ -259,12 +255,12 @@ final class FLBuilderServiceCampayn extends FLBuilderService {
259
  }
260
 
261
  // Check if email already exists
262
- $result = $this->get_api_response( $account_data['api_host'], $account_data['api_key'],
263
- "/lists/{$settings->list_id}/contacts.json?filter[contact]=". $email
264
- );
265
 
266
  // Already exists
267
- if ( ! isset($result['error']) && (is_array($result) && isset($result[0]['id'])) ) {
268
  $contact_id = $result[0]['id'];
269
  }
270
 
@@ -272,23 +268,22 @@ final class FLBuilderServiceCampayn extends FLBuilderService {
272
  if ( ! $contact_id ) {
273
  $endpoint = "/lists/{$settings->list_id}/contacts.json";
274
  $method = 'POST';
275
- }
276
- else {
277
  $endpoint = "/contacts/{$contact_id}.json";
278
  $method = 'PUT';
279
  $data['id'] = $contact_id;
280
  }
281
 
282
- $result = $this->get_api_response( $account_data['api_host'], $account_data['api_key'], $endpoint, array(
283
  'data' => $data,
284
- 'method' => $method
285
- ) );
286
 
287
- if ( isset($result['error']) ) {
288
- $response['error'] = sprintf(__( 'There was an error subscribing to Campayn. %s', 'fl-builder' ), $result['error']);
289
  }
290
- }
291
-
292
  return $response;
293
  }
294
- }
12
  *
13
  * @since 1.5.4
14
  * @var string $id
15
+ */
16
  public $id = 'campayn';
17
 
18
  /**
21
  * @since 1.5.8
22
  * @access private
23
  * @var string $api_protocol
24
+ */
25
+ private $api_protocol = 'http';
26
 
27
+ /**
28
  * The API version
29
  *
30
  * @since 1.5.8
31
  * @access private
32
  * @var string $api_version
33
+ */
34
+ private $api_version = 1;
35
 
36
  /**
37
  * Request data from the thir party API.
42
  * @param string $endpoint Method to request available from this service.
43
  * @param array $params Data to be passed to API
44
  * @return array|object The API response.
45
+ */
46
+ private function get_api_response( $base_url, $api_key, $endpoint, $params = array() ) {
 
47
  // Exclude http:// from the user's input
48
+ $request_uri = $this->api_protocol . '://' . preg_replace( '#^https?://#', '', $base_url ) . '/api/v' . $this->api_version . $endpoint;
49
 
50
  $params['timeout'] = 60;
51
+ $params['body'] = isset( $params['data'] ) && $params['data'] ? json_encode( $params['data'] ) : '';
52
+ $params['headers'] = array(
53
+ 'Authorization' => 'TRUEREST apikey=' . $api_key,
54
+ );
55
+ $response = wp_remote_get( $request_uri, $params );
56
+ $response_code = wp_remote_retrieve_response_code( $response );
57
  $response_message = wp_remote_retrieve_response_message( $response );
58
+ $get_response = json_decode( wp_remote_retrieve_body( $response ), true );
59
 
60
+ if ( is_wp_error( $response ) || (200 != $response_code) ) {
61
 
62
  if ( is_wp_error( $response ) ) {
63
  $data['error'] = $response->get_error_message();
64
+ } else {
65
+ $data['error'] = isset( $get_response['msg'] ) ? $get_response['msg'] : $response_code . ' - ' . $response_message;
 
66
  }
67
+ } else {
68
+ if ( $get_response ) {
 
 
69
  $data = $get_response;
70
+ } else {
 
71
  $data = $response;
72
+ }
73
  }
74
  return $data;
75
  }
76
+
77
  /**
78
  * Test the API connection.
79
  *
86
  * @type bool|string $error The error message or false if no error.
87
  * @type array $data An array of data used to make the connection.
88
  * }
89
+ */
90
+ public function connect( $fields = array() ) {
91
+ $response = array(
 
92
  'error' => false,
93
+ 'data' => array(),
94
  );
95
+
96
  // Make sure we have the Host.
97
  if ( ! isset( $fields['api_host'] ) || empty( $fields['api_host'] ) ) {
98
  $response['error'] = __( 'Error: You must provide a Host.', 'fl-builder' );
99
+ } // End if().
100
+ elseif ( ! isset( $fields['api_key'] ) || empty( $fields['api_key'] ) ) {
 
101
  $response['error'] = __( 'Error: You must provide an API key.', 'fl-builder' );
102
+ } // Try to connect and store the connection data.
 
103
  else {
104
 
105
  $result = $this->get_api_response( $fields['api_host'], $fields['api_key'], '/lists.json' );
106
+
107
+ if ( ! isset( $result['error'] ) ) {
108
+ $response['data'] = array(
109
+ 'api_host' => $fields['api_host'],
110
+ 'api_key' => $fields['api_key'],
111
+ );
112
+ } else {
113
+ $response['error'] = sprintf( __( 'Error: Could not connect to Campayn. %s', 'fl-builder' ), $result['error'] );
114
+ }
115
  }
116
+
117
  return $response;
118
  }
119
 
122
  *
123
  * @since 1.5.4
124
  * @return string The connection settings markup.
125
+ */
126
+ public function render_connect_settings() {
 
127
  ob_start();
128
+
129
  FLBuilder::render_settings_field( 'api_host', array(
130
  'row_class' => 'fl-builder-service-connect-row',
131
  'class' => 'fl-builder-service-connect-input',
133
  'label' => __( 'Host', 'fl-builder' ),
134
  'help' => __( 'The host you chose when you signed up for your account. Check your welcome email if you forgot it. Please enter it without the initial http:// (for example: demo.campayn.com).', 'fl-builder' ),
135
  'preview' => array(
136
+ 'type' => 'none',
137
+ ),
138
  ));
139
 
140
  FLBuilder::render_settings_field( 'api_key', array(
144
  'label' => __( 'API Key', 'fl-builder' ),
145
  'help' => __( 'Your API key can be found in your Campayn account under Settings > API Key.', 'fl-builder' ),
146
  'preview' => array(
147
+ 'type' => 'none',
148
+ ),
149
+ ));
150
+
151
  return ob_get_clean();
152
  }
153
 
154
  /**
155
+ * Render the markup for service specific fields.
156
  *
157
  * @since 1.5.4
158
  * @param string $account The name of the saved account.
161
  * @type bool|string $error The error message or false if no error.
162
  * @type string $html The field markup.
163
  * }
164
+ */
165
+ public function render_fields( $account, $settings ) {
 
166
  $account_data = $this->get_account_data( $account );
167
  $results = $this->get_api_response( $account_data['api_host'], $account_data['api_key'], '/lists.json' );
168
 
169
+ $response = array(
170
+ 'error' => false,
171
+ 'html' => '',
172
  );
173
 
174
+ if ( isset( $results['error'] ) ) {
175
+ $response['error'] = sprintf( __( 'Error: Please check your API key. %s', 'fl-builder' ), $results['error'] );
176
+ } else {
 
177
  $response['html'] = $this->render_list_field( $results, $settings );
178
  }
179
+
180
  return $response;
181
  }
182
 
183
  /**
184
+ * Render markup for the list field.
185
  *
186
  * @since 1.5.4
187
  * @param array $lists List data from the API.
188
  * @param object $settings Saved module settings.
189
  * @return string The markup for the list field.
190
  * @access private
191
+ */
192
+ private function render_list_field( $lists, $settings ) {
 
193
  ob_start();
194
+
195
+ $options = array(
196
+ '' => __( 'Choose...', 'fl-builder' ),
197
+ );
198
+
199
  foreach ( $lists as $list ) {
200
  $options[ $list['id'] ] = $list['list_name'];
201
  }
202
+
203
  FLBuilder::render_settings_field( 'list_id', array(
204
  'row_class' => 'fl-builder-service-field-row',
205
  'class' => 'fl-builder-service-list-select',
207
  'label' => _x( 'List', 'An email list from third party provider.', 'fl-builder' ),
208
  'options' => $options,
209
  'preview' => array(
210
+ 'type' => 'none',
211
+ ),
212
+ ), $settings);
213
+
214
  return ob_get_clean();
215
  }
216
 
217
+ /**
218
  * Subscribe an email address to Campayn.
219
  *
220
  * @since 1.5.4
224
  * @return array {
225
  * @type bool|string $error The error message or false if no error.
226
  * }
227
+ */
228
+ public function subscribe( $settings, $email, $name = '' ) {
 
229
  $account_data = $this->get_account_data( $settings->service_account );
230
+ $response = array(
231
+ 'error' => false,
232
+ );
233
  $contact_id = null;
234
+
235
  if ( ! $account_data ) {
236
  $response['error'] = __( 'There was an error subscribing to Campayn. The account is no longer connected.', 'fl-builder' );
237
+ } else {
238
+
 
239
  // Build data array
240
+ $data = array(
241
+ 'email' => $email,
242
+ );
243
 
244
  // Add the name to the data array if we have one.
245
  if ( $name ) {
246
+
247
  $names = explode( ' ', $name );
248
+
249
  if ( isset( $names[0] ) ) {
250
  $data['first_name'] = $names[0];
251
  }
255
  }
256
 
257
  // Check if email already exists
258
+ $result = $this->get_api_response( $account_data['api_host'], $account_data['api_key'],
259
+ "/lists/{$settings->list_id}/contacts.json?filter[contact]=" . $email
260
+ );
261
 
262
  // Already exists
263
+ if ( ! isset( $result['error'] ) && (is_array( $result ) && isset( $result[0]['id'] )) ) {
264
  $contact_id = $result[0]['id'];
265
  }
266
 
268
  if ( ! $contact_id ) {
269
  $endpoint = "/lists/{$settings->list_id}/contacts.json";
270
  $method = 'POST';
271
+ } else {
 
272
  $endpoint = "/contacts/{$contact_id}.json";
273
  $method = 'PUT';
274
  $data['id'] = $contact_id;
275
  }
276
 
277
+ $result = $this->get_api_response( $account_data['api_host'], $account_data['api_key'], $endpoint, array(
278
  'data' => $data,
279
+ 'method' => $method,
280
+ ) );
281
 
282
+ if ( isset( $result['error'] ) ) {
283
+ $response['error'] = sprintf( __( 'There was an error subscribing to Campayn. %s', 'fl-builder' ), $result['error'] );
284
  }
285
+ }// End if().
286
+
287
  return $response;
288
  }
289
+ }
classes/class-fl-builder-service-constant-contact.php CHANGED
@@ -12,7 +12,7 @@ final class FLBuilderServiceConstantContact extends FLBuilderService {
12
  *
13
  * @since 1.5.4
14
  * @var string $id
15
- */
16
  public $id = 'constant-contact';
17
 
18
  /**
@@ -20,9 +20,9 @@ final class FLBuilderServiceConstantContact extends FLBuilderService {
20
  *
21
  * @since 1.5.4
22
  * @var string $api_url
23
- */
24
  public $api_url = 'https://api.constantcontact.com/v2/';
25
-
26
  /**
27
  * Test the API connection.
28
  *
@@ -35,39 +35,35 @@ final class FLBuilderServiceConstantContact extends FLBuilderService {
35
  * @type bool|string $error The error message or false if no error.
36
  * @type array $data An array of data used to make the connection.
37
  * }
38
- */
39
- public function connect( $fields = array() )
40
- {
41
- $response = array(
42
  'error' => false,
43
- 'data' => array()
44
  );
45
-
46
  // Make sure we have an API key.
47
  if ( ! isset( $fields['api_key'] ) || empty( $fields['api_key'] ) ) {
48
  $response['error'] = __( 'Error: You must provide an API key.', 'fl-builder' );
49
- }
50
- // Make sure we have an access token.
51
- else if ( ! isset( $fields['access_token'] ) || empty( $fields['access_token'] ) ) {
52
  $response['error'] = __( 'Error: You must provide an access token.', 'fl-builder' );
53
- }
54
- // Try to connect and store the connection data.
55
  else {
56
-
57
  $url = $this->api_url . 'lists?api_key=' . $fields['api_key'] . '&access_token=' . $fields['access_token'];
58
  $request = json_decode( wp_remote_retrieve_body( wp_remote_get( $url ) ) );
59
-
60
  if ( ! is_array( $request ) || ( isset( $request[0] ) && isset( $request[0]->error_message ) ) ) {
61
  $response['error'] = sprintf( __( 'Error: Could not connect to Constant Contact. %s', 'fl-builder' ), $request[0]->error_message );
62
- }
63
- else {
64
- $response['data'] = array(
65
  'api_key' => $fields['api_key'],
66
- 'access_token' => $fields['access_token']
67
  );
68
  }
69
  }
70
-
71
  return $response;
72
  }
73
 
@@ -76,11 +72,10 @@ final class FLBuilderServiceConstantContact 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,10 +83,10 @@ final class FLBuilderServiceConstantContact extends FLBuilderService {
88
  'label' => __( 'API Key', 'fl-builder' ),
89
  'help' => __( 'Your Constant Contact API key.', 'fl-builder' ),
90
  'preview' => array(
91
- 'type' => 'none'
92
- )
93
- ));
94
-
95
  FLBuilder::render_settings_field( 'access_token', array(
96
  'row_class' => 'fl-builder-service-connect-row',
97
  'class' => 'fl-builder-service-connect-input',
@@ -100,8 +95,8 @@ final class FLBuilderServiceConstantContact extends FLBuilderService {
100
  'help' => __( 'Your Constant Contact access token.', 'fl-builder' ),
101
  'description' => sprintf( __( 'You must register a <a%1$s>Developer Account</a> with Constant Contact to obtain an API key and access token. Please see <a%2$s>Getting an API key</a> for complete instructions.', 'fl-builder' ), ' href="https://constantcontact.mashery.com/member/register" target="_blank"', ' href="https://developer.constantcontact.com/home/api-keys.html" target="_blank"' ),
102
  'preview' => array(
103
- 'type' => 'none'
104
- )
105
  ));
106
 
107
  return ob_get_clean();
@@ -117,48 +112,47 @@ final class FLBuilderServiceConstantContact extends FLBuilderService {
117
  * @type bool|string $error The error message or false if no error.
118
  * @type string $html The field markup.
119
  * }
120
- */
121
- public function render_fields( $account, $settings )
122
- {
123
  $account_data = $this->get_account_data( $account );
124
  $api_key = $account_data['api_key'];
125
  $access_token = $account_data['access_token'];
126
  $url = $this->api_url . 'lists?api_key=' . $api_key . '&access_token=' . $access_token;
127
  $request = json_decode( wp_remote_retrieve_body( wp_remote_get( $url ) ) );
128
- $response = array(
129
- 'error' => false,
130
- 'html' => ''
131
  );
132
-
133
  if ( ! is_array( $request ) || ( isset( $request[0] ) && isset( $request[0]->error_message ) ) ) {
134
  $response['error'] = sprintf( __( 'Error: Could not connect to Constant Contact. %s', 'fl-builder' ), $request[0]->error_message );
135
- }
136
- else {
137
  $response['html'] = $this->render_list_field( $request, $settings );
138
  }
139
-
140
  return $response;
141
  }
142
 
143
  /**
144
- * Render markup for the list field.
145
  *
146
  * @since 1.5.4
147
  * @param array $lists List data from the API.
148
  * @param object $settings Saved module settings.
149
  * @return string The markup for the list field.
150
  * @access private
151
- */
152
- private function render_list_field( $lists, $settings )
153
- {
154
  ob_start();
155
-
156
- $options = array( '' => __( 'Choose...', 'fl-builder' ) );
157
-
 
 
158
  foreach ( $lists as $list ) {
159
  $options[ $list->id ] = $list->name;
160
  }
161
-
162
  FLBuilder::render_settings_field( 'list_id', array(
163
  'row_class' => 'fl-builder-service-field-row',
164
  'class' => 'fl-builder-service-list-select',
@@ -166,14 +160,14 @@ final class FLBuilderServiceConstantContact extends FLBuilderService {
166
  'label' => _x( 'List', 'An email list from a third party provider.', 'fl-builder' ),
167
  'options' => $options,
168
  'preview' => array(
169
- 'type' => 'none'
170
- )
171
- ), $settings);
172
-
173
  return ob_get_clean();
174
  }
175
 
176
- /**
177
  * Subscribe an email address to Constant Contact.
178
  *
179
  * @since 1.5.4
@@ -183,48 +177,47 @@ final class FLBuilderServiceConstantContact extends FLBuilderService {
183
  * @return array {
184
  * @type bool|string $error The error message or false if no error.
185
  * }
186
- */
187
- public function subscribe( $settings, $email, $name = false )
188
- {
189
  $account_data = $this->get_account_data( $settings->service_account );
190
- $response = array( 'error' => false );
191
-
 
 
192
  if ( ! $account_data ) {
193
  $response['error'] = __( 'There was an error subscribing to Constant Contact. The account is no longer connected.', 'fl-builder' );
194
- }
195
- else {
196
-
197
  $api_key = $account_data['api_key'];
198
  $access_token = $account_data['access_token'];
199
  $url = $this->api_url . 'contacts?api_key=' . $api_key . '&access_token=' . $access_token . '&email=' . $email;
200
  $request = wp_remote_get( $url );
201
  $contact = json_decode( wp_remote_retrieve_body( $request ) );
202
  $list_id = $settings->list_id;
203
-
204
  // This contact exists.
205
  if ( ! empty( $contact->results ) ) {
206
-
207
  $args = array();
208
  $data = $contact->results[0];
209
-
210
  // Check if already subscribed to this list.
211
  if ( ! empty( $data->lists ) ) {
212
-
213
  // Return early if already added.
214
  foreach ( $data->lists as $key => $list ) {
215
  if ( isset( $list->id ) && $list_id == $list->id ) {
216
  return $response;
217
  }
218
  }
219
-
220
  // Add an existing contact to the list.
221
  $new_list = new stdClass;
222
  $new_list->id = $list_id;
223
  $new_list->status = 'ACTIVE';
224
  $data->lists[ count( $data->lists ) ] = $new_list;
225
- }
226
- else {
227
-
228
  // Add an existing contact that has no list.
229
  $data->lists = array();
230
  $new_list = new stdClass;
@@ -232,7 +225,7 @@ final class FLBuilderServiceConstantContact extends FLBuilderService {
232
  $new_list->status = 'ACTIVE';
233
  $data->lists[0] = $new_list;
234
  }
235
-
236
  $args['body'] = json_encode( $data );
237
  $args['method'] = 'PUT';
238
  $args['headers']['Content-Type'] = 'application/json';
@@ -240,14 +233,13 @@ final class FLBuilderServiceConstantContact extends FLBuilderService {
240
  $url = $this->api_url . 'contacts/' . $contact->results[0]->id . '?api_key=' . $api_key . '&access_token=' . $access_token . '&action_by=ACTION_BY_VISITOR';
241
  $update = wp_remote_request( $url, $args );
242
  $res = json_decode( wp_remote_retrieve_body( $update ) );
243
-
244
  if ( isset( $res->error_key ) ) {
245
  $response['error'] = sprintf( __( 'There was an error subscribing to Constant Contact. %s', 'fl-builder' ), $res->error_key );
246
  }
247
- }
248
- // Add a new contact.
249
  else {
250
-
251
  $args = $data = array();
252
  $data['email_addresses'] = array();
253
  $data['email_addresses'][0]['id'] = $list_id;
@@ -256,11 +248,11 @@ final class FLBuilderServiceConstantContact extends FLBuilderService {
256
  $data['email_addresses'][0]['email_address'] = $email;
257
  $data['lists'] = array();
258
  $data['lists'][0]['id'] = $list_id;
259
-
260
  if ( $name ) {
261
-
262
  $names = explode( ' ', $name );
263
-
264
  if ( isset( $names[0] ) ) {
265
  $data['first_name'] = $names[0];
266
  }
@@ -268,19 +260,19 @@ final class FLBuilderServiceConstantContact extends FLBuilderService {
268
  $data['last_name'] = $names[1];
269
  }
270
  }
271
-
272
  $args['body'] = json_encode( $data );
273
  $args['headers']['Content-Type'] = 'application/json';
274
  $args['headers']['Content-Length'] = strlen( json_encode( $data ) );
275
  $url = $this->api_url . 'contacts?api_key=' . $api_key . '&access_token=' . $access_token . '&action_by=ACTION_BY_VISITOR';
276
  $create = wp_remote_post( $url, $args );
277
-
278
  if ( isset( $create->error_key ) ) {
279
  $response['error'] = sprintf( __( 'There was an error subscribing to Constant Contact. %s', 'fl-builder' ), $create->error_key );
280
  }
281
  }
282
- }
283
-
284
  return $response;
285
  }
286
- }
12
  *
13
  * @since 1.5.4
14
  * @var string $id
15
+ */
16
  public $id = 'constant-contact';
17
 
18
  /**
20
  *
21
  * @since 1.5.4
22
  * @var string $api_url
23
+ */
24
  public $api_url = 'https://api.constantcontact.com/v2/';
25
+
26
  /**
27
  * Test the API connection.
28
  *
35
  * @type bool|string $error The error message or false if no error.
36
  * @type array $data An array of data used to make the connection.
37
  * }
38
+ */
39
+ public function connect( $fields = array() ) {
40
+ $response = array(
 
41
  'error' => false,
42
+ 'data' => array(),
43
  );
44
+
45
  // Make sure we have an API key.
46
  if ( ! isset( $fields['api_key'] ) || empty( $fields['api_key'] ) ) {
47
  $response['error'] = __( 'Error: You must provide an API key.', 'fl-builder' );
48
+ } // End if().
49
+ elseif ( ! isset( $fields['access_token'] ) || empty( $fields['access_token'] ) ) {
 
50
  $response['error'] = __( 'Error: You must provide an access token.', 'fl-builder' );
51
+ } // Try to connect and store the connection data.
 
52
  else {
53
+
54
  $url = $this->api_url . 'lists?api_key=' . $fields['api_key'] . '&access_token=' . $fields['access_token'];
55
  $request = json_decode( wp_remote_retrieve_body( wp_remote_get( $url ) ) );
56
+
57
  if ( ! is_array( $request ) || ( isset( $request[0] ) && isset( $request[0]->error_message ) ) ) {
58
  $response['error'] = sprintf( __( 'Error: Could not connect to Constant Contact. %s', 'fl-builder' ), $request[0]->error_message );
59
+ } else {
60
+ $response['data'] = array(
 
61
  'api_key' => $fields['api_key'],
62
+ 'access_token' => $fields['access_token'],
63
  );
64
  }
65
  }
66
+
67
  return $response;
68
  }
69
 
72
  *
73
  * @since 1.5.4
74
  * @return string The connection settings markup.
75
+ */
76
+ public function render_connect_settings() {
 
77
  ob_start();
78
+
79
  FLBuilder::render_settings_field( 'api_key', array(
80
  'row_class' => 'fl-builder-service-connect-row',
81
  'class' => 'fl-builder-service-connect-input',
83
  'label' => __( 'API Key', 'fl-builder' ),
84
  'help' => __( 'Your Constant Contact API key.', 'fl-builder' ),
85
  'preview' => array(
86
+ 'type' => 'none',
87
+ ),
88
+ ));
89
+
90
  FLBuilder::render_settings_field( 'access_token', array(
91
  'row_class' => 'fl-builder-service-connect-row',
92
  'class' => 'fl-builder-service-connect-input',
95
  'help' => __( 'Your Constant Contact access token.', 'fl-builder' ),
96
  'description' => sprintf( __( 'You must register a <a%1$s>Developer Account</a> with Constant Contact to obtain an API key and access token. Please see <a%2$s>Getting an API key</a> for complete instructions.', 'fl-builder' ), ' href="https://constantcontact.mashery.com/member/register" target="_blank"', ' href="https://developer.constantcontact.com/home/api-keys.html" target="_blank"' ),
97
  'preview' => array(
98
+ 'type' => 'none',
99
+ ),
100
  ));
101
 
102
  return ob_get_clean();
112
  * @type bool|string $error The error message or false if no error.
113
  * @type string $html The field markup.
114
  * }
115
+ */
116
+ public function render_fields( $account, $settings ) {
 
117
  $account_data = $this->get_account_data( $account );
118
  $api_key = $account_data['api_key'];
119
  $access_token = $account_data['access_token'];
120
  $url = $this->api_url . 'lists?api_key=' . $api_key . '&access_token=' . $access_token;
121
  $request = json_decode( wp_remote_retrieve_body( wp_remote_get( $url ) ) );
122
+ $response = array(
123
+ 'error' => false,
124
+ 'html' => '',
125
  );
126
+
127
  if ( ! is_array( $request ) || ( isset( $request[0] ) && isset( $request[0]->error_message ) ) ) {
128
  $response['error'] = sprintf( __( 'Error: Could not connect to Constant Contact. %s', 'fl-builder' ), $request[0]->error_message );
129
+ } else {
 
130
  $response['html'] = $this->render_list_field( $request, $settings );
131
  }
132
+
133
  return $response;
134
  }
135
 
136
  /**
137
+ * Render markup for the list field.
138
  *
139
  * @since 1.5.4
140
  * @param array $lists List data from the API.
141
  * @param object $settings Saved module settings.
142
  * @return string The markup for the list field.
143
  * @access private
144
+ */
145
+ private function render_list_field( $lists, $settings ) {
 
146
  ob_start();
147
+
148
+ $options = array(
149
+ '' => __( 'Choose...', 'fl-builder' ),
150
+ );
151
+
152
  foreach ( $lists as $list ) {
153
  $options[ $list->id ] = $list->name;
154
  }
155
+
156
  FLBuilder::render_settings_field( 'list_id', array(
157
  'row_class' => 'fl-builder-service-field-row',
158
  'class' => 'fl-builder-service-list-select',
160
  'label' => _x( 'List', 'An email list from a third party provider.', 'fl-builder' ),
161
  'options' => $options,
162
  'preview' => array(
163
+ 'type' => 'none',
164
+ ),
165
+ ), $settings);
166
+
167
  return ob_get_clean();
168
  }
169
 
170
+ /**
171
  * Subscribe an email address to Constant Contact.
172
  *
173
  * @since 1.5.4
177
  * @return array {
178
  * @type bool|string $error The error message or false if no error.
179
  * }
180
+ */
181
+ public function subscribe( $settings, $email, $name = false ) {
 
182
  $account_data = $this->get_account_data( $settings->service_account );
183
+ $response = array(
184
+ 'error' => false,
185
+ );
186
+
187
  if ( ! $account_data ) {
188
  $response['error'] = __( 'There was an error subscribing to Constant Contact. The account is no longer connected.', 'fl-builder' );
189
+ } else {
190
+
 
191
  $api_key = $account_data['api_key'];
192
  $access_token = $account_data['access_token'];
193
  $url = $this->api_url . 'contacts?api_key=' . $api_key . '&access_token=' . $access_token . '&email=' . $email;
194
  $request = wp_remote_get( $url );
195
  $contact = json_decode( wp_remote_retrieve_body( $request ) );
196
  $list_id = $settings->list_id;
197
+
198
  // This contact exists.
199
  if ( ! empty( $contact->results ) ) {
200
+
201
  $args = array();
202
  $data = $contact->results[0];
203
+
204
  // Check if already subscribed to this list.
205
  if ( ! empty( $data->lists ) ) {
206
+
207
  // Return early if already added.
208
  foreach ( $data->lists as $key => $list ) {
209
  if ( isset( $list->id ) && $list_id == $list->id ) {
210
  return $response;
211
  }
212
  }
213
+
214
  // Add an existing contact to the list.
215
  $new_list = new stdClass;
216
  $new_list->id = $list_id;
217
  $new_list->status = 'ACTIVE';
218
  $data->lists[ count( $data->lists ) ] = $new_list;
219
+ } else {
220
+
 
221
  // Add an existing contact that has no list.
222
  $data->lists = array();
223
  $new_list = new stdClass;
225
  $new_list->status = 'ACTIVE';
226
  $data->lists[0] = $new_list;
227
  }
228
+
229
  $args['body'] = json_encode( $data );
230
  $args['method'] = 'PUT';
231
  $args['headers']['Content-Type'] = 'application/json';
233
  $url = $this->api_url . 'contacts/' . $contact->results[0]->id . '?api_key=' . $api_key . '&access_token=' . $access_token . '&action_by=ACTION_BY_VISITOR';
234
  $update = wp_remote_request( $url, $args );
235
  $res = json_decode( wp_remote_retrieve_body( $update ) );
236
+
237
  if ( isset( $res->error_key ) ) {
238
  $response['error'] = sprintf( __( 'There was an error subscribing to Constant Contact. %s', 'fl-builder' ), $res->error_key );
239
  }
240
+ } // End if().
 
241
  else {
242
+ // @codingStandardsIgnoreLine
243
  $args = $data = array();
244
  $data['email_addresses'] = array();
245
  $data['email_addresses'][0]['id'] = $list_id;
248
  $data['email_addresses'][0]['email_address'] = $email;
249
  $data['lists'] = array();
250
  $data['lists'][0]['id'] = $list_id;
251
+
252
  if ( $name ) {
253
+
254
  $names = explode( ' ', $name );
255
+
256
  if ( isset( $names[0] ) ) {
257
  $data['first_name'] = $names[0];
258
  }
260
  $data['last_name'] = $names[1];
261
  }
262
  }
263
+
264
  $args['body'] = json_encode( $data );
265
  $args['headers']['Content-Type'] = 'application/json';
266
  $args['headers']['Content-Length'] = strlen( json_encode( $data ) );
267
  $url = $this->api_url . 'contacts?api_key=' . $api_key . '&access_token=' . $access_token . '&action_by=ACTION_BY_VISITOR';
268
  $create = wp_remote_post( $url, $args );
269
+
270
  if ( isset( $create->error_key ) ) {
271
  $response['error'] = sprintf( __( 'There was an error subscribing to Constant Contact. %s', 'fl-builder' ), $create->error_key );
272
  }
273
  }
274
+ }// End if().
275
+
276
  return $response;
277
  }
278
+ }
classes/class-fl-builder-service-convertkit.php CHANGED
@@ -12,14 +12,14 @@ final class FLBuilderServiceConvertKit extends FLBuilderService {
12
  *
13
  * @since 1.5.4
14
  * @var string $id
15
- */
16
  public $id = 'convertkit';
17
 
18
  /**
19
  * @since 1.5.4
20
  * @var object $api_instance
21
  * @access private
22
- */
23
  private $api_instance = null;
24
 
25
  /**
@@ -28,9 +28,8 @@ final class FLBuilderServiceConvertKit extends FLBuilderService {
28
  * @since 1.5.4
29
  * @param string $api_key A valid API key.
30
  * @return object The API instance.
31
- */
32
- public function get_api( $api_key )
33
- {
34
  if ( $this->api_instance ) {
35
  return $this->api_instance;
36
  }
@@ -39,10 +38,10 @@ final class FLBuilderServiceConvertKit extends FLBuilderService {
39
  }
40
 
41
  $this->api_instance = new ConvertKit( $api_key );
42
-
43
  return $this->api_instance;
44
  }
45
-
46
  /**
47
  * Test the API connection.
48
  *
@@ -54,31 +53,30 @@ final class FLBuilderServiceConvertKit extends FLBuilderService {
54
  * @type bool|string $error The error message or false if no error.
55
  * @type array $data An array of data used to make the connection.
56
  * }
57
- */
58
- public function connect( $fields = array() )
59
- {
60
- $response = array(
61
  'error' => false,
62
- 'data' => array()
63
  );
64
-
65
  // Make sure we have an API key.
66
  if ( ! isset( $fields['api_key'] ) || empty( $fields['api_key'] ) ) {
67
  $response['error'] = __( 'Error: You must provide an API key.', 'fl-builder' );
68
- }
69
- // Try to connect and store the connection data.
70
  else {
71
 
72
  $api = $this->get_api( $fields['api_key'] );
73
 
74
- if ($api->is_authenticated()) {
75
- $response['data'] = array( 'api_key' => $fields['api_key'] );
76
- }
77
- else {
78
- $response['error'] = sprintf(__( 'Error: Please check your API key. %s', 'fl-builder' ), $api::$response['error_message']);
79
- }
 
80
  }
81
-
82
  return $response;
83
  }
84
 
@@ -87,11 +85,10 @@ final class FLBuilderServiceConvertKit extends FLBuilderService {
87
  *
88
  * @since 1.5.4
89
  * @return string The connection settings markup.
90
- */
91
- public function render_connect_settings()
92
- {
93
  ob_start();
94
-
95
  FLBuilder::render_settings_field( 'api_key', array(
96
  'row_class' => 'fl-builder-service-connect-row',
97
  'class' => 'fl-builder-service-connect-input',
@@ -99,15 +96,15 @@ final class FLBuilderServiceConvertKit extends FLBuilderService {
99
  'label' => __( 'API Key', 'fl-builder' ),
100
  'help' => __( 'Your API key can be found in your ConvertKit account under Account > Account Settings > API Key.', 'fl-builder' ),
101
  'preview' => array(
102
- 'type' => 'none'
103
- )
104
- ));
105
-
106
  return ob_get_clean();
107
  }
108
 
109
  /**
110
- * Render the markup for service specific fields.
111
  *
112
  * @since 1.5.4
113
  * @param string $account The name of the saved account.
@@ -116,46 +113,45 @@ final class FLBuilderServiceConvertKit extends FLBuilderService {
116
  * @type bool|string $error The error message or false if no error.
117
  * @type string $html The field markup.
118
  * }
119
- */
120
- public function render_fields( $account, $settings )
121
- {
122
  $account_data = $this->get_account_data( $account );
123
  $api = $this->get_api( $account_data['api_key'] );
124
- $forms = $api->get_resources('forms');
125
- $response = array(
126
- 'error' => false,
127
- 'html' => ''
128
  );
129
-
130
  if ( ! $forms ) {
131
  $response['error'] = __( 'Error: Please check your API key.', 'fl-builder' );
132
- }
133
- else {
134
  $response['html'] = $this->render_list_field( $forms, $settings );
135
  }
136
-
137
  return $response;
138
  }
139
 
140
  /**
141
- * Render markup for the list field.
142
  *
143
  * @since 1.5.4
144
  * @param array $lists List data from the API.
145
  * @param object $settings Saved module settings.
146
  * @return string The markup for the list field.
147
  * @access private
148
- */
149
- private function render_list_field( $forms, $settings )
150
- {
151
  ob_start();
152
-
153
- $options = array( '' => __( 'Choose...', 'fl-builder' ) );
154
-
 
 
155
  foreach ( $forms as $form ) {
156
  $options[ $form['id'] ] = $form['name'];
157
  }
158
-
159
  FLBuilder::render_settings_field( 'list_id', array(
160
  'row_class' => 'fl-builder-service-field-row',
161
  'class' => 'fl-builder-service-list-select',
@@ -163,14 +159,14 @@ final class FLBuilderServiceConvertKit extends FLBuilderService {
163
  'label' => _x( 'List', 'An email list from a third party provider.', 'fl-builder' ),
164
  'options' => $options,
165
  'preview' => array(
166
- 'type' => 'none'
167
- )
168
- ), $settings);
169
-
170
  return ob_get_clean();
171
  }
172
 
173
- /**
174
  * Subscribe an email address to ConvertKit.
175
  *
176
  * @since 1.5.4
@@ -180,30 +176,32 @@ final class FLBuilderServiceConvertKit extends FLBuilderService {
180
  * @return array {
181
  * @type bool|string $error The error message or false if no error.
182
  * }
183
- */
184
- public function subscribe( $settings, $email, $name = '' )
185
- {
186
  $account_data = $this->get_account_data( $settings->service_account );
187
- $response = array( 'error' => false );
188
-
 
 
189
  if ( ! $account_data ) {
190
  $response['error'] = __( 'There was an error subscribing to ConvertKit. The account is no longer connected.', 'fl-builder' );
191
- }
192
- else {
193
-
194
  $api = $this->get_api( $account_data['api_key'] );
195
- $data = array('email' => $email);
 
 
196
 
197
- if ( !empty( $name ) ) {
198
  $data['fname'] = $name;
199
  }
200
 
201
  $result = $api->form_subscribe( $settings->list_id, $data );
202
- if ($result->status != "created") {
203
- $response['error'] = __( 'There was an error subscribing to ConvertKit.', 'fl-builder' );
204
  }
205
  }
206
-
207
  return $response;
208
  }
209
- }
12
  *
13
  * @since 1.5.4
14
  * @var string $id
15
+ */
16
  public $id = 'convertkit';
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 $api_key A valid API key.
30
  * @return object The API instance.
31
+ */
32
+ public function get_api( $api_key ) {
 
33
  if ( $this->api_instance ) {
34
  return $this->api_instance;
35
  }
38
  }
39
 
40
  $this->api_instance = new ConvertKit( $api_key );
41
+
42
  return $this->api_instance;
43
  }
44
+
45
  /**
46
  * Test the API connection.
47
  *
53
  * @type bool|string $error The error message or false if no error.
54
  * @type array $data An array of data used to make the connection.
55
  * }
56
+ */
57
+ public function connect( $fields = array() ) {
58
+ $response = array(
 
59
  'error' => false,
60
+ 'data' => array(),
61
  );
62
+
63
  // Make sure we have an API key.
64
  if ( ! isset( $fields['api_key'] ) || empty( $fields['api_key'] ) ) {
65
  $response['error'] = __( 'Error: You must provide an API key.', 'fl-builder' );
66
+ } // End if().
 
67
  else {
68
 
69
  $api = $this->get_api( $fields['api_key'] );
70
 
71
+ if ( $api->is_authenticated() ) {
72
+ $response['data'] = array(
73
+ 'api_key' => $fields['api_key'],
74
+ );
75
+ } else {
76
+ $response['error'] = sprintf( __( 'Error: Please check your API key. %s', 'fl-builder' ), $api::$response['error_message'] );
77
+ }
78
  }
79
+
80
  return $response;
81
  }
82
 
85
  *
86
  * @since 1.5.4
87
  * @return string The connection settings markup.
88
+ */
89
+ public function render_connect_settings() {
 
90
  ob_start();
91
+
92
  FLBuilder::render_settings_field( 'api_key', array(
93
  'row_class' => 'fl-builder-service-connect-row',
94
  'class' => 'fl-builder-service-connect-input',
96
  'label' => __( 'API Key', 'fl-builder' ),
97
  'help' => __( 'Your API key can be found in your ConvertKit account under Account > Account Settings > API Key.', 'fl-builder' ),
98
  'preview' => array(
99
+ 'type' => 'none',
100
+ ),
101
+ ));
102
+
103
  return ob_get_clean();
104
  }
105
 
106
  /**
107
+ * Render the markup for service specific fields.
108
  *
109
  * @since 1.5.4
110
  * @param string $account The name of the saved account.
113
  * @type bool|string $error The error message or false if no error.
114
  * @type string $html The field markup.
115
  * }
116
+ */
117
+ public function render_fields( $account, $settings ) {
 
118
  $account_data = $this->get_account_data( $account );
119
  $api = $this->get_api( $account_data['api_key'] );
120
+ $forms = $api->get_resources( 'forms' );
121
+ $response = array(
122
+ 'error' => false,
123
+ 'html' => '',
124
  );
125
+
126
  if ( ! $forms ) {
127
  $response['error'] = __( 'Error: Please check your API key.', 'fl-builder' );
128
+ } else {
 
129
  $response['html'] = $this->render_list_field( $forms, $settings );
130
  }
131
+
132
  return $response;
133
  }
134
 
135
  /**
136
+ * Render markup for the list field.
137
  *
138
  * @since 1.5.4
139
  * @param array $lists List 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_list_field( $forms, $settings ) {
 
145
  ob_start();
146
+
147
+ $options = array(
148
+ '' => __( 'Choose...', 'fl-builder' ),
149
+ );
150
+
151
  foreach ( $forms as $form ) {
152
  $options[ $form['id'] ] = $form['name'];
153
  }
154
+
155
  FLBuilder::render_settings_field( 'list_id', array(
156
  'row_class' => 'fl-builder-service-field-row',
157
  'class' => 'fl-builder-service-list-select',
159
  'label' => _x( 'List', 'An email list from a third party provider.', 'fl-builder' ),
160
  'options' => $options,
161
  'preview' => array(
162
+ 'type' => 'none',
163
+ ),
164
+ ), $settings);
165
+
166
  return ob_get_clean();
167
  }
168
 
169
+ /**
170
  * Subscribe an email address to ConvertKit.
171
  *
172
  * @since 1.5.4
176
  * @return array {
177
  * @type bool|string $error The error message or false if no error.
178
  * }
179
+ */
180
+ public function subscribe( $settings, $email, $name = '' ) {
 
181
  $account_data = $this->get_account_data( $settings->service_account );
182
+ $response = array(
183
+ 'error' => false,
184
+ );
185
+
186
  if ( ! $account_data ) {
187
  $response['error'] = __( 'There was an error subscribing to ConvertKit. The account is no longer connected.', 'fl-builder' );
188
+ } else {
189
+
 
190
  $api = $this->get_api( $account_data['api_key'] );
191
+ $data = array(
192
+ 'email' => $email,
193
+ );
194
 
195
+ if ( ! empty( $name ) ) {
196
  $data['fname'] = $name;
197
  }
198
 
199
  $result = $api->form_subscribe( $settings->list_id, $data );
200
+ if ( 'created' != $result->status ) {
201
+ $response['error'] = __( 'There was an error subscribing to ConvertKit.', 'fl-builder' );
202
  }
203
  }
204
+
205
  return $response;
206
  }
207
+ }
classes/class-fl-builder-service-drip.php CHANGED
@@ -12,14 +12,14 @@ final class FLBuilderServiceDrip extends FLBuilderService {
12
  *
13
  * @since 1.5.4
14
  * @var string $id
15
- */
16
  public $id = 'drip';
17
 
18
  /**
19
  * @since 1.5.4
20
  * @var object $api_instance
21
  * @access private
22
- */
23
  private $api_instance = null;
24
 
25
  /**
@@ -28,21 +28,20 @@ final class FLBuilderServiceDrip extends FLBuilderService {
28
  * @since 1.5.4
29
  * @param string $api_key A valid API token.
30
  * @return object The API instance.
31
- */
32
- public function get_api( $api_key )
33
- {
34
  if ( $this->api_instance ) {
35
  return $this->api_instance;
36
  }
37
  if ( ! class_exists( 'Drip_Api' ) ) {
38
  require_once FL_BUILDER_DIR . 'includes/vendor/drip/Drip_API.class.php';
39
  }
40
-
41
  $this->api_instance = new Drip_Api( $api_key );
42
-
43
  return $this->api_instance;
44
  }
45
-
46
  /**
47
  * Test the API connection.
48
  *
@@ -54,23 +53,20 @@ final class FLBuilderServiceDrip extends FLBuilderService {
54
  * @type bool|string $error The error message or false if no error.
55
  * @type array $data An array of data used to make the connection.
56
  * }
57
- */
58
- public function connect( $fields = array() )
59
- {
60
- $response = array(
61
  'error' => false,
62
- 'data' => array()
63
  );
64
-
65
  // Make sure we have an API token.
66
  if ( ! isset( $fields['api_key'] ) || empty( $fields['api_key'] ) ) {
67
  $response['error'] = __( 'Error: You must provide an API token.', 'fl-builder' );
68
- }
69
- // Make sure we have an Account ID.
70
  elseif ( ! isset( $fields['api_account_id'] ) || empty( $fields['api_account_id'] ) ) {
71
  $response['error'] = __( 'Error: You must provide an Account ID.', 'fl-builder' );
72
- }
73
- // Try to connect and store the connection data.
74
  else {
75
  try {
76
 
@@ -79,29 +75,29 @@ final class FLBuilderServiceDrip extends FLBuilderService {
79
 
80
  $account = $api->fetch_account( $fields['api_account_id'] );
81
  $error_message = $api->get_error_message();
82
-
83
  if ( ! empty( $error_message ) ) {
84
  $response['error'] = $error_message;
85
- }
86
- else {
87
- $response['data'] = array( 'api_key' => $fields['api_key'], 'api_account_id' => $fields['api_account_id'] );
 
 
88
  }
89
- }
90
- catch (Exception $e) {
91
  $response['error'] = sprintf(
92
  __( 'Error: Please check your Account ID. %s', 'fl-builder' ),
93
  $e->getMessage()
94
  );
95
- }
96
- }
97
- catch (Exception $e) {
98
  $response['error'] = sprintf(
99
  __( 'Error: Please check your API token. %s', 'fl-builder' ),
100
  $e->getMessage()
101
  );
102
  }
103
  }
104
-
105
  return $response;
106
  }
107
 
@@ -110,11 +106,10 @@ final class FLBuilderServiceDrip extends FLBuilderService {
110
  *
111
  * @since 1.5.4
112
  * @return string The connection settings markup.
113
- */
114
- public function render_connect_settings()
115
- {
116
  ob_start();
117
-
118
  FLBuilder::render_settings_field( 'api_key', array(
119
  'row_class' => 'fl-builder-service-connect-row',
120
  'class' => 'fl-builder-service-connect-input',
@@ -122,9 +117,9 @@ final class FLBuilderServiceDrip extends FLBuilderService {
122
  'label' => __( 'API Token', 'fl-builder' ),
123
  'description' => sprintf( __( 'Your API Token can be found in your Drip account under Settings > My User Settings. Or, you can click this <a%s>direct link</a>.', 'fl-builder' ), ' href="https://www.getdrip.com/user/edit" target="_blank"' ),
124
  'preview' => array(
125
- 'type' => 'none'
126
- )
127
- ));
128
 
129
  FLBuilder::render_settings_field( 'api_account_id', array(
130
  'row_class' => 'fl-builder-service-connect-row',
@@ -133,15 +128,15 @@ final class FLBuilderServiceDrip extends FLBuilderService {
133
  'label' => __( 'Account ID', 'fl-builder' ),
134
  'help' => __( 'Your Account ID can be found in your Drip account under Settings > Site Setup.', 'fl-builder' ),
135
  'preview' => array(
136
- 'type' => 'none'
137
- )
138
  ));
139
-
140
  return ob_get_clean();
141
  }
142
 
143
  /**
144
- * Render the markup for service specific fields.
145
  *
146
  * @since 1.5.4
147
  * @param string $account The name of the saved account.
@@ -150,42 +145,42 @@ final class FLBuilderServiceDrip extends FLBuilderService {
150
  * @type bool|string $error The error message or false if no error.
151
  * @type string $html The field markup.
152
  * }
153
- */
154
- public function render_fields( $account, $settings )
155
- {
156
  $account_data = $this->get_account_data( $account );
157
  $api = $this->get_api( $account_data['api_key'] );
158
- $campaigns = $api->get_campaigns( array(
159
- 'account_id' => $account_data['api_account_id']
160
  ) );
161
 
162
- $response = array(
163
- 'error' => false,
164
- 'html' => $this->render_campaigns_field( $campaigns, $settings ) . $this->render_tag_field( $settings )
165
  );
166
-
167
  return $response;
168
  }
169
 
170
  /**
171
- * Render markup for the campaign field.
172
  *
173
  * @since 1.10.5
174
  * @param array $campaigns Campaigns data from the API.
175
  * @param object $settings Saved module settings.
176
  * @return string The markup for the campaign field.
177
  * @access private
178
- */
179
- private function render_campaigns_field( $campaigns, $settings )
180
- {
181
  ob_start();
182
-
183
- $options = array( '' => __( 'Choose...', 'fl-builder' ) );
184
-
 
 
185
  foreach ( $campaigns as $campaign ) {
186
  $options[ $campaign['id'] ] = $campaign['name'];
187
  }
188
-
189
  FLBuilder::render_settings_field( 'campaign_id', array(
190
  'row_class' => 'fl-builder-service-field-row',
191
  'class' => 'fl-builder-service-campaign-select',
@@ -193,40 +188,39 @@ final class FLBuilderServiceDrip extends FLBuilderService {
193
  'label' => _x( 'Campaign', 'An email campaign from your GetDrip account.', '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 tag field.
205
  *
206
  * @since 1.5.4
207
  * @param object $settings Saved module settings.
208
  * @return string The markup for the tag field.
209
  * @access private
210
- */
211
- private function render_tag_field( $settings )
212
- {
213
  ob_start();
214
-
215
  FLBuilder::render_settings_field( 'list_id', array(
216
  'row_class' => 'fl-builder-service-field-row',
217
  'class' => 'fl-builder-service-list-select',
218
  'type' => 'text',
219
  'label' => _x( 'Tags', 'A tag to add to contacts in Drip when they subscribe.', 'fl-builder' ),
220
- 'help' => __('For multiple tags, separate with comma.', '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 Drip.
231
  *
232
  * @since 1.5.4
@@ -236,34 +230,32 @@ final class FLBuilderServiceDrip 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 = '' )
241
- {
242
  $account_data = $this->get_account_data( $settings->service_account );
243
- $response = array( 'error' => false );
 
 
244
  $subscriber_id = null;
245
-
246
  if ( ! $account_data ) {
247
  $response['error'] = __( 'There was an error subscribing to Drip. The account is no longer connected.', 'fl-builder' );
248
- }
249
- else {
250
-
251
  $api = $this->get_api( $account_data['api_key'] );
252
  $args = array(
253
  'account_id' => $account_data['api_account_id'],
254
- 'email' => $email
255
  );
256
 
257
  // Check if the contact already exists
258
  try {
259
  $result = $api->fetch_subscriber( $args );
260
 
261
- if ( $result && isset($result['id']) ) {
262
  $subscriber_id = $result['id'];
263
  }
264
-
265
- }
266
- catch ( Exception $e ) {
267
  $response['error'] = sprintf(
268
  __( 'There was an error searching contact from Drip. %s', 'fl-builder' ),
269
  $e->getMessage()
@@ -276,32 +268,33 @@ final class FLBuilderServiceDrip extends FLBuilderService {
276
  }
277
 
278
  if ( $settings->list_id ) {
279
- $args['tags'] = explode(',', $settings->list_id);
280
  }
281
 
282
  if ( $name ) {
283
- $args['custom_fields'] = array( 'name' => $name );
 
 
284
  }
285
 
286
  // Create or update contact
287
  try {
288
-
289
  $result = $api->create_or_update_subscriber( $args );
290
 
291
  if ( isset( $result['id'] ) && isset( $settings->campaign_id ) ) {
292
- $args[ 'campaign_id' ] = $settings->campaign_id;
293
- $args[ 'double_optin' ] = false;
294
  $get_res = $api->subscribe_subscriber( $args );
295
  }
296
- }
297
- catch ( Exception $e ) {
298
  $response['error'] = sprintf(
299
  __( 'There was an error subscribing to Drip. %s', 'fl-builder' ),
300
  $e->getMessage()
301
  );
302
  }
303
- }
304
-
305
  return $response;
306
  }
307
- }
12
  *
13
  * @since 1.5.4
14
  * @var string $id
15
+ */
16
  public $id = 'drip';
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 $api_key A valid API token.
30
  * @return object The API instance.
31
+ */
32
+ public function get_api( $api_key ) {
 
33
  if ( $this->api_instance ) {
34
  return $this->api_instance;
35
  }
36
  if ( ! class_exists( 'Drip_Api' ) ) {
37
  require_once FL_BUILDER_DIR . 'includes/vendor/drip/Drip_API.class.php';
38
  }
39
+
40
  $this->api_instance = new Drip_Api( $api_key );
41
+
42
  return $this->api_instance;
43
  }
44
+
45
  /**
46
  * Test the API connection.
47
  *
53
  * @type bool|string $error The error message or false if no error.
54
  * @type array $data An array of data used to make the connection.
55
  * }
56
+ */
57
+ public function connect( $fields = array() ) {
58
+ $response = array(
 
59
  'error' => false,
60
+ 'data' => array(),
61
  );
62
+
63
  // Make sure we have an API token.
64
  if ( ! isset( $fields['api_key'] ) || empty( $fields['api_key'] ) ) {
65
  $response['error'] = __( 'Error: You must provide an API token.', 'fl-builder' );
66
+ } // End if().
 
67
  elseif ( ! isset( $fields['api_account_id'] ) || empty( $fields['api_account_id'] ) ) {
68
  $response['error'] = __( 'Error: You must provide an Account ID.', 'fl-builder' );
69
+ } // Try to connect and store the connection data.
 
70
  else {
71
  try {
72
 
75
 
76
  $account = $api->fetch_account( $fields['api_account_id'] );
77
  $error_message = $api->get_error_message();
78
+
79
  if ( ! empty( $error_message ) ) {
80
  $response['error'] = $error_message;
81
+ } else {
82
+ $response['data'] = array(
83
+ 'api_key' => $fields['api_key'],
84
+ 'api_account_id' => $fields['api_account_id'],
85
+ );
86
  }
87
+ } catch ( Exception $e ) {
 
88
  $response['error'] = sprintf(
89
  __( 'Error: Please check your Account ID. %s', 'fl-builder' ),
90
  $e->getMessage()
91
  );
92
+ }
93
+ } catch ( Exception $e ) {
 
94
  $response['error'] = sprintf(
95
  __( 'Error: Please check your API token. %s', 'fl-builder' ),
96
  $e->getMessage()
97
  );
98
  }
99
  }
100
+
101
  return $response;
102
  }
103
 
106
  *
107
  * @since 1.5.4
108
  * @return string The connection settings markup.
109
+ */
110
+ public function render_connect_settings() {
 
111
  ob_start();
112
+
113
  FLBuilder::render_settings_field( 'api_key', array(
114
  'row_class' => 'fl-builder-service-connect-row',
115
  'class' => 'fl-builder-service-connect-input',
117
  'label' => __( 'API Token', 'fl-builder' ),
118
  'description' => sprintf( __( 'Your API Token can be found in your Drip account under Settings > My User Settings. Or, you can click this <a%s>direct link</a>.', 'fl-builder' ), ' href="https://www.getdrip.com/user/edit" target="_blank"' ),
119
  'preview' => array(
120
+ 'type' => 'none',
121
+ ),
122
+ ));
123
 
124
  FLBuilder::render_settings_field( 'api_account_id', array(
125
  'row_class' => 'fl-builder-service-connect-row',
128
  'label' => __( 'Account ID', 'fl-builder' ),
129
  'help' => __( 'Your Account ID can be found in your Drip account under Settings > Site Setup.', 'fl-builder' ),
130
  'preview' => array(
131
+ 'type' => 'none',
132
+ ),
133
  ));
134
+
135
  return ob_get_clean();
136
  }
137
 
138
  /**
139
+ * Render the markup for service specific fields.
140
  *
141
  * @since 1.5.4
142
  * @param string $account The name of the saved account.
145
  * @type bool|string $error The error message or false if no error.
146
  * @type string $html The field markup.
147
  * }
148
+ */
149
+ public function render_fields( $account, $settings ) {
 
150
  $account_data = $this->get_account_data( $account );
151
  $api = $this->get_api( $account_data['api_key'] );
152
+ $campaigns = $api->get_campaigns( array(
153
+ 'account_id' => $account_data['api_account_id'],
154
  ) );
155
 
156
+ $response = array(
157
+ 'error' => false,
158
+ 'html' => $this->render_campaigns_field( $campaigns, $settings ) . $this->render_tag_field( $settings ),
159
  );
160
+
161
  return $response;
162
  }
163
 
164
  /**
165
+ * Render markup for the campaign field.
166
  *
167
  * @since 1.10.5
168
  * @param array $campaigns Campaigns data from the API.
169
  * @param object $settings Saved module settings.
170
  * @return string The markup for the campaign field.
171
  * @access private
172
+ */
173
+ private function render_campaigns_field( $campaigns, $settings ) {
 
174
  ob_start();
175
+
176
+ $options = array(
177
+ '' => __( 'Choose...', 'fl-builder' ),
178
+ );
179
+
180
  foreach ( $campaigns as $campaign ) {
181
  $options[ $campaign['id'] ] = $campaign['name'];
182
  }
183
+
184
  FLBuilder::render_settings_field( 'campaign_id', array(
185
  'row_class' => 'fl-builder-service-field-row',
186
  'class' => 'fl-builder-service-campaign-select',
188
  'label' => _x( 'Campaign', 'An email campaign from your GetDrip account.', 'fl-builder' ),
189
  'options' => $options,
190
  'preview' => array(
191
+ 'type' => 'none',
192
+ ),
193
+ ), $settings);
194
+
195
  return ob_get_clean();
196
  }
197
 
198
  /**
199
+ * Render markup for the tag field.
200
  *
201
  * @since 1.5.4
202
  * @param object $settings Saved module settings.
203
  * @return string The markup for the tag field.
204
  * @access private
205
+ */
206
+ private function render_tag_field( $settings ) {
 
207
  ob_start();
208
+
209
  FLBuilder::render_settings_field( 'list_id', array(
210
  'row_class' => 'fl-builder-service-field-row',
211
  'class' => 'fl-builder-service-list-select',
212
  'type' => 'text',
213
  'label' => _x( 'Tags', 'A tag to add to contacts in Drip when they subscribe.', 'fl-builder' ),
214
+ 'help' => __( 'For multiple tags, separate with comma.', 'fl-builder' ),
215
  'preview' => array(
216
+ 'type' => 'none',
217
+ ),
218
+ ), $settings);
219
+
220
  return ob_get_clean();
221
  }
222
 
223
+ /**
224
  * Subscribe an email address to Drip.
225
  *
226
  * @since 1.5.4
230
  * @return array {
231
  * @type bool|string $error The error message or false if no error.
232
  * }
233
+ */
234
+ public function subscribe( $settings, $email, $name = '' ) {
 
235
  $account_data = $this->get_account_data( $settings->service_account );
236
+ $response = array(
237
+ 'error' => false,
238
+ );
239
  $subscriber_id = null;
240
+
241
  if ( ! $account_data ) {
242
  $response['error'] = __( 'There was an error subscribing to Drip. The account is no longer connected.', 'fl-builder' );
243
+ } else {
244
+
 
245
  $api = $this->get_api( $account_data['api_key'] );
246
  $args = array(
247
  'account_id' => $account_data['api_account_id'],
248
+ 'email' => $email,
249
  );
250
 
251
  // Check if the contact already exists
252
  try {
253
  $result = $api->fetch_subscriber( $args );
254
 
255
+ if ( $result && isset( $result['id'] ) ) {
256
  $subscriber_id = $result['id'];
257
  }
258
+ } catch ( Exception $e ) {
 
 
259
  $response['error'] = sprintf(
260
  __( 'There was an error searching contact from Drip. %s', 'fl-builder' ),
261
  $e->getMessage()
268
  }
269
 
270
  if ( $settings->list_id ) {
271
+ $args['tags'] = explode( ',', $settings->list_id );
272
  }
273
 
274
  if ( $name ) {
275
+ $args['custom_fields'] = array(
276
+ 'name' => $name,
277
+ );
278
  }
279
 
280
  // Create or update contact
281
  try {
282
+
283
  $result = $api->create_or_update_subscriber( $args );
284
 
285
  if ( isset( $result['id'] ) && isset( $settings->campaign_id ) ) {
286
+ $args['campaign_id'] = $settings->campaign_id;
287
+ $args['double_optin'] = false;
288
  $get_res = $api->subscribe_subscriber( $args );
289
  }
290
+ } catch ( Exception $e ) {
 
291
  $response['error'] = sprintf(
292
  __( 'There was an error subscribing to Drip. %s', 'fl-builder' ),
293
  $e->getMessage()
294
  );
295
  }
296
+ }// End if().
297
+
298
  return $response;
299
  }
300
+ }
classes/class-fl-builder-service-email-address.php CHANGED
@@ -27,20 +27,20 @@ final class FLBuilderServiceEmailAddress extends FLBuilderService {
27
  * @type array $data An array of data used to make the connection.
28
  * }
29
  */
30
- public function connect( $fields = array() )
31
- {
32
  $response = array(
33
  'error' => false,
34
- 'data' => array()
35
  );
36
 
37
  // Make sure we have an email address.
38
  if ( ! isset( $fields['email'] ) || empty( $fields['email'] ) ) {
39
  $response['error'] = __( 'Error: You must provide an email address.', 'fl-builder' );
40
- }
41
- // Store the connection data.
42
  else {
43
- $response['data'] = array( 'email' => $fields['email'] );
 
 
44
  }
45
 
46
  return $response;
@@ -52,8 +52,7 @@ final class FLBuilderServiceEmailAddress extends FLBuilderService {
52
  * @since 1.6.0
53
  * @return string The connection settings markup.
54
  */
55
- public function render_connect_settings()
56
- {
57
  ob_start();
58
 
59
  FLBuilder::render_settings_field( 'email', array(
@@ -62,8 +61,8 @@ final class FLBuilderServiceEmailAddress extends FLBuilderService {
62
  'type' => 'text',
63
  'label' => __( 'Email Address', 'fl-builder' ),
64
  'preview' => array(
65
- 'type' => 'none'
66
- )
67
  ));
68
 
69
  return ob_get_clean();
@@ -80,11 +79,10 @@ final class FLBuilderServiceEmailAddress extends FLBuilderService {
80
  * @type string $html The field markup.
81
  * }
82
  */
83
- public function render_fields( $account, $settings )
84
- {
85
  $response = array(
86
  'error' => false,
87
- 'html' => ''
88
  );
89
 
90
  return $response;
@@ -101,19 +99,19 @@ final class FLBuilderServiceEmailAddress extends FLBuilderService {
101
  * @type bool|string $error The error message or false if no error.
102
  * }
103
  */
104
- public function subscribe( $settings, $email, $name = false )
105
- {
106
  $account_data = $this->get_account_data( $settings->service_account );
107
- $response = array( 'error' => false );
 
 
108
 
109
  if ( ! $account_data ) {
110
  $response['error'] = __( 'There was an error subscribing. The account is no longer connected.', 'fl-builder' );
111
- }
112
- else {
113
 
114
  $subject = __( 'Subscribe Form Signup', 'fl-builder' );
115
 
116
- if( $settings->custom_subject ) {
117
  $subject = $settings->custom_subject;
118
  }
119
 
27
  * @type array $data An array of data used to make the connection.
28
  * }
29
  */
30
+ public function connect( $fields = array() ) {
 
31
  $response = array(
32
  'error' => false,
33
+ 'data' => array(),
34
  );
35
 
36
  // Make sure we have an email address.
37
  if ( ! isset( $fields['email'] ) || empty( $fields['email'] ) ) {
38
  $response['error'] = __( 'Error: You must provide an email address.', 'fl-builder' );
39
+ } // End if().
 
40
  else {
41
+ $response['data'] = array(
42
+ 'email' => $fields['email'],
43
+ );
44
  }
45
 
46
  return $response;
52
  * @since 1.6.0
53
  * @return string The connection settings markup.
54
  */
55
+ public function render_connect_settings() {
 
56
  ob_start();
57
 
58
  FLBuilder::render_settings_field( 'email', array(
61
  'type' => 'text',
62
  'label' => __( 'Email Address', 'fl-builder' ),
63
  'preview' => array(
64
+ 'type' => 'none',
65
+ ),
66
  ));
67
 
68
  return ob_get_clean();
79
  * @type string $html The field markup.
80
  * }
81
  */
82
+ public function render_fields( $account, $settings ) {
 
83
  $response = array(
84
  'error' => false,
85
+ 'html' => '',
86
  );
87
 
88
  return $response;
99
  * @type bool|string $error The error message or false if no error.
100
  * }
101
  */
102
+ public function subscribe( $settings, $email, $name = false ) {
 
103
  $account_data = $this->get_account_data( $settings->service_account );
104
+ $response = array(
105
+ 'error' => false,
106
+ );
107
 
108
  if ( ! $account_data ) {
109
  $response['error'] = __( 'There was an error subscribing. The account is no longer connected.', 'fl-builder' );
110
+ } else {
 
111
 
112
  $subject = __( 'Subscribe Form Signup', 'fl-builder' );
113
 
114
+ if ( $settings->custom_subject ) {
115
  $subject = $settings->custom_subject;
116
  }
117
 
classes/class-fl-builder-service-enormail.php CHANGED
@@ -12,14 +12,14 @@ final class FLBuilderServiceEnormail extends FLBuilderService {
12
  *
13
  * @since 1.9.5
14
  * @var string $id
15
- */
16
  public $id = 'enormail';
17
 
18
  /**
19
  * @since 1.9.5
20
  * @var object $api_instance
21
  * @access private
22
- */
23
  private $api_instance = null;
24
 
25
  /**
@@ -28,9 +28,8 @@ final class FLBuilderServiceEnormail extends FLBuilderService {
28
  * @since 1.9.5
29
  * @param array $api_key A valid API key to authenticate.
30
  * @return object The API instance.
31
- */
32
- public function get_api( $api_key )
33
- {
34
  if ( $this->api_instance ) {
35
  return $this->api_instance;
36
  }
@@ -38,12 +37,12 @@ final class FLBuilderServiceEnormail extends FLBuilderService {
38
  if ( ! class_exists( '\\Enormail\\ApiClient' ) ) {
39
  require_once FL_BUILDER_DIR . 'includes/vendor/enormail/autoload.php';
40
  }
41
-
42
  $this->api_instance = new \Enormail\ApiClient( $api_key );
43
-
44
  return $this->api_instance;
45
  }
46
-
47
  /**
48
  * Test the API connection.
49
  *
@@ -56,19 +55,17 @@ final class FLBuilderServiceEnormail 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 key.
68
  if ( ! isset( $fields['api_key'] ) || empty( $fields['api_key'] ) ) {
69
  $response['error'] = __( 'Error: You must provide an API key.', 'fl-builder' );
70
- }
71
- // Try to connect and store the connection data.
72
  else {
73
 
74
  $api = $this->get_api( $fields['api_key'] );
@@ -77,11 +74,12 @@ final class FLBuilderServiceEnormail extends FLBuilderService {
77
  $api_response = json_decode( $api->test() );
78
 
79
  if ( isset( $api_response->ping ) && 'hello' === $api_response->ping ) {
80
- $response['data'] = array('api_key' => $fields['api_key']);
81
- }
82
- else {
83
- $response['error'] = sprintf(__( 'Error: Could not connect to Enormail. %s', 'fl-builder' ),
84
- '('.$api_response->error->http_code .': '. $api_response->error->message.')'
 
85
  );
86
  }
87
  }
@@ -94,11 +92,10 @@ final class FLBuilderServiceEnormail extends FLBuilderService {
94
  *
95
  * @since 1.9.5
96
  * @return string The connection settings markup.
97
- */
98
- public function render_connect_settings()
99
- {
100
  ob_start();
101
-
102
  FLBuilder::render_settings_field( 'api_key', array(
103
  'row_class' => 'fl-builder-service-connect-row',
104
  'class' => 'fl-builder-service-connect-input',
@@ -106,15 +103,15 @@ final class FLBuilderServiceEnormail extends FLBuilderService {
106
  'label' => __( 'API Key', 'fl-builder' ),
107
  'help' => __( 'Found in your Sendy application under Settings.', 'fl-builder' ),
108
  'preview' => array(
109
- 'type' => 'none'
110
- )
111
  ));
112
 
113
  return ob_get_clean();
114
  }
115
 
116
  /**
117
- * Render the markup for service specific fields.
118
  *
119
  * @since 1.9.5
120
  * @param string $account The name of the saved account.
@@ -123,48 +120,47 @@ final class FLBuilderServiceEnormail extends FLBuilderService {
123
  * @type bool|string $error The error message or false if no error.
124
  * @type string $html The field markup.
125
  * }
126
- */
127
- public function render_fields( $account, $settings )
128
- {
129
  $account_data = $this->get_account_data( $account );
130
  $api = $this->get_api( $account_data['api_key'] );
131
  $lists = json_decode( $api->lists->get() );
132
- $response = array(
133
- 'error' => false,
134
- 'html' => ''
135
  );
136
-
137
  if ( ! $lists ) {
138
  $response['error'] = __( 'Error: Please check your API key.', 'fl-builder' );
139
- }
140
- else {
141
  $response['html'] = $this->render_list_field( $lists, $settings );
142
  }
143
-
144
  return $response;
145
  }
146
 
147
  /**
148
- * Render markup for the list field.
149
  *
150
  * @since 1.9.5
151
  * @param array $lists List data from the API.
152
  * @param object $settings Saved module settings.
153
  * @return string The markup for the list field.
154
  * @access private
155
- */
156
- private function render_list_field( $lists, $settings )
157
- {
158
  ob_start();
159
-
160
- $options = array( '' => __( 'Choose...', 'fl-builder' ) );
 
 
161
 
162
  foreach ( $lists as $list ) {
163
- if ( isset($list->listid) ) {
164
  $options[ $list->listid ] = $list->title;
165
- }
166
  }
167
-
168
  FLBuilder::render_settings_field( 'list_id', array(
169
  'row_class' => 'fl-builder-service-field-row',
170
  'class' => 'fl-builder-service-list-select',
@@ -172,14 +168,14 @@ final class FLBuilderServiceEnormail extends FLBuilderService {
172
  'label' => _x( 'List', 'An email list from a third party provider.', 'fl-builder' ),
173
  'options' => $options,
174
  'preview' => array(
175
- 'type' => 'none'
176
- )
177
- ), $settings);
178
-
179
  return ob_get_clean();
180
  }
181
 
182
- /**
183
  * Subscribe an email address to Sendy.
184
  *
185
  * @since 1.9.5
@@ -189,32 +185,31 @@ final class FLBuilderServiceEnormail extends FLBuilderService {
189
  * @return array {
190
  * @type bool|string $error The error message or false if no error.
191
  * }
192
- */
193
- public function subscribe( $settings, $email, $name = '' )
194
- {
195
  $account_data = $this->get_account_data( $settings->service_account );
196
- $response = array( 'error' => false );
197
-
 
 
198
  if ( ! $account_data ) {
199
  $response['error'] = __( 'There was an error subscribing to Enormail. The account is no longer connected.', 'fl-builder' );
200
- }
201
- else {
202
-
203
  $api = $this->get_api( $account_data['api_key'] );
204
 
205
  // Search user if already exists
206
- $contact = json_decode( $api->contacts->details($settings->list_id, $email) );
207
 
208
  // Name is required
209
  if ( empty( $name ) ) {
210
- $name = explode('@', $email)[0];
211
  }
212
 
213
  // Add if not exists
214
- if ( $contact->code == -1 ) {
215
  $result = $api->contacts->add( $settings->list_id, $name, $email );
216
- }
217
- // Update
218
  else {
219
  $result = $api->contacts->update( $settings->list_id, $name, $email );
220
  }
@@ -222,12 +217,12 @@ final class FLBuilderServiceEnormail extends FLBuilderService {
222
  $get_results = json_decode( $result );
223
 
224
  if ( isset( $get_results->status ) && 'error' === $get_results->status ) {
225
- $response['error'] = sprintf(__( 'There was an error subscribing to Enormail. %s', 'fl-builder' ),
226
- '('. $get_results->code .': '. $get_results->message .')'
227
- );
228
- }
229
  }
230
-
231
  return $response;
232
  }
233
- }
12
  *
13
  * @since 1.9.5
14
  * @var string $id
15
+ */
16
  public $id = 'enormail';
17
 
18
  /**
19
  * @since 1.9.5
20
  * @var object $api_instance
21
  * @access private
22
+ */
23
  private $api_instance = null;
24
 
25
  /**
28
  * @since 1.9.5
29
  * @param array $api_key A valid API key to authenticate.
30
  * @return object The API instance.
31
+ */
32
+ public function get_api( $api_key ) {
 
33
  if ( $this->api_instance ) {
34
  return $this->api_instance;
35
  }
37
  if ( ! class_exists( '\\Enormail\\ApiClient' ) ) {
38
  require_once FL_BUILDER_DIR . 'includes/vendor/enormail/autoload.php';
39
  }
40
+
41
  $this->api_instance = new \Enormail\ApiClient( $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 key.
66
  if ( ! isset( $fields['api_key'] ) || empty( $fields['api_key'] ) ) {
67
  $response['error'] = __( 'Error: You must provide an API key.', 'fl-builder' );
68
+ } // End if().
 
69
  else {
70
 
71
  $api = $this->get_api( $fields['api_key'] );
74
  $api_response = json_decode( $api->test() );
75
 
76
  if ( isset( $api_response->ping ) && 'hello' === $api_response->ping ) {
77
+ $response['data'] = array(
78
+ 'api_key' => $fields['api_key'],
79
+ );
80
+ } else {
81
+ $response['error'] = sprintf(__( 'Error: Could not connect to Enormail. %s', 'fl-builder' ),
82
+ '(' . $api_response->error->http_code . ': ' . $api_response->error->message . ')'
83
  );
84
  }
85
  }
92
  *
93
  * @since 1.9.5
94
  * @return string The connection settings markup.
95
+ */
96
+ public function render_connect_settings() {
 
97
  ob_start();
98
+
99
  FLBuilder::render_settings_field( 'api_key', array(
100
  'row_class' => 'fl-builder-service-connect-row',
101
  'class' => 'fl-builder-service-connect-input',
103
  'label' => __( 'API Key', 'fl-builder' ),
104
  'help' => __( 'Found in your Sendy application under Settings.', 'fl-builder' ),
105
  'preview' => array(
106
+ 'type' => 'none',
107
+ ),
108
  ));
109
 
110
  return ob_get_clean();
111
  }
112
 
113
  /**
114
+ * Render the markup for service specific fields.
115
  *
116
  * @since 1.9.5
117
  * @param string $account The name of the saved account.
120
  * @type bool|string $error The error message or false if no error.
121
  * @type string $html The field markup.
122
  * }
123
+ */
124
+ public function render_fields( $account, $settings ) {
 
125
  $account_data = $this->get_account_data( $account );
126
  $api = $this->get_api( $account_data['api_key'] );
127
  $lists = json_decode( $api->lists->get() );
128
+ $response = array(
129
+ 'error' => false,
130
+ 'html' => '',
131
  );
132
+
133
  if ( ! $lists ) {
134
  $response['error'] = __( 'Error: Please check your API key.', 'fl-builder' );
135
+ } else {
 
136
  $response['html'] = $this->render_list_field( $lists, $settings );
137
  }
138
+
139
  return $response;
140
  }
141
 
142
  /**
143
+ * Render markup for the list field.
144
  *
145
  * @since 1.9.5
146
  * @param array $lists List data from the API.
147
  * @param object $settings Saved module settings.
148
  * @return string The markup for the list field.
149
  * @access private
150
+ */
151
+ private function render_list_field( $lists, $settings ) {
 
152
  ob_start();
153
+
154
+ $options = array(
155
+ '' => __( 'Choose...', 'fl-builder' ),
156
+ );
157
 
158
  foreach ( $lists as $list ) {
159
+ if ( isset( $list->listid ) ) {
160
  $options[ $list->listid ] = $list->title;
161
+ }
162
  }
163
+
164
  FLBuilder::render_settings_field( 'list_id', array(
165
  'row_class' => 'fl-builder-service-field-row',
166
  'class' => 'fl-builder-service-list-select',
168
  'label' => _x( 'List', 'An email list from a third party provider.', 'fl-builder' ),
169
  'options' => $options,
170
  'preview' => array(
171
+ 'type' => 'none',
172
+ ),
173
+ ), $settings);
174
+
175
  return ob_get_clean();
176
  }
177
 
178
+ /**
179
  * Subscribe an email address to Sendy.
180
  *
181
  * @since 1.9.5
185
  * @return array {
186
  * @type bool|string $error The error message or false if no error.
187
  * }
188
+ */
189
+ public function subscribe( $settings, $email, $name = '' ) {
 
190
  $account_data = $this->get_account_data( $settings->service_account );
191
+ $response = array(
192
+ 'error' => false,
193
+ );
194
+
195
  if ( ! $account_data ) {
196
  $response['error'] = __( 'There was an error subscribing to Enormail. The account is no longer connected.', 'fl-builder' );
197
+ } else {
198
+
 
199
  $api = $this->get_api( $account_data['api_key'] );
200
 
201
  // Search user if already exists
202
+ $contact = json_decode( $api->contacts->details( $settings->list_id, $email ) );
203
 
204
  // Name is required
205
  if ( empty( $name ) ) {
206
+ $name = explode( '@', $email )[0];
207
  }
208
 
209
  // Add if not exists
210
+ if ( -1 == $contact->code ) {
211
  $result = $api->contacts->add( $settings->list_id, $name, $email );
212
+ } // End if().
 
213
  else {
214
  $result = $api->contacts->update( $settings->list_id, $name, $email );
215
  }
217
  $get_results = json_decode( $result );
218
 
219
  if ( isset( $get_results->status ) && 'error' === $get_results->status ) {
220
+ $response['error'] = sprintf(__( 'There was an error subscribing to Enormail. %s', 'fl-builder' ),
221
+ '(' . $get_results->code . ': ' . $get_results->message . ')'
222
+ );
223
+ }
224
  }
225
+
226
  return $response;
227
  }
228
+ }
classes/class-fl-builder-service-getresponse.php CHANGED
@@ -12,14 +12,14 @@ final class FLBuilderServiceGetResponse extends FLBuilderService {
12
  *
13
  * @since 1.5.4
14
  * @var string $id
15
- */
16
  public $id = 'getresponse';
17
 
18
  /**
19
  * @since 1.5.4
20
  * @var object $api_instance
21
  * @access private
22
- */
23
  private $api_instance = null;
24
 
25
  /**
@@ -28,21 +28,20 @@ final class FLBuilderServiceGetResponse extends FLBuilderService {
28
  * @since 1.5.4
29
  * @param string $api_key A valid API key.
30
  * @return object The API instance.
31
- */
32
- public function get_api( $api_key )
33
- {
34
  if ( $this->api_instance ) {
35
  return $this->api_instance;
36
  }
37
  if ( ! class_exists( 'GetResponse' ) ) {
38
  require_once FL_BUILDER_DIR . 'includes/vendor/getresponse/getresponse.php';
39
  }
40
-
41
  $this->api_instance = new GetResponse( $api_key );
42
-
43
  return $this->api_instance;
44
  }
45
-
46
  /**
47
  * Test the API connection.
48
  *
@@ -54,32 +53,31 @@ final class FLBuilderServiceGetResponse extends FLBuilderService {
54
  * @type bool|string $error The error message or false if no error.
55
  * @type array $data An array of data used to make the connection.
56
  * }
57
- */
58
- public function connect( $fields = array() )
59
- {
60
- $response = array(
61
  'error' => false,
62
- 'data' => array()
63
  );
64
-
65
  // Make sure we have an API key.
66
  if ( ! isset( $fields['api_key'] ) || empty( $fields['api_key'] ) ) {
67
  $response['error'] = __( 'Error: You must provide an API key.', 'fl-builder' );
68
- }
69
- // Try to connect and store the connection data.
70
  else {
71
-
72
  $api = $this->get_api( $fields['api_key'] );
73
  $ping = $api->ping();
74
-
75
  if ( ! $ping ) {
76
  $response['error'] = __( 'Error: Please check your API key.', 'fl-builder' );
77
- }
78
- else {
79
- $response['data'] = array( 'api_key' => $fields['api_key'] );
 
80
  }
81
  }
82
-
83
  return $response;
84
  }
85
 
@@ -88,11 +86,10 @@ final class FLBuilderServiceGetResponse extends FLBuilderService {
88
  *
89
  * @since 1.5.4
90
  * @return string The connection settings markup.
91
- */
92
- public function render_connect_settings()
93
- {
94
  ob_start();
95
-
96
  FLBuilder::render_settings_field( 'api_key', array(
97
  'row_class' => 'fl-builder-service-connect-row',
98
  'class' => 'fl-builder-service-connect-input',
@@ -100,15 +97,15 @@ final class FLBuilderServiceGetResponse extends FLBuilderService {
100
  'label' => __( 'API Key', 'fl-builder' ),
101
  'help' => __( 'Your API key can be found in your GetResponse account under My Account > GetResponse API.', 'fl-builder' ),
102
  'preview' => array(
103
- 'type' => 'none'
104
- )
105
- ));
106
-
107
  return ob_get_clean();
108
  }
109
 
110
  /**
111
- * Render the markup for service specific fields.
112
  *
113
  * @since 1.5.4
114
  * @param string $account The name of the saved account.
@@ -117,46 +114,45 @@ final class FLBuilderServiceGetResponse extends FLBuilderService {
117
  * @type bool|string $error The error message or false if no error.
118
  * @type string $html The field markup.
119
  * }
120
- */
121
- public function render_fields( $account, $settings )
122
- {
123
  $account_data = $this->get_account_data( $account );
124
  $api = $this->get_api( $account_data['api_key'] );
125
  $lists = $api->getCampaigns();
126
- $response = array(
127
- 'error' => false,
128
- 'html' => ''
129
  );
130
-
131
  if ( ! $lists ) {
132
  $response['error'] = __( 'Error: Please check your API key.', 'fl-builder' );
133
- }
134
- else {
135
  $response['html'] = $this->render_list_field( $lists, $settings );
136
  }
137
-
138
  return $response;
139
  }
140
 
141
  /**
142
- * Render markup for the list field.
143
  *
144
  * @since 1.5.4
145
  * @param array $lists List data from the API.
146
  * @param object $settings Saved module settings.
147
  * @return string The markup for the list field.
148
  * @access private
149
- */
150
- private function render_list_field( $lists, $settings )
151
- {
152
  ob_start();
153
-
154
- $options = array( '' => __( 'Choose...', 'fl-builder' ) );
155
-
 
 
156
  foreach ( $lists as $id => $data ) {
157
  $options[ $id ] = $data->name;
158
  }
159
-
160
  FLBuilder::render_settings_field( 'list_id', array(
161
  'row_class' => 'fl-builder-service-field-row',
162
  'class' => 'fl-builder-service-list-select',
@@ -164,14 +160,14 @@ final class FLBuilderServiceGetResponse extends FLBuilderService {
164
  'label' => _x( 'List', 'An email list from a third party provider.', 'fl-builder' ),
165
  'options' => $options,
166
  'preview' => array(
167
- 'type' => 'none'
168
- )
169
- ), $settings);
170
-
171
  return ob_get_clean();
172
  }
173
 
174
- /**
175
  * Subscribe an email address to GetResponse.
176
  *
177
  * @since 1.5.4
@@ -181,50 +177,50 @@ final class FLBuilderServiceGetResponse extends FLBuilderService {
181
  * @return array {
182
  * @type bool|string $error The error message or false if no error.
183
  * }
184
- */
185
- public function subscribe( $settings, $email, $name = '' )
186
- {
187
  $account_data = $this->get_account_data( $settings->service_account );
188
- $response = array( 'error' => false );
189
-
 
 
190
  if ( ! $account_data ) {
191
  $response['error'] = __( 'There was an error subscribing to GetResponse. The account is no longer connected.', 'fl-builder' );
192
- }
193
- else {
194
-
195
  $api = $this->get_api( $account_data['api_key'] );
196
-
197
  try {
198
 
199
  // Fix, name should not be empty
200
  if ( ! $name ) {
201
- $names = explode('@', $email);
202
  $name = $names[0];
203
  }
204
 
205
  // Check if email exists
206
  $get_contact = $api->getContactsByEmail( $email );
207
 
 
208
  if ( $contact = (array) $get_contact ) {
209
- reset($contact);
210
- $contact_id = key($contact);
211
 
212
  $result = $api->setContactName( $contact_id, $name );
213
  $api->setContactCampaign( $contact_id, $settings->list_id );
214
 
215
- // New contact
216
  } else {
217
  $result = $api->addContact( $settings->list_id, $name, $email );
218
  }
219
- }
220
- catch ( Exception $e ) {
221
  $response['error'] = sprintf(
222
  __( 'There was an error subscribing to GetResponse. %s', 'fl-builder' ),
223
  $e->getMessage()
224
  );
225
  }
226
- }
227
-
228
  return $response;
229
  }
230
- }
12
  *
13
  * @since 1.5.4
14
  * @var string $id
15
+ */
16
  public $id = 'getresponse';
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 $api_key A valid API key.
30
  * @return object The API instance.
31
+ */
32
+ public function get_api( $api_key ) {
 
33
  if ( $this->api_instance ) {
34
  return $this->api_instance;
35
  }
36
  if ( ! class_exists( 'GetResponse' ) ) {
37
  require_once FL_BUILDER_DIR . 'includes/vendor/getresponse/getresponse.php';
38
  }
39
+
40
  $this->api_instance = new GetResponse( $api_key );
41
+
42
  return $this->api_instance;
43
  }
44
+
45
  /**
46
  * Test the API connection.
47
  *
53
  * @type bool|string $error The error message or false if no error.
54
  * @type array $data An array of data used to make the connection.
55
  * }
56
+ */
57
+ public function connect( $fields = array() ) {
58
+ $response = array(
 
59
  'error' => false,
60
+ 'data' => array(),
61
  );
62
+
63
  // Make sure we have an API key.
64
  if ( ! isset( $fields['api_key'] ) || empty( $fields['api_key'] ) ) {
65
  $response['error'] = __( 'Error: You must provide an API key.', 'fl-builder' );
66
+ } // End if().
 
67
  else {
68
+
69
  $api = $this->get_api( $fields['api_key'] );
70
  $ping = $api->ping();
71
+
72
  if ( ! $ping ) {
73
  $response['error'] = __( 'Error: Please check your API key.', 'fl-builder' );
74
+ } else {
75
+ $response['data'] = array(
76
+ 'api_key' => $fields['api_key'],
77
+ );
78
  }
79
  }
80
+
81
  return $response;
82
  }
83
 
86
  *
87
  * @since 1.5.4
88
  * @return string The connection settings markup.
89
+ */
90
+ public function render_connect_settings() {
 
91
  ob_start();
92
+
93
  FLBuilder::render_settings_field( 'api_key', array(
94
  'row_class' => 'fl-builder-service-connect-row',
95
  'class' => 'fl-builder-service-connect-input',
97
  'label' => __( 'API Key', 'fl-builder' ),
98
  'help' => __( 'Your API key can be found in your GetResponse account under My Account > GetResponse API.', 'fl-builder' ),
99
  'preview' => array(
100
+ 'type' => 'none',
101
+ ),
102
+ ));
103
+
104
  return ob_get_clean();
105
  }
106
 
107
  /**
108
+ * Render the markup for service specific fields.
109
  *
110
  * @since 1.5.4
111
  * @param string $account The name of the saved account.
114
  * @type bool|string $error The error message or false if no error.
115
  * @type string $html The field markup.
116
  * }
117
+ */
118
+ public function render_fields( $account, $settings ) {
 
119
  $account_data = $this->get_account_data( $account );
120
  $api = $this->get_api( $account_data['api_key'] );
121
  $lists = $api->getCampaigns();
122
+ $response = array(
123
+ 'error' => false,
124
+ 'html' => '',
125
  );
126
+
127
  if ( ! $lists ) {
128
  $response['error'] = __( 'Error: Please check your API key.', 'fl-builder' );
129
+ } else {
 
130
  $response['html'] = $this->render_list_field( $lists, $settings );
131
  }
132
+
133
  return $response;
134
  }
135
 
136
  /**
137
+ * Render markup for the list field.
138
  *
139
  * @since 1.5.4
140
  * @param array $lists List data from the API.
141
  * @param object $settings Saved module settings.
142
  * @return string The markup for the list field.
143
  * @access private
144
+ */
145
+ private function render_list_field( $lists, $settings ) {
 
146
  ob_start();
147
+
148
+ $options = array(
149
+ '' => __( 'Choose...', 'fl-builder' ),
150
+ );
151
+
152
  foreach ( $lists as $id => $data ) {
153
  $options[ $id ] = $data->name;
154
  }
155
+
156
  FLBuilder::render_settings_field( 'list_id', array(
157
  'row_class' => 'fl-builder-service-field-row',
158
  'class' => 'fl-builder-service-list-select',
160
  'label' => _x( 'List', 'An email list from a third party provider.', 'fl-builder' ),
161
  'options' => $options,
162
  'preview' => array(
163
+ 'type' => 'none',
164
+ ),
165
+ ), $settings);
166
+
167
  return ob_get_clean();
168
  }
169
 
170
+ /**
171
  * Subscribe an email address to GetResponse.
172
  *
173
  * @since 1.5.4
177
  * @return array {
178
  * @type bool|string $error The error message or false if no error.
179
  * }
180
+ */
181
+ public function subscribe( $settings, $email, $name = '' ) {
 
182
  $account_data = $this->get_account_data( $settings->service_account );
183
+ $response = array(
184
+ 'error' => false,
185
+ );
186
+
187
  if ( ! $account_data ) {
188
  $response['error'] = __( 'There was an error subscribing to GetResponse. The account is no longer connected.', 'fl-builder' );
189
+ } else {
190
+
 
191
  $api = $this->get_api( $account_data['api_key'] );
192
+
193
  try {
194
 
195
  // Fix, name should not be empty
196
  if ( ! $name ) {
197
+ $names = explode( '@', $email );
198
  $name = $names[0];
199
  }
200
 
201
  // Check if email exists
202
  $get_contact = $api->getContactsByEmail( $email );
203
 
204
+ // @codingStandardsIgnoreLine
205
  if ( $contact = (array) $get_contact ) {
206
+ reset( $contact );
207
+ $contact_id = key( $contact );
208
 
209
  $result = $api->setContactName( $contact_id, $name );
210
  $api->setContactCampaign( $contact_id, $settings->list_id );
211
 
212
+ // New contact
213
  } else {
214
  $result = $api->addContact( $settings->list_id, $name, $email );
215
  }
216
+ } catch ( Exception $e ) {
 
217
  $response['error'] = sprintf(
218
  __( 'There was an error subscribing to GetResponse. %s', 'fl-builder' ),
219
  $e->getMessage()
220
  );
221
  }
222
+ }// End if().
223
+
224
  return $response;
225
  }
226
+ }
classes/class-fl-builder-service-godaddy-email-marketing.php CHANGED
@@ -12,14 +12,14 @@ final class FLBuilderServiceGoDaddyEmailMarketing extends FLBuilderService {
12
  *
13
  * @since 1.10.5
14
  * @var string $id
15
- */
16
  public $id = 'godaddy-email-marketing';
17
 
18
  /**
19
  * @since 1.10.5
20
  * @var object $api_instance
21
  * @access private
22
- */
23
  private $api_instance = null;
24
 
25
  /**
@@ -29,21 +29,20 @@ final class FLBuilderServiceGoDaddyEmailMarketing extends FLBuilderService {
29
  * @param string $api_username The email address associated with the API key.
30
  * @param string $api_key A valid API key.
31
  * @return object The API instance.
32
- */
33
- public function get_api( $api_username, $api_key )
34
- {
35
  if ( $this->api_instance ) {
36
  return $this->api_instance;
37
  }
38
  if ( ! class_exists( 'GoDaddyEM' ) ) {
39
  require_once FL_BUILDER_DIR . 'includes/vendor/godaddy-email-marketing/class-godaddy-em.php';
40
  }
41
-
42
- $this->api_instance = new GoDaddyEM( $api_username, $api_key );
43
-
44
  return $this->api_instance;
45
  }
46
-
47
  /**
48
  * Test the API connection.
49
  *
@@ -56,38 +55,34 @@ final class FLBuilderServiceGoDaddyEmailMarketing 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 email address.
68
  if ( ! isset( $fields['api_username'] ) || empty( $fields['api_username'] ) ) {
69
  $response['error'] = __( 'Error: You must provide an API username.', '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_username'], $fields['api_key'] );
79
-
80
  if ( ! $api::is_account_ok() ) {
81
  $response['error'] = __( 'Unable to connect to GoDaddy Email Marketing. Please check your credentials.', 'fl-builder' );
82
- }
83
- else {
84
- $response['data'] = array(
85
  'api_username' => $fields['api_username'],
86
- 'api_key' => $fields['api_key']
87
  );
88
  }
89
  }
90
-
91
  return $response;
92
  }
93
 
@@ -96,11 +91,10 @@ final class FLBuilderServiceGoDaddyEmailMarketing extends FLBuilderService {
96
  *
97
  * @since 1.10.5
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_username', array(
105
  'row_class' => 'fl-builder-service-connect-row',
106
  'class' => 'fl-builder-service-connect-input',
@@ -108,10 +102,10 @@ final class FLBuilderServiceGoDaddyEmailMarketing extends FLBuilderService {
108
  'label' => __( 'API Username', 'fl-builder' ),
109
  'help' => __( 'The username associated with your GoDaddy Email Marketing account.', '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',
@@ -120,15 +114,15 @@ final class FLBuilderServiceGoDaddyEmailMarketing extends FLBuilderService {
120
  'help' => __( 'Your API key from your GoDaddy Email Marketing account.', 'fl-builder' ),
121
  'description' => sprintf( __( '<a%1$s>Sign in</a> to get your username and API key. <a%2$s>Signup</a> if you don\'t have a GoDaddy Email Marketing account.', 'fl-builder' ), ' href="https://gem.godaddy.com/mwp/accounts" target="_blank"', ' href="https://sso.godaddy.com/account/create?path=/wordpress_plugin&app=gem&realm=idp&ssoreturnpath=/%3Fpath%3D%2Fwordpress_plugin%26app%3Dgem%26realm%3Didp" 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.10.5
134
  * @param string $account The name of the saved account.
@@ -137,49 +131,48 @@ final class FLBuilderServiceGoDaddyEmailMarketing extends FLBuilderService {
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
- {
143
  $account_data = $this->get_account_data( $account );
144
  $api = $this->get_api( $account_data['api_username'], $account_data['api_key'] );
145
- $response = array(
146
- 'error' => false,
147
- 'html' => ''
148
  );
149
-
150
  $result = $api::get_forms();
151
 
152
  if ( ! $result ) {
153
  $response['error'] = __( 'There was a problem retrieving your lists. Please check your API credentials.', 'fl-builder' );
154
- }
155
- else {
156
  $response['html'] = $this->render_list_field( $result, $settings );
157
  }
158
-
159
  return $response;
160
  }
161
 
162
  /**
163
- * Render markup for the list field.
164
  *
165
  * @since 1.10.5
166
  * @param array $forms GoDaddy Signup Forms data from the API.
167
  * @param object $settings Saved module settings.
168
  * @return string The markup for the list field.
169
  * @access private
170
- */
171
- private function render_list_field( $forms, $settings )
172
- {
173
  ob_start();
174
-
175
- $options = array( '' => __( 'Choose...', 'fl-builder' ) );
176
-
 
 
177
  if ( ! empty( $forms->signups ) ) {
178
  foreach ( $forms->signups as $form ) {
179
  $options[ $form->id ] = $form->name;
180
  }
181
  }
182
-
183
  FLBuilder::render_settings_field( 'form_id', array(
184
  'row_class' => 'fl-builder-service-field-row',
185
  'class' => 'fl-builder-service-list-select',
@@ -187,14 +180,14 @@ final class FLBuilderServiceGoDaddyEmailMarketing extends FLBuilderService {
187
  'label' => _x( 'Form', 'A signup form from your GoDaddy Email Marketing account.', 'fl-builder' ),
188
  'options' => $options,
189
  'preview' => array(
190
- 'type' => 'none'
191
- )
192
- ), $settings);
193
-
194
  return ob_get_clean();
195
  }
196
 
197
- /**
198
  * Subscribe an email address to GoDaddy Email Marketing.
199
  *
200
  * @since 1.10.5
@@ -204,27 +197,27 @@ final class FLBuilderServiceGoDaddyEmailMarketing extends FLBuilderService {
204
  * @return array {
205
  * @type bool|string $error The error message or false if no error.
206
  * }
207
- */
208
- public function subscribe( $settings, $email, $name = false )
209
- {
210
  $account_data = $this->get_account_data( $settings->service_account );
211
- $response = array( 'error' => false );
212
-
 
 
213
  if ( ! $account_data ) {
214
  $response['error'] = __( 'There was an error subscribing to GoDaddy Email Marketing. The account is no longer connected.', 'fl-builder' );
215
- }
216
- else {
217
-
218
  $api = $this->get_api( $account_data['api_username'], $account_data['api_key'] );
219
- $data = array(
220
  'email' => $email,
221
- 'form_id' => $settings->form_id
222
  );
223
-
224
  if ( $name ) {
225
-
226
  $names = explode( ' ', $name );
227
-
228
  if ( isset( $names[0] ) ) {
229
  $data['first_name'] = $names[0];
230
  }
@@ -232,14 +225,14 @@ final class FLBuilderServiceGoDaddyEmailMarketing extends FLBuilderService {
232
  $data['last_name'] = $names[1];
233
  }
234
  }
235
-
236
  $result = $api->add_subscriber( $data );
237
-
238
  if ( ! $result ) {
239
  $response['error'] = __( 'There was an error subscribing to GoDaddy Email Marketing. The account is no longer connected.', 'fl-builder' );
240
  }
241
  }
242
-
243
  return $response;
244
  }
245
- }
12
  *
13
  * @since 1.10.5
14
  * @var string $id
15
+ */
16
  public $id = 'godaddy-email-marketing';
17
 
18
  /**
19
  * @since 1.10.5
20
  * @var object $api_instance
21
  * @access private
22
+ */
23
  private $api_instance = null;
24
 
25
  /**
29
  * @param string $api_username The email address associated with the API key.
30
  * @param string $api_key A valid API key.
31
  * @return object The API instance.
32
+ */
33
+ public function get_api( $api_username, $api_key ) {
 
34
  if ( $this->api_instance ) {
35
  return $this->api_instance;
36
  }
37
  if ( ! class_exists( 'GoDaddyEM' ) ) {
38
  require_once FL_BUILDER_DIR . 'includes/vendor/godaddy-email-marketing/class-godaddy-em.php';
39
  }
40
+
41
+ $this->api_instance = new GoDaddyEM( $api_username, $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 email address.
66
  if ( ! isset( $fields['api_username'] ) || empty( $fields['api_username'] ) ) {
67
  $response['error'] = __( 'Error: You must provide an API username.', '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_username'], $fields['api_key'] );
75
+
76
  if ( ! $api::is_account_ok() ) {
77
  $response['error'] = __( 'Unable to connect to GoDaddy Email Marketing. Please check your credentials.', 'fl-builder' );
78
+ } else {
79
+ $response['data'] = array(
 
80
  'api_username' => $fields['api_username'],
81
+ 'api_key' => $fields['api_key'],
82
  );
83
  }
84
  }
85
+
86
  return $response;
87
  }
88
 
91
  *
92
  * @since 1.10.5
93
  * @return string The connection settings markup.
94
+ */
95
+ public function render_connect_settings() {
 
96
  ob_start();
97
+
98
  FLBuilder::render_settings_field( 'api_username', array(
99
  'row_class' => 'fl-builder-service-connect-row',
100
  'class' => 'fl-builder-service-connect-input',
102
  'label' => __( 'API Username', 'fl-builder' ),
103
  'help' => __( 'The username associated with your GoDaddy Email Marketing account.', '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',
114
  'help' => __( 'Your API key from your GoDaddy Email Marketing account.', 'fl-builder' ),
115
  'description' => sprintf( __( '<a%1$s>Sign in</a> to get your username and API key. <a%2$s>Signup</a> if you don\'t have a GoDaddy Email Marketing account.', 'fl-builder' ), ' href="https://gem.godaddy.com/mwp/accounts" target="_blank"', ' href="https://sso.godaddy.com/account/create?path=/wordpress_plugin&app=gem&realm=idp&ssoreturnpath=/%3Fpath%3D%2Fwordpress_plugin%26app%3Dgem%26realm%3Didp" target="_blank"' ),
116
  'preview' => array(
117
+ 'type' => 'none',
118
+ ),
119
+ ));
120
+
121
  return ob_get_clean();
122
  }
123
 
124
  /**
125
+ * Render the markup for service specific fields.
126
  *
127
  * @since 1.10.5
128
  * @param string $account The name of the saved account.
131
  * @type bool|string $error The error message or false if no error.
132
  * @type string $html The field markup.
133
  * }
134
+ */
135
+ public function render_fields( $account, $settings ) {
 
136
  $account_data = $this->get_account_data( $account );
137
  $api = $this->get_api( $account_data['api_username'], $account_data['api_key'] );
138
+ $response = array(
139
+ 'error' => false,
140
+ 'html' => '',
141
  );
142
+
143
  $result = $api::get_forms();
144
 
145
  if ( ! $result ) {
146
  $response['error'] = __( 'There was a problem retrieving your lists. Please check your API credentials.', 'fl-builder' );
147
+ } else {
 
148
  $response['html'] = $this->render_list_field( $result, $settings );
149
  }
150
+
151
  return $response;
152
  }
153
 
154
  /**
155
+ * Render markup for the list field.
156
  *
157
  * @since 1.10.5
158
  * @param array $forms GoDaddy Signup Forms data from the API.
159
  * @param object $settings Saved module settings.
160
  * @return string The markup for the list field.
161
  * @access private
162
+ */
163
+ private function render_list_field( $forms, $settings ) {
 
164
  ob_start();
165
+
166
+ $options = array(
167
+ '' => __( 'Choose...', 'fl-builder' ),
168
+ );
169
+
170
  if ( ! empty( $forms->signups ) ) {
171
  foreach ( $forms->signups as $form ) {
172
  $options[ $form->id ] = $form->name;
173
  }
174
  }
175
+
176
  FLBuilder::render_settings_field( 'form_id', array(
177
  'row_class' => 'fl-builder-service-field-row',
178
  'class' => 'fl-builder-service-list-select',
180
  'label' => _x( 'Form', 'A signup form from your GoDaddy Email Marketing account.', 'fl-builder' ),
181
  'options' => $options,
182
  'preview' => array(
183
+ 'type' => 'none',
184
+ ),
185
+ ), $settings);
186
+
187
  return ob_get_clean();
188
  }
189
 
190
+ /**
191
  * Subscribe an email address to GoDaddy Email Marketing.
192
  *
193
  * @since 1.10.5
197
  * @return array {
198
  * @type bool|string $error The error message or false if no error.
199
  * }
200
+ */
201
+ public function subscribe( $settings, $email, $name = false ) {
 
202
  $account_data = $this->get_account_data( $settings->service_account );
203
+ $response = array(
204
+ 'error' => false,
205
+ );
206
+
207
  if ( ! $account_data ) {
208
  $response['error'] = __( 'There was an error subscribing to GoDaddy Email Marketing. The account is no longer connected.', 'fl-builder' );
209
+ } else {
210
+
 
211
  $api = $this->get_api( $account_data['api_username'], $account_data['api_key'] );
212
+ $data = array(
213
  'email' => $email,
214
+ 'form_id' => $settings->form_id,
215
  );
216
+
217
  if ( $name ) {
218
+
219
  $names = explode( ' ', $name );
220
+
221
  if ( isset( $names[0] ) ) {
222
  $data['first_name'] = $names[0];
223
  }
225
  $data['last_name'] = $names[1];
226
  }
227
  }
228
+
229
  $result = $api->add_subscriber( $data );
230
+
231
  if ( ! $result ) {
232
  $response['error'] = __( 'There was an error subscribing to GoDaddy Email Marketing. The account is no longer connected.', 'fl-builder' );
233
  }
234
  }
235
+
236
  return $response;
237
  }
238
+ }
classes/class-fl-builder-service-hatchbuck.php CHANGED
@@ -12,7 +12,7 @@ final class FLBuilderServiceHatchbuck extends FLBuilderService {
12
  *
13
  * @since 1.5.8
14
  * @var string $id
15
- */
16
  public $id = 'hatchbuck';
17
 
18
  /**
@@ -21,9 +21,9 @@ final class FLBuilderServiceHatchbuck extends FLBuilderService {
21
  * @since 1.5.8
22
  * @access private
23
  * @var string $api_url
24
- */
25
  private $api_url = 'https://api.hatchbuck.com/api/v1/contact/';
26
-
27
  /**
28
  * Test the API connection.
29
  *
@@ -35,38 +35,37 @@ final class FLBuilderServiceHatchbuck extends FLBuilderService {
35
  * @type bool|string $error The error message or false if no error.
36
  * @type array $data An array of data used to make the connection.
37
  * }
38
- */
39
- public function connect( $fields = array() )
40
- {
41
- $response = array(
42
  'error' => false,
43
- 'data' => array()
44
  );
45
-
46
  // Make sure we have an API key.
47
  if ( ! isset( $fields['api_key'] ) || empty( $fields['api_key'] ) ) {
48
  $response['error'] = __( 'Error: You must provide an API key.', 'fl-builder' );
49
- }
50
- // Try to connect and store the connection data.
51
  else {
52
-
53
  $result = wp_remote_post( $this->api_url . 'search?api_key=' . $fields['api_key'], array(
54
  'method' => 'POST',
55
  'timeout' => 60,
56
  'headers' => array(
57
- 'Content-Type' => 'application/json'
58
  ),
59
  'body' => array(),
60
  ) );
61
-
62
  if ( 401 == $result['response']['code'] ) {
63
  $response['error'] = __( 'Error: Please check your API key.', 'fl-builder' );
64
- }
65
- else {
66
- $response['data'] = array( 'api_key' => $fields['api_key'] );
 
67
  }
68
  }
69
-
70
  return $response;
71
  }
72
 
@@ -75,11 +74,10 @@ final class FLBuilderServiceHatchbuck extends FLBuilderService {
75
  *
76
  * @since 1.5.8
77
  * @return string The connection settings markup.
78
- */
79
- public function render_connect_settings()
80
- {
81
  ob_start();
82
-
83
  FLBuilder::render_settings_field( 'api_key', array(
84
  'row_class' => 'fl-builder-service-connect-row',
85
  'class' => 'fl-builder-service-connect-input',
@@ -87,15 +85,15 @@ final class FLBuilderServiceHatchbuck extends FLBuilderService {
87
  'label' => __( 'API Key', 'fl-builder' ),
88
  'help' => __( 'Your API key can be found in your Hatchbuck account under Account Settings > Web API.', 'fl-builder' ),
89
  'preview' => array(
90
- 'type' => 'none'
91
- )
92
- ));
93
-
94
  return ob_get_clean();
95
  }
96
 
97
  /**
98
- * Render the markup for service specific fields.
99
  *
100
  * @since 1.5.8
101
  * @param string $account The name of the saved account.
@@ -104,43 +102,41 @@ final class FLBuilderServiceHatchbuck extends FLBuilderService {
104
  * @type bool|string $error The error message or false if no error.
105
  * @type string $html The field markup.
106
  * }
107
- */
108
- public function render_fields( $account, $settings )
109
- {
110
- $response = array(
111
- 'error' => false,
112
- 'html' => $this->render_tag_field( $settings )
113
  );
114
-
115
  return $response;
116
  }
117
 
118
  /**
119
- * Render markup for the tag field.
120
  *
121
  * @since 1.5.8
122
  * @param object $settings Saved module settings.
123
  * @return string The markup for the tag field.
124
  * @access private
125
- */
126
- private function render_tag_field( $settings )
127
- {
128
  ob_start();
129
-
130
  FLBuilder::render_settings_field( 'list_id', array(
131
  'row_class' => 'fl-builder-service-field-row',
132
  'class' => 'fl-builder-service-list-select',
133
  'type' => 'text',
134
  'label' => _x( 'Tag', 'A tag to add to contacts in Hatchbuck when they subscribe.', 'fl-builder' ),
135
  'preview' => array(
136
- 'type' => 'none'
137
- )
138
- ), $settings);
139
-
140
  return ob_get_clean();
141
  }
142
 
143
- /**
144
  * Subscribe an email address to Hatchbuck.
145
  *
146
  * @since 1.5.8
@@ -150,65 +146,63 @@ final class FLBuilderServiceHatchbuck extends FLBuilderService {
150
  * @return array {
151
  * @type bool|string $error The error message or false if no error.
152
  * }
153
- */
154
- public function subscribe( $settings, $email, $name = false )
155
- {
156
  $contact_id = null;
157
  $account_data = $this->get_account_data( $settings->service_account );
158
- $response = array( 'error' => false );
159
-
 
 
160
  if ( ! $account_data ) {
161
  $response['error'] = __( 'There was an error subscribing to Hatchbuck. The account is no longer connected.', 'fl-builder' );
162
- }
163
- else {
164
-
165
  // Build the data array.
166
- $data = array(
167
  'emails' => array(
168
  array(
169
  'address' => $email,
170
- 'type' => 'Work'
171
- )
172
  ),
173
  'status' => array(
174
- 'name' => 'Lead'
175
- )
176
  );
177
-
178
  // Check if the contact exists.
179
  $result = wp_remote_post( $this->api_url . 'search?api_key=' . $account_data['api_key'], array(
180
  'method' => 'POST',
181
  'timeout' => 60,
182
  'headers' => array(
183
- 'Content-Type' => 'application/json'
184
  ),
185
  'body' => json_encode( $data ),
186
  ) );
187
-
188
  // Return if we have an API key error.
189
  if ( 401 == $result['response']['code'] ) {
190
  $response['error'] = __( 'There was an error subscribing to Hatchbuck. The API key is invalid.', 'fl-builder' );
191
  return $response; // Invalid API key.
192
- }
193
- // Contact already exists.
194
- else if ( 200 == $result['response']['code'] ) {
195
  $result_data = json_decode( $result['body'] );
196
  $contact_id = $result_data[0]->contactId;
197
- }
198
- // Generic error. Contact not found should be 400.
199
- else if ( 400 != $result['response']['code'] ) {
200
  $response['error'] = __( 'There was an error subscribing to Hatchbuck.', 'fl-builder' );
201
  return $response;
202
  }
203
-
204
  // Add the contact if it doesn't exist.
205
  if ( ! $contact_id ) {
206
-
207
  // Add the name to the data array if we have one.
208
  if ( $name ) {
209
-
210
  $names = explode( ' ', $name );
211
-
212
  if ( isset( $names[0] ) ) {
213
  $data['firstName'] = $names[0];
214
  }
@@ -216,41 +210,44 @@ final class FLBuilderServiceHatchbuck extends FLBuilderService {
216
  $data['lastName'] = $names[1];
217
  }
218
  }
219
-
220
  // Add the contact to Hatchbuck.
221
  $result = wp_remote_post( $this->api_url . '?api_key=' . $account_data['api_key'], array(
222
  'method' => 'POST',
223
  'timeout' => 60,
224
  'headers' => array(
225
- 'Content-Type' => 'application/json'
226
  ),
227
  'body' => json_encode( $data ),
228
  ) );
229
-
230
  // Return if we have an error.
231
  if ( 200 != $result['response']['code'] ) {
232
  $response['error'] = __( 'There was an error subscribing to Hatchbuck.', 'fl-builder' );
233
  return $response;
234
  }
235
-
236
  // Get the result data that contains the new contact ID.
237
  $result_data = json_decode( $result['body'] );
 
238
  $contact_id = $result_data->contactId;
239
- }
240
-
241
- // Add the tag to the contact.
242
- $result = wp_remote_post( $this->api_url . $contact_id . '/Tags?api_key=' . $account_data['api_key'], array(
243
  'method' => 'POST',
244
  'timeout' => 60,
245
  'headers' => array(
246
- 'Content-Type' => 'application/json'
247
  ),
248
  'body' => json_encode( array(
249
- array( 'name' => $settings->list_id )
 
 
250
  ) ),
251
  ) );
252
- }
253
-
254
  return $response;
255
  }
256
- }
12
  *
13
  * @since 1.5.8
14
  * @var string $id
15
+ */
16
  public $id = 'hatchbuck';
17
 
18
  /**
21
  * @since 1.5.8
22
  * @access private
23
  * @var string $api_url
24
+ */
25
  private $api_url = 'https://api.hatchbuck.com/api/v1/contact/';
26
+
27
  /**
28
  * Test the API connection.
29
  *
35
  * @type bool|string $error The error message or false if no error.
36
  * @type array $data An array of data used to make the connection.
37
  * }
38
+ */
39
+ public function connect( $fields = array() ) {
40
+ $response = array(
 
41
  'error' => false,
42
+ 'data' => array(),
43
  );
44
+
45
  // Make sure we have an API key.
46
  if ( ! isset( $fields['api_key'] ) || empty( $fields['api_key'] ) ) {
47
  $response['error'] = __( 'Error: You must provide an API key.', 'fl-builder' );
48
+ } // End if().
 
49
  else {
50
+
51
  $result = wp_remote_post( $this->api_url . 'search?api_key=' . $fields['api_key'], array(
52
  'method' => 'POST',
53
  'timeout' => 60,
54
  'headers' => array(
55
+ 'Content-Type' => 'application/json',
56
  ),
57
  'body' => array(),
58
  ) );
59
+
60
  if ( 401 == $result['response']['code'] ) {
61
  $response['error'] = __( 'Error: Please check your API key.', 'fl-builder' );
62
+ } else {
63
+ $response['data'] = array(
64
+ 'api_key' => $fields['api_key'],
65
+ );
66
  }
67
  }
68
+
69
  return $response;
70
  }
71
 
74
  *
75
  * @since 1.5.8
76
  * @return string The connection settings markup.
77
+ */
78
+ public function render_connect_settings() {
 
79
  ob_start();
80
+
81
  FLBuilder::render_settings_field( 'api_key', array(
82
  'row_class' => 'fl-builder-service-connect-row',
83
  'class' => 'fl-builder-service-connect-input',
85
  'label' => __( 'API Key', 'fl-builder' ),
86
  'help' => __( 'Your API key can be found in your Hatchbuck account under Account Settings > Web API.', 'fl-builder' ),
87
  'preview' => array(
88
+ 'type' => 'none',
89
+ ),
90
+ ));
91
+
92
  return ob_get_clean();
93
  }
94
 
95
  /**
96
+ * Render the markup for service specific fields.
97
  *
98
  * @since 1.5.8
99
  * @param string $account The name of the saved account.
102
  * @type bool|string $error The error message or false if no error.
103
  * @type string $html The field markup.
104
  * }
105
+ */
106
+ public function render_fields( $account, $settings ) {
107
+ $response = array(
108
+ 'error' => false,
109
+ 'html' => $this->render_tag_field( $settings ),
 
110
  );
111
+
112
  return $response;
113
  }
114
 
115
  /**
116
+ * Render markup for the tag field.
117
  *
118
  * @since 1.5.8
119
  * @param object $settings Saved module settings.
120
  * @return string The markup for the tag field.
121
  * @access private
122
+ */
123
+ private function render_tag_field( $settings ) {
 
124
  ob_start();
125
+
126
  FLBuilder::render_settings_field( 'list_id', array(
127
  'row_class' => 'fl-builder-service-field-row',
128
  'class' => 'fl-builder-service-list-select',
129
  'type' => 'text',
130
  'label' => _x( 'Tag', 'A tag to add to contacts in Hatchbuck when they subscribe.', 'fl-builder' ),
131
  'preview' => array(
132
+ 'type' => 'none',
133
+ ),
134
+ ), $settings);
135
+
136
  return ob_get_clean();
137
  }
138
 
139
+ /**
140
  * Subscribe an email address to Hatchbuck.
141
  *
142
  * @since 1.5.8
146
  * @return array {
147
  * @type bool|string $error The error message or false if no error.
148
  * }
149
+ */
150
+ public function subscribe( $settings, $email, $name = false ) {
 
151
  $contact_id = null;
152
  $account_data = $this->get_account_data( $settings->service_account );
153
+ $response = array(
154
+ 'error' => false,
155
+ );
156
+
157
  if ( ! $account_data ) {
158
  $response['error'] = __( 'There was an error subscribing to Hatchbuck. The account is no longer connected.', 'fl-builder' );
159
+ } else {
160
+
 
161
  // Build the data array.
162
+ $data = array(
163
  'emails' => array(
164
  array(
165
  'address' => $email,
166
+ 'type' => 'Work',
167
+ ),
168
  ),
169
  'status' => array(
170
+ 'name' => 'Lead',
171
+ ),
172
  );
173
+
174
  // Check if the contact exists.
175
  $result = wp_remote_post( $this->api_url . 'search?api_key=' . $account_data['api_key'], array(
176
  'method' => 'POST',
177
  'timeout' => 60,
178
  'headers' => array(
179
+ 'Content-Type' => 'application/json',
180
  ),
181
  'body' => json_encode( $data ),
182
  ) );
183
+
184
  // Return if we have an API key error.
185
  if ( 401 == $result['response']['code'] ) {
186
  $response['error'] = __( 'There was an error subscribing to Hatchbuck. The API key is invalid.', 'fl-builder' );
187
  return $response; // Invalid API key.
188
+ } // End if().
189
+ elseif ( 200 == $result['response']['code'] ) {
 
190
  $result_data = json_decode( $result['body'] );
191
  $contact_id = $result_data[0]->contactId;
192
+ } // Generic error. Contact not found should be 400.
193
+ elseif ( 400 != $result['response']['code'] ) {
 
194
  $response['error'] = __( 'There was an error subscribing to Hatchbuck.', 'fl-builder' );
195
  return $response;
196
  }
197
+
198
  // Add the contact if it doesn't exist.
199
  if ( ! $contact_id ) {
200
+
201
  // Add the name to the data array if we have one.
202
  if ( $name ) {
203
+
204
  $names = explode( ' ', $name );
205
+
206
  if ( isset( $names[0] ) ) {
207
  $data['firstName'] = $names[0];
208
  }
210
  $data['lastName'] = $names[1];
211
  }
212
  }
213
+
214
  // Add the contact to Hatchbuck.
215
  $result = wp_remote_post( $this->api_url . '?api_key=' . $account_data['api_key'], array(
216
  'method' => 'POST',
217
  'timeout' => 60,
218
  'headers' => array(
219
+ 'Content-Type' => 'application/json',
220
  ),
221
  'body' => json_encode( $data ),
222
  ) );
223
+
224
  // Return if we have an error.
225
  if ( 200 != $result['response']['code'] ) {
226
  $response['error'] = __( 'There was an error subscribing to Hatchbuck.', 'fl-builder' );
227
  return $response;
228
  }
229
+
230
  // Get the result data that contains the new contact ID.
231
  $result_data = json_decode( $result['body'] );
232
+ // @codingStandardsIgnoreLine
233
  $contact_id = $result_data->contactId;
234
+ }// End if().
235
+
236
+ // Add the tag to the contact.
237
+ $result = wp_remote_post( $this->api_url . $contact_id . '/Tags?api_key=' . $account_data['api_key'], array(
238
  'method' => 'POST',
239
  'timeout' => 60,
240
  'headers' => array(
241
+ 'Content-Type' => 'application/json',
242
  ),
243
  'body' => json_encode( array(
244
+ array(
245
+ 'name' => $settings->list_id,
246
+ ),
247
  ) ),
248
  ) );
249
+ }// End if().
250
+
251
  return $response;
252
  }
253
+ }
classes/class-fl-builder-service-icontact-pro.php CHANGED
@@ -12,14 +12,14 @@ final class FLBuilderServiceIContactPro extends FLBuilderService {
12
  *
13
  * @since 1.10.6
14
  * @var string $id
15
- */
16
  public $id = 'icontact-pro';
17
 
18
  /**
19
  * @since 1.10.6
20
  * @var object $api_instance
21
  * @access private
22
- */
23
  private $api_instance = null;
24
 
25
  /**
@@ -34,23 +34,22 @@ final class FLBuilderServiceIContactPro extends FLBuilderService {
34
  * @type string $profile_id A valid iContact Pro Profile ID.
35
  * }
36
  * @return object The API instance.
37
- */
38
- public function get_api( $data )
39
- {
40
  if ( $this->api_instance ) {
41
  return $this->api_instance;
42
  }
43
  if ( ! class_exists( 'iContactProApi' ) ) {
44
  require_once FL_BUILDER_DIR . 'includes/vendor/icontact/iContactProApi.php';
45
  }
46
-
47
  iContactProApi::getInstance()->setConfig( $data );
48
-
49
  $this->api_instance = iContactProApi::getInstance();
50
-
51
  return $this->api_instance;
52
  }
53
-
54
  /**
55
  * Test the API connection.
56
  *
@@ -66,61 +65,54 @@ final class FLBuilderServiceIContactPro extends FLBuilderService {
66
  * @type bool|string $error The error message or false if no error.
67
  * @type array $data An array of data used to make the connection.
68
  * }
69
- */
70
- public function connect( $fields = array() )
71
- {
72
- $response = array(
73
  'error' => false,
74
- 'data' => array()
75
  );
76
-
77
  // Make sure we have a username.
78
  if ( ! isset( $fields['username'] ) || empty( $fields['username'] ) ) {
79
  $response['error'] = __( 'Error: You must provide a username.', 'fl-builder' );
80
- }
81
- // Make sure we have an app ID.
82
- else if ( ! isset( $fields['app_id'] ) || empty( $fields['app_id'] ) ) {
83
  $response['error'] = __( 'Error: You must provide an app ID.', 'fl-builder' );
84
- }
85
- // Make sure we have an app password.
86
- else if ( ! isset( $fields['app_password'] ) || empty( $fields['app_password'] ) ) {
87
  $response['error'] = __( 'Error: You must provide an app password.', 'fl-builder' );
88
- }
89
- // Make sure we have a company ID
90
- else if ( ! isset( $fields['company_id'] ) || empty( $fields['company_id'] ) ) {
91
  $response['error'] = __( 'Error: You must provide a company ID.', 'fl-builder' );
92
- }
93
- // Make sure we have a profile ID
94
- else if ( ! isset( $fields['profile_id'] ) || empty( $fields['profile_id'] ) ) {
95
  $response['error'] = __( 'Error: You must provide a profile ID.', 'fl-builder' );
96
- }
97
- // Try to connect and store the connection data.
98
  else {
99
-
100
  $api = $this->get_api( array(
101
  'apiUsername' => $fields['username'],
102
  'appId' => $fields['app_id'],
103
  'apiPassword' => $fields['app_password'],
104
  'companyId' => $fields['company_id'],
105
- 'profileId' => $fields['profile_id']
106
  ));
107
-
108
  try {
109
  $api->getLists();
110
- $response['data'] = array(
111
  'username' => $fields['username'],
112
  'app_id' => $fields['app_id'],
113
  'app_password' => $fields['app_password'],
114
  'company_id' => $fields['company_id'],
115
- 'profile_id' => $fields['profile_id']
116
  );
117
- }
118
- catch ( Exception $e ) {
119
  $errors = $api->getErrors();
120
  $response['error'] = sprintf( __( 'Error: Could not connect to iContact Pro. %s', 'fl-builder' ), $errors[0] );
121
  }
122
  }
123
-
124
  return $response;
125
  }
126
 
@@ -129,11 +121,10 @@ final class FLBuilderServiceIContactPro extends FLBuilderService {
129
  *
130
  * @since 1.10.6
131
  * @return string The connection settings markup.
132
- */
133
- public function render_connect_settings()
134
- {
135
  ob_start();
136
-
137
  FLBuilder::render_settings_field( 'username', array(
138
  'row_class' => 'fl-builder-service-connect-row',
139
  'class' => 'fl-builder-service-connect-input',
@@ -141,10 +132,10 @@ final class FLBuilderServiceIContactPro extends FLBuilderService {
141
  'label' => __( 'Username', 'fl-builder' ),
142
  'help' => __( 'Your iContact Pro username.', 'fl-builder' ),
143
  'preview' => array(
144
- 'type' => 'none'
145
- )
146
- ));
147
-
148
  FLBuilder::render_settings_field( 'app_id', array(
149
  'row_class' => 'fl-builder-service-connect-row',
150
  'class' => 'fl-builder-service-connect-input',
@@ -152,10 +143,10 @@ final class FLBuilderServiceIContactPro extends FLBuilderService {
152
  'label' => __( 'App ID', 'fl-builder' ),
153
  'help' => __( 'Your iContact Pro app ID.', 'fl-builder' ),
154
  'preview' => array(
155
- 'type' => 'none'
156
- )
157
  ));
158
-
159
  FLBuilder::render_settings_field( 'app_password', array(
160
  'row_class' => 'fl-builder-service-connect-row',
161
  'class' => 'fl-builder-service-connect-input',
@@ -164,8 +155,8 @@ final class FLBuilderServiceIContactPro extends FLBuilderService {
164
  'help' => __( 'Your iContact Pro app password.', 'fl-builder' ),
165
  'description' => sprintf( __( 'You must <a%1$s>create an app</a> in iContact Pro to obtain an app ID and password. Please see <a%2$s>the iContact docs</a> for complete instructions.', 'fl-builder' ), ' href="https://app.icontactpro.com/MKT/Settings/Api?returnUrl=/MKT/Settings" target="_blank"', ' href="http://www.icontact.com/developerportal/api-documentation/vocus-register-your-app/" target="_blank"' ),
166
  'preview' => array(
167
- 'type' => 'none'
168
- )
169
  ));
170
 
171
  FLBuilder::render_settings_field( 'company_id', array(
@@ -175,8 +166,8 @@ final class FLBuilderServiceIContactPro extends FLBuilderService {
175
  'label' => __( 'Company ID', 'fl-builder' ),
176
  'help' => __( 'Your iContact Pro Company ID.', 'fl-builder' ),
177
  'preview' => array(
178
- 'type' => 'none'
179
- )
180
  ));
181
 
182
  FLBuilder::render_settings_field( 'profile_id', array(
@@ -187,8 +178,8 @@ final class FLBuilderServiceIContactPro extends FLBuilderService {
187
  'help' => __( 'Your iContact Pro Profile ID.', 'fl-builder' ),
188
  'description' => sprintf( __( 'Your Company and Profile ID can also be found in the <a%1$s>iContact Pro API settings</a> under Account Information.', 'fl-builder' ), ' href="https://app.icontactpro.com/MKT/Settings/Api?returnUrl=/MKT/Settings" target="_blank"' ),
189
  'preview' => array(
190
- 'type' => 'none'
191
- )
192
  ));
193
 
194
  return ob_get_clean();
@@ -204,53 +195,52 @@ final class FLBuilderServiceIContactPro extends FLBuilderService {
204
  * @type bool|string $error The error message or false if no error.
205
  * @type string $html The field markup.
206
  * }
207
- */
208
- public function render_fields( $account, $settings )
209
- {
210
  $account_data = $this->get_account_data( $account );
211
  $api = $this->get_api( array(
212
  'apiUsername' => $account_data['username'],
213
  'appId' => $account_data['app_id'],
214
  'apiPassword' => $account_data['app_password'],
215
  'companyId' => $account_data['company_id'],
216
- 'profileId' => $account_data['profile_id']
217
  ));
218
- $response = array(
219
- 'error' => false,
220
- 'html' => ''
221
  );
222
-
223
  try {
224
  $lists = $api->getLists();
225
  $response['html'] = $this->render_list_field( $lists, $settings );
226
- }
227
- catch ( Exception $e ) {
228
  $errors = $api->getErrors();
229
  $response['error'] = sprintf( __( 'Error: Could not connect to iContact Pro. %s', 'fl-builder' ), $errors[0] );
230
  }
231
-
232
  return $response;
233
  }
234
 
235
  /**
236
- * Render markup for the list field.
237
  *
238
  * @since 1.10.6
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 ( $lists as $id => $list ) {
251
- $options[ $list->listId ] = $list->name;
252
  }
253
-
254
  FLBuilder::render_settings_field( 'list_id', array(
255
  'row_class' => 'fl-builder-service-field-row',
256
  'class' => 'fl-builder-service-list-select',
@@ -258,14 +248,14 @@ final class FLBuilderServiceIContactPro extends FLBuilderService {
258
  'label' => _x( 'List', 'An email list from a third party provider.', 'fl-builder' ),
259
  'options' => $options,
260
  'preview' => array(
261
- 'type' => 'none'
262
- )
263
- ), $settings);
264
-
265
  return ob_get_clean();
266
  }
267
 
268
- /**
269
  * Subscribe an email address to iContact.
270
  *
271
  * @since 1.10.6
@@ -275,55 +265,55 @@ final class FLBuilderServiceIContactPro extends FLBuilderService {
275
  * @return array {
276
  * @type bool|string $error The error message or false if no error.
277
  * }
278
- */
279
- public function subscribe( $settings, $email, $name = false )
280
- {
281
  $account_data = $this->get_account_data( $settings->service_account );
282
- $response = array( 'error' => false );
283
-
 
 
284
  if ( ! $account_data ) {
285
  $response['error'] = __( 'There was an error subscribing to iContact. The account is no longer connected.', 'fl-builder' );
286
- }
287
- else {
288
-
289
- $data = array( 'email' => $email );
 
290
  $api = $this->get_api( array(
291
  'apiUsername' => $account_data['username'],
292
  'appId' => $account_data['app_id'],
293
  'apiPassword' => $account_data['app_password'],
294
  'companyId' => $account_data['company_id'],
295
- 'profileId' => $account_data['profile_id']
296
  ));
297
-
298
  try {
299
-
300
  if ( $name ) {
301
-
302
  $names = explode( ' ', $name );
303
  $data['first_name'] = null;
304
  $data['last_name'] = null;
305
-
306
  if ( isset( $names[0] ) ) {
307
  $data['first_name'] = $names[0];
308
  }
309
  if ( isset( $names[1] ) ) {
310
  $data['last_name'] = $names[1];
311
  }
312
-
313
  $result = $api->addContact( $data['email'], 'normal', null, $data['first_name'], $data['last_name'] );
314
- }
315
- else {
316
  $result = $api->addContact( $data['email'] );
317
  }
318
-
319
- $api->subscribeContactToList( $result->contactId, $settings->list_id );
320
- }
321
- catch ( Exception $e ) {
322
  $errors = $api->getErrors();
323
  $response['error'] = sprintf( __( 'There was an error subscribing to iContact Pro. %s', 'fl-builder' ), $errors[0] );
324
  }
325
- }
326
-
327
  return $response;
328
  }
329
- }
12
  *
13
  * @since 1.10.6
14
  * @var string $id
15
+ */
16
  public $id = 'icontact-pro';
17
 
18
  /**
19
  * @since 1.10.6
20
  * @var object $api_instance
21
  * @access private
22
+ */
23
  private $api_instance = null;
24
 
25
  /**
34
  * @type string $profile_id A valid iContact Pro Profile ID.
35
  * }
36
  * @return object The API instance.
37
+ */
38
+ public function get_api( $data ) {
 
39
  if ( $this->api_instance ) {
40
  return $this->api_instance;
41
  }
42
  if ( ! class_exists( 'iContactProApi' ) ) {
43
  require_once FL_BUILDER_DIR . 'includes/vendor/icontact/iContactProApi.php';
44
  }
45
+
46
  iContactProApi::getInstance()->setConfig( $data );
47
+
48
  $this->api_instance = iContactProApi::getInstance();
49
+
50
  return $this->api_instance;
51
  }
52
+
53
  /**
54
  * Test the API connection.
55
  *
65
  * @type bool|string $error The error message or false if no error.
66
  * @type array $data An array of data used to make the connection.
67
  * }
68
+ */
69
+ public function connect( $fields = array() ) {
70
+ $response = array(
 
71
  'error' => false,
72
+ 'data' => array(),
73
  );
74
+
75
  // Make sure we have a username.
76
  if ( ! isset( $fields['username'] ) || empty( $fields['username'] ) ) {
77
  $response['error'] = __( 'Error: You must provide a username.', 'fl-builder' );
78
+ } // End if().
79
+ elseif ( ! isset( $fields['app_id'] ) || empty( $fields['app_id'] ) ) {
 
80
  $response['error'] = __( 'Error: You must provide an app ID.', 'fl-builder' );
81
+ } // Make sure we have an app password.
82
+ elseif ( ! isset( $fields['app_password'] ) || empty( $fields['app_password'] ) ) {
 
83
  $response['error'] = __( 'Error: You must provide an app password.', 'fl-builder' );
84
+ } // Make sure we have a company ID
85
+ elseif ( ! isset( $fields['company_id'] ) || empty( $fields['company_id'] ) ) {
 
86
  $response['error'] = __( 'Error: You must provide a company ID.', 'fl-builder' );
87
+ } // Make sure we have a profile ID
88
+ elseif ( ! isset( $fields['profile_id'] ) || empty( $fields['profile_id'] ) ) {
 
89
  $response['error'] = __( 'Error: You must provide a profile ID.', 'fl-builder' );
90
+ } // Try to connect and store the connection data.
 
91
  else {
92
+
93
  $api = $this->get_api( array(
94
  'apiUsername' => $fields['username'],
95
  'appId' => $fields['app_id'],
96
  'apiPassword' => $fields['app_password'],
97
  'companyId' => $fields['company_id'],
98
+ 'profileId' => $fields['profile_id'],
99
  ));
100
+
101
  try {
102
  $api->getLists();
103
+ $response['data'] = array(
104
  'username' => $fields['username'],
105
  'app_id' => $fields['app_id'],
106
  'app_password' => $fields['app_password'],
107
  'company_id' => $fields['company_id'],
108
+ 'profile_id' => $fields['profile_id'],
109
  );
110
+ } catch ( Exception $e ) {
 
111
  $errors = $api->getErrors();
112
  $response['error'] = sprintf( __( 'Error: Could not connect to iContact Pro. %s', 'fl-builder' ), $errors[0] );
113
  }
114
  }
115
+
116
  return $response;
117
  }
118
 
121
  *
122
  * @since 1.10.6
123
  * @return string The connection settings markup.
124
+ */
125
+ public function render_connect_settings() {
 
126
  ob_start();
127
+
128
  FLBuilder::render_settings_field( 'username', array(
129
  'row_class' => 'fl-builder-service-connect-row',
130
  'class' => 'fl-builder-service-connect-input',
132
  'label' => __( 'Username', 'fl-builder' ),
133
  'help' => __( 'Your iContact Pro username.', 'fl-builder' ),
134
  'preview' => array(
135
+ 'type' => 'none',
136
+ ),
137
+ ));
138
+
139
  FLBuilder::render_settings_field( 'app_id', array(
140
  'row_class' => 'fl-builder-service-connect-row',
141
  'class' => 'fl-builder-service-connect-input',
143
  'label' => __( 'App ID', 'fl-builder' ),
144
  'help' => __( 'Your iContact Pro app ID.', 'fl-builder' ),
145
  'preview' => array(
146
+ 'type' => 'none',
147
+ ),
148
  ));
149
+
150
  FLBuilder::render_settings_field( 'app_password', array(
151
  'row_class' => 'fl-builder-service-connect-row',
152
  'class' => 'fl-builder-service-connect-input',
155
  'help' => __( 'Your iContact Pro app password.', 'fl-builder' ),
156
  'description' => sprintf( __( 'You must <a%1$s>create an app</a> in iContact Pro to obtain an app ID and password. Please see <a%2$s>the iContact docs</a> for complete instructions.', 'fl-builder' ), ' href="https://app.icontactpro.com/MKT/Settings/Api?returnUrl=/MKT/Settings" target="_blank"', ' href="http://www.icontact.com/developerportal/api-documentation/vocus-register-your-app/" target="_blank"' ),
157
  'preview' => array(
158
+ 'type' => 'none',
159
+ ),
160
  ));
161
 
162
  FLBuilder::render_settings_field( 'company_id', array(
166
  'label' => __( 'Company ID', 'fl-builder' ),
167
  'help' => __( 'Your iContact Pro Company ID.', 'fl-builder' ),
168
  'preview' => array(
169
+ 'type' => 'none',
170
+ ),
171
  ));
172
 
173
  FLBuilder::render_settings_field( 'profile_id', array(
178
  'help' => __( 'Your iContact Pro Profile ID.', 'fl-builder' ),
179
  'description' => sprintf( __( 'Your Company and Profile ID can also be found in the <a%1$s>iContact Pro API settings</a> under Account Information.', 'fl-builder' ), ' href="https://app.icontactpro.com/MKT/Settings/Api?returnUrl=/MKT/Settings" target="_blank"' ),
180
  'preview' => array(
181
+ 'type' => 'none',
182
+ ),
183
  ));
184
 
185
  return ob_get_clean();
195
  * @type bool|string $error The error message or false if no error.
196
  * @type string $html The field markup.
197
  * }
198
+ */
199
+ public function render_fields( $account, $settings ) {
 
200
  $account_data = $this->get_account_data( $account );
201
  $api = $this->get_api( array(
202
  'apiUsername' => $account_data['username'],
203
  'appId' => $account_data['app_id'],
204
  'apiPassword' => $account_data['app_password'],
205
  'companyId' => $account_data['company_id'],
206
+ 'profileId' => $account_data['profile_id'],
207
  ));
208
+ $response = array(
209
+ 'error' => false,
210
+ 'html' => '',
211
  );
212
+
213
  try {
214
  $lists = $api->getLists();
215
  $response['html'] = $this->render_list_field( $lists, $settings );
216
+ } catch ( Exception $e ) {
 
217
  $errors = $api->getErrors();
218
  $response['error'] = sprintf( __( 'Error: Could not connect to iContact Pro. %s', 'fl-builder' ), $errors[0] );
219
  }
220
+
221
  return $response;
222
  }
223
 
224
  /**
225
+ * Render markup for the list field.
226
  *
227
  * @since 1.10.6
228
  * @param array $lists List data from the API.
229
  * @param object $settings Saved module settings.
230
  * @return string The markup for the list field.
231
  * @access private
232
+ */
233
+ private function render_list_field( $lists, $settings ) {
 
234
  ob_start();
235
+
236
+ $options = array(
237
+ '' => __( 'Choose...', 'fl-builder' ),
238
+ );
239
+
240
  foreach ( $lists as $id => $list ) {
241
+ $options[ $list->listId ] = $list->name; // @codingStandardsIgnoreLine
242
  }
243
+
244
  FLBuilder::render_settings_field( 'list_id', array(
245
  'row_class' => 'fl-builder-service-field-row',
246
  'class' => 'fl-builder-service-list-select',
248
  'label' => _x( 'List', 'An email list from a third party provider.', 'fl-builder' ),
249
  'options' => $options,
250
  'preview' => array(
251
+ 'type' => 'none',
252
+ ),
253
+ ), $settings);
254
+
255
  return ob_get_clean();
256
  }
257
 
258
+ /**
259
  * Subscribe an email address to iContact.
260
  *
261
  * @since 1.10.6
265
  * @return array {
266
  * @type bool|string $error The error message or false if no error.
267
  * }
268
+ */
269
+ public function subscribe( $settings, $email, $name = false ) {
 
270
  $account_data = $this->get_account_data( $settings->service_account );
271
+ $response = array(
272
+ 'error' => false,
273
+ );
274
+
275
  if ( ! $account_data ) {
276
  $response['error'] = __( 'There was an error subscribing to iContact. The account is no longer connected.', 'fl-builder' );
277
+ } else {
278
+
279
+ $data = array(
280
+ 'email' => $email,
281
+ );
282
  $api = $this->get_api( array(
283
  'apiUsername' => $account_data['username'],
284
  'appId' => $account_data['app_id'],
285
  'apiPassword' => $account_data['app_password'],
286
  'companyId' => $account_data['company_id'],
287
+ 'profileId' => $account_data['profile_id'],
288
  ));
289
+
290
  try {
291
+
292
  if ( $name ) {
293
+
294
  $names = explode( ' ', $name );
295
  $data['first_name'] = null;
296
  $data['last_name'] = null;
297
+
298
  if ( isset( $names[0] ) ) {
299
  $data['first_name'] = $names[0];
300
  }
301
  if ( isset( $names[1] ) ) {
302
  $data['last_name'] = $names[1];
303
  }
304
+
305
  $result = $api->addContact( $data['email'], 'normal', null, $data['first_name'], $data['last_name'] );
306
+ } else {
 
307
  $result = $api->addContact( $data['email'] );
308
  }
309
+
310
+ $api->subscribeContactToList( $result->contactId, $settings->list_id ); // @codingStandardsIgnoreLine
311
+ } catch ( Exception $e ) {
 
312
  $errors = $api->getErrors();
313
  $response['error'] = sprintf( __( 'There was an error subscribing to iContact Pro. %s', 'fl-builder' ), $errors[0] );
314
  }
315
+ }// End if().
316
+
317
  return $response;
318
  }
319
+ }
classes/class-fl-builder-service-icontact.php CHANGED
@@ -12,14 +12,14 @@ final class FLBuilderServiceIContact extends FLBuilderService {
12
  *
13
  * @since 1.5.4
14
  * @var string $id
15
- */
16
  public $id = 'icontact';
17
 
18
  /**
19
  * @since 1.5.4
20
  * @var object $api_instance
21
  * @access private
22
- */
23
  private $api_instance = null;
24
 
25
  /**
@@ -32,23 +32,22 @@ final class FLBuilderServiceIContact extends FLBuilderService {
32
  * @type string $app_password A valid app password.
33
  * }
34
  * @return object The API instance.
35
- */
36
- public function get_api( $data )
37
- {
38
  if ( $this->api_instance ) {
39
  return $this->api_instance;
40
  }
41
  if ( ! class_exists( 'iContactApi' ) ) {
42
  require_once FL_BUILDER_DIR . 'includes/vendor/icontact/iContactApi.php';
43
  }
44
-
45
  iContactApi::getInstance()->setConfig( $data );
46
-
47
  $this->api_instance = iContactApi::getInstance();
48
-
49
  return $this->api_instance;
50
  }
51
-
52
  /**
53
  * Test the API connection.
54
  *
@@ -62,49 +61,44 @@ final class FLBuilderServiceIContact extends FLBuilderService {
62
  * @type bool|string $error The error message or false if no error.
63
  * @type array $data An array of data used to make the connection.
64
  * }
65
- */
66
- public function connect( $fields = array() )
67
- {
68
- $response = array(
69
  'error' => false,
70
- 'data' => array()
71
  );
72
-
73
  // Make sure we have a username.
74
  if ( ! isset( $fields['username'] ) || empty( $fields['username'] ) ) {
75
  $response['error'] = __( 'Error: You must provide a username.', 'fl-builder' );
76
- }
77
- // Make sure we have an app ID.
78
- else if ( ! isset( $fields['app_id'] ) || empty( $fields['app_id'] ) ) {
79
  $response['error'] = __( 'Error: You must provide a app ID.', 'fl-builder' );
80
- }
81
- // Make sure we have an app password.
82
- else if ( ! isset( $fields['app_password'] ) || empty( $fields['app_password'] ) ) {
83
  $response['error'] = __( 'Error: You must provide a app password.', 'fl-builder' );
84
- }
85
- // Try to connect and store the connection data.
86
  else {
87
-
88
  $api = $this->get_api( array(
89
  'apiUsername' => $fields['username'],
90
  'appId' => $fields['app_id'],
91
  'apiPassword' => $fields['app_password'],
92
  ));
93
-
94
  try {
95
  $api->getLists();
96
- $response['data'] = array(
97
  'username' => $fields['username'],
98
  'app_id' => $fields['app_id'],
99
  'app_password' => $fields['app_password'],
100
  );
101
- }
102
- catch ( Exception $e ) {
103
  $errors = $api->getErrors();
104
  $response['error'] = sprintf( __( 'Error: Could not connect to iContact. %s', 'fl-builder' ), $errors[0] );
105
  }
106
  }
107
-
108
  return $response;
109
  }
110
 
@@ -113,11 +107,10 @@ final class FLBuilderServiceIContact extends FLBuilderService {
113
  *
114
  * @since 1.5.4
115
  * @return string The connection settings markup.
116
- */
117
- public function render_connect_settings()
118
- {
119
  ob_start();
120
-
121
  FLBuilder::render_settings_field( 'username', array(
122
  'row_class' => 'fl-builder-service-connect-row',
123
  'class' => 'fl-builder-service-connect-input',
@@ -125,10 +118,10 @@ final class FLBuilderServiceIContact extends FLBuilderService {
125
  'label' => __( 'Username', 'fl-builder' ),
126
  'help' => __( 'Your iContact username.', 'fl-builder' ),
127
  'preview' => array(
128
- 'type' => 'none'
129
- )
130
- ));
131
-
132
  FLBuilder::render_settings_field( 'app_id', array(
133
  'row_class' => 'fl-builder-service-connect-row',
134
  'class' => 'fl-builder-service-connect-input',
@@ -136,10 +129,10 @@ final class FLBuilderServiceIContact extends FLBuilderService {
136
  'label' => __( 'App ID', 'fl-builder' ),
137
  'help' => __( 'Your iContact app ID.', 'fl-builder' ),
138
  'preview' => array(
139
- 'type' => 'none'
140
- )
141
  ));
142
-
143
  FLBuilder::render_settings_field( 'app_password', array(
144
  'row_class' => 'fl-builder-service-connect-row',
145
  'class' => 'fl-builder-service-connect-input',
@@ -148,8 +141,8 @@ final class FLBuilderServiceIContact extends FLBuilderService {
148
  'help' => __( 'Your iContact app password.', 'fl-builder' ),
149
  'description' => sprintf( __( 'You must <a%1$s>create an app</a> in iContact to obtain an app ID and password. Please see <a%2$s>the iContact docs</a> for complete instructions.', 'fl-builder' ), ' href="https://app.icontact.com/icp/core/registerapp/" target="_blank"', ' href="http://www.icontact.com/developerportal/api-documentation/vocus-register-your-app/" target="_blank"' ),
150
  'preview' => array(
151
- 'type' => 'none'
152
- )
153
  ));
154
 
155
  return ob_get_clean();
@@ -165,51 +158,51 @@ final class FLBuilderServiceIContact extends FLBuilderService {
165
  * @type bool|string $error The error message or false if no error.
166
  * @type string $html The field markup.
167
  * }
168
- */
169
- public function render_fields( $account, $settings )
170
- {
171
  $account_data = $this->get_account_data( $account );
172
  $api = $this->get_api( array(
173
  'apiUsername' => $account_data['username'],
174
  'appId' => $account_data['app_id'],
175
  'apiPassword' => $account_data['app_password'],
176
  ));
177
- $response = array(
178
- 'error' => false,
179
- 'html' => ''
180
  );
181
-
182
  try {
183
  $lists = $api->getLists();
184
  $response['html'] = $this->render_list_field( $lists, $settings );
185
- }
186
- catch ( Exception $e ) {
187
  $errors = $api->getErrors();
188
  $response['error'] = sprintf( __( 'Error: Could not connect to iContact. %s', 'fl-builder' ), $errors[0] );
189
  }
190
-
191
  return $response;
192
  }
193
 
194
  /**
195
- * Render markup for the list field.
196
  *
197
  * @since 1.5.4
198
  * @param array $lists List data from the API.
199
  * @param object $settings Saved module settings.
200
  * @return string The markup for the list field.
201
  * @access private
202
- */
203
- private function render_list_field( $lists, $settings )
204
- {
205
  ob_start();
206
-
207
- $options = array( '' => __( 'Choose...', 'fl-builder' ) );
208
-
 
 
209
  foreach ( $lists as $id => $list ) {
 
210
  $options[ $list->listId ] = $list->name;
211
  }
212
-
213
  FLBuilder::render_settings_field( 'list_id', array(
214
  'row_class' => 'fl-builder-service-field-row',
215
  'class' => 'fl-builder-service-list-select',
@@ -217,14 +210,14 @@ final class FLBuilderServiceIContact extends FLBuilderService {
217
  'label' => _x( 'List', 'An email list from a third party provider.', 'fl-builder' ),
218
  'options' => $options,
219
  'preview' => array(
220
- 'type' => 'none'
221
- )
222
- ), $settings);
223
-
224
  return ob_get_clean();
225
  }
226
 
227
- /**
228
  * Subscribe an email address to iContact.
229
  *
230
  * @since 1.5.4
@@ -234,53 +227,54 @@ final class FLBuilderServiceIContact extends FLBuilderService {
234
  * @return array {
235
  * @type bool|string $error The error message or false if no error.
236
  * }
237
- */
238
- public function subscribe( $settings, $email, $name = false )
239
- {
240
  $account_data = $this->get_account_data( $settings->service_account );
241
- $response = array( 'error' => false );
242
-
 
 
243
  if ( ! $account_data ) {
244
  $response['error'] = __( 'There was an error subscribing to iContact. The account is no longer connected.', 'fl-builder' );
245
- }
246
- else {
247
-
248
- $data = array( 'email' => $email );
 
249
  $api = $this->get_api( array(
250
  'apiUsername' => $account_data['username'],
251
  'appId' => $account_data['app_id'],
252
  'apiPassword' => $account_data['app_password'],
253
  ));
254
-
255
  try {
256
-
257
  if ( $name ) {
258
-
259
  $names = explode( ' ', $name );
260
  $data['first_name'] = null;
261
  $data['last_name'] = null;
262
-
263
  if ( isset( $names[0] ) ) {
264
  $data['first_name'] = $names[0];
265
  }
266
  if ( isset( $names[1] ) ) {
267
  $data['last_name'] = $names[1];
268
  }
269
-
270
  $result = $api->addContact( $data['email'], 'normal', null, $data['first_name'], $data['last_name'] );
271
- }
272
- else {
273
  $result = $api->addContact( $data['email'] );
274
  }
275
-
 
276
  $api->subscribeContactToList( $result->contactId, $settings->list_id );
277
- }
278
- catch ( Exception $e ) {
279
  $errors = $api->getErrors();
280
  $response['error'] = sprintf( __( 'There was an error subscribing to iContact. %s', 'fl-builder' ), $errors[0] );
281
  }
282
- }
283
-
284
  return $response;
285
  }
286
- }
12
  *
13
  * @since 1.5.4
14
  * @var string $id
15
+ */
16
  public $id = 'icontact';
17
 
18
  /**
19
  * @since 1.5.4
20
  * @var object $api_instance
21
  * @access private
22
+ */
23
  private $api_instance = null;
24
 
25
  /**
32
  * @type string $app_password A valid app password.
33
  * }
34
  * @return object The API instance.
35
+ */
36
+ public function get_api( $data ) {
 
37
  if ( $this->api_instance ) {
38
  return $this->api_instance;
39
  }
40
  if ( ! class_exists( 'iContactApi' ) ) {
41
  require_once FL_BUILDER_DIR . 'includes/vendor/icontact/iContactApi.php';
42
  }
43
+
44
  iContactApi::getInstance()->setConfig( $data );
45
+
46
  $this->api_instance = iContactApi::getInstance();
47
+
48
  return $this->api_instance;
49
  }
50
+
51
  /**
52
  * Test the API connection.
53
  *
61
  * @type bool|string $error The error message or false if no error.
62
  * @type array $data An array of data used to make the connection.
63
  * }
64
+ */
65
+ public function connect( $fields = array() ) {
66
+ $response = array(
 
67
  'error' => false,
68
+ 'data' => array(),
69
  );
70
+
71
  // Make sure we have a username.
72
  if ( ! isset( $fields['username'] ) || empty( $fields['username'] ) ) {
73
  $response['error'] = __( 'Error: You must provide a username.', 'fl-builder' );
74
+ } // End if().
75
+ elseif ( ! isset( $fields['app_id'] ) || empty( $fields['app_id'] ) ) {
 
76
  $response['error'] = __( 'Error: You must provide a app ID.', 'fl-builder' );
77
+ } // Make sure we have an app password.
78
+ elseif ( ! isset( $fields['app_password'] ) || empty( $fields['app_password'] ) ) {
 
79
  $response['error'] = __( 'Error: You must provide a app password.', 'fl-builder' );
80
+ } // Try to connect and store the connection data.
 
81
  else {
82
+
83
  $api = $this->get_api( array(
84
  'apiUsername' => $fields['username'],
85
  'appId' => $fields['app_id'],
86
  'apiPassword' => $fields['app_password'],
87
  ));
88
+
89
  try {
90
  $api->getLists();
91
+ $response['data'] = array(
92
  'username' => $fields['username'],
93
  'app_id' => $fields['app_id'],
94
  'app_password' => $fields['app_password'],
95
  );
96
+ } catch ( Exception $e ) {
 
97
  $errors = $api->getErrors();
98
  $response['error'] = sprintf( __( 'Error: Could not connect to iContact. %s', 'fl-builder' ), $errors[0] );
99
  }
100
  }
101
+
102
  return $response;
103
  }
104
 
107
  *
108
  * @since 1.5.4
109
  * @return string The connection settings markup.
110
+ */
111
+ public function render_connect_settings() {
 
112
  ob_start();
113
+
114
  FLBuilder::render_settings_field( 'username', array(
115
  'row_class' => 'fl-builder-service-connect-row',
116
  'class' => 'fl-builder-service-connect-input',
118
  'label' => __( 'Username', 'fl-builder' ),
119
  'help' => __( 'Your iContact username.', 'fl-builder' ),
120
  'preview' => array(
121
+ 'type' => 'none',
122
+ ),
123
+ ));
124
+
125
  FLBuilder::render_settings_field( 'app_id', array(
126
  'row_class' => 'fl-builder-service-connect-row',
127
  'class' => 'fl-builder-service-connect-input',
129
  'label' => __( 'App ID', 'fl-builder' ),
130
  'help' => __( 'Your iContact app ID.', 'fl-builder' ),
131
  'preview' => array(
132
+ 'type' => 'none',
133
+ ),
134
  ));
135
+
136
  FLBuilder::render_settings_field( 'app_password', array(
137
  'row_class' => 'fl-builder-service-connect-row',
138
  'class' => 'fl-builder-service-connect-input',
141
  'help' => __( 'Your iContact app password.', 'fl-builder' ),
142
  'description' => sprintf( __( 'You must <a%1$s>create an app</a> in iContact to obtain an app ID and password. Please see <a%2$s>the iContact docs</a> for complete instructions.', 'fl-builder' ), ' href="https://app.icontact.com/icp/core/registerapp/" target="_blank"', ' href="http://www.icontact.com/developerportal/api-documentation/vocus-register-your-app/" target="_blank"' ),
143
  'preview' => array(
144
+ 'type' => 'none',
145
+ ),
146
  ));
147
 
148
  return ob_get_clean();
158
  * @type bool|string $error The error message or false if no error.
159
  * @type string $html The field markup.
160
  * }
161
+ */
162
+ public function render_fields( $account, $settings ) {
 
163
  $account_data = $this->get_account_data( $account );
164
  $api = $this->get_api( array(
165
  'apiUsername' => $account_data['username'],
166
  'appId' => $account_data['app_id'],
167
  'apiPassword' => $account_data['app_password'],
168
  ));
169
+ $response = array(
170
+ 'error' => false,
171
+ 'html' => '',
172
  );
173
+
174
  try {
175
  $lists = $api->getLists();
176
  $response['html'] = $this->render_list_field( $lists, $settings );
177
+ } catch ( Exception $e ) {
 
178
  $errors = $api->getErrors();
179
  $response['error'] = sprintf( __( 'Error: Could not connect to iContact. %s', 'fl-builder' ), $errors[0] );
180
  }
181
+
182
  return $response;
183
  }
184
 
185
  /**
186
+ * Render markup for the list field.
187
  *
188
  * @since 1.5.4
189
  * @param array $lists List data from the API.
190
  * @param object $settings Saved module settings.
191
  * @return string The markup for the list field.
192
  * @access private
193
+ */
194
+ private function render_list_field( $lists, $settings ) {
 
195
  ob_start();
196
+
197
+ $options = array(
198
+ '' => __( 'Choose...', 'fl-builder' ),
199
+ );
200
+
201
  foreach ( $lists as $id => $list ) {
202
+ // @codingStandardsIgnoreLine
203
  $options[ $list->listId ] = $list->name;
204
  }
205
+
206
  FLBuilder::render_settings_field( 'list_id', array(
207
  'row_class' => 'fl-builder-service-field-row',
208
  'class' => 'fl-builder-service-list-select',
210
  'label' => _x( 'List', 'An email list from a third party provider.', 'fl-builder' ),
211
  'options' => $options,
212
  'preview' => array(
213
+ 'type' => 'none',
214
+ ),
215
+ ), $settings);
216
+
217
  return ob_get_clean();
218
  }
219
 
220
+ /**
221
  * Subscribe an email address to iContact.
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 iContact. The account is no longer connected.', 'fl-builder' );
239
+ } else {
240
+
241
+ $data = array(
242
+ 'email' => $email,
243
+ );
244
  $api = $this->get_api( array(
245
  'apiUsername' => $account_data['username'],
246
  'appId' => $account_data['app_id'],
247
  'apiPassword' => $account_data['app_password'],
248
  ));
249
+
250
  try {
251
+
252
  if ( $name ) {
253
+
254
  $names = explode( ' ', $name );
255
  $data['first_name'] = null;
256
  $data['last_name'] = null;
257
+
258
  if ( isset( $names[0] ) ) {
259
  $data['first_name'] = $names[0];
260
  }
261
  if ( isset( $names[1] ) ) {
262
  $data['last_name'] = $names[1];
263
  }
264
+
265
  $result = $api->addContact( $data['email'], 'normal', null, $data['first_name'], $data['last_name'] );
266
+ } else {
 
267
  $result = $api->addContact( $data['email'] );
268
  }
269
+
270
+ // @codingStandardsIgnoreLine
271
  $api->subscribeContactToList( $result->contactId, $settings->list_id );
272
+ } catch ( Exception $e ) {
 
273
  $errors = $api->getErrors();
274
  $response['error'] = sprintf( __( 'There was an error subscribing to iContact. %s', 'fl-builder' ), $errors[0] );
275
  }
276
+ }// End if().
277
+
278
  return $response;
279
  }
280
+ }
classes/class-fl-builder-service-infusionsoft.php CHANGED
@@ -12,14 +12,14 @@ final class FLBuilderServiceInfusionsoft extends FLBuilderService {
12
  *
13
  * @since 1.5.7
14
  * @var string $id
15
- */
16
  public $id = 'infusionsoft';
17
 
18
  /**
19
  * @since 1.5.7
20
  * @var object $api_instance
21
  * @access private
22
- */
23
  private $api_instance = null;
24
 
25
  /**
@@ -29,31 +29,29 @@ final class FLBuilderServiceInfusionsoft extends FLBuilderService {
29
  * @param string $app_id A valid app ID.
30
  * @param string $api_key A valid API key.
31
  * @return object The API instance.
32
- */
33
- public function get_api( $app_id, $api_key )
34
- {
35
  if ( $this->api_instance ) {
36
  return $this->api_instance;
37
  }
38
  if ( ! class_exists( 'iSDK' ) ) {
39
  require_once FL_BUILDER_DIR . 'includes/vendor/infusionsoft/isdk.php';
40
  }
41
-
42
  try {
43
  $this->api_instance = new iSDK();
44
  $this->api_instance->cfgCon( $app_id, $api_key, 'throw' );
45
- }
46
- catch ( iSDKException $e ) {
47
  $this->api_instance = new stdClass();
48
  $this->api_instance->error = sprintf(
49
  __( 'There was an error connecting to Infusionsoft. %s', 'fl-builder' ),
50
  $e->getMessage()
51
  );
52
  }
53
-
54
  return $this->api_instance;
55
  }
56
-
57
  /**
58
  * Test the API connection.
59
  *
@@ -66,38 +64,34 @@ final class FLBuilderServiceInfusionsoft extends FLBuilderService {
66
  * @type bool|string $error The error message or false if no error.
67
  * @type array $data An array of data used to make the connection.
68
  * }
69
- */
70
- public function connect( $fields = array() )
71
- {
72
- $response = array(
73
  'error' => false,
74
- 'data' => array()
75
  );
76
-
77
  // Make sure we have an API key.
78
  if ( ! isset( $fields['api_key'] ) || empty( $fields['api_key'] ) ) {
79
  $response['error'] = __( 'Error: You must provide an API key.', 'fl-builder' );
80
- }
81
- // Make sure we have an app ID.
82
- else if ( ! isset( $fields['app_id'] ) || empty( $fields['app_id'] ) ) {
83
  $response['error'] = __( 'Error: You must provide an app ID.', 'fl-builder' );
84
- }
85
- // Try to connect and store the connection data.
86
  else {
87
-
88
  $api = $this->get_api( $fields['app_id'], $fields['api_key'] );
89
-
90
  if ( isset( $api->error ) ) {
91
  $response['error'] = $api->error;
92
- }
93
- else {
94
- $response['data'] = array(
95
  'app_id' => $fields['app_id'],
96
- 'api_key' => $fields['api_key']
97
  );
98
  }
99
  }
100
-
101
  return $response;
102
  }
103
 
@@ -106,11 +100,10 @@ final class FLBuilderServiceInfusionsoft extends FLBuilderService {
106
  *
107
  * @since 1.5.7
108
  * @return string The connection settings markup.
109
- */
110
- public function render_connect_settings()
111
- {
112
  ob_start();
113
-
114
  FLBuilder::render_settings_field( 'app_id', array(
115
  'row_class' => 'fl-builder-service-connect-row',
116
  'class' => 'fl-builder-service-connect-input',
@@ -118,10 +111,10 @@ final class FLBuilderServiceInfusionsoft extends FLBuilderService {
118
  'label' => __( 'App ID', 'fl-builder' ),
119
  'help' => __( 'Your App ID can be found in the URL for your account. For example, if the URL for your account is myaccount.infusionsoft.com, your App ID would be <strong>myaccount</strong>.', 'fl-builder' ),
120
  'preview' => array(
121
- 'type' => 'none'
122
- )
123
  ));
124
-
125
  FLBuilder::render_settings_field( 'api_key', array(
126
  'row_class' => 'fl-builder-service-connect-row',
127
  'class' => 'fl-builder-service-connect-input',
@@ -129,15 +122,15 @@ final class FLBuilderServiceInfusionsoft extends FLBuilderService {
129
  'label' => __( 'API Key', 'fl-builder' ),
130
  'help' => __( 'Your API key can be found in your Infusionsoft account under Admin > Settings > Application > API > Encrypted Key.', 'fl-builder' ),
131
  'preview' => array(
132
- 'type' => 'none'
133
- )
134
  ));
135
-
136
  return ob_get_clean();
137
  }
138
 
139
  /**
140
- * Render the markup for service specific fields.
141
  *
142
  * @since 1.5.7
143
  * @param string $account The name of the saved account.
@@ -146,67 +139,68 @@ final class FLBuilderServiceInfusionsoft extends FLBuilderService {
146
  * @type bool|string $error The error message or false if no error.
147
  * @type string $html The field markup.
148
  * }
149
- */
150
- public function render_fields( $account, $settings )
151
- {
152
  $account_data = $this->get_account_data( $account );
153
  $api = $this->get_api( $account_data['app_id'], $account_data['api_key'] );
154
  $page = 0;
155
  $lists = array();
156
- $response = array(
157
- 'error' => false,
158
- 'html' => ''
159
  );
160
-
161
  if ( isset( $api->error ) ) {
162
  $response['error'] = $api->error;
163
- }
164
- else {
165
-
166
  while ( true ) {
167
-
168
  $result = $api->dsQuery(
169
  'ContactGroup',
170
  1000,
171
  $page,
172
- array( 'Id' => '%' ),
 
 
173
  array( 'Id', 'GroupName' )
174
  );
175
-
176
  $lists = array_merge( $lists, $result );
177
-
178
  if ( count( $result ) < 1000 ) {
179
  break;
180
  }
181
-
182
  $page ++;
183
  }
184
-
185
  $response['html'] = $this->render_list_field( $lists, $settings );
186
  }
187
-
188
  return $response;
189
  }
190
 
191
  /**
192
- * Render markup for the list field.
193
  *
194
  * @since 1.5.7
195
  * @param array $lists List data from the API.
196
  * @param object $settings Saved module settings.
197
  * @return string The markup for the list field.
198
  * @access private
199
- */
200
- private function render_list_field( $lists, $settings )
201
- {
202
  ob_start();
203
-
204
- $options = array( '' => __( 'Choose...', 'fl-builder' ) );
205
-
 
 
206
  foreach ( $lists as $list ) {
207
  $options[ $list['Id'] ] = $list['GroupName'];
208
  }
209
-
210
  FLBuilder::render_settings_field( 'list_id', array(
211
  'row_class' => 'fl-builder-service-field-row',
212
  'class' => 'fl-builder-service-list-select',
@@ -214,14 +208,14 @@ final class FLBuilderServiceInfusionsoft extends FLBuilderService {
214
  'label' => _x( 'List', 'An email list from a third party provider.', 'fl-builder' ),
215
  'options' => $options,
216
  'preview' => array(
217
- 'type' => 'none'
218
- )
219
- ), $settings);
220
-
221
  return ob_get_clean();
222
  }
223
 
224
- /**
225
  * Subscribe an email address to Infusionsoft.
226
  *
227
  * @since 1.5.7
@@ -231,70 +225,67 @@ final class FLBuilderServiceInfusionsoft extends FLBuilderService {
231
  * @return array {
232
  * @type bool|string $error The error message or false if no error.
233
  * }
234
- */
235
- public function subscribe( $settings, $email, $name = false )
236
- {
237
  $account_data = $this->get_account_data( $settings->service_account );
238
- $response = array( 'error' => false );
 
 
239
  $data = array();
240
-
241
  if ( ! $account_data ) {
242
  $response['error'] = __( 'There was an error subscribing to Infusionsoft. The account is no longer connected.', 'fl-builder' );
243
- }
244
- else {
245
-
246
  $api = $this->get_api( $account_data['app_id'], $account_data['api_key'] );
247
-
248
  if ( isset( $api->error ) ) {
249
  $response['error'] = $api->error;
250
- }
251
- else {
252
-
253
  if ( $name ) {
254
-
255
  $names = explode( ' ', $name );
256
-
257
  if ( isset( $names[0] ) && isset( $names[1] ) ) {
258
- $data = array(
259
  'FirstName' => $names[0],
260
  'LastName' => $names[1],
261
- 'Email' => $email
262
  );
263
- }
264
- else {
265
- $data = array(
266
  'FirstName' => $name,
267
- 'Email' => $email
268
  );
269
  }
270
- }
271
- else {
272
- $data = array( 'Email' => $email );
 
273
  }
274
-
275
  try {
276
-
277
  $contact = $api->findByEmail( $email, array( 'Id' ) );
278
-
279
  if ( isset( $contact[0] ) && ! empty( $contact[0]['Id'] ) ) {
280
  $contact_id = $contact[0]['Id'];
281
  $api->updateCon( $contact_id, $data );
282
  $group = $api->grpAssign( $contact[0]['Id'], $settings->list_id );
283
- }
284
- else {
285
  $contact_id = $api->addCon( $data );
286
  $group_add = $api->grpAssign( $contact_id, $settings->list_id );
287
  }
288
- }
289
- catch ( iSDKException $e ) {
290
  $response['error'] = sprintf(
291
  __( 'There was an error subscribing to Infusionsoft. %s', 'fl-builder' ),
292
  $e->getMessage()
293
  );
294
  }
295
- }
296
- }
297
-
298
  return $response;
299
  }
300
- }
12
  *
13
  * @since 1.5.7
14
  * @var string $id
15
+ */
16
  public $id = 'infusionsoft';
17
 
18
  /**
19
  * @since 1.5.7
20
  * @var object $api_instance
21
  * @access private
22
+ */
23
  private $api_instance = null;
24
 
25
  /**
29
  * @param string $app_id A valid app ID.
30
  * @param string $api_key A valid API key.
31
  * @return object The API instance.
32
+ */
33
+ public function get_api( $app_id, $api_key ) {
 
34
  if ( $this->api_instance ) {
35
  return $this->api_instance;
36
  }
37
  if ( ! class_exists( 'iSDK' ) ) {
38
  require_once FL_BUILDER_DIR . 'includes/vendor/infusionsoft/isdk.php';
39
  }
40
+
41
  try {
42
  $this->api_instance = new iSDK();
43
  $this->api_instance->cfgCon( $app_id, $api_key, 'throw' );
44
+ } catch ( iSDKException $e ) {
 
45
  $this->api_instance = new stdClass();
46
  $this->api_instance->error = sprintf(
47
  __( 'There was an error connecting to Infusionsoft. %s', 'fl-builder' ),
48
  $e->getMessage()
49
  );
50
  }
51
+
52
  return $this->api_instance;
53
  }
54
+
55
  /**
56
  * Test the API connection.
57
  *
64
  * @type bool|string $error The error message or false if no error.
65
  * @type array $data An array of data used to make the connection.
66
  * }
67
+ */
68
+ public function connect( $fields = array() ) {
69
+ $response = array(
 
70
  'error' => false,
71
+ 'data' => array(),
72
  );
73
+
74
  // Make sure we have an API key.
75
  if ( ! isset( $fields['api_key'] ) || empty( $fields['api_key'] ) ) {
76
  $response['error'] = __( 'Error: You must provide an API key.', 'fl-builder' );
77
+ } // End if().
78
+ elseif ( ! isset( $fields['app_id'] ) || empty( $fields['app_id'] ) ) {
 
79
  $response['error'] = __( 'Error: You must provide an app ID.', 'fl-builder' );
80
+ } // Try to connect and store the connection data.
 
81
  else {
82
+
83
  $api = $this->get_api( $fields['app_id'], $fields['api_key'] );
84
+
85
  if ( isset( $api->error ) ) {
86
  $response['error'] = $api->error;
87
+ } else {
88
+ $response['data'] = array(
 
89
  'app_id' => $fields['app_id'],
90
+ 'api_key' => $fields['api_key'],
91
  );
92
  }
93
  }
94
+
95
  return $response;
96
  }
97
 
100
  *
101
  * @since 1.5.7
102
  * @return string The connection settings markup.
103
+ */
104
+ public function render_connect_settings() {
 
105
  ob_start();
106
+
107
  FLBuilder::render_settings_field( 'app_id', array(
108
  'row_class' => 'fl-builder-service-connect-row',
109
  'class' => 'fl-builder-service-connect-input',
111
  'label' => __( 'App ID', 'fl-builder' ),
112
  'help' => __( 'Your App ID can be found in the URL for your account. For example, if the URL for your account is myaccount.infusionsoft.com, your App ID would be <strong>myaccount</strong>.', 'fl-builder' ),
113
  'preview' => array(
114
+ 'type' => 'none',
115
+ ),
116
  ));
117
+
118
  FLBuilder::render_settings_field( 'api_key', array(
119
  'row_class' => 'fl-builder-service-connect-row',
120
  'class' => 'fl-builder-service-connect-input',
122
  'label' => __( 'API Key', 'fl-builder' ),
123
  'help' => __( 'Your API key can be found in your Infusionsoft account under Admin > Settings > Application > API > Encrypted Key.', 'fl-builder' ),
124
  'preview' => array(
125
+ 'type' => 'none',
126
+ ),
127
  ));
128
+
129
  return ob_get_clean();
130
  }
131
 
132
  /**
133
+ * Render the markup for service specific fields.
134
  *
135
  * @since 1.5.7
136
  * @param string $account The name of the saved account.
139
  * @type bool|string $error The error message or false if no error.
140
  * @type string $html The field markup.
141
  * }
142
+ */
143
+ public function render_fields( $account, $settings ) {
 
144
  $account_data = $this->get_account_data( $account );
145
  $api = $this->get_api( $account_data['app_id'], $account_data['api_key'] );
146
  $page = 0;
147
  $lists = array();
148
+ $response = array(
149
+ 'error' => false,
150
+ 'html' => '',
151
  );
152
+
153
  if ( isset( $api->error ) ) {
154
  $response['error'] = $api->error;
155
+ } else {
156
+
 
157
  while ( true ) {
158
+
159
  $result = $api->dsQuery(
160
  'ContactGroup',
161
  1000,
162
  $page,
163
+ array(
164
+ 'Id' => '%',
165
+ ),
166
  array( 'Id', 'GroupName' )
167
  );
168
+
169
  $lists = array_merge( $lists, $result );
170
+
171
  if ( count( $result ) < 1000 ) {
172
  break;
173
  }
174
+
175
  $page ++;
176
  }
177
+
178
  $response['html'] = $this->render_list_field( $lists, $settings );
179
  }
180
+
181
  return $response;
182
  }
183
 
184
  /**
185
+ * Render markup for the list field.
186
  *
187
  * @since 1.5.7
188
  * @param array $lists List data from the API.
189
  * @param object $settings Saved module settings.
190
  * @return string The markup for the list field.
191
  * @access private
192
+ */
193
+ private function render_list_field( $lists, $settings ) {
 
194
  ob_start();
195
+
196
+ $options = array(
197
+ '' => __( 'Choose...', 'fl-builder' ),
198
+ );
199
+
200
  foreach ( $lists as $list ) {
201
  $options[ $list['Id'] ] = $list['GroupName'];
202
  }
203
+
204
  FLBuilder::render_settings_field( 'list_id', array(
205
  'row_class' => 'fl-builder-service-field-row',
206
  'class' => 'fl-builder-service-list-select',
208
  'label' => _x( 'List', 'An email list from a third party provider.', 'fl-builder' ),
209
  'options' => $options,
210
  'preview' => array(
211
+ 'type' => 'none',
212
+ ),
213
+ ), $settings);
214
+
215
  return ob_get_clean();
216
  }
217
 
218
+ /**
219
  * Subscribe an email address to Infusionsoft.
220
  *
221
  * @since 1.5.7
225
  * @return array {
226
  * @type bool|string $error The error message or false if no error.
227
  * }
228
+ */
229
+ public function subscribe( $settings, $email, $name = false ) {
 
230
  $account_data = $this->get_account_data( $settings->service_account );
231
+ $response = array(
232
+ 'error' => false,
233
+ );
234
  $data = array();
235
+
236
  if ( ! $account_data ) {
237
  $response['error'] = __( 'There was an error subscribing to Infusionsoft. The account is no longer connected.', 'fl-builder' );
238
+ } else {
239
+
 
240
  $api = $this->get_api( $account_data['app_id'], $account_data['api_key'] );
241
+
242
  if ( isset( $api->error ) ) {
243
  $response['error'] = $api->error;
244
+ } else {
245
+
 
246
  if ( $name ) {
247
+
248
  $names = explode( ' ', $name );
249
+
250
  if ( isset( $names[0] ) && isset( $names[1] ) ) {
251
+ $data = array(
252
  'FirstName' => $names[0],
253
  'LastName' => $names[1],
254
+ 'Email' => $email,
255
  );
256
+ } else {
257
+ $data = array(
 
258
  'FirstName' => $name,
259
+ 'Email' => $email,
260
  );
261
  }
262
+ } else {
263
+ $data = array(
264
+ 'Email' => $email,
265
+ );
266
  }
267
+
268
  try {
269
+
270
  $contact = $api->findByEmail( $email, array( 'Id' ) );
271
+
272
  if ( isset( $contact[0] ) && ! empty( $contact[0]['Id'] ) ) {
273
  $contact_id = $contact[0]['Id'];
274
  $api->updateCon( $contact_id, $data );
275
  $group = $api->grpAssign( $contact[0]['Id'], $settings->list_id );
276
+ } else {
 
277
  $contact_id = $api->addCon( $data );
278
  $group_add = $api->grpAssign( $contact_id, $settings->list_id );
279
  }
280
+ } catch ( iSDKException $e ) {
 
281
  $response['error'] = sprintf(
282
  __( 'There was an error subscribing to Infusionsoft. %s', 'fl-builder' ),
283
  $e->getMessage()
284
  );
285
  }
286
+ }// End if().
287
+ }// End if().
288
+
289
  return $response;
290
  }
291
+ }
classes/class-fl-builder-service-madmimi.php CHANGED
@@ -12,14 +12,14 @@ final class FLBuilderServiceMadMimi extends FLBuilderService {
12
  *
13
  * @since 1.5.2
14
  * @var string $id
15
- */
16
  public $id = 'madmimi';
17
 
18
  /**
19
  * @since 1.5.2
20
  * @var object $api_instance
21
  * @access private
22
- */
23
  private $api_instance = null;
24
 
25
  /**
@@ -29,21 +29,20 @@ final class FLBuilderServiceMadMimi extends FLBuilderService {
29
  * @param string $api_email The email address associated with the API key.
30
  * @param string $api_key A valid API key.
31
  * @return object The API instance.
32
- */
33
- public function get_api( $api_email, $api_key )
34
- {
35
  if ( $this->api_instance ) {
36
  return $this->api_instance;
37
  }
38
  if ( ! class_exists( 'MadMimi' ) ) {
39
  require_once FL_BUILDER_DIR . 'includes/vendor/madmimi/MadMimi.class.php';
40
  }
41
-
42
  $this->api_instance = new MadMimi( $api_email, $api_key );
43
-
44
  return $this->api_instance;
45
  }
46
-
47
  /**
48
  * Test the API connection.
49
  *
@@ -56,40 +55,36 @@ final class FLBuilderServiceMadMimi 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 email address.
68
  if ( ! isset( $fields['api_email'] ) || empty( $fields['api_email'] ) ) {
69
  $response['error'] = __( 'Error: You must provide an email address.', '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_email'], $fields['api_key'] );
79
-
80
  libxml_use_internal_errors( true );
81
 
82
  if ( ! simplexml_load_string( $api->Lists() ) ) {
83
  $response['error'] = __( 'Unable to connect to Mad Mimi. Please check your credentials.', 'fl-builder' );
84
- }
85
- else {
86
- $response['data'] = array(
87
  'api_email' => $fields['api_email'],
88
- 'api_key' => $fields['api_key']
89
  );
90
  }
91
  }
92
-
93
  return $response;
94
  }
95
 
@@ -98,11 +93,10 @@ final class FLBuilderServiceMadMimi extends FLBuilderService {
98
  *
99
  * @since 1.5.2
100
  * @return string The connection settings markup.
101
- */
102
- public function render_connect_settings()
103
- {
104
  ob_start();
105
-
106
  FLBuilder::render_settings_field( 'api_email', array(
107
  'row_class' => 'fl-builder-service-connect-row',
108
  'class' => 'fl-builder-service-connect-input',
@@ -110,10 +104,10 @@ final class FLBuilderServiceMadMimi extends FLBuilderService {
110
  'label' => __( 'Email Address', 'fl-builder' ),
111
  'help' => __( 'The email address associated with your Mad Mimi account.', 'fl-builder' ),
112
  'preview' => array(
113
- 'type' => 'none'
114
- )
115
- ));
116
-
117
  FLBuilder::render_settings_field( 'api_key', array(
118
  'row_class' => 'fl-builder-service-connect-row',
119
  'class' => 'fl-builder-service-connect-input',
@@ -121,15 +115,15 @@ final class FLBuilderServiceMadMimi extends FLBuilderService {
121
  'label' => __( 'API Key', 'fl-builder' ),
122
  'help' => __( 'Your API key can be found in your Mad Mimi account under Account > Settings &amp; Billing > API.', 'fl-builder' ),
123
  'preview' => array(
124
- 'type' => 'none'
125
- )
126
- ));
127
-
128
  return ob_get_clean();
129
  }
130
 
131
  /**
132
- * Render the markup for service specific fields.
133
  *
134
  * @since 1.5.2
135
  * @param string $account The name of the saved account.
@@ -138,49 +132,48 @@ final class FLBuilderServiceMadMimi extends FLBuilderService {
138
  * @type bool|string $error The error message or false if no error.
139
  * @type string $html The field markup.
140
  * }
141
- */
142
- public function render_fields( $account, $settings )
143
- {
144
  $account_data = $this->get_account_data( $account );
145
  $api = $this->get_api( $account_data['api_email'], $account_data['api_key'] );
146
- $response = array(
147
- 'error' => false,
148
- 'html' => ''
149
  );
150
-
151
  libxml_use_internal_errors( true );
152
 
153
  $result = simplexml_load_string( $api->Lists() );
154
-
155
  if ( ! $result ) {
156
  $response['error'] = __( 'There was a problem retrieving your lists. Please check your API credentials.', 'fl-builder' );
157
- }
158
- else {
159
  $response['html'] = $this->render_list_field( $result, $settings );
160
  }
161
-
162
  return $response;
163
  }
164
 
165
  /**
166
- * Render markup for the list field.
167
  *
168
  * @since 1.5.2
169
  * @param array $lists List data from the API.
170
  * @param object $settings Saved module settings.
171
  * @return string The markup for the list field.
172
  * @access private
173
- */
174
- private function render_list_field( $lists, $settings )
175
- {
176
  ob_start();
177
-
178
- $options = array( '' => __( 'Choose...', 'fl-builder' ) );
179
-
 
 
180
  foreach ( $lists->list as $list ) {
181
- $options[ ( string ) $list['id'] ] = $list['name'];
182
  }
183
-
184
  FLBuilder::render_settings_field( 'list_id', array(
185
  'row_class' => 'fl-builder-service-field-row',
186
  'class' => 'fl-builder-service-list-select',
@@ -188,14 +181,14 @@ final class FLBuilderServiceMadMimi extends FLBuilderService {
188
  'label' => _x( 'List', 'An email list from a third party provider.', 'fl-builder' ),
189
  'options' => $options,
190
  'preview' => array(
191
- 'type' => 'none'
192
- )
193
- ), $settings);
194
-
195
  return ob_get_clean();
196
  }
197
 
198
- /**
199
  * Subscribe an email address to Mad Mimi.
200
  *
201
  * @since 1.5.2
@@ -205,27 +198,27 @@ final class FLBuilderServiceMadMimi extends FLBuilderService {
205
  * @return array {
206
  * @type bool|string $error The error message or false if no error.
207
  * }
208
- */
209
- public function subscribe( $settings, $email, $name = false )
210
- {
211
  $account_data = $this->get_account_data( $settings->service_account );
212
- $response = array( 'error' => false );
213
-
 
 
214
  if ( ! $account_data ) {
215
  $response['error'] = __( 'There was an error subscribing to Mad Mimi. The account is no longer connected.', 'fl-builder' );
216
- }
217
- else {
218
-
219
  $api = $this->get_api( $account_data['api_email'], $account_data['api_key'] );
220
- $data = array(
221
  'email' => $email,
222
- 'add_list' => $settings->list_id
223
  );
224
-
225
  if ( $name ) {
226
-
227
  $names = explode( ' ', $name );
228
-
229
  if ( isset( $names[0] ) ) {
230
  $data['firstName'] = $names[0];
231
  }
@@ -233,16 +226,16 @@ final class FLBuilderServiceMadMimi extends FLBuilderService {
233
  $data['lastName'] = $names[1];
234
  }
235
  }
236
-
237
  ob_start();
238
  $api->AddUser( $data, true );
239
  $request = ob_get_clean();
240
-
241
  if ( stristr( $request, 'Unable to authenticate' ) ) {
242
  $response['error'] = __( 'There was an error subscribing to Mad Mimi. The account is no longer connected.', 'fl-builder' );
243
  }
244
  }
245
-
246
  return $response;
247
  }
248
- }
12
  *
13
  * @since 1.5.2
14
  * @var string $id
15
+ */
16
  public $id = 'madmimi';
17
 
18
  /**
19
  * @since 1.5.2
20
  * @var object $api_instance
21
  * @access private
22
+ */
23
  private $api_instance = null;
24
 
25
  /**
29
  * @param string $api_email The email address associated with the API key.
30
  * @param string $api_key A valid API key.
31
  * @return object The API instance.
32
+ */
33
+ public function get_api( $api_email, $api_key ) {
 
34
  if ( $this->api_instance ) {
35
  return $this->api_instance;
36
  }
37
  if ( ! class_exists( 'MadMimi' ) ) {
38
  require_once FL_BUILDER_DIR . 'includes/vendor/madmimi/MadMimi.class.php';
39
  }
40
+
41
  $this->api_instance = new MadMimi( $api_email, $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 email address.
66
  if ( ! isset( $fields['api_email'] ) || empty( $fields['api_email'] ) ) {
67
  $response['error'] = __( 'Error: You must provide an email address.', '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_email'], $fields['api_key'] );
75
+
76
  libxml_use_internal_errors( true );
77
 
78
  if ( ! simplexml_load_string( $api->Lists() ) ) {
79
  $response['error'] = __( 'Unable to connect to Mad Mimi. Please check your credentials.', 'fl-builder' );
80
+ } else {
81
+ $response['data'] = array(
 
82
  'api_email' => $fields['api_email'],
83
+ 'api_key' => $fields['api_key'],
84
  );
85
  }
86
  }
87
+
88
  return $response;
89
  }
90
 
93
  *
94
  * @since 1.5.2
95
  * @return string The connection settings markup.
96
+ */
97
+ public function render_connect_settings() {
 
98
  ob_start();
99
+
100
  FLBuilder::render_settings_field( 'api_email', array(
101
  'row_class' => 'fl-builder-service-connect-row',
102
  'class' => 'fl-builder-service-connect-input',
104
  'label' => __( 'Email Address', 'fl-builder' ),
105
  'help' => __( 'The email address associated with your Mad Mimi account.', 'fl-builder' ),
106
  'preview' => array(
107
+ 'type' => 'none',
108
+ ),
109
+ ));
110
+
111
  FLBuilder::render_settings_field( 'api_key', array(
112
  'row_class' => 'fl-builder-service-connect-row',
113
  'class' => 'fl-builder-service-connect-input',
115
  'label' => __( 'API Key', 'fl-builder' ),
116
  'help' => __( 'Your API key can be found in your Mad Mimi account under Account > Settings &amp; Billing > API.', 'fl-builder' ),
117
  'preview' => array(
118
+ 'type' => 'none',
119
+ ),
120
+ ));
121
+
122
  return ob_get_clean();
123
  }
124
 
125
  /**
126
+ * Render the markup for service specific fields.
127
  *
128
  * @since 1.5.2
129
  * @param string $account The name of the saved account.
132
  * @type bool|string $error The error message or false if no error.
133
  * @type string $html The field markup.
134
  * }
135
+ */
136
+ public function render_fields( $account, $settings ) {
 
137
  $account_data = $this->get_account_data( $account );
138
  $api = $this->get_api( $account_data['api_email'], $account_data['api_key'] );
139
+ $response = array(
140
+ 'error' => false,
141
+ 'html' => '',
142
  );
143
+
144
  libxml_use_internal_errors( true );
145
 
146
  $result = simplexml_load_string( $api->Lists() );
147
+
148
  if ( ! $result ) {
149
  $response['error'] = __( 'There was a problem retrieving your lists. Please check your API credentials.', 'fl-builder' );
150
+ } else {
 
151
  $response['html'] = $this->render_list_field( $result, $settings );
152
  }
153
+
154
  return $response;
155
  }
156
 
157
  /**
158
+ * Render markup for the list field.
159
  *
160
  * @since 1.5.2
161
  * @param array $lists List data from the API.
162
  * @param object $settings Saved module settings.
163
  * @return string The markup for the list field.
164
  * @access private
165
+ */
166
+ private function render_list_field( $lists, $settings ) {
 
167
  ob_start();
168
+
169
+ $options = array(
170
+ '' => __( 'Choose...', 'fl-builder' ),
171
+ );
172
+
173
  foreach ( $lists->list as $list ) {
174
+ $options[ (string) $list['id'] ] = $list['name'];
175
  }
176
+
177
  FLBuilder::render_settings_field( 'list_id', array(
178
  'row_class' => 'fl-builder-service-field-row',
179
  'class' => 'fl-builder-service-list-select',
181
  'label' => _x( 'List', 'An email list from a third party provider.', 'fl-builder' ),
182
  'options' => $options,
183
  'preview' => array(
184
+ 'type' => 'none',
185
+ ),
186
+ ), $settings);
187
+
188
  return ob_get_clean();
189
  }
190
 
191
+ /**
192
  * Subscribe an email address to Mad Mimi.
193
  *
194
  * @since 1.5.2
198
  * @return array {
199
  * @type bool|string $error The error message or false if no error.
200
  * }
201
+ */
202
+ public function subscribe( $settings, $email, $name = false ) {
 
203
  $account_data = $this->get_account_data( $settings->service_account );
204
+ $response = array(
205
+ 'error' => false,
206
+ );
207
+
208
  if ( ! $account_data ) {
209
  $response['error'] = __( 'There was an error subscribing to Mad Mimi. The account is no longer connected.', 'fl-builder' );
210
+ } else {
211
+
 
212
  $api = $this->get_api( $account_data['api_email'], $account_data['api_key'] );
213
+ $data = array(
214
  'email' => $email,
215
+ 'add_list' => $settings->list_id,
216
  );
217
+
218
  if ( $name ) {
219
+
220
  $names = explode( ' ', $name );
221
+
222
  if ( isset( $names[0] ) ) {
223
  $data['firstName'] = $names[0];
224
  }
226
  $data['lastName'] = $names[1];
227
  }
228
  }
229
+
230
  ob_start();
231
  $api->AddUser( $data, true );
232
  $request = ob_get_clean();
233
+
234
  if ( stristr( $request, 'Unable to authenticate' ) ) {
235
  $response['error'] = __( 'There was an error subscribing to Mad Mimi. The account is no longer connected.', 'fl-builder' );
236
  }
237
  }
238
+
239
  return $response;
240
  }
241
+ }
classes/class-fl-builder-service-mailchimp.php CHANGED
@@ -12,14 +12,14 @@ final class FLBuilderServiceMailChimp extends FLBuilderService {
12
  *
13
  * @since 1.5.4
14
  * @var string $id
15
- */
16
  public $id = 'mailchimp';
17
 
18
  /**
19
  * @since 1.5.4
20
  * @var object $api_instance
21
  * @access private
22
- */
23
  private $api_instance = null;
24
 
25
  /**
@@ -28,21 +28,20 @@ final class FLBuilderServiceMailChimp extends FLBuilderService {
28
  * @since 1.5.4
29
  * @param string $api_key A valid API key.
30
  * @return object The API instance.
31
- */
32
- public function get_api( $api_key )
33
- {
34
  if ( $this->api_instance ) {
35
  return $this->api_instance;
36
  }
37
  if ( ! class_exists( 'Mailchimp' ) ) {
38
  require_once FL_BUILDER_DIR . 'includes/vendor/mailchimp/mailchimp.php';
39
  }
40
-
41
  $this->api_instance = new Mailchimp( $api_key );
42
-
43
  return $this->api_instance;
44
  }
45
-
46
  /**
47
  * Test the API connection.
48
  *
@@ -54,32 +53,31 @@ final class FLBuilderServiceMailChimp extends FLBuilderService {
54
  * @type bool|string $error The error message or false if no error.
55
  * @type array $data An array of data used to make the connection.
56
  * }
57
- */
58
- public function connect( $fields = array() )
59
- {
60
- $response = array(
61
  'error' => false,
62
- 'data' => array()
63
  );
64
-
65
  // Make sure we have an API key.
66
  if ( ! isset( $fields['api_key'] ) || empty( $fields['api_key'] ) ) {
67
  $response['error'] = __( 'Error: You must provide an API key.', 'fl-builder' );
68
- }
69
- // Try to connect and store the connection data.
70
  else {
71
-
72
  $api = $this->get_api( $fields['api_key'] );
73
 
74
  try {
75
  $api->helper->ping();
76
- $response['data'] = array( 'api_key' => $fields['api_key'] );
77
- }
78
- catch ( Mailchimp_Invalid_ApiKey $e ) {
 
79
  $response['error'] = $e->getMessage();
80
  }
81
  }
82
-
83
  return $response;
84
  }
85
 
@@ -88,11 +86,10 @@ final class FLBuilderServiceMailChimp extends FLBuilderService {
88
  *
89
  * @since 1.5.4
90
  * @return string The connection settings markup.
91
- */
92
- public function render_connect_settings()
93
- {
94
  ob_start();
95
-
96
  FLBuilder::render_settings_field( 'api_key', array(
97
  'row_class' => 'fl-builder-service-connect-row',
98
  'class' => 'fl-builder-service-connect-input',
@@ -100,15 +97,15 @@ final class FLBuilderServiceMailChimp extends FLBuilderService {
100
  'label' => __( 'API Key', 'fl-builder' ),
101
  'help' => __( 'Your API key can be found in your MailChimp account under Account > Extras > API Keys.', 'fl-builder' ),
102
  'preview' => array(
103
- 'type' => 'none'
104
- )
105
- ));
106
-
107
  return ob_get_clean();
108
  }
109
 
110
  /**
111
- * Render the markup for service specific fields.
112
  *
113
  * @since 1.5.4
114
  * @param string $account The name of the saved account.
@@ -117,69 +114,66 @@ final class FLBuilderServiceMailChimp extends FLBuilderService {
117
  * @type bool|string $error The error message or false if no error.
118
  * @type string $html The field markup.
119
  * }
120
- */
121
- public function render_fields( $account, $settings )
122
- {
123
  $post_data = FLBuilderModel::get_post_data();
124
  $account_data = $this->get_account_data( $account );
125
  $api = $this->get_api( $account_data['api_key'] );
126
- $response = array(
127
- 'error' => false,
128
- 'html' => ''
129
  );
130
-
131
  // Lists field
132
  try {
133
-
134
  if ( ! isset( $post_data['list_id'] ) ) {
135
  $lists = $api->lists->getList();
136
  $response['html'] .= $this->render_list_field( $lists, $settings );
137
  }
138
- }
139
- catch ( Mailchimp_Error $e ) {
140
  $response['error'] = $e->getMessage();
141
  }
142
-
143
  // Groups field
144
  try {
145
-
146
  if ( isset( $post_data['list_id'] ) || isset( $settings->list_id ) ) {
147
-
148
  if ( isset( $post_data['list_id'] ) ) {
149
  $list_id = $post_data['list_id'];
150
- }
151
- else {
152
  $list_id = $settings->list_id;
153
  }
154
-
155
  $groups = $api->lists->interestGroupings( $list_id );
156
  $response['html'] .= $this->render_groups_field( $list_id, $groups, $settings );
157
  }
158
- }
159
- catch ( Mailchimp_Error $e ) {}
160
-
161
  return $response;
162
  }
163
 
164
  /**
165
- * Render markup for the list field.
166
  *
167
  * @since 1.5.4
168
  * @param array $lists List data from the API.
169
  * @param object $settings Saved module settings.
170
  * @return string The markup for the list field.
171
  * @access private
172
- */
173
- private function render_list_field( $lists, $settings )
174
- {
175
  ob_start();
176
-
177
- $options = array( '' => __( 'Choose...', 'fl-builder' ) );
178
-
 
 
179
  foreach ( $lists['data'] as $list ) {
180
  $options[ $list['id'] ] = $list['name'];
181
  }
182
-
183
  FLBuilder::render_settings_field( 'list_id', array(
184
  'row_class' => 'fl-builder-service-field-row',
185
  'class' => 'fl-builder-service-list-select fl-builder-mailchimp-list-select',
@@ -187,15 +181,15 @@ final class FLBuilderServiceMailChimp extends FLBuilderService {
187
  'label' => _x( 'List', 'An email list from a third party provider.', 'fl-builder' ),
188
  'options' => $options,
189
  'preview' => array(
190
- 'type' => 'none'
191
- )
192
- ), $settings);
193
-
194
  return ob_get_clean();
195
  }
196
 
197
  /**
198
- * Render markup for the groups field.
199
  *
200
  * @since 1.6.0
201
  * @param string $list_id The ID of the list for this groups.
@@ -203,23 +197,24 @@ final class FLBuilderServiceMailChimp extends FLBuilderService {
203
  * @param object $settings Saved module settings.
204
  * @return string The markup for the group field.
205
  * @access private
206
- */
207
- private function render_groups_field( $list_id, $groups, $settings )
208
- {
209
  if ( ! is_array( $groups ) || 0 === count( $groups ) ) {
210
  return;
211
  }
212
-
213
  ob_start();
214
-
215
- $options = array( '' => __( 'No Group', 'fl-builder' ) );
216
-
 
 
217
  foreach ( $groups as $group ) {
218
  foreach ( $group['groups'] as $subgroup ) {
219
  $options[ $list_id . '_' . $group['id'] . '_' . $subgroup['id'] ] = $group['name'] . ' - ' . $subgroup['name'];
220
  }
221
  }
222
-
223
  FLBuilder::render_settings_field( 'groups', array(
224
  'row_class' => 'fl-builder-service-field-row',
225
  'class' => 'fl-builder-mailchimp-group-select',
@@ -228,14 +223,14 @@ final class FLBuilderServiceMailChimp extends FLBuilderService {
228
  'multi-select' => true,
229
  'options' => $options,
230
  'preview' => array(
231
- 'type' => 'none'
232
- )
233
- ), $settings);
234
-
235
  return ob_get_clean();
236
  }
237
 
238
- /**
239
  * Subscribe an email address to MailChimp.
240
  *
241
  * @since 1.5.4
@@ -245,28 +240,30 @@ final class FLBuilderServiceMailChimp extends FLBuilderService {
245
  * @return array {
246
  * @type bool|string $error The error message or false if no error.
247
  * }
248
- */
249
- public function subscribe( $settings, $email, $name = false )
250
- {
251
  $account_data = $this->get_account_data( $settings->service_account );
252
- $response = array( 'error' => false );
253
-
 
 
254
  if ( ! $account_data ) {
255
  $response['error'] = __( 'There was an error subscribing to MailChimp. The account is no longer connected.', 'fl-builder' );
256
- }
257
- else {
258
-
259
  $api = $this->get_api( $account_data['api_key'] );
260
  $double = apply_filters( 'fl_builder_mailchimp_double_option', true );
261
  $welcome = apply_filters( 'fl_builder_mailchimp_welcome', true );
262
- $email = array( 'email' => $email );
 
 
263
  $data = array();
264
-
265
  // Name
266
  if ( $name ) {
267
-
268
  $names = explode( ' ', $name );
269
-
270
  if ( isset( $names[0] ) ) {
271
  $data['FNAME'] = $names[0];
272
  }
@@ -274,87 +271,84 @@ final class FLBuilderServiceMailChimp extends FLBuilderService {
274
  $data['LNAME'] = $names[1];
275
  }
276
  }
277
-
278
  // Groups
279
  if ( isset( $settings->groups ) && is_array( $settings->groups ) ) {
280
-
281
  $groups = array();
282
-
283
  // Build the array of saved group data.
284
  for ( $i = 0; $i < count( $settings->groups ); $i++ ) {
285
-
286
  if ( empty( $settings->groups[ $i ] ) ) {
287
  continue;
288
  }
289
-
290
  $group_data = explode( '_', $settings->groups[ $i ] );
291
-
292
  if ( $group_data[0] != $settings->list_id ) {
293
  continue;
294
  }
295
  if ( ! isset( $groups[ $group_data[1] ] ) ) {
296
  $groups[ $group_data[1] ] = array();
297
  }
298
-
299
  $groups[ $group_data[1] ][] = $group_data[2];
300
  }
301
-
302
  // Get the subgroup names from the API and add to the $data array.
303
  if ( count( $groups ) > 0 ) {
304
-
305
  $groups_result = $api->lists->interestGroupings( $settings->list_id );
306
-
307
  if ( is_array( $groups_result ) && count( $groups_result ) > 0 ) {
308
-
309
  foreach ( $groups_result as $group ) {
310
-
311
  if ( ! isset( $groups[ $group['id'] ] ) ) {
312
  continue;
313
  }
314
-
315
  $subgroup_names = array();
316
-
317
  foreach ( $group['groups'] as $subgroup ) {
318
-
319
  if ( in_array( $subgroup['id'], $groups[ $group['id'] ] ) ) {
320
  $subgroup_names[] = $subgroup['name'];
321
  }
322
  }
323
-
324
  if ( 0 === count( $subgroup_names ) ) {
325
  unset( $groups[ $group['id'] ] );
326
- }
327
- else {
328
  $groups[ $group['id'] ] = $subgroup_names;
329
  }
330
  }
331
-
332
  $i = 0;
333
-
334
  foreach ( $groups as $group_id => $subgroups ) {
335
  $data['groupings'][ $i ]['id'] = $group_id;
336
  $data['groupings'][ $i ]['groups'] = $subgroups;
337
  $i++;
338
  }
339
  }
340
- }
341
- }
342
-
343
  // Subscribe
344
  try {
345
  $api->lists->subscribe( $settings->list_id, $email, $data, 'html', (bool) $double, true, false, (bool) $welcome );
346
- }
347
- catch( Mailchimp_List_AlreadySubscribed $e ) {
348
  return $response;
349
- }
350
- catch ( Mailchimp_Error $e ) {
351
  $response['error'] = sprintf(
352
  __( 'There was an error subscribing to MailChimp. %s', 'fl-builder' ),
353
  $e->getMessage()
354
  );
355
  }
356
- }
357
-
358
  return $response;
359
  }
360
- }
12
  *
13
  * @since 1.5.4
14
  * @var string $id
15
+ */
16
  public $id = 'mailchimp';
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 $api_key A valid API key.
30
  * @return object The API instance.
31
+ */
32
+ public function get_api( $api_key ) {
 
33
  if ( $this->api_instance ) {
34
  return $this->api_instance;
35
  }
36
  if ( ! class_exists( 'Mailchimp' ) ) {
37
  require_once FL_BUILDER_DIR . 'includes/vendor/mailchimp/mailchimp.php';
38
  }
39
+
40
  $this->api_instance = new Mailchimp( $api_key );
41
+
42
  return $this->api_instance;
43
  }
44
+
45
  /**
46
  * Test the API connection.
47
  *
53
  * @type bool|string $error The error message or false if no error.
54
  * @type array $data An array of data used to make the connection.
55
  * }
56
+ */
57
+ public function connect( $fields = array() ) {
58
+ $response = array(
 
59
  'error' => false,
60
+ 'data' => array(),
61
  );
62
+
63
  // Make sure we have an API key.
64
  if ( ! isset( $fields['api_key'] ) || empty( $fields['api_key'] ) ) {
65
  $response['error'] = __( 'Error: You must provide an API key.', 'fl-builder' );
66
+ } // End if().
 
67
  else {
68
+
69
  $api = $this->get_api( $fields['api_key'] );
70
 
71
  try {
72
  $api->helper->ping();
73
+ $response['data'] = array(
74
+ 'api_key' => $fields['api_key'],
75
+ );
76
+ } catch ( Mailchimp_Invalid_ApiKey $e ) {
77
  $response['error'] = $e->getMessage();
78
  }
79
  }
80
+
81
  return $response;
82
  }
83
 
86
  *
87
  * @since 1.5.4
88
  * @return string The connection settings markup.
89
+ */
90
+ public function render_connect_settings() {
 
91
  ob_start();
92
+
93
  FLBuilder::render_settings_field( 'api_key', array(
94
  'row_class' => 'fl-builder-service-connect-row',
95
  'class' => 'fl-builder-service-connect-input',
97
  'label' => __( 'API Key', 'fl-builder' ),
98
  'help' => __( 'Your API key can be found in your MailChimp account under Account > Extras > API Keys.', 'fl-builder' ),
99
  'preview' => array(
100
+ 'type' => 'none',
101
+ ),
102
+ ));
103
+
104
  return ob_get_clean();
105
  }
106
 
107
  /**
108
+ * Render the markup for service specific fields.
109
  *
110
  * @since 1.5.4
111
  * @param string $account The name of the saved account.
114
  * @type bool|string $error The error message or false if no error.
115
  * @type string $html The field markup.
116
  * }
117
+ */
118
+ public function render_fields( $account, $settings ) {
 
119
  $post_data = FLBuilderModel::get_post_data();
120
  $account_data = $this->get_account_data( $account );
121
  $api = $this->get_api( $account_data['api_key'] );
122
+ $response = array(
123
+ 'error' => false,
124
+ 'html' => '',
125
  );
126
+
127
  // Lists field
128
  try {
129
+
130
  if ( ! isset( $post_data['list_id'] ) ) {
131
  $lists = $api->lists->getList();
132
  $response['html'] .= $this->render_list_field( $lists, $settings );
133
  }
134
+ } catch ( Mailchimp_Error $e ) {
 
135
  $response['error'] = $e->getMessage();
136
  }
137
+
138
  // Groups field
139
  try {
140
+
141
  if ( isset( $post_data['list_id'] ) || isset( $settings->list_id ) ) {
142
+
143
  if ( isset( $post_data['list_id'] ) ) {
144
  $list_id = $post_data['list_id'];
145
+ } else {
 
146
  $list_id = $settings->list_id;
147
  }
148
+
149
  $groups = $api->lists->interestGroupings( $list_id );
150
  $response['html'] .= $this->render_groups_field( $list_id, $groups, $settings );
151
  }
152
+ } catch ( Mailchimp_Error $e ) {}
153
+
 
154
  return $response;
155
  }
156
 
157
  /**
158
+ * Render markup for the list field.
159
  *
160
  * @since 1.5.4
161
  * @param array $lists List data from the API.
162
  * @param object $settings Saved module settings.
163
  * @return string The markup for the list field.
164
  * @access private
165
+ */
166
+ private function render_list_field( $lists, $settings ) {
 
167
  ob_start();
168
+
169
+ $options = array(
170
+ '' => __( 'Choose...', 'fl-builder' ),
171
+ );
172
+
173
  foreach ( $lists['data'] as $list ) {
174
  $options[ $list['id'] ] = $list['name'];
175
  }
176
+
177
  FLBuilder::render_settings_field( 'list_id', array(
178
  'row_class' => 'fl-builder-service-field-row',
179
  'class' => 'fl-builder-service-list-select fl-builder-mailchimp-list-select',
181
  'label' => _x( 'List', 'An email list from a third party provider.', 'fl-builder' ),
182
  'options' => $options,
183
  'preview' => array(
184
+ 'type' => 'none',
185
+ ),
186
+ ), $settings);
187
+
188
  return ob_get_clean();
189
  }
190
 
191
  /**
192
+ * Render markup for the groups field.
193
  *
194
  * @since 1.6.0
195
  * @param string $list_id The ID of the list for this groups.
197
  * @param object $settings Saved module settings.
198
  * @return string The markup for the group field.
199
  * @access private
200
+ */
201
+ private function render_groups_field( $list_id, $groups, $settings ) {
 
202
  if ( ! is_array( $groups ) || 0 === count( $groups ) ) {
203
  return;
204
  }
205
+
206
  ob_start();
207
+
208
+ $options = array(
209
+ '' => __( 'No Group', 'fl-builder' ),
210
+ );
211
+
212
  foreach ( $groups as $group ) {
213
  foreach ( $group['groups'] as $subgroup ) {
214
  $options[ $list_id . '_' . $group['id'] . '_' . $subgroup['id'] ] = $group['name'] . ' - ' . $subgroup['name'];
215
  }
216
  }
217
+
218
  FLBuilder::render_settings_field( 'groups', array(
219
  'row_class' => 'fl-builder-service-field-row',
220
  'class' => 'fl-builder-mailchimp-group-select',
223
  'multi-select' => true,
224
  'options' => $options,
225
  'preview' => array(
226
+ 'type' => 'none',
227
+ ),
228
+ ), $settings);
229
+
230
  return ob_get_clean();
231
  }
232
 
233
+ /**
234
  * Subscribe an email address to MailChimp.
235
  *
236
  * @since 1.5.4
240
  * @return array {
241
  * @type bool|string $error The error message or false if no error.
242
  * }
243
+ */
244
+ public function subscribe( $settings, $email, $name = false ) {
 
245
  $account_data = $this->get_account_data( $settings->service_account );
246
+ $response = array(
247
+ 'error' => false,
248
+ );
249
+
250
  if ( ! $account_data ) {
251
  $response['error'] = __( 'There was an error subscribing to MailChimp. The account is no longer connected.', 'fl-builder' );
252
+ } else {
253
+
 
254
  $api = $this->get_api( $account_data['api_key'] );
255
  $double = apply_filters( 'fl_builder_mailchimp_double_option', true );
256
  $welcome = apply_filters( 'fl_builder_mailchimp_welcome', true );
257
+ $email = array(
258
+ 'email' => $email,
259
+ );
260
  $data = array();
261
+
262
  // Name
263
  if ( $name ) {
264
+
265
  $names = explode( ' ', $name );
266
+
267
  if ( isset( $names[0] ) ) {
268
  $data['FNAME'] = $names[0];
269
  }
271
  $data['LNAME'] = $names[1];
272
  }
273
  }
274
+
275
  // Groups
276
  if ( isset( $settings->groups ) && is_array( $settings->groups ) ) {
277
+
278
  $groups = array();
279
+
280
  // Build the array of saved group data.
281
  for ( $i = 0; $i < count( $settings->groups ); $i++ ) {
282
+
283
  if ( empty( $settings->groups[ $i ] ) ) {
284
  continue;
285
  }
286
+
287
  $group_data = explode( '_', $settings->groups[ $i ] );
288
+
289
  if ( $group_data[0] != $settings->list_id ) {
290
  continue;
291
  }
292
  if ( ! isset( $groups[ $group_data[1] ] ) ) {
293
  $groups[ $group_data[1] ] = array();
294
  }
295
+
296
  $groups[ $group_data[1] ][] = $group_data[2];
297
  }
298
+
299
  // Get the subgroup names from the API and add to the $data array.
300
  if ( count( $groups ) > 0 ) {
301
+
302
  $groups_result = $api->lists->interestGroupings( $settings->list_id );
303
+
304
  if ( is_array( $groups_result ) && count( $groups_result ) > 0 ) {
305
+
306
  foreach ( $groups_result as $group ) {
307
+
308
  if ( ! isset( $groups[ $group['id'] ] ) ) {
309
  continue;
310
  }
311
+
312
  $subgroup_names = array();
313
+
314
  foreach ( $group['groups'] as $subgroup ) {
315
+
316
  if ( in_array( $subgroup['id'], $groups[ $group['id'] ] ) ) {
317
  $subgroup_names[] = $subgroup['name'];
318
  }
319
  }
320
+
321
  if ( 0 === count( $subgroup_names ) ) {
322
  unset( $groups[ $group['id'] ] );
323
+ } else {
 
324
  $groups[ $group['id'] ] = $subgroup_names;
325
  }
326
  }
327
+
328
  $i = 0;
329
+
330
  foreach ( $groups as $group_id => $subgroups ) {
331
  $data['groupings'][ $i ]['id'] = $group_id;
332
  $data['groupings'][ $i ]['groups'] = $subgroups;
333
  $i++;
334
  }
335
  }
336
+ }// End if().
337
+ }// End if().
338
+
339
  // Subscribe
340
  try {
341
  $api->lists->subscribe( $settings->list_id, $email, $data, 'html', (bool) $double, true, false, (bool) $welcome );
342
+ } catch ( Mailchimp_List_AlreadySubscribed $e ) {
 
343
  return $response;
344
+ } catch ( Mailchimp_Error $e ) {
 
345
  $response['error'] = sprintf(
346
  __( 'There was an error subscribing to MailChimp. %s', 'fl-builder' ),
347
  $e->getMessage()
348
  );
349
  }
350
+ }// End if().
351
+
352
  return $response;
353
  }
354
+ }
classes/class-fl-builder-service-mailerlite.php CHANGED
@@ -12,7 +12,7 @@ final class FLBuilderServiceMailerLite extends FLBuilderService {
12
  *
13
  * @since 1.9
14
  * @var string $id
15
- */
16
  public $id = 'mailerlite';
17
 
18
  /**
@@ -27,7 +27,7 @@ final class FLBuilderServiceMailerLite extends FLBuilderService {
27
  * @since 1.9
28
  * @var object $api_instance
29
  * @access private
30
- */
31
  private $api_instance = null;
32
 
33
  /**
@@ -36,22 +36,21 @@ final class FLBuilderServiceMailerLite extends FLBuilderService {
36
  * @since 1.9
37
  * @param string $api_key A valid API token.
38
  * @return object The API instance.
39
- */
40
- public function get_api( $api_key )
41
- {
42
  if ( $this->api_instance ) {
43
  return $this->api_instance;
44
  }
45
  if ( ! class_exists( 'ML_Rest' ) ) {
46
  require_once FL_BUILDER_DIR . 'includes/vendor/mailerlite/ML_Rest.php';
47
  }
48
-
49
  $this->api_instance = new ML_Rest( $api_key );
50
  $this->api_instance->setUrl( $this->api_url );
51
-
52
  return $this->api_instance;
53
  }
54
-
55
  /**
56
  * Test the API connection.
57
  *
@@ -63,34 +62,33 @@ final class FLBuilderServiceMailerLite extends FLBuilderService {
63
  * @type bool|string $error The error message or false if no error.
64
  * @type array $data An array of data used to make the connection.
65
  * }
66
- */
67
- public function connect( $fields = array() )
68
- {
69
- $response = array(
70
  'error' => false,
71
- 'data' => array()
72
  );
73
-
74
  // Make sure we have an API token.
75
  if ( ! isset( $fields['api_key'] ) ) {
76
  $response['error'] = __( 'Error: You must provide an API token.', 'fl-builder' );
77
- }
78
- // Try to connect and store the connection data.
79
  else {
80
 
81
  $api = $this->get_api( $fields['api_key'] );
82
- $api->setPath('groups');
83
  $api->getAll();
84
  $get_api_response = $api->getResponseInfo();
85
 
86
  if ( 200 === $get_api_response['http_code'] ) {
87
- $response['data'] = array('api_key' => $fields['api_key']);
88
- }
89
- else {
90
- $response['error'] = sprintf(__( 'Error: Could not connect to MailerLite. %s', 'fl-builder' ), $get_api_response['http_code']);
91
- }
 
92
  }
93
-
94
  return $response;
95
  }
96
 
@@ -99,11 +97,10 @@ final class FLBuilderServiceMailerLite extends FLBuilderService {
99
  *
100
  * @since 1.9
101
  * @return string The connection settings markup.
102
- */
103
- public function render_connect_settings()
104
- {
105
  ob_start();
106
-
107
  FLBuilder::render_settings_field( 'api_key', array(
108
  'row_class' => 'fl-builder-service-connect-row',
109
  'class' => 'fl-builder-service-connect-input',
@@ -111,15 +108,15 @@ final class FLBuilderServiceMailerLite extends FLBuilderService {
111
  'label' => __( 'API Key', 'fl-builder' ),
112
  'help' => __( 'Found in your MailerLite account under Integrations > Developer API.', 'fl-builder' ),
113
  'preview' => array(
114
- 'type' => 'none'
115
- )
116
  ));
117
 
118
  return ob_get_clean();
119
  }
120
 
121
  /**
122
- * Render the markup for service specific fields.
123
  *
124
  * @since 1.9
125
  * @param string $account The name of the saved account.
@@ -128,47 +125,47 @@ final class FLBuilderServiceMailerLite extends FLBuilderService {
128
  * @type bool|string $error The error message or false if no error.
129
  * @type string $html The field markup.
130
  * }
131
- */
132
- public function render_fields( $account, $settings )
133
- {
134
  $account_data = $this->get_account_data( $account );
135
  $api = $this->get_api( $account_data['api_key'] );
136
- $api->setPath('groups');
137
- $get_lists = json_decode($api->getAll());
138
  $lists = array();
139
 
140
- if ( $get_lists && count($get_lists) > 0 ) {
141
  $lists = $get_lists;
142
  }
143
-
144
- $response = array(
145
- 'error' => false,
146
- 'html' => $this->render_list_field( $lists, $settings )
147
  );
148
-
149
  return $response;
150
  }
151
 
152
  /**
153
- * Render markup for the list field.
154
  *
155
  * @since 1.9
156
  * @param array $lists List data from the API.
157
  * @param object $settings Saved module settings.
158
  * @return string The markup for the list field.
159
  * @access private
160
- */
161
- private function render_list_field( $lists, $settings )
162
- {
163
  ob_start();
164
-
165
- $options = array( '' => __( 'Choose...', 'fl-builder' ) );
 
 
166
  if ( $lists ) {
167
  foreach ( $lists as $list ) {
168
  $options[ $list->id ] = $list->name;
169
  }
170
  }
171
-
172
  FLBuilder::render_settings_field( 'list_id', array(
173
  'row_class' => 'fl-builder-service-field-row',
174
  'class' => 'fl-builder-service-list-select',
@@ -176,14 +173,14 @@ final class FLBuilderServiceMailerLite extends FLBuilderService {
176
  'label' => _x( 'List', 'An email list from a third party provider.', 'fl-builder' ),
177
  'options' => $options,
178
  'preview' => array(
179
- 'type' => 'none'
180
- )
181
- ), $settings);
182
-
183
  return ob_get_clean();
184
  }
185
 
186
- /**
187
  * Subscribe an email address to Drip.
188
  *
189
  * @since 1.9
@@ -193,17 +190,17 @@ final class FLBuilderServiceMailerLite extends FLBuilderService {
193
  * @return array {
194
  * @type bool|string $error The error message or false if no error.
195
  * }
196
- */
197
- public function subscribe( $settings, $email, $name = '' )
198
- {
199
  $account_data = $this->get_account_data( $settings->service_account );
200
- $response = array( 'error' => false );
201
-
 
 
202
  if ( ! $account_data ) {
203
  $response['error'] = __( 'There was an error subscribing to MailerLite. The account is no longer connected.', 'fl-builder' );
204
- }
205
- else {
206
-
207
  $api = $this->get_api( $account_data['api_key'] );
208
 
209
  $data['email'] = $email;
@@ -212,7 +209,7 @@ final class FLBuilderServiceMailerLite extends FLBuilderService {
212
  if ( $name ) {
213
 
214
  $names = explode( ' ', $name );
215
-
216
  if ( isset( $names[0] ) ) {
217
  $data['name'] = $names[0];
218
  }
@@ -229,20 +226,20 @@ final class FLBuilderServiceMailerLite extends FLBuilderService {
229
  echo 'existing email...';
230
  // Update subscriber
231
  $api->setPath('subscribers/'. $search_results[0]->id);
232
-
233
  $response = $api->put($data);
234
  }*/
235
 
236
  // Add new
237
- $api->setPath('groups/'. $settings->list_id .'/subscribers');
238
  $api->add( $data );
239
  $response = $api->getResponseInfo();
240
-
241
  if ( 200 !== $response['http_code'] ) {
242
- $response['error'] = sprintf(__( 'There was an error subscribing to MailerLite. Code: %s', 'fl-builder' ), $response['http_code']);
243
  }
244
- }
245
-
246
  return $response;
247
  }
248
- }
12
  *
13
  * @since 1.9
14
  * @var string $id
15
+ */
16
  public $id = 'mailerlite';
17
 
18
  /**
27
  * @since 1.9
28
  * @var object $api_instance
29
  * @access private
30
+ */
31
  private $api_instance = null;
32
 
33
  /**
36
  * @since 1.9
37
  * @param string $api_key A valid API token.
38
  * @return object The API instance.
39
+ */
40
+ public function get_api( $api_key ) {
 
41
  if ( $this->api_instance ) {
42
  return $this->api_instance;
43
  }
44
  if ( ! class_exists( 'ML_Rest' ) ) {
45
  require_once FL_BUILDER_DIR . 'includes/vendor/mailerlite/ML_Rest.php';
46
  }
47
+
48
  $this->api_instance = new ML_Rest( $api_key );
49
  $this->api_instance->setUrl( $this->api_url );
50
+
51
  return $this->api_instance;
52
  }
53
+
54
  /**
55
  * Test the API connection.
56
  *
62
  * @type bool|string $error The error message or false if no error.
63
  * @type array $data An array of data used to make the connection.
64
  * }
65
+ */
66
+ public function connect( $fields = array() ) {
67
+ $response = array(
 
68
  'error' => false,
69
+ 'data' => array(),
70
  );
71
+
72
  // Make sure we have an API token.
73
  if ( ! isset( $fields['api_key'] ) ) {
74
  $response['error'] = __( 'Error: You must provide an API token.', 'fl-builder' );
75
+ } // End if().
 
76
  else {
77
 
78
  $api = $this->get_api( $fields['api_key'] );
79
+ $api->setPath( 'groups' );
80
  $api->getAll();
81
  $get_api_response = $api->getResponseInfo();
82
 
83
  if ( 200 === $get_api_response['http_code'] ) {
84
+ $response['data'] = array(
85
+ 'api_key' => $fields['api_key'],
86
+ );
87
+ } else {
88
+ $response['error'] = sprintf( __( 'Error: Could not connect to MailerLite. %s', 'fl-builder' ), $get_api_response['http_code'] );
89
+ }
90
  }
91
+
92
  return $response;
93
  }
94
 
97
  *
98
  * @since 1.9
99
  * @return string The connection settings markup.
100
+ */
101
+ public function render_connect_settings() {
 
102
  ob_start();
103
+
104
  FLBuilder::render_settings_field( 'api_key', array(
105
  'row_class' => 'fl-builder-service-connect-row',
106
  'class' => 'fl-builder-service-connect-input',
108
  'label' => __( 'API Key', 'fl-builder' ),
109
  'help' => __( 'Found in your MailerLite account under Integrations > Developer API.', 'fl-builder' ),
110
  'preview' => array(
111
+ 'type' => 'none',
112
+ ),
113
  ));
114
 
115
  return ob_get_clean();
116
  }
117
 
118
  /**
119
+ * Render the markup for service specific fields.
120
  *
121
  * @since 1.9
122
  * @param string $account The name of the saved account.
125
  * @type bool|string $error The error message or false if no error.
126
  * @type string $html The field markup.
127
  * }
128
+ */
129
+ public function render_fields( $account, $settings ) {
 
130
  $account_data = $this->get_account_data( $account );
131
  $api = $this->get_api( $account_data['api_key'] );
132
+ $api->setPath( 'groups' );
133
+ $get_lists = json_decode( $api->getAll() );
134
  $lists = array();
135
 
136
+ if ( $get_lists && count( $get_lists ) > 0 ) {
137
  $lists = $get_lists;
138
  }
139
+
140
+ $response = array(
141
+ 'error' => false,
142
+ 'html' => $this->render_list_field( $lists, $settings ),
143
  );
144
+
145
  return $response;
146
  }
147
 
148
  /**
149
+ * Render markup for the list field.
150
  *
151
  * @since 1.9
152
  * @param array $lists List data from the API.
153
  * @param object $settings Saved module settings.
154
  * @return string The markup for the list field.
155
  * @access private
156
+ */
157
+ private function render_list_field( $lists, $settings ) {
 
158
  ob_start();
159
+
160
+ $options = array(
161
+ '' => __( 'Choose...', 'fl-builder' ),
162
+ );
163
  if ( $lists ) {
164
  foreach ( $lists as $list ) {
165
  $options[ $list->id ] = $list->name;
166
  }
167
  }
168
+
169
  FLBuilder::render_settings_field( 'list_id', array(
170
  'row_class' => 'fl-builder-service-field-row',
171
  'class' => 'fl-builder-service-list-select',
173
  'label' => _x( 'List', 'An email list from a third party provider.', 'fl-builder' ),
174
  'options' => $options,
175
  'preview' => array(
176
+ 'type' => 'none',
177
+ ),
178
+ ), $settings);
179
+
180
  return ob_get_clean();
181
  }
182
 
183
+ /**
184
  * Subscribe an email address to Drip.
185
  *
186
  * @since 1.9
190
  * @return array {
191
  * @type bool|string $error The error message or false if no error.
192
  * }
193
+ */
194
+ public function subscribe( $settings, $email, $name = '' ) {
 
195
  $account_data = $this->get_account_data( $settings->service_account );
196
+ $response = array(
197
+ 'error' => false,
198
+ );
199
+
200
  if ( ! $account_data ) {
201
  $response['error'] = __( 'There was an error subscribing to MailerLite. The account is no longer connected.', 'fl-builder' );
202
+ } else {
203
+
 
204
  $api = $this->get_api( $account_data['api_key'] );
205
 
206
  $data['email'] = $email;
209
  if ( $name ) {
210
 
211
  $names = explode( ' ', $name );
212
+
213
  if ( isset( $names[0] ) ) {
214
  $data['name'] = $names[0];
215
  }
226
  echo 'existing email...';
227
  // Update subscriber
228
  $api->setPath('subscribers/'. $search_results[0]->id);
229
+
230
  $response = $api->put($data);
231
  }*/
232
 
233
  // Add new
234
+ $api->setPath( 'groups/' . $settings->list_id . '/subscribers' );
235
  $api->add( $data );
236
  $response = $api->getResponseInfo();
237
+
238
  if ( 200 !== $response['http_code'] ) {
239
+ $response['error'] = sprintf( __( 'There was an error subscribing to MailerLite. Code: %s', 'fl-builder' ), $response['http_code'] );
240
  }
241
+ }// End if().
242
+
243
  return $response;
244
  }
245
+ }
classes/class-fl-builder-service-mailpoet.php CHANGED
@@ -12,9 +12,9 @@ final class FLBuilderServiceMailPoet extends FLBuilderService {
12
  *
13
  * @since 1.5.4
14
  * @var string $id
15
- */
16
  public $id = 'mailpoet';
17
-
18
  /**
19
  * Test the API connection.
20
  *
@@ -24,14 +24,13 @@ final class FLBuilderServiceMailPoet extends FLBuilderService {
24
  * @type bool|string $error The error message or false if no error.
25
  * @type array $data An array of data used to make the connection.
26
  * }
27
- */
28
- public function connect( $fields = array() )
29
- {
30
- $response = array(
31
  'error' => false,
32
- 'data' => array()
33
  );
34
-
35
  return $response;
36
  }
37
 
@@ -40,14 +39,13 @@ final class FLBuilderServiceMailPoet extends FLBuilderService {
40
  *
41
  * @since 1.5.4
42
  * @return string The connection settings markup.
43
- */
44
- public function render_connect_settings()
45
- {
46
  return '';
47
  }
48
 
49
  /**
50
- * Render the markup for service specific fields.
51
  *
52
  * @since 1.5.4
53
  * @param string $account The name of the saved account.
@@ -56,65 +54,66 @@ final class FLBuilderServiceMailPoet extends FLBuilderService {
56
  * @type bool|string $error The error message or false if no error.
57
  * @type string $html The field markup.
58
  * }
59
- */
60
- public function render_fields( $account, $settings )
61
- {
62
- $response = array(
63
- 'error' => false,
64
- 'html' => ''
65
  );
66
  $lists = array();
67
-
68
  try {
69
  // Mailpoet 2+
70
  if ( class_exists( 'WYSIJA' ) ) {
71
  $list_model = WYSIJA::get( 'list', 'model' );
72
- $lists = $list_model->get( array( 'name', 'list_id' ), array( 'is_enabled' => 1 ) );
73
-
74
- // Mailpoet 3.0
 
 
75
  } elseif ( defined( 'MAILPOET_INITIALIZED' ) && true === MAILPOET_INITIALIZED ) {
76
 
77
  $listing = new MailPoet\Listing\Handler( '\MailPoet\Models\Segment' );
78
  $listing_data = $listing->get();
79
 
80
- if ( isset( $listing_data[ 'items' ] ) ) {
81
- foreach( $listing_data[ 'items' ] as $segment ) {
82
  $lists[] = array(
83
  'list_id' => $segment->id,
84
- 'name' => $segment->name
85
  );
86
  }
87
- }
88
  }
89
 
90
- $response['html'] = self::render_list_field( $lists, $settings );
91
- }
92
- catch ( Exception $e ) {
93
  $response['error'] = __( 'There was an error retrieveing your lists.', 'fl-builder' );
94
  }
95
-
96
  return $response;
97
  }
98
 
99
  /**
100
- * Render markup for the list field.
101
  *
102
  * @since 1.5.4
103
  * @param array $lists List data from the API.
104
  * @param object $settings Saved module settings.
105
  * @return string The markup for the list field.
106
  * @access private
107
- */
108
- private function render_list_field( $lists, $settings )
109
- {
110
  ob_start();
111
-
112
- $options = array( '' => __( 'Choose...', 'fl-builder' ) );
113
-
 
 
114
  foreach ( $lists as $list ) {
115
  $options[ $list['list_id'] ] = $list['name'];
116
  }
117
-
118
  FLBuilder::render_settings_field( 'list_id', array(
119
  'row_class' => 'fl-builder-service-field-row',
120
  'class' => 'fl-builder-service-list-select',
@@ -122,14 +121,14 @@ final class FLBuilderServiceMailPoet extends FLBuilderService {
122
  'label' => _x( 'List', 'An email list from a third party provider.', 'fl-builder' ),
123
  'options' => $options,
124
  'preview' => array(
125
- 'type' => 'none'
126
- )
127
- ), $settings);
128
-
129
  return ob_get_clean();
130
  }
131
 
132
- /**
133
  * Subscribe an email address to MailPoet.
134
  *
135
  * @since 1.5.4
@@ -139,26 +138,28 @@ final class FLBuilderServiceMailPoet extends FLBuilderService {
139
  * @return array {
140
  * @type bool|string $error The error message or false if no error.
141
  * }
142
- */
143
- public function subscribe( $settings, $email, $name = false )
144
- {
145
- $response = array( 'error' => false );
146
- $user = array( 'email' => $email );
147
-
148
- if ( ! class_exists( 'WYSIJA' )
 
 
 
149
  && ( ! defined( 'MAILPOET_INITIALIZED' ) || ( defined( 'MAILPOET_INITIALIZED' ) && false === MAILPOET_INITIALIZED ) )
150
- ) {
151
  $response['error'] = __( 'There was an error subscribing. MailPoet is not installed.', 'fl-builder' );
152
- }
153
- else {
154
 
155
- if ( $name ) {
156
  $names = explode( ' ', $name );
157
  }
158
-
159
  // Mailpoet 2+
160
  if ( class_exists( 'WYSIJA' ) ) {
161
-
162
  if ( $names && isset( $names[0] ) ) {
163
  $user['firstname'] = $names[0];
164
  }
@@ -170,10 +171,12 @@ final class FLBuilderServiceMailPoet extends FLBuilderService {
170
 
171
  $helper->addSubscriber( array(
172
  'user' => $user,
173
- 'user_list' => array( 'list_ids' => array( $settings->list_id ) ),
 
 
174
  ));
175
 
176
- // Mailpoet 3.0
177
  } elseif ( defined( 'MAILPOET_INITIALIZED' ) && true === MAILPOET_INITIALIZED ) {
178
  $subscriber = new MailPoet\Models\Subscriber();
179
 
@@ -185,14 +188,14 @@ final class FLBuilderServiceMailPoet extends FLBuilderService {
185
  }
186
 
187
  $subscribed = $subscriber::subscribe( $user, array( $settings->list_id ) );
188
- $errors = $subscribed->getErrors();
 
 
 
 
 
 
189
 
190
- if( $errors !== false ) {
191
- $response['error'] = sprintf( __( 'There was an error subscribing to Mailpoet. %s', 'fl-builder' ), $errors[0] );
192
- }
193
- }
194
- }
195
-
196
  return $response;
197
  }
198
- }
12
  *
13
  * @since 1.5.4
14
  * @var string $id
15
+ */
16
  public $id = 'mailpoet';
17
+
18
  /**
19
  * Test the API connection.
20
  *
24
  * @type bool|string $error The error message or false if no error.
25
  * @type array $data An array of data used to make the connection.
26
  * }
27
+ */
28
+ public function connect( $fields = array() ) {
29
+ $response = array(
 
30
  'error' => false,
31
+ 'data' => array(),
32
  );
33
+
34
  return $response;
35
  }
36
 
39
  *
40
  * @since 1.5.4
41
  * @return string The connection settings markup.
42
+ */
43
+ public function render_connect_settings() {
 
44
  return '';
45
  }
46
 
47
  /**
48
+ * Render the markup for service specific fields.
49
  *
50
  * @since 1.5.4
51
  * @param string $account The name of the saved account.
54
  * @type bool|string $error The error message or false if no error.
55
  * @type string $html The field markup.
56
  * }
57
+ */
58
+ public function render_fields( $account, $settings ) {
59
+ $response = array(
60
+ 'error' => false,
61
+ 'html' => '',
 
62
  );
63
  $lists = array();
64
+
65
  try {
66
  // Mailpoet 2+
67
  if ( class_exists( 'WYSIJA' ) ) {
68
  $list_model = WYSIJA::get( 'list', 'model' );
69
+ $lists = $list_model->get( array( 'name', 'list_id' ), array(
70
+ 'is_enabled' => 1,
71
+ ) );
72
+
73
+ // Mailpoet 3.0
74
  } elseif ( defined( 'MAILPOET_INITIALIZED' ) && true === MAILPOET_INITIALIZED ) {
75
 
76
  $listing = new MailPoet\Listing\Handler( '\MailPoet\Models\Segment' );
77
  $listing_data = $listing->get();
78
 
79
+ if ( isset( $listing_data['items'] ) ) {
80
+ foreach ( $listing_data['items'] as $segment ) {
81
  $lists[] = array(
82
  'list_id' => $segment->id,
83
+ 'name' => $segment->name,
84
  );
85
  }
86
+ }
87
  }
88
 
89
+ $response['html'] = self::render_list_field( $lists, $settings );
90
+ } catch ( Exception $e ) {
 
91
  $response['error'] = __( 'There was an error retrieveing your lists.', 'fl-builder' );
92
  }
93
+
94
  return $response;
95
  }
96
 
97
  /**
98
+ * Render markup for the list field.
99
  *
100
  * @since 1.5.4
101
  * @param array $lists List data from the API.
102
  * @param object $settings Saved module settings.
103
  * @return string The markup for the list field.
104
  * @access private
105
+ */
106
+ private function render_list_field( $lists, $settings ) {
 
107
  ob_start();
108
+
109
+ $options = array(
110
+ '' => __( 'Choose...', 'fl-builder' ),
111
+ );
112
+
113
  foreach ( $lists as $list ) {
114
  $options[ $list['list_id'] ] = $list['name'];
115
  }
116
+
117
  FLBuilder::render_settings_field( 'list_id', array(
118
  'row_class' => 'fl-builder-service-field-row',
119
  'class' => 'fl-builder-service-list-select',
121
  'label' => _x( 'List', 'An email list from a third party provider.', 'fl-builder' ),
122
  'options' => $options,
123
  'preview' => array(
124
+ 'type' => 'none',
125
+ ),
126
+ ), $settings);
127
+
128
  return ob_get_clean();
129
  }
130
 
131
+ /**
132
  * Subscribe an email address to MailPoet.
133
  *
134
  * @since 1.5.4
138
  * @return array {
139
  * @type bool|string $error The error message or false if no error.
140
  * }
141
+ */
142
+ public function subscribe( $settings, $email, $name = false ) {
143
+ $response = array(
144
+ 'error' => false,
145
+ );
146
+ $user = array(
147
+ 'email' => $email,
148
+ );
149
+
150
+ if ( ! class_exists( 'WYSIJA' )
151
  && ( ! defined( 'MAILPOET_INITIALIZED' ) || ( defined( 'MAILPOET_INITIALIZED' ) && false === MAILPOET_INITIALIZED ) )
152
+ ) {
153
  $response['error'] = __( 'There was an error subscribing. MailPoet is not installed.', 'fl-builder' );
154
+ } else {
 
155
 
156
+ if ( $name ) {
157
  $names = explode( ' ', $name );
158
  }
159
+
160
  // Mailpoet 2+
161
  if ( class_exists( 'WYSIJA' ) ) {
162
+
163
  if ( $names && isset( $names[0] ) ) {
164
  $user['firstname'] = $names[0];
165
  }
171
 
172
  $helper->addSubscriber( array(
173
  'user' => $user,
174
+ 'user_list' => array(
175
+ 'list_ids' => array( $settings->list_id ),
176
+ ),
177
  ));
178
 
179
+ // Mailpoet 3.0
180
  } elseif ( defined( 'MAILPOET_INITIALIZED' ) && true === MAILPOET_INITIALIZED ) {
181
  $subscriber = new MailPoet\Models\Subscriber();
182
 
188
  }
189
 
190
  $subscribed = $subscriber::subscribe( $user, array( $settings->list_id ) );
191
+ $errors = $subscribed->getErrors();
192
+
193
+ if ( false !== $errors ) {
194
+ $response['error'] = sprintf( __( 'There was an error subscribing to Mailpoet. %s', 'fl-builder' ), $errors[0] );
195
+ }
196
+ }// End if().
197
+ }// End if().
198
 
 
 
 
 
 
 
199
  return $response;
200
  }
201
+ }
classes/class-fl-builder-service-mailrelay.php CHANGED
@@ -33,22 +33,22 @@ final class FLBuilderServiceMailrelay extends FLBuilderService {
33
  * @param array $params Data to be passed to API
34
  * @return array|object The API response.
35
  */
36
- private function get_api_response( $base_url, $params )
37
- {
38
  // Exclude http:// for the specific service
39
- $base_url = preg_replace('#^https?://#', '', $base_url);
40
- $response = wp_remote_post( 'https://'. $base_url . $this->api_url, array( 'timeout' => 60, 'body' => $params ) );
 
 
 
41
 
42
- if (is_wp_error($response) || (isset($response->status) && $response->status == 0)) {
43
- if (isset($response->status)) {
44
- $data = json_decode($response, true);
45
- }
46
- else {
47
  $data['error'] = $response->get_error_message();
48
  }
49
-
50
  } else {
51
- $data = json_decode(wp_remote_retrieve_body( $response ), true);
52
  }
53
  return $data;
54
  }
@@ -66,36 +66,35 @@ final class FLBuilderServiceMailrelay extends FLBuilderService {
66
  * @type array $data An array of data used to make the connection.
67
  * }
68
  */
69
- public function connect( $fields = array() )
70
- {
71
  $response = array(
72
  'error' => false,
73
- 'data' => array()
74
  );
75
 
76
  // Make sure we have the Host.
77
  if ( ! isset( $fields['api_host'] ) || empty( $fields['api_host'] ) ) {
78
  $response['error'] = __( 'Error: You must provide a Host.', 'fl-builder' );
79
- }
80
- // Make sure we have an API key.
81
- else if ( ! isset( $fields['api_key'] ) || empty( $fields['api_key'] ) ) {
82
  $response['error'] = __( 'Error: You must provide an API key.', 'fl-builder' );
83
- }
84
- // Try to connect and store the connection data.
85
  else {
86
 
87
  $result = $this->get_api_response( $fields['api_host'], array(
88
  'function' => 'getGroups',
89
  'apiKey' => $fields['api_key'],
90
  'offset' => 0,
91
- 'count' => 1
92
  ) );
93
 
94
- if (!isset($result['error'])) {
95
- $response['data'] = array( 'api_host' => $fields['api_host'], 'api_key' => $fields['api_key'] );
96
- }
97
- else {
98
- $response['error'] = sprintf(__( 'Error: Could not connect to Mailrelay. %s', 'fl-builder' ), $result['error']);
 
 
99
  }
100
  }
101
 
@@ -108,8 +107,7 @@ final class FLBuilderServiceMailrelay extends FLBuilderService {
108
  * @since 1.5.4
109
  * @return string The connection settings markup.
110
  */
111
- public function render_connect_settings()
112
- {
113
  ob_start();
114
 
115
  FLBuilder::render_settings_field( 'api_host', array(
@@ -119,8 +117,8 @@ final class FLBuilderServiceMailrelay extends FLBuilderService {
119
  'label' => __( 'Host', 'fl-builder' ),
120
  'help' => __( 'The host you chose when you signed up for your account. Check your welcome email if you forgot it. Please enter it without the initial http:// (e.g. demo.ip-zone.com).', 'fl-builder' ),
121
  'preview' => array(
122
- 'type' => 'none'
123
- )
124
  ));
125
 
126
  FLBuilder::render_settings_field( 'api_key', array(
@@ -130,8 +128,8 @@ final class FLBuilderServiceMailrelay extends FLBuilderService {
130
  'label' => __( 'API Key', 'fl-builder' ),
131
  'help' => __( 'Your API key can be found in your Mailrelay account under Menu > Settings > API access.', 'fl-builder' ),
132
  'preview' => array(
133
- 'type' => 'none'
134
- )
135
  ));
136
 
137
  return ob_get_clean();
@@ -148,23 +146,21 @@ final class FLBuilderServiceMailrelay extends FLBuilderService {
148
  * @type string $html The field markup.
149
  * }
150
  */
151
- public function render_fields( $account, $settings )
152
- {
153
  $account_data = $this->get_account_data( $account );
154
  $result = $this->get_api_response( $account_data['api_host'], array(
155
  'function' => 'getGroups',
156
- 'apiKey' => $account_data['api_key']
157
  ) );
158
 
159
  $response = array(
160
  'error' => false,
161
- 'html' => ''
162
  );
163
 
164
- if ( isset($result['error']) ) {
165
- $response['error'] = sprintf(__( 'Error: Please check your API key. %s', 'fl-builder' ), $result['error']);
166
- }
167
- else {
168
  $response['html'] = $this->render_list_field( $result['data'], $settings );
169
  }
170
 
@@ -180,11 +176,12 @@ final class FLBuilderServiceMailrelay extends FLBuilderService {
180
  * @return string The markup for the list field.
181
  * @access private
182
  */
183
- private function render_list_field( $groups, $settings )
184
- {
185
  ob_start();
186
 
187
- $options = array( '' => __( 'Choose...', 'fl-builder' ) );
 
 
188
 
189
  foreach ( $groups as $group ) {
190
  $options[ $group['id'] ] = $group['name'];
@@ -198,8 +195,8 @@ final class FLBuilderServiceMailrelay extends FLBuilderService {
198
  'label' => _x( 'Group', 'A list of subscribers group from a Mailrelay account.', 'fl-builder' ),
199
  'options' => $options,
200
  'preview' => array(
201
- 'type' => 'none'
202
- )
203
  ), $settings);
204
 
205
  return ob_get_clean();
@@ -216,15 +213,15 @@ final class FLBuilderServiceMailrelay extends FLBuilderService {
216
  * @type bool|string $error The error message or false if no error.
217
  * }
218
  */
219
- public function subscribe( $settings, $email, $name = '' )
220
- {
221
  $account_data = $this->get_account_data( $settings->service_account );
222
- $response = array( 'error' => false );
 
 
223
 
224
  if ( ! $account_data ) {
225
  $response['error'] = __( 'There was an error subscribing to Mailrelay. The account is no longer connected.', 'fl-builder' );
226
- }
227
- else {
228
 
229
  $result = $this->get_api_response( $account_data['api_host'], array(
230
  'function' => 'addSubscriber',
@@ -234,8 +231,8 @@ final class FLBuilderServiceMailrelay extends FLBuilderService {
234
  'groups' => $settings->list_id,
235
  ) );
236
 
237
- if (isset($result['error'])) {
238
- $response['error'] = sprintf(__( 'There was an error subscribing to Mailrelay. %s', 'fl-builder' ), $result['error']);
239
  }
240
  }
241
 
33
  * @param array $params Data to be passed to API
34
  * @return array|object The API response.
35
  */
36
+ private function get_api_response( $base_url, $params ) {
 
37
  // Exclude http:// for the specific service
38
+ $base_url = preg_replace( '#^https?://#', '', $base_url );
39
+ $response = wp_remote_post( 'https://' . $base_url . $this->api_url, array(
40
+ 'timeout' => 60,
41
+ 'body' => $params,
42
+ ) );
43
 
44
+ if ( is_wp_error( $response ) || (isset( $response->status ) && 0 == $response->status ) ) {
45
+ if ( isset( $response->status ) ) {
46
+ $data = json_decode( $response, true );
47
+ } else {
 
48
  $data['error'] = $response->get_error_message();
49
  }
 
50
  } else {
51
+ $data = json_decode( wp_remote_retrieve_body( $response ), true );
52
  }
53
  return $data;
54
  }
66
  * @type array $data An array of data used to make the connection.
67
  * }
68
  */
69
+ public function connect( $fields = array() ) {
 
70
  $response = array(
71
  'error' => false,
72
+ 'data' => array(),
73
  );
74
 
75
  // Make sure we have the Host.
76
  if ( ! isset( $fields['api_host'] ) || empty( $fields['api_host'] ) ) {
77
  $response['error'] = __( 'Error: You must provide a Host.', 'fl-builder' );
78
+ } // End if().
79
+ elseif ( ! isset( $fields['api_key'] ) || empty( $fields['api_key'] ) ) {
 
80
  $response['error'] = __( 'Error: You must provide an API key.', 'fl-builder' );
81
+ } // Try to connect and store the connection data.
 
82
  else {
83
 
84
  $result = $this->get_api_response( $fields['api_host'], array(
85
  'function' => 'getGroups',
86
  'apiKey' => $fields['api_key'],
87
  'offset' => 0,
88
+ 'count' => 1,
89
  ) );
90
 
91
+ if ( ! isset( $result['error'] ) ) {
92
+ $response['data'] = array(
93
+ 'api_host' => $fields['api_host'],
94
+ 'api_key' => $fields['api_key'],
95
+ );
96
+ } else {
97
+ $response['error'] = sprintf( __( 'Error: Could not connect to Mailrelay. %s', 'fl-builder' ), $result['error'] );
98
  }
99
  }
100
 
107
  * @since 1.5.4
108
  * @return string The connection settings markup.
109
  */
110
+ public function render_connect_settings() {
 
111
  ob_start();
112
 
113
  FLBuilder::render_settings_field( 'api_host', array(
117
  'label' => __( 'Host', 'fl-builder' ),
118
  'help' => __( 'The host you chose when you signed up for your account. Check your welcome email if you forgot it. Please enter it without the initial http:// (e.g. demo.ip-zone.com).', 'fl-builder' ),
119
  'preview' => array(
120
+ 'type' => 'none',
121
+ ),
122
  ));
123
 
124
  FLBuilder::render_settings_field( 'api_key', array(
128
  'label' => __( 'API Key', 'fl-builder' ),
129
  'help' => __( 'Your API key can be found in your Mailrelay account under Menu > Settings > API access.', 'fl-builder' ),
130
  'preview' => array(
131
+ 'type' => 'none',
132
+ ),
133
  ));
134
 
135
  return ob_get_clean();
146
  * @type string $html The field markup.
147
  * }
148
  */
149
+ public function render_fields( $account, $settings ) {
 
150
  $account_data = $this->get_account_data( $account );
151
  $result = $this->get_api_response( $account_data['api_host'], array(
152
  'function' => 'getGroups',
153
+ 'apiKey' => $account_data['api_key'],
154
  ) );
155
 
156
  $response = array(
157
  'error' => false,
158
+ 'html' => '',
159
  );
160
 
161
+ if ( isset( $result['error'] ) ) {
162
+ $response['error'] = sprintf( __( 'Error: Please check your API key. %s', 'fl-builder' ), $result['error'] );
163
+ } else {
 
164
  $response['html'] = $this->render_list_field( $result['data'], $settings );
165
  }
166
 
176
  * @return string The markup for the list field.
177
  * @access private
178
  */
179
+ private function render_list_field( $groups, $settings ) {
 
180
  ob_start();
181
 
182
+ $options = array(
183
+ '' => __( 'Choose...', 'fl-builder' ),
184
+ );
185
 
186
  foreach ( $groups as $group ) {
187
  $options[ $group['id'] ] = $group['name'];
195
  'label' => _x( 'Group', 'A list of subscribers group from a Mailrelay account.', 'fl-builder' ),
196
  'options' => $options,
197
  'preview' => array(
198
+ 'type' => 'none',
199
+ ),
200
  ), $settings);
201
 
202
  return ob_get_clean();
213
  * @type bool|string $error The error message or false if no error.
214
  * }
215
  */
216
+ public function subscribe( $settings, $email, $name = '' ) {
 
217
  $account_data = $this->get_account_data( $settings->service_account );
218
+ $response = array(
219
+ 'error' => false,
220
+ );
221
 
222
  if ( ! $account_data ) {
223
  $response['error'] = __( 'There was an error subscribing to Mailrelay. The account is no longer connected.', 'fl-builder' );
224
+ } else {
 
225
 
226
  $result = $this->get_api_response( $account_data['api_host'], array(
227
  'function' => 'addSubscriber',
231
  'groups' => $settings->list_id,
232
  ) );
233
 
234
+ if ( isset( $result['error'] ) ) {
235
+ $response['error'] = sprintf( __( 'There was an error subscribing to Mailrelay. %s', 'fl-builder' ), $result['error'] );
236
  }
237
  }
238
 
classes/class-fl-builder-service-sendinblue.php CHANGED
@@ -12,14 +12,14 @@ final class FLBuilderServiceSendinBlue extends FLBuilderService {
12
  *
13
  * @since 1.5.6
14
  * @var string $id
15
- */
16
  public $id = 'sendinblue';
17
 
18
  /**
19
  * @since 1.5.6
20
  * @var object $api_instance
21
  * @access private
22
- */
23
  private $api_instance = null;
24
 
25
  /**
@@ -28,21 +28,20 @@ final class FLBuilderServiceSendinBlue extends FLBuilderService {
28
  * @since 1.5.6
29
  * @param string $access_key A valid access key.
30
  * @return object The API instance.
31
- */
32
- public function get_api( $access_key )
33
- {
34
  if ( $this->api_instance ) {
35
  return $this->api_instance;
36
  }
37
  if ( ! class_exists( 'Mailin' ) ) {
38
  require_once FL_BUILDER_DIR . 'includes/vendor/sendinblue/Mailin.php';
39
  }
40
-
41
  $this->api_instance = new Mailin( 'https://api.sendinblue.com/v2.0', $access_key );
42
-
43
  return $this->api_instance;
44
  }
45
-
46
  /**
47
  * Test the API connection.
48
  *
@@ -54,35 +53,33 @@ final class FLBuilderServiceSendinBlue extends FLBuilderService {
54
  * @type bool|string $error The error message or false if no error.
55
  * @type array $data An array of data used to make the connection.
56
  * }
57
- */
58
- public function connect( $fields = array() )
59
- {
60
- $response = array(
61
  'error' => false,
62
- 'data' => array()
63
  );
64
-
65
  // Make sure we have an access key.
66
  if ( ! isset( $fields['access_key'] ) || empty( $fields['access_key'] ) ) {
67
  $response['error'] = __( 'Error: You must provide an Access Key.', 'fl-builder' );
68
- }
69
- // Try to connect and store the connection data.
70
  else {
71
-
72
  $api = $this->get_api( $fields['access_key'] );
73
  $result = $api->get_account();
74
-
75
  if ( ! is_array( $result ) ) {
76
  $response['error'] = __( 'There was an error connecting to SendinBlue. Please try again.', 'fl-builder' );
77
- }
78
- else if ( isset( $result['code'] ) && 'failure' == $result['code'] ) {
79
  $response['error'] = sprintf( __( 'Error: Could not connect to SendinBlue. %s', 'fl-builder' ), $result['message'] );
80
- }
81
- else {
82
- $response['data'] = array( 'access_key' => $fields['access_key'] );
 
83
  }
84
  }
85
-
86
  return $response;
87
  }
88
 
@@ -91,11 +88,10 @@ final class FLBuilderServiceSendinBlue extends FLBuilderService {
91
  *
92
  * @since 1.5.6
93
  * @return string The connection settings markup.
94
- */
95
- public function render_connect_settings()
96
- {
97
  ob_start();
98
-
99
  FLBuilder::render_settings_field( 'access_key', array(
100
  'row_class' => 'fl-builder-service-connect-row',
101
  'class' => 'fl-builder-service-connect-input',
@@ -103,15 +99,15 @@ final class FLBuilderServiceSendinBlue extends FLBuilderService {
103
  'label' => __( 'Access Key', 'fl-builder' ),
104
  'help' => __( 'Your Access Key can be found in your SendinBlue account under API & Integration > Manager Your Keys > Version 2.0 > Access Key.', 'fl-builder' ),
105
  'preview' => array(
106
- 'type' => 'none'
107
- )
108
- ));
109
-
110
  return ob_get_clean();
111
  }
112
 
113
  /**
114
- * Render the markup for service specific fields.
115
  *
116
  * @since 1.5.6
117
  * @param string $account The name of the saved account.
@@ -120,25 +116,22 @@ final class FLBuilderServiceSendinBlue extends FLBuilderService {
120
  * @type bool|string $error The error message or false if no error.
121
  * @type string $html The field markup.
122
  * }
123
- */
124
- public function render_fields( $account, $settings )
125
- {
126
  $account_data = $this->get_account_data( $account );
127
  $api = $this->get_api( $account_data['access_key'] );
128
- $response = array(
129
- 'error' => false,
130
- 'html' => ''
131
  );
132
-
133
  $result = $api->get_lists( 1, 50 );
134
-
135
  if ( ! is_array( $result ) ) {
136
  $response['error'] = __( 'There was an error connecting to SendinBlue. Please try again.', 'fl-builder' );
137
- }
138
- else if ( isset( $result['code'] ) && 'failure' == $result['code'] ) {
139
  $response['error'] = sprintf( __( 'Error: Could not connect to SendinBlue. %s', 'fl-builder' ), $result['message'] );
140
- }
141
- else {
142
  $response['html'] = $this->render_list_field( $result['data']['lists'], $settings );
143
  }
144
 
@@ -146,24 +139,25 @@ final class FLBuilderServiceSendinBlue extends FLBuilderService {
146
  }
147
 
148
  /**
149
- * Render markup for the list field.
150
  *
151
  * @since 1.5.6
152
  * @param array $lists List data from the API.
153
  * @param object $settings Saved module settings.
154
  * @return string The markup for the list field.
155
  * @access private
156
- */
157
- private function render_list_field( $lists, $settings )
158
- {
159
  ob_start();
160
-
161
- $options = array( '' => __( 'Choose...', 'fl-builder' ) );
162
-
 
 
163
  foreach ( $lists as $list ) {
164
  $options[ $list['id'] ] = $list['name'];
165
  }
166
-
167
  FLBuilder::render_settings_field( 'list_id', array(
168
  'row_class' => 'fl-builder-service-field-row',
169
  'class' => 'fl-builder-service-list-select',
@@ -171,14 +165,14 @@ final class FLBuilderServiceSendinBlue extends FLBuilderService {
171
  'label' => _x( 'List', 'An email list from a third party provider.', 'fl-builder' ),
172
  'options' => $options,
173
  'preview' => array(
174
- 'type' => 'none'
175
- )
176
- ), $settings);
177
-
178
  return ob_get_clean();
179
  }
180
 
181
- /**
182
  * Subscribe an email address to SendinBlue.
183
  *
184
  * @since 1.5.6
@@ -188,24 +182,24 @@ final class FLBuilderServiceSendinBlue extends FLBuilderService {
188
  * @return array {
189
  * @type bool|string $error The error message or false if no error.
190
  * }
191
- */
192
- public function subscribe( $settings, $email, $name = false )
193
- {
194
  $account_data = $this->get_account_data( $settings->service_account );
195
- $response = array( 'error' => false );
196
-
 
 
197
  if ( ! $account_data ) {
198
  $response['error'] = __( 'There was an error subscribing to SendinBlue. The account is no longer connected.', 'fl-builder' );
199
- }
200
- else {
201
-
202
  $api = $this->get_api( $account_data['access_key'] );
203
  $data = array();
204
-
205
  if ( $name ) {
206
-
207
  $names = explode( ' ', $name );
208
-
209
  if ( isset( $names[0] ) ) {
210
  $data['NAME'] = $names[0];
211
  }
@@ -213,17 +207,16 @@ final class FLBuilderServiceSendinBlue extends FLBuilderService {
213
  $data['SURNAME'] = $names[1];
214
  }
215
  }
216
-
217
  $result = $api->create_update_user( $email, $data, 0, array( $settings->list_id ), array(), 0 );
218
-
219
  if ( ! is_array( $result ) ) {
220
  $response['error'] = __( 'There was an error subscribing to SendinBlue. Please try again.', 'fl-builder' );
221
- }
222
- else if ( isset( $result['code'] ) && 'failure' == $result['code'] ) {
223
  $response['error'] = sprintf( __( 'Error: Could not subscribe to SendinBlue. %s', 'fl-builder' ), $result['message'] );
224
  }
225
  }
226
-
227
  return $response;
228
  }
229
- }
12
  *
13
  * @since 1.5.6
14
  * @var string $id
15
+ */
16
  public $id = 'sendinblue';
17
 
18
  /**
19
  * @since 1.5.6
20
  * @var object $api_instance
21
  * @access private
22
+ */
23
  private $api_instance = null;
24
 
25
  /**
28
  * @since 1.5.6
29
  * @param string $access_key A valid access key.
30
  * @return object The API instance.
31
+ */
32
+ public function get_api( $access_key ) {
 
33
  if ( $this->api_instance ) {
34
  return $this->api_instance;
35
  }
36
  if ( ! class_exists( 'Mailin' ) ) {
37
  require_once FL_BUILDER_DIR . 'includes/vendor/sendinblue/Mailin.php';
38
  }
39
+
40
  $this->api_instance = new Mailin( 'https://api.sendinblue.com/v2.0', $access_key );
41
+
42
  return $this->api_instance;
43
  }
44
+
45
  /**
46
  * Test the API connection.
47
  *
53
  * @type bool|string $error The error message or false if no error.
54
  * @type array $data An array of data used to make the connection.
55
  * }
56
+ */
57
+ public function connect( $fields = array() ) {
58
+ $response = array(
 
59
  'error' => false,
60
+ 'data' => array(),
61
  );
62
+
63
  // Make sure we have an access key.
64
  if ( ! isset( $fields['access_key'] ) || empty( $fields['access_key'] ) ) {
65
  $response['error'] = __( 'Error: You must provide an Access Key.', 'fl-builder' );
66
+ } // End if().
 
67
  else {
68
+
69
  $api = $this->get_api( $fields['access_key'] );
70
  $result = $api->get_account();
71
+
72
  if ( ! is_array( $result ) ) {
73
  $response['error'] = __( 'There was an error connecting to SendinBlue. Please try again.', 'fl-builder' );
74
+ } elseif ( isset( $result['code'] ) && 'failure' == $result['code'] ) {
 
75
  $response['error'] = sprintf( __( 'Error: Could not connect to SendinBlue. %s', 'fl-builder' ), $result['message'] );
76
+ } else {
77
+ $response['data'] = array(
78
+ 'access_key' => $fields['access_key'],
79
+ );
80
  }
81
  }
82
+
83
  return $response;
84
  }
85
 
88
  *
89
  * @since 1.5.6
90
  * @return string The connection settings markup.
91
+ */
92
+ public function render_connect_settings() {
 
93
  ob_start();
94
+
95
  FLBuilder::render_settings_field( 'access_key', array(
96
  'row_class' => 'fl-builder-service-connect-row',
97
  'class' => 'fl-builder-service-connect-input',
99
  'label' => __( 'Access Key', 'fl-builder' ),
100
  'help' => __( 'Your Access Key can be found in your SendinBlue account under API & Integration > Manager Your Keys > Version 2.0 > Access Key.', 'fl-builder' ),
101
  'preview' => array(
102
+ 'type' => 'none',
103
+ ),
104
+ ));
105
+
106
  return ob_get_clean();
107
  }
108
 
109
  /**
110
+ * Render the markup for service specific fields.
111
  *
112
  * @since 1.5.6
113
  * @param string $account The name of the saved account.
116
  * @type bool|string $error The error message or false if no error.
117
  * @type string $html The field markup.
118
  * }
119
+ */
120
+ public function render_fields( $account, $settings ) {
 
121
  $account_data = $this->get_account_data( $account );
122
  $api = $this->get_api( $account_data['access_key'] );
123
+ $response = array(
124
+ 'error' => false,
125
+ 'html' => '',
126
  );
127
+
128
  $result = $api->get_lists( 1, 50 );
129
+
130
  if ( ! is_array( $result ) ) {
131
  $response['error'] = __( 'There was an error connecting to SendinBlue. Please try again.', 'fl-builder' );
132
+ } elseif ( isset( $result['code'] ) && 'failure' == $result['code'] ) {
 
133
  $response['error'] = sprintf( __( 'Error: Could not connect to SendinBlue. %s', 'fl-builder' ), $result['message'] );
134
+ } else {
 
135
  $response['html'] = $this->render_list_field( $result['data']['lists'], $settings );
136
  }
137
 
139
  }
140
 
141
  /**
142
+ * Render markup for the list field.
143
  *
144
  * @since 1.5.6
145
  * @param array $lists List data from the API.
146
  * @param object $settings Saved module settings.
147
  * @return string The markup for the list field.
148
  * @access private
149
+ */
150
+ private function render_list_field( $lists, $settings ) {
 
151
  ob_start();
152
+
153
+ $options = array(
154
+ '' => __( 'Choose...', 'fl-builder' ),
155
+ );
156
+
157
  foreach ( $lists as $list ) {
158
  $options[ $list['id'] ] = $list['name'];
159
  }
160
+
161
  FLBuilder::render_settings_field( 'list_id', array(
162
  'row_class' => 'fl-builder-service-field-row',
163
  'class' => 'fl-builder-service-list-select',
165
  'label' => _x( 'List', 'An email list from a third party provider.', 'fl-builder' ),
166
  'options' => $options,
167
  'preview' => array(
168
+ 'type' => 'none',
169
+ ),
170
+ ), $settings);
171
+
172
  return ob_get_clean();
173
  }
174
 
175
+ /**
176
  * Subscribe an email address to SendinBlue.
177
  *
178
  * @since 1.5.6
182
  * @return array {
183
  * @type bool|string $error The error message or false if no error.
184
  * }
185
+ */
186
+ public function subscribe( $settings, $email, $name = false ) {
 
187
  $account_data = $this->get_account_data( $settings->service_account );
188
+ $response = array(
189
+ 'error' => false,
190
+ );
191
+
192
  if ( ! $account_data ) {
193
  $response['error'] = __( 'There was an error subscribing to SendinBlue. The account is no longer connected.', 'fl-builder' );
194
+ } else {
195
+
 
196
  $api = $this->get_api( $account_data['access_key'] );
197
  $data = array();
198
+
199
  if ( $name ) {
200
+
201
  $names = explode( ' ', $name );
202
+
203
  if ( isset( $names[0] ) ) {
204
  $data['NAME'] = $names[0];
205
  }
207
  $data['SURNAME'] = $names[1];
208
  }
209
  }
210
+
211
  $result = $api->create_update_user( $email, $data, 0, array( $settings->list_id ), array(), 0 );
212
+
213
  if ( ! is_array( $result ) ) {
214
  $response['error'] = __( 'There was an error subscribing to SendinBlue. Please try again.', 'fl-builder' );
215
+ } elseif ( isset( $result['code'] ) && 'failure' == $result['code'] ) {
 
216
  $response['error'] = sprintf( __( 'Error: Could not subscribe to SendinBlue. %s', 'fl-builder' ), $result['message'] );
217
  }
218
  }
219
+
220
  return $response;
221
  }
222
+ }
classes/class-fl-builder-service-sendy.php CHANGED
@@ -12,14 +12,14 @@ final class FLBuilderServiceSendy extends FLBuilderService {
12
  *
13
  * @since 1.5.4
14
  * @var string $id
15
- */
16
  public $id = 'sendy';
17
 
18
  /**
19
  * @since 1.5.4
20
  * @var object $api_instance
21
  * @access private
22
- */
23
  private $api_instance = null;
24
 
25
  /**
@@ -28,21 +28,20 @@ final class FLBuilderServiceSendy extends FLBuilderService {
28
  * @since 1.5.4
29
  * @param array $args A valid API authentication data.
30
  * @return object The API instance.
31
- */
32
- public function get_api( array $args )
33
- {
34
  if ( $this->api_instance ) {
35
  return $this->api_instance;
36
  }
37
  if ( ! class_exists( '\\SendyPHP\\SendyPHP' ) ) {
38
  require_once FL_BUILDER_DIR . 'includes/vendor/sendy/SendyPHP.php';
39
  }
40
-
41
  $this->api_instance = new \SendyPHP\SendyPHP( $args );
42
-
43
  return $this->api_instance;
44
  }
45
-
46
  /**
47
  * Test the API connection.
48
  *
@@ -55,14 +54,13 @@ final class FLBuilderServiceSendy extends FLBuilderService {
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
- {
61
- $response = array(
62
  'error' => false,
63
- 'data' => array()
64
  );
65
-
66
  // Make sure we have the Host.
67
  if ( ! isset( $fields['api_host'] ) || empty( $fields['api_host'] ) ) {
68
  $response['error'] = __( 'Error: You must provide your Sendy installation URL.', 'fl-builder' );
@@ -74,27 +72,29 @@ final class FLBuilderServiceSendy extends FLBuilderService {
74
  // Make sure we have the list ID.
75
  if ( ! isset( $fields['list_id'] ) || empty( $fields['list_id'] ) ) {
76
  $response['error'] = __( 'Error: You must provide a list ID.', 'fl-builder' );
77
- }
78
- // Try to connect and store the connection data.
79
  else {
80
 
81
  $api = $this->get_api( array(
82
- 'installation_url' => $fields['api_host'],
83
- 'api_key' => $fields['api_key'],
84
- 'list_id' => $fields['list_id']
85
  ) );
86
 
87
  // Send request for list ID validation
88
  $get_api_response = $api->subcount();
89
-
90
  if ( true === $get_api_response['status'] ) {
91
- $response['data'] = array('api_host' => $fields['api_host'], 'api_key' => $fields['api_key'], 'list_id' => $fields['list_id']);
92
- }
93
- else {
94
- $response['error'] = sprintf(__( 'Error: Could not connect to Sendy. %s', 'fl-builder' ), $get_api_response['message']);
95
- }
 
 
 
96
  }
97
-
98
  return $response;
99
  }
100
 
@@ -103,11 +103,10 @@ final class FLBuilderServiceSendy extends FLBuilderService {
103
  *
104
  * @since 1.5.4
105
  * @return string The connection settings markup.
106
- */
107
- public function render_connect_settings()
108
- {
109
  ob_start();
110
-
111
  FLBuilder::render_settings_field( 'api_host', array(
112
  'row_class' => 'fl-builder-service-connect-row',
113
  'class' => 'fl-builder-service-connect-input',
@@ -115,8 +114,8 @@ final class FLBuilderServiceSendy extends FLBuilderService {
115
  'label' => __( 'Installation URL', 'fl-builder' ),
116
  'help' => __( 'The URL where your Sendy application is installed (e.g. http://mywebsite.com/sendy).', 'fl-builder' ),
117
  'preview' => array(
118
- 'type' => 'none'
119
- )
120
  ));
121
 
122
  FLBuilder::render_settings_field( 'api_key', array(
@@ -126,8 +125,8 @@ final class FLBuilderServiceSendy extends FLBuilderService {
126
  'label' => __( 'API Key', 'fl-builder' ),
127
  'help' => __( 'Found in your Sendy application under Settings.', 'fl-builder' ),
128
  'preview' => array(
129
- 'type' => 'none'
130
- )
131
  ));
132
 
133
  FLBuilder::render_settings_field( 'list_id', array(
@@ -137,15 +136,15 @@ final class FLBuilderServiceSendy extends FLBuilderService {
137
  'label' => __( 'List ID', 'fl-builder' ),
138
  'help' => __( 'The ID of the list you would like users to subscribe to. The ID of a list can be found under "View all lists" in the section named ID.', 'fl-builder' ),
139
  'preview' => array(
140
- 'type' => 'none'
141
- )
142
  ));
143
 
144
  return ob_get_clean();
145
  }
146
 
147
  /**
148
- * Render the markup for service specific fields.
149
  *
150
  * @since 1.5.4
151
  * @param string $account The name of the saved account.
@@ -154,19 +153,18 @@ final class FLBuilderServiceSendy extends FLBuilderService {
154
  * @type bool|string $error The error message or false if no error.
155
  * @type string $html The field markup.
156
  * }
157
- */
158
- public function render_fields( $account, $settings )
159
- {
160
-
161
- $response = array(
162
- 'error' => false,
163
- 'html' => ''
164
  );
165
-
166
  return $response;
167
  }
168
 
169
- /**
170
  * Subscribe an email address to Sendy.
171
  *
172
  * @since 1.5.4
@@ -176,31 +174,34 @@ final class FLBuilderServiceSendy extends FLBuilderService {
176
  * @return array {
177
  * @type bool|string $error The error message or false if no error.
178
  * }
179
- */
180
- public function subscribe( $settings, $email, $name = '' )
181
- {
182
  $account_data = $this->get_account_data( $settings->service_account );
183
- $response = array( 'error' => false );
184
-
 
 
185
  if ( ! $account_data ) {
186
  $response['error'] = __( 'There was an error subscribing to Sendy. The account is no longer connected.', 'fl-builder' );
187
- }
188
- else {
189
-
190
  $api = $this->get_api( array(
191
- 'installation_url' => $account_data['api_host'],
192
- 'api_key' => $account_data['api_key'],
193
- 'list_id' => $account_data['list_id']
194
  ) );
195
 
196
  // Send request for list ID validation
197
- $get_api_response = $api->subscribe(array('name' => $name, 'email' => $email));
 
 
 
198
 
199
  if ( false === $get_api_response['status'] ) {
200
- $response['error'] = sprintf(__( 'There was an error subscribing to Sendy. %s', 'fl-builder' ), $get_api_response['message']);
201
  }
202
  }
203
-
204
  return $response;
205
  }
206
- }
12
  *
13
  * @since 1.5.4
14
  * @var string $id
15
+ */
16
  public $id = 'sendy';
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 array $args A valid API authentication data.
30
  * @return object The API instance.
31
+ */
32
+ public function get_api( array $args ) {
 
33
  if ( $this->api_instance ) {
34
  return $this->api_instance;
35
  }
36
  if ( ! class_exists( '\\SendyPHP\\SendyPHP' ) ) {
37
  require_once FL_BUILDER_DIR . 'includes/vendor/sendy/SendyPHP.php';
38
  }
39
+
40
  $this->api_instance = new \SendyPHP\SendyPHP( $args );
41
+
42
  return $this->api_instance;
43
  }
44
+
45
  /**
46
  * Test the API connection.
47
  *
54
  * @type bool|string $error The error message or false if no error.
55
  * @type array $data An array of data used to make the connection.
56
  * }
57
+ */
58
+ public function connect( $fields = array() ) {
59
+ $response = array(
 
60
  'error' => false,
61
+ 'data' => array(),
62
  );
63
+
64
  // Make sure we have the Host.
65
  if ( ! isset( $fields['api_host'] ) || empty( $fields['api_host'] ) ) {
66
  $response['error'] = __( 'Error: You must provide your Sendy installation URL.', 'fl-builder' );
72
  // Make sure we have the list ID.
73
  if ( ! isset( $fields['list_id'] ) || empty( $fields['list_id'] ) ) {
74
  $response['error'] = __( 'Error: You must provide a list ID.', 'fl-builder' );
75
+ } // End if().
 
76
  else {
77
 
78
  $api = $this->get_api( array(
79
+ 'installation_url' => $fields['api_host'],
80
+ 'api_key' => $fields['api_key'],
81
+ 'list_id' => $fields['list_id'],
82
  ) );
83
 
84
  // Send request for list ID validation
85
  $get_api_response = $api->subcount();
86
+
87
  if ( true === $get_api_response['status'] ) {
88
+ $response['data'] = array(
89
+ 'api_host' => $fields['api_host'],
90
+ 'api_key' => $fields['api_key'],
91
+ 'list_id' => $fields['list_id'],
92
+ );
93
+ } else {
94
+ $response['error'] = sprintf( __( 'Error: Could not connect to Sendy. %s', 'fl-builder' ), $get_api_response['message'] );
95
+ }
96
  }
97
+
98
  return $response;
99
  }
100
 
103
  *
104
  * @since 1.5.4
105
  * @return string The connection settings markup.
106
+ */
107
+ public function render_connect_settings() {
 
108
  ob_start();
109
+
110
  FLBuilder::render_settings_field( 'api_host', array(
111
  'row_class' => 'fl-builder-service-connect-row',
112
  'class' => 'fl-builder-service-connect-input',
114
  'label' => __( 'Installation URL', 'fl-builder' ),
115
  'help' => __( 'The URL where your Sendy application is installed (e.g. http://mywebsite.com/sendy).', 'fl-builder' ),
116
  'preview' => array(
117
+ 'type' => 'none',
118
+ ),
119
  ));
120
 
121
  FLBuilder::render_settings_field( 'api_key', array(
125
  'label' => __( 'API Key', 'fl-builder' ),
126
  'help' => __( 'Found in your Sendy application under Settings.', 'fl-builder' ),
127
  'preview' => array(
128
+ 'type' => 'none',
129
+ ),
130
  ));
131
 
132
  FLBuilder::render_settings_field( 'list_id', array(
136
  'label' => __( 'List ID', 'fl-builder' ),
137
  'help' => __( 'The ID of the list you would like users to subscribe to. The ID of a list can be found under "View all lists" in the section named ID.', 'fl-builder' ),
138
  'preview' => array(
139
+ 'type' => 'none',
140
+ ),
141
  ));
142
 
143
  return ob_get_clean();
144
  }
145
 
146
  /**
147
+ * Render the markup for service specific fields.
148
  *
149
  * @since 1.5.4
150
  * @param string $account The name of the saved account.
153
  * @type bool|string $error The error message or false if no error.
154
  * @type string $html The field markup.
155
  * }
156
+ */
157
+ public function render_fields( $account, $settings ) {
158
+
159
+ $response = array(
160
+ 'error' => false,
161
+ 'html' => '',
 
162
  );
163
+
164
  return $response;
165
  }
166
 
167
+ /**
168
  * Subscribe an email address to Sendy.
169
  *
170
  * @since 1.5.4
174
  * @return array {
175
  * @type bool|string $error The error message or false if no error.
176
  * }
177
+ */
178
+ public function subscribe( $settings, $email, $name = '' ) {
 
179
  $account_data = $this->get_account_data( $settings->service_account );
180
+ $response = array(
181
+ 'error' => false,
182
+ );
183
+
184
  if ( ! $account_data ) {
185
  $response['error'] = __( 'There was an error subscribing to Sendy. The account is no longer connected.', 'fl-builder' );
186
+ } else {
187
+
 
188
  $api = $this->get_api( array(
189
+ 'installation_url' => $account_data['api_host'],
190
+ 'api_key' => $account_data['api_key'],
191
+ 'list_id' => $account_data['list_id'],
192
  ) );
193
 
194
  // Send request for list ID validation
195
+ $get_api_response = $api->subscribe( array(
196
+ 'name' => $name,
197
+ 'email' => $email,
198
+ ) );
199
 
200
  if ( false === $get_api_response['status'] ) {
201
+ $response['error'] = sprintf( __( 'There was an error subscribing to Sendy. %s', 'fl-builder' ), $get_api_response['message'] );
202
  }
203
  }
204
+
205
  return $response;
206
  }
207
+ }
classes/class-fl-builder-service.php CHANGED
@@ -12,9 +12,9 @@ abstract class FLBuilderService {
12
  *
13
  * @since 1.5.4
14
  * @var string $id
15
- */
16
  public $id = '';
17
-
18
  /**
19
  * Test the API connection.
20
  *
@@ -24,7 +24,7 @@ abstract class FLBuilderService {
24
  * @type bool|string $error The error message or false if no error.
25
  * @type array $data An array of data used to make the connection.
26
  * }
27
- */
28
  abstract public function connect( $fields = array() );
29
 
30
  /**
@@ -32,11 +32,11 @@ abstract class FLBuilderService {
32
  *
33
  * @since 1.5.4
34
  * @return string The connection settings markup.
35
- */
36
  abstract public function render_connect_settings();
37
 
38
  /**
39
- * Render the markup for service specific fields.
40
  *
41
  * @since 1.5.4
42
  * @param string $account The name of the saved account.
@@ -45,7 +45,7 @@ abstract class FLBuilderService {
45
  * @type bool|string $error The error message or false if no error.
46
  * @type string $html The field markup.
47
  * }
48
- */
49
  abstract public function render_fields( $account, $settings );
50
 
51
  /**
@@ -54,15 +54,14 @@ abstract class FLBuilderService {
54
  * @since 1.5.4
55
  * @param string $account The account name.
56
  * @return array|bool The account data or false if it doesn't exist.
57
- */
58
- public function get_account_data( $account )
59
- {
60
  $saved_services = FLBuilderModel::get_services();
61
-
62
  if ( isset( $saved_services[ $this->id ] ) && isset( $saved_services[ $this->id ][ $account ] ) ) {
63
  return $saved_services[ $this->id ][ $account ];
64
  }
65
-
66
  return false;
67
  }
68
- }
12
  *
13
  * @since 1.5.4
14
  * @var string $id
15
+ */
16
  public $id = '';
17
+
18
  /**
19
  * Test the API connection.
20
  *
24
  * @type bool|string $error The error message or false if no error.
25
  * @type array $data An array of data used to make the connection.
26
  * }
27
+ */
28
  abstract public function connect( $fields = array() );
29
 
30
  /**
32
  *
33
  * @since 1.5.4
34
  * @return string The connection settings markup.
35
+ */
36
  abstract public function render_connect_settings();
37
 
38
  /**
39
+ * Render the markup for service specific fields.
40
  *
41
  * @since 1.5.4
42
  * @param string $account The name of the saved account.
45
  * @type bool|string $error The error message or false if no error.
46
  * @type string $html The field markup.
47
  * }
48
+ */
49
  abstract public function render_fields( $account, $settings );
50
 
51
  /**
54
  * @since 1.5.4
55
  * @param string $account The account name.
56
  * @return array|bool The account data or false if it doesn't exist.
57
+ */
58
+ public function get_account_data( $account ) {
 
59
  $saved_services = FLBuilderModel::get_services();
60
+
61
  if ( isset( $saved_services[ $this->id ] ) && isset( $saved_services[ $this->id ][ $account ] ) ) {
62
  return $saved_services[ $this->id ][ $account ];
63
  }
64
+
65
  return false;
66
  }
67
+ }
classes/class-fl-builder-services.php CHANGED
@@ -18,114 +18,114 @@ final class FLBuilderServices {
18
  'activecampaign' => array(
19
  'type' => 'autoresponder',
20
  'name' => 'ActiveCampaign',
21
- 'class' => 'FLBuilderServiceActiveCampaign'
22
  ),
23
  'aweber' => array(
24
  'type' => 'autoresponder',
25
  'name' => 'AWeber',
26
- 'class' => 'FLBuilderServiceAWeber'
27
  ),
28
  'campaign-monitor' => array(
29
  'type' => 'autoresponder',
30
  'name' => 'Campaign Monitor',
31
- 'class' => 'FLBuilderServiceCampaignMonitor'
32
  ),
33
  'campayn' => array(
34
  'type' => 'autoresponder',
35
  'name' => 'Campayn',
36
- 'class' => 'FLBuilderServiceCampayn'
37
  ),
38
  'constant-contact' => array(
39
  'type' => 'autoresponder',
40
  'name' => 'Constant Contact',
41
- 'class' => 'FLBuilderServiceConstantContact'
42
  ),
43
  'convertkit' => array(
44
  'type' => 'autoresponder',
45
  'name' => 'ConvertKit',
46
- 'class' => 'FLBuilderServiceConvertKit'
47
  ),
48
  'drip' => array(
49
  'type' => 'autoresponder',
50
  'name' => 'Drip',
51
- 'class' => 'FLBuilderServiceDrip'
52
  ),
53
  'email-address' => array(
54
  'type' => 'autoresponder',
55
  'name' => 'Email Address',
56
- 'class' => 'FLBuilderServiceEmailAddress'
57
  ),
58
  'enormail' => array(
59
  'type' => 'autoresponder',
60
  'name' => 'Enormail',
61
- 'class' => 'FLBuilderServiceEnormail'
62
  ),
63
  'getresponse' => array(
64
  'type' => 'autoresponder',
65
  'name' => 'GetResponse',
66
- 'class' => 'FLBuilderServiceGetResponse'
67
  ),
68
  'godaddy-email-marketing' => array(
69
  'type' => 'autoresponder',
70
  'name' => 'GoDaddy Email Marketing',
71
- 'class' => 'FLBuilderServiceGoDaddyEmailMarketing'
72
  ),
73
  'hatchbuck' => array(
74
  'type' => 'autoresponder',
75
  'name' => 'Hatchbuck',
76
- 'class' => 'FLBuilderServiceHatchbuck'
77
  ),
78
  'icontact' => array(
79
  'type' => 'autoresponder',
80
  'name' => 'iContact',
81
- 'class' => 'FLBuilderServiceIContact'
82
  ),
83
  'icontact-pro' => array(
84
  'type' => 'autoresponder',
85
  'name' => 'iContact Pro',
86
- 'class' => 'FLBuilderServiceIContactPro'
87
  ),
88
  'infusionsoft' => array(
89
  'type' => 'autoresponder',
90
  'name' => 'Infusionsoft',
91
- 'class' => 'FLBuilderServiceInfusionsoft'
92
  ),
93
  'madmimi' => array(
94
  'type' => 'autoresponder',
95
  'name' => 'Mad Mimi',
96
- 'class' => 'FLBuilderServiceMadMimi'
97
  ),
98
  'mailchimp' => array(
99
  'type' => 'autoresponder',
100
  'name' => 'MailChimp',
101
- 'class' => 'FLBuilderServiceMailChimp'
102
  ),
103
  'mailerlite' => array(
104
  'type' => 'autoresponder',
105
  'name' => 'MailerLite',
106
- 'class' => 'FLBuilderServiceMailerLite'
107
  ),
108
  'mailpoet' => array(
109
  'type' => 'autoresponder',
110
  'name' => 'MailPoet',
111
- 'class' => 'FLBuilderServiceMailPoet'
112
  ),
113
  'mailrelay' => array(
114
  'type' => 'autoresponder',
115
  'name' => 'Mailrelay',
116
- 'class' => 'FLBuilderServiceMailrelay'
117
  ),
118
  'sendinblue' => array(
119
  'type' => 'autoresponder',
120
  'name' => 'SendinBlue',
121
- 'class' => 'FLBuilderServiceSendinBlue'
122
  ),
123
  'sendy' => array(
124
  'type' => 'autoresponder',
125
  'name' => 'Sendy',
126
  'class' => 'FLBuilderServiceSendy',
127
- 'namespace' => true
128
- )
129
  );
130
 
131
  /**
@@ -136,15 +136,13 @@ final class FLBuilderServices {
136
  * @param string $type The type of service data to return.
137
  * @return array An array of services and related data.
138
  */
139
- static public function get_services_data( $type = null )
140
- {
141
  $services = array();
142
 
143
  // Return all services.
144
  if ( ! $type ) {
145
  $services = self::$services_data;
146
- }
147
- // Return services of a specific type.
148
  else {
149
 
150
  foreach ( self::$services_data as $key => $service ) {
@@ -155,8 +153,8 @@ final class FLBuilderServices {
155
  }
156
 
157
  foreach ( $services as $key => $service ) {
158
- if( isset( $service['namespace'] ) && ! version_compare( phpversion(), '5.3', '>=' ) ) {
159
- unset( $services[$key] );
160
  }
161
  }
162
  return $services;
@@ -169,8 +167,7 @@ final class FLBuilderServices {
169
  * @param string $type The type of service.
170
  * @return object
171
  */
172
- static public function get_service_instance( $service )
173
- {
174
  $services = self::get_services_data();
175
  $data = $services[ $service ];
176
 
@@ -195,23 +192,20 @@ final class FLBuilderServices {
195
  * @since 1.5.4
196
  * @return array The response array.
197
  */
198
- static public function connect_service()
199
- {
200
  $saved_services = FLBuilderModel::get_services();
201
  $post_data = FLBuilderModel::get_post_data();
202
  $response = array(
203
  'error' => false,
204
- 'html' => ''
205
  );
206
 
207
  // Validate the service data.
208
  if ( ! isset( $post_data['service'] ) || empty( $post_data['service'] ) ) {
209
  $response['error'] = _x( 'Error: Missing service type.', 'Third party service such as MailChimp.', 'fl-builder' );
210
- }
211
- else if ( ! isset( $post_data['fields'] ) || 0 === count( $post_data['fields'] ) ) {
212
  $response['error'] = _x( 'Error: Missing service data.', 'Connection data such as an API key.', 'fl-builder' );
213
- }
214
- else if ( ! isset( $post_data['fields']['service_account'] ) || empty( $post_data['fields']['service_account'] ) ) {
215
  $response['error'] = _x( 'Error: Missing account name.', 'Account name for a third party service such as MailChimp.', 'fl-builder' );
216
  }
217
 
@@ -232,8 +226,7 @@ final class FLBuilderServices {
232
 
233
  if ( $connection['error'] ) {
234
  $response['error'] = $connection['error'];
235
- }
236
- else {
237
 
238
  FLBuilderModel::update_services(
239
  $service,
@@ -257,8 +250,7 @@ final class FLBuilderServices {
257
  * @since 1.5.4
258
  * @return array The response array.
259
  */
260
- static public function render_settings()
261
- {
262
  $post_data = FLBuilderModel::get_post_data();
263
  $saved_services = FLBuilderModel::get_services();
264
  $module = FLBuilderModel::get_module( $post_data['node_id'] );
@@ -266,14 +258,13 @@ final class FLBuilderServices {
266
  $service = $post_data['service'];
267
  $response = array(
268
  'error' => false,
269
- 'html' => ''
270
  );
271
 
272
  // Render the settings to connect a new account.
273
  if ( isset( $post_data['add_new'] ) || ! isset( $saved_services[ $service ] ) ) {
274
  $response['html'] = self::render_connect_settings( $service );
275
- }
276
- // Render the settings to select a connected account.
277
  else {
278
  $account = isset( $settings->service_account ) ? $settings->service_account : '';
279
  $response['html'] = self::render_account_settings( $service, $account );
@@ -289,8 +280,7 @@ final class FLBuilderServices {
289
  * @since 1.5.4
290
  * @return string The settings markup.
291
  */
292
- static public function render_connect_settings( $service )
293
- {
294
  ob_start();
295
 
296
  FLBuilder::render_settings_field( 'service_account', array(
@@ -300,8 +290,8 @@ final class FLBuilderServices {
300
  'label' => __( 'Account Name', 'fl-builder' ),
301
  'help' => __( 'Used to identify this connection within the accounts list and can be anything you like.', 'fl-builder' ),
302
  'preview' => array(
303
- 'type' => 'none'
304
- )
305
  ));
306
 
307
  $instance = self::get_service_instance( $service );
@@ -311,7 +301,7 @@ final class FLBuilderServices {
311
  'row_class' => 'fl-builder-service-connect-row',
312
  'class' => 'fl-builder-service-connect-button',
313
  'type' => 'button',
314
- 'label' => __( 'Connect', 'fl-builder' )
315
  ));
316
 
317
  return ob_get_clean();
@@ -325,14 +315,15 @@ final class FLBuilderServices {
325
  * @param string $active The name of the active account, if any.
326
  * @return string The account settings markup.
327
  */
328
- static public function render_account_settings( $service, $active = '' )
329
- {
330
  ob_start();
331
 
332
  $saved_services = FLBuilderModel::get_services();
333
  $settings = new stdClass();
334
  $settings->service_account = $active;
335
- $options = array( '' => __( 'Choose...', 'fl-builder' ) );
 
 
336
 
337
  // Build the account select options.
338
  foreach ( $saved_services[ $service ] as $account => $data ) {
@@ -349,8 +340,8 @@ final class FLBuilderServices {
349
  'label' => __( 'Account', 'fl-builder' ),
350
  'options' => $options,
351
  'preview' => array(
352
- 'type' => 'none'
353
- )
354
  ), $settings);
355
 
356
  // Render additional service fields if we have a saved account.
@@ -377,8 +368,7 @@ final class FLBuilderServices {
377
  * @since 1.5.4
378
  * @return array The response array.
379
  */
380
- static public function render_fields()
381
- {
382
  $post_data = FLBuilderModel::get_post_data();
383
  $module = FLBuilderModel::get_module( $post_data['node_id'] );
384
  $instance = self::get_service_instance( $post_data['service'] );
@@ -395,8 +385,7 @@ final class FLBuilderServices {
395
  * @since 1.5.4
396
  * @return void
397
  */
398
- static public function delete_account()
399
- {
400
  $post_data = FLBuilderModel::get_post_data();
401
 
402
  if ( ! isset( $post_data['service'] ) || ! isset( $post_data['account'] ) ) {
18
  'activecampaign' => array(
19
  'type' => 'autoresponder',
20
  'name' => 'ActiveCampaign',
21
+ 'class' => 'FLBuilderServiceActiveCampaign',
22
  ),
23
  'aweber' => array(
24
  'type' => 'autoresponder',
25
  'name' => 'AWeber',
26
+ 'class' => 'FLBuilderServiceAWeber',
27
  ),
28
  'campaign-monitor' => array(
29
  'type' => 'autoresponder',
30
  'name' => 'Campaign Monitor',
31
+ 'class' => 'FLBuilderServiceCampaignMonitor',
32
  ),
33
  'campayn' => array(
34
  'type' => 'autoresponder',
35
  'name' => 'Campayn',
36
+ 'class' => 'FLBuilderServiceCampayn',
37
  ),
38
  'constant-contact' => array(
39
  'type' => 'autoresponder',
40
  'name' => 'Constant Contact',
41
+ 'class' => 'FLBuilderServiceConstantContact',
42
  ),
43
  'convertkit' => array(
44
  'type' => 'autoresponder',
45
  'name' => 'ConvertKit',
46
+ 'class' => 'FLBuilderServiceConvertKit',
47
  ),
48
  'drip' => array(
49
  'type' => 'autoresponder',
50
  'name' => 'Drip',
51
+ 'class' => 'FLBuilderServiceDrip',
52
  ),
53
  'email-address' => array(
54
  'type' => 'autoresponder',
55
  'name' => 'Email Address',
56
+ 'class' => 'FLBuilderServiceEmailAddress',
57
  ),
58
  'enormail' => array(
59
  'type' => 'autoresponder',
60
  'name' => 'Enormail',
61
+ 'class' => 'FLBuilderServiceEnormail',
62
  ),
63
  'getresponse' => array(
64
  'type' => 'autoresponder',
65
  'name' => 'GetResponse',
66
+ 'class' => 'FLBuilderServiceGetResponse',
67
  ),
68
  'godaddy-email-marketing' => array(
69
  'type' => 'autoresponder',
70
  'name' => 'GoDaddy Email Marketing',
71
+ 'class' => 'FLBuilderServiceGoDaddyEmailMarketing',
72
  ),
73
  'hatchbuck' => array(
74
  'type' => 'autoresponder',
75
  'name' => 'Hatchbuck',
76
+ 'class' => 'FLBuilderServiceHatchbuck',
77
  ),
78
  'icontact' => array(
79
  'type' => 'autoresponder',
80
  'name' => 'iContact',
81
+ 'class' => 'FLBuilderServiceIContact',
82
  ),
83
  'icontact-pro' => array(
84
  'type' => 'autoresponder',
85
  'name' => 'iContact Pro',
86
+ 'class' => 'FLBuilderServiceIContactPro',
87
  ),
88
  'infusionsoft' => array(
89
  'type' => 'autoresponder',
90
  'name' => 'Infusionsoft',
91
+ 'class' => 'FLBuilderServiceInfusionsoft',
92
  ),
93
  'madmimi' => array(
94
  'type' => 'autoresponder',
95
  'name' => 'Mad Mimi',
96
+ 'class' => 'FLBuilderServiceMadMimi',
97
  ),
98
  'mailchimp' => array(
99
  'type' => 'autoresponder',
100
  'name' => 'MailChimp',
101
+ 'class' => 'FLBuilderServiceMailChimp',
102
  ),
103
  'mailerlite' => array(
104
  'type' => 'autoresponder',
105
  'name' => 'MailerLite',
106
+ 'class' => 'FLBuilderServiceMailerLite',
107
  ),
108
  'mailpoet' => array(
109
  'type' => 'autoresponder',
110
  'name' => 'MailPoet',
111
+ 'class' => 'FLBuilderServiceMailPoet',
112
  ),
113
  'mailrelay' => array(
114
  'type' => 'autoresponder',
115
  'name' => 'Mailrelay',
116
+ 'class' => 'FLBuilderServiceMailrelay',
117
  ),
118
  'sendinblue' => array(
119
  'type' => 'autoresponder',
120
  'name' => 'SendinBlue',
121
+ 'class' => 'FLBuilderServiceSendinBlue',
122
  ),
123
  'sendy' => array(
124
  'type' => 'autoresponder',
125
  'name' => 'Sendy',
126
  'class' => 'FLBuilderServiceSendy',
127
+ 'namespace' => true,
128
+ ),
129
  );
130
 
131
  /**
136
  * @param string $type The type of service data to return.
137
  * @return array An array of services and related data.
138
  */
139
+ static public function get_services_data( $type = null ) {
 
140
  $services = array();
141
 
142
  // Return all services.
143
  if ( ! $type ) {
144
  $services = self::$services_data;
145
+ } // End if().
 
146
  else {
147
 
148
  foreach ( self::$services_data as $key => $service ) {
153
  }
154
 
155
  foreach ( $services as $key => $service ) {
156
+ if ( isset( $service['namespace'] ) && ! version_compare( phpversion(), '5.3', '>=' ) ) {
157
+ unset( $services[ $key ] );
158
  }
159
  }
160
  return $services;
167
  * @param string $type The type of service.
168
  * @return object
169
  */
170
+ static public function get_service_instance( $service ) {
 
171
  $services = self::get_services_data();
172
  $data = $services[ $service ];
173
 
192
  * @since 1.5.4
193
  * @return array The response array.
194
  */
195
+ static public function connect_service() {
 
196
  $saved_services = FLBuilderModel::get_services();
197
  $post_data = FLBuilderModel::get_post_data();
198
  $response = array(
199
  'error' => false,
200
+ 'html' => '',
201
  );
202
 
203
  // Validate the service data.
204
  if ( ! isset( $post_data['service'] ) || empty( $post_data['service'] ) ) {
205
  $response['error'] = _x( 'Error: Missing service type.', 'Third party service such as MailChimp.', 'fl-builder' );
206
+ } elseif ( ! isset( $post_data['fields'] ) || 0 === count( $post_data['fields'] ) ) {
 
207
  $response['error'] = _x( 'Error: Missing service data.', 'Connection data such as an API key.', 'fl-builder' );
208
+ } elseif ( ! isset( $post_data['fields']['service_account'] ) || empty( $post_data['fields']['service_account'] ) ) {
 
209
  $response['error'] = _x( 'Error: Missing account name.', 'Account name for a third party service such as MailChimp.', 'fl-builder' );
210
  }
211
 
226
 
227
  if ( $connection['error'] ) {
228
  $response['error'] = $connection['error'];
229
+ } else {
 
230
 
231
  FLBuilderModel::update_services(
232
  $service,
250
  * @since 1.5.4
251
  * @return array The response array.
252
  */
253
+ static public function render_settings() {
 
254
  $post_data = FLBuilderModel::get_post_data();
255
  $saved_services = FLBuilderModel::get_services();
256
  $module = FLBuilderModel::get_module( $post_data['node_id'] );
258
  $service = $post_data['service'];
259
  $response = array(
260
  'error' => false,
261
+ 'html' => '',
262
  );
263
 
264
  // Render the settings to connect a new account.
265
  if ( isset( $post_data['add_new'] ) || ! isset( $saved_services[ $service ] ) ) {
266
  $response['html'] = self::render_connect_settings( $service );
267
+ } // End if().
 
268
  else {
269
  $account = isset( $settings->service_account ) ? $settings->service_account : '';
270
  $response['html'] = self::render_account_settings( $service, $account );
280
  * @since 1.5.4
281
  * @return string The settings markup.
282
  */
283
+ static public function render_connect_settings( $service ) {
 
284
  ob_start();
285
 
286
  FLBuilder::render_settings_field( 'service_account', array(
290
  'label' => __( 'Account Name', 'fl-builder' ),
291
  'help' => __( 'Used to identify this connection within the accounts list and can be anything you like.', 'fl-builder' ),
292
  'preview' => array(
293
+ 'type' => 'none',
294
+ ),
295
  ));
296
 
297
  $instance = self::get_service_instance( $service );
301
  'row_class' => 'fl-builder-service-connect-row',
302
  'class' => 'fl-builder-service-connect-button',
303
  'type' => 'button',
304
+ 'label' => __( 'Connect', 'fl-builder' ),
305
  ));
306
 
307
  return ob_get_clean();
315
  * @param string $active The name of the active account, if any.
316
  * @return string The account settings markup.
317
  */
318
+ static public function render_account_settings( $service, $active = '' ) {
 
319
  ob_start();
320
 
321
  $saved_services = FLBuilderModel::get_services();
322
  $settings = new stdClass();
323
  $settings->service_account = $active;
324
+ $options = array(
325
+ '' => __( 'Choose...', 'fl-builder' ),
326
+ );
327
 
328
  // Build the account select options.
329
  foreach ( $saved_services[ $service ] as $account => $data ) {
340
  'label' => __( 'Account', 'fl-builder' ),
341
  'options' => $options,
342
  'preview' => array(
343
+ 'type' => 'none',
344
+ ),
345
  ), $settings);
346
 
347
  // Render additional service fields if we have a saved account.
368
  * @since 1.5.4
369
  * @return array The response array.
370
  */
371
+ static public function render_fields() {
 
372
  $post_data = FLBuilderModel::get_post_data();
373
  $module = FLBuilderModel::get_module( $post_data['node_id'] );
374
  $instance = self::get_service_instance( $post_data['service'] );
385
  * @since 1.5.4
386
  * @return void
387
  */
388
+ static public function delete_account() {
 
389
  $post_data = FLBuilderModel::get_post_data();
390
 
391
  if ( ! isset( $post_data['service'] ) || ! isset( $post_data['account'] ) ) {
classes/class-fl-builder-shortcodes.php CHANGED
@@ -13,65 +13,60 @@ final class FLBuilderShortcodes {
13
  * @since 1.7
14
  * @return void
15
  */
16
- static public function init()
17
- {
18
  add_shortcode( 'fl_builder_insert_layout', 'FLBuilderShortcodes::insert_layout' );
19
  }
20
 
21
  /**
22
- * Renders a layout with the provided post ID and enqueues the
23
  * necessary styles and scripts.
24
  *
25
  * @since 1.7
26
  * @param array $attrs The shortcode attributes.
27
  * @return string
28
  */
29
- static public function insert_layout( $attrs )
30
- {
31
  $builder_active = in_the_loop() && FLBuilderModel::is_builder_active();
32
  $post_type = isset( $attrs['type'] ) ? $attrs['type'] : get_post_types();
33
  $site_id = isset( $attrs['site'] ) ? absint( $attrs['site'] ) : null;
34
  $args = array(
35
  'post_type' => $post_type,
36
- 'posts_per_page' => -1
37
  );
38
-
39
  // Build the args array.
40
  if ( isset( $attrs['id'] ) ) {
41
-
42
  $args['orderby'] = 'post__in';
43
  $args['ignore_sticky_posts'] = true;
44
-
45
  if ( is_numeric( $attrs['id'] ) ) {
46
  $args['post__in'] = array( $attrs['id'] );
47
- }
48
- else {
49
  $args['post__in'] = explode( ',', $attrs['id'] );
50
  }
51
- }
52
- else if ( isset( $attrs['slug'] ) ) {
53
  $args['orderby'] = 'name';
54
  $args['name'] = $attrs['slug'];
55
- }
56
- else {
57
  return;
58
  }
59
-
60
  // Render and return the layout.
61
  ob_start();
62
-
63
  if ( $builder_active ) {
64
  echo '<div class="fl-builder-shortcode-mask-wrap"><div class="fl-builder-shortcode-mask"></div>';
65
  }
66
-
67
  FLBuilder::render_query( $args, $site_id );
68
-
69
  if ( $builder_active ) {
70
  echo '</div>';
71
  }
72
-
73
  return ob_get_clean();
74
  }
75
  }
76
 
77
- FLBuilderShortcodes::init();
13
  * @since 1.7
14
  * @return void
15
  */
16
+ static public function init() {
 
17
  add_shortcode( 'fl_builder_insert_layout', 'FLBuilderShortcodes::insert_layout' );
18
  }
19
 
20
  /**
21
+ * Renders a layout with the provided post ID and enqueues the
22
  * necessary styles and scripts.
23
  *
24
  * @since 1.7
25
  * @param array $attrs The shortcode attributes.
26
  * @return string
27
  */
28
+ static public function insert_layout( $attrs ) {
 
29
  $builder_active = in_the_loop() && FLBuilderModel::is_builder_active();
30
  $post_type = isset( $attrs['type'] ) ? $attrs['type'] : get_post_types();
31
  $site_id = isset( $attrs['site'] ) ? absint( $attrs['site'] ) : null;
32
  $args = array(
33
  'post_type' => $post_type,
34
+ 'posts_per_page' => -1,
35
  );
36
+
37
  // Build the args array.
38
  if ( isset( $attrs['id'] ) ) {
39
+
40
  $args['orderby'] = 'post__in';
41
  $args['ignore_sticky_posts'] = true;
42
+
43
  if ( is_numeric( $attrs['id'] ) ) {
44
  $args['post__in'] = array( $attrs['id'] );
45
+ } else {
 
46
  $args['post__in'] = explode( ',', $attrs['id'] );
47
  }
48
+ } elseif ( isset( $attrs['slug'] ) ) {
 
49
  $args['orderby'] = 'name';
50
  $args['name'] = $attrs['slug'];
51
+ } else {
 
52
  return;
53
  }
54
+
55
  // Render and return the layout.
56
  ob_start();
57
+
58
  if ( $builder_active ) {
59
  echo '<div class="fl-builder-shortcode-mask-wrap"><div class="fl-builder-shortcode-mask"></div>';
60
  }
61
+
62
  FLBuilder::render_query( $args, $site_id );
63
+
64
  if ( $builder_active ) {
65
  echo '</div>';
66
  }
67
+
68
  return ob_get_clean();
69
  }
70
  }
71
 
72
+ FLBuilderShortcodes::init();
classes/class-fl-builder-update.php CHANGED
@@ -1,24 +1,23 @@
1
  <?php
2
 
3
  /**
4
- * Helper class for builder updates.
5
  *
6
  * @since 1.2.8
7
  */
8
  final class FLBuilderUpdate {
9
 
10
- /**
11
  * Initialize hooks.
12
  *
13
  * @since 1.8
14
  * @return void
15
  */
16
- static public function init()
17
- {
18
  add_action( 'init', __CLASS__ . '::maybe_run', 11 );
19
  }
20
 
21
- /**
22
  * Checks to see if an update should be run. If it should,
23
  * the appropriate update method is run and the version
24
  * number is updated in the database.
@@ -26,124 +25,118 @@ final class FLBuilderUpdate {
26
  * @since 1.2.8
27
  * @return void
28
  */
29
- static public function maybe_run()
30
- {
31
  // Make sure the user is logged in.
32
  if ( ! is_user_logged_in() ) {
33
  return;
34
  }
35
-
36
  // Don't update for dev copies.
37
  if ( FL_BUILDER_VERSION == '{FL_BUILDER_VERSION}' ) {
38
  return;
39
  }
40
-
41
- // Get the saved version.
42
  $saved_version = get_site_option( '_fl_builder_version' );
43
-
44
  // No saved version number. This must be a fresh install.
45
  if ( ! $saved_version ) {
46
  update_site_option( '_fl_builder_version', FL_BUILDER_VERSION );
47
  return;
48
- }
49
- // Only run updates if the version numbers don't match.
50
- else if ( ! version_compare( $saved_version, FL_BUILDER_VERSION, '=' ) ) {
51
-
52
  if ( is_multisite() ) {
53
  self::run_multisite( $saved_version );
 
 
54
  }
55
- else {
56
- self::run( $saved_version );
57
- }
58
-
59
  update_site_option( '_fl_builder_version', FL_BUILDER_VERSION );
60
  }
61
  }
62
 
63
- /**
64
  * Runs the update for a specific version.
65
  *
66
  * @since 1.2.8
67
  * @access private
68
  * @return void
69
  */
70
- static private function run( $saved_version )
71
- {
72
  // Update to 1.2.8 or greater.
73
  if ( version_compare( $saved_version, '1.2.8', '<' ) ) {
74
  self::v_1_2_8();
75
  }
76
-
77
  // Update to 1.4.6 or greater.
78
  if ( version_compare( $saved_version, '1.4.6', '<' ) ) {
79
  self::v_1_4_6();
80
  }
81
-
82
  // Update to 1.6.3 or greater.
83
  if ( version_compare( $saved_version, '1.6.3', '<' ) ) {
84
  self::v_1_6_3();
85
  }
86
-
87
  // Update to 1.10 or greater.
88
  if ( version_compare( $saved_version, '1.10', '<' ) ) {
89
  self::v_1_10();
90
  }
91
-
92
  // Clear all asset cache.
93
  FLBuilderModel::delete_asset_cache_for_all_posts();
94
-
95
  // Flush the rewrite rules.
96
  flush_rewrite_rules();
97
  }
98
 
99
- /**
100
  * Runs the update for all sites on a network install.
101
  *
102
  * @since 1.2.8
103
  * @access private
104
  * @return void
105
  */
106
- static private function run_multisite( $saved_version )
107
- {
108
  global $blog_id;
109
  global $wpdb;
110
-
111
  // Network update to 1.10 or greater.
112
  if ( version_compare( $saved_version, '1.10', '<' ) ) {
113
  self::v_1_10( true );
114
  }
115
-
116
  // Save the original blog id.
117
  $original_blog_id = $blog_id;
118
-
119
  // Get all blog ids.
120
  $blog_ids = $wpdb->get_col( "SELECT blog_id FROM $wpdb->blogs" );
121
-
122
  // Loop through the blog ids and run the update.
123
  foreach ( $blog_ids as $id ) {
124
  switch_to_blog( $id );
125
  self::run( $saved_version );
126
  }
127
-
128
  // Revert to the original blog.
129
  switch_to_blog( $original_blog_id );
130
  }
131
 
132
- /**
133
  * Check for the fl_builder_nodes table that existed before 1.2.8.
134
  *
135
  * @since 1.2.8
136
  * @access private
137
  * @return bool
138
  */
139
- static private function pre_1_2_8_table_exists()
140
- {
141
  global $wpdb;
142
 
143
  $table = $wpdb->prefix . 'fl_builder_nodes';
144
- $results = $wpdb->get_results( $wpdb->prepare( "SHOW TABLES LIKE %s", $table ) );
145
 
146
- return count($results) > 0;
147
  }
148
 
149
  /**
@@ -154,16 +147,15 @@ final class FLBuilderUpdate {
154
  * @access private
155
  * @return bool
156
  */
157
- static private function pre_1_2_8_table_is_empty()
158
- {
159
  global $wpdb;
160
 
161
- if(self::pre_1_2_8_table_exists()) {
162
 
163
  $table = $wpdb->prefix . 'fl_builder_nodes';
164
- $nodes = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM %s", $table ) );
165
 
166
- return count($nodes) === 0;
167
  }
168
 
169
  return true;
@@ -176,64 +168,62 @@ final class FLBuilderUpdate {
176
  * @access private
177
  * @return void
178
  */
179
- static private function pre_1_2_8_backup()
180
- {
181
  global $wpdb;
182
 
183
- if(self::pre_1_2_8_table_exists()) {
184
 
185
  $cache_dir = FLBuilderModel::get_cache_dir();
186
  $table = $wpdb->prefix . 'fl_builder_nodes';
187
 
188
  // Get the data to backup.
189
- $nodes = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM %s", $table ) );
190
- $meta = $wpdb->get_results("SELECT * FROM {$wpdb->postmeta} WHERE meta_key = '_fl_builder_layout'");
191
 
192
  // Build the export object.
193
  $data = new StdClass();
194
  $data->version = FL_BUILDER_VERSION;
195
  $data->nodes = $nodes;
196
  $data->meta = $meta;
197
-
198
  // Save the backup.
199
- file_put_contents($cache_dir['path'] . 'backup.dat', serialize($data));
200
  }
201
  }
202
 
203
- /**
204
  * Restores a site to pre 1.2.8.
205
  *
206
  * @since 1.2.8
207
  * @access private
208
  * @return void
209
  */
210
- static private function pre_1_2_8_restore()
211
- {
212
  global $wpdb;
213
-
214
- if(!self::pre_1_2_8_table_exists() || self::pre_1_2_8_table_is_empty()) {
215
-
216
  $cache_dir = FLBuilderModel::get_cache_dir();
217
  $backup_path = $cache_dir['path'] . 'backup.dat';
218
-
219
  // Install the database.
220
  FLBuilderModel::install_database();
221
-
222
- // Check for the backup file.
223
- if(file_exists($backup_path)) {
224
-
225
  // Get the backup data.
226
- $backup = unserialize(file_get_contents($backup_path));
227
-
228
  // Check for the correct backup data.
229
- if(!isset($backup->nodes) || !isset($backup->meta)) {
230
  return;
231
  }
232
-
233
  // Restore the nodes.
234
- foreach($backup->nodes as $node) {
235
-
236
- $wpdb->insert("{$wpdb->prefix}fl_builder_nodes",
237
  array(
238
  'node' => $node->node,
239
  'type' => $node->type,
@@ -241,102 +231,100 @@ final class FLBuilderUpdate {
241
  'parent' => $node->parent,
242
  'position' => $node->position,
243
  'settings' => $node->settings,
244
- 'status' => $node->status
245
- ),
246
- array('%s', '%s', '%s', '%s', '%d', '%s', '%s')
247
  );
248
  }
249
-
250
  // Restore the meta.
251
- foreach($backup->meta as $meta) {
252
- update_post_meta($meta->post_id, '_fl_builder_layout', $meta->meta_value);
253
  }
254
  }
255
- }
256
  }
257
 
258
- /**
259
  * Update to version 1.2.8 or later.
260
  *
261
  * @since 1.2.8
262
  * @access private
263
  * @return void
264
  */
265
- static private function v_1_2_8()
266
- {
267
  global $wpdb;
268
 
269
- if(self::pre_1_2_8_table_exists()) {
270
 
271
  $table = $wpdb->prefix . 'fl_builder_nodes';
272
- $metas = $wpdb->get_results("SELECT * FROM {$wpdb->postmeta} WHERE meta_key = '_fl_builder_layout'");
273
  $cache_dir = FLBuilderModel::get_cache_dir();
274
 
275
  // Loop through the layout ids for each post.
276
- foreach($metas as $meta) {
277
 
278
  // Get the old layout nodes from the database.
279
  $published = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM %s WHERE layout = %s AND status = 'published'", $table, $meta->meta_value ) );
280
  $draft = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM %s WHERE layout = %s AND status = 'draft'", $table, $meta->meta_value ) );
281
 
282
  // Convert the old nodes to new ones.
283
- $published = self::v_1_2_8_convert_nodes($published);
284
- $draft = self::v_1_2_8_convert_nodes($draft);
285
 
286
  // Add the new layout post meta.
287
- update_post_meta($meta->post_id, '_fl_builder_data', $published);
288
- update_post_meta($meta->post_id, '_fl_builder_draft', $draft);
289
  }
290
 
291
  // Backup the old builder table.
292
  self::pre_1_2_8_backup();
293
 
294
  // Drop the old builder table.
295
- if(file_exists($cache_dir['path'] . 'backup.dat')) {
296
- $wpdb->query("DROP TABLE {$wpdb->prefix}fl_builder_nodes");
297
  }
298
 
299
  // Delete old post meta.
300
- delete_post_meta_by_key('_fl_builder_layout');
301
- delete_post_meta_by_key('_fl_builder_layout_export');
302
- delete_post_meta_by_key('_fl_builder_css');
303
- delete_post_meta_by_key('_fl_builder_css-draft');
304
- delete_post_meta_by_key('_fl_builder_js');
305
- delete_post_meta_by_key('_fl_builder_js-draft');
306
-
307
  // Convert global settings.
308
  self::v_1_2_8_convert_global_settings();
309
-
310
  // Delete all asset cache.
311
  $css = glob( $cache_dir['path'] . '*.css' );
312
  $js = glob( $cache_dir['path'] . '*.js' );
313
-
314
  if ( is_array( $css ) ) {
315
  array_map( 'unlink', $css );
316
  }
317
  if ( is_array( $js ) ) {
318
  array_map( 'unlink', $js );
319
  }
320
- }
321
  }
322
 
323
- /**
324
  * Convert the global settings for 1.2.8 or later.
325
  *
326
  * @since 1.2.8
327
  * @access private
328
  * @return void
329
  */
330
- static private function v_1_2_8_convert_global_settings()
331
- {
332
- $settings = get_option('_fl_builder_settings');
333
-
334
- if($settings && is_string($settings)) {
335
- update_option('_fl_builder_settings', json_decode($settings));
336
  }
337
  }
338
 
339
- /**
340
  * Convert the nodes for 1.2.8 or earlier.
341
  *
342
  * @since 1.2.8
@@ -344,28 +332,27 @@ final class FLBuilderUpdate {
344
  * @param array $nodes An array of node data.
345
  * @return array
346
  */
347
- static private function v_1_2_8_convert_nodes($nodes)
348
- {
349
  $new_nodes = array();
350
-
351
- foreach($nodes as $node) {
352
-
353
- unset($node->id);
354
- unset($node->layout);
355
- unset($node->status);
356
-
357
- if($node->type == 'row') {
358
  $node->parent = null;
359
  }
360
-
361
- $node->settings = self::v_1_2_8_json_decode_settings($node->settings);
362
- $new_nodes[$node->node] = $node;
363
  }
364
-
365
  return $new_nodes;
366
  }
367
 
368
- /**
369
  * Convert a JSON encoded settings string for 1.2.8 or earlier.
370
  *
371
  * @since 1.2.8
@@ -373,214 +360,203 @@ final class FLBuilderUpdate {
373
  * @param object $settings The settings object.
374
  * @return object
375
  */
376
- static private function v_1_2_8_json_decode_settings($settings)
377
- {
378
- if(!$settings || empty($settings)) {
379
- return null;
380
  }
381
-
382
- $settings = json_decode($settings);
383
-
384
- foreach($settings as $key => $val) {
385
-
386
- if(is_string($val)) {
387
-
388
- $decoded = json_decode($val);
389
-
390
- if(is_object($decoded) || is_array($decoded)) {
391
-
392
  $settings->{$key} = $decoded;
393
  }
394
- }
395
- else if(is_array($val)) {
396
-
397
- foreach($val as $sub_key => $sub_val) {
398
-
399
- if(is_string($sub_val)) {
400
-
401
- $decoded = json_decode($sub_val);
402
-
403
- if(is_object($decoded) || is_array($decoded)) {
404
-
405
- $settings->{$key}[$sub_key] = $decoded;
406
  }
407
  }
408
  }
409
  }
410
  }
411
-
412
  return $settings;
413
  }
414
-
415
- /**
416
  * Update to version 1.4.6 or later.
417
  *
418
  * @since 1.4.6
419
  * @access private
420
  * @return void
421
  */
422
- static private function v_1_4_6()
423
- {
424
  // Remove the old fl-builder uploads folder.
425
  $filesystem = FLBuilderUtils::get_filesystem();
426
  $upload_dir = wp_upload_dir();
427
  $path = trailingslashit( $upload_dir['basedir'] ) . 'fl-builder';
428
-
429
  if ( file_exists( $path ) ) {
430
  $filesystem->rmdir( $path, true );
431
  }
432
  }
433
-
434
- /**
435
  * Update to version 1.6.3 or later.
436
  *
437
  * @since 1.6.3
438
  * @access private
439
  * @return void
440
  */
441
- static private function v_1_6_3()
442
- {
443
  $posts = get_posts( array(
444
  'post_type' => 'fl-builder-template',
445
- 'posts_per_page' => '-1'
446
  ) );
447
-
448
  foreach ( $posts as $post ) {
449
-
450
  $type = wp_get_post_terms( $post->ID, 'fl-builder-template-type' );
451
-
452
  if ( 0 === count( $type ) ) {
453
  wp_set_post_terms( $post->ID, 'layout', 'fl-builder-template-type' );
454
  }
455
  }
456
  }
457
-
458
- /**
459
  * Update to version 1.10 or later.
460
  *
461
  * @since 1.10
462
  * @access private
463
  * @return void
464
  */
465
- static private function v_1_10( $network = false )
466
- {
467
  if ( ! function_exists( 'get_editable_roles' ) ) {
468
- require_once( ABSPATH . 'wp-admin/includes/user.php' );
469
  }
470
-
471
  $roles = get_editable_roles();
472
  $user_access = array();
473
  $unrestricted = self::v_1_10_convert_cap_to_roles( '_fl_builder_editing_capability', $roles, $network );
474
  $global_templates = self::v_1_10_convert_cap_to_roles( '_fl_builder_global_templates_editing_capability', $roles, $network );
475
  $builder_admin = self::v_1_10_convert_option_to_roles( '_fl_builder_user_templates_admin', $roles, $network );
476
  $template_exporter = self::v_1_10_convert_option_to_roles( '_fl_builder_template_data_exporter', $roles, $network );
477
-
478
  if ( ! empty( $unrestricted ) ) {
479
- $user_access[ 'unrestricted_editing' ] = $unrestricted;
480
  }
481
-
482
  if ( ! empty( $global_templates ) ) {
483
- $user_access[ 'global_node_editing' ] = $global_templates;
484
  }
485
-
486
  if ( ! empty( $builder_admin ) ) {
487
- $user_access[ 'builder_admin' ] = $builder_admin;
488
  }
489
-
490
  if ( ! empty( $template_exporter ) ) {
491
- $user_access[ 'template_data_exporter' ] = $template_exporter;
492
  }
493
-
494
  if ( ! empty( $user_access ) ) {
495
-
496
  if ( $network ) {
497
  update_site_option( '_fl_builder_user_access', $user_access );
498
- }
499
- else {
500
  update_option( '_fl_builder_user_access', $user_access );
501
  }
502
  }
503
  }
504
-
505
- /**
506
  * Convert an old editing capability to a role settings.
507
  *
508
  * @since 1.10
509
  * @access private
510
  * @return array
511
  */
512
- static private function v_1_10_convert_cap_to_roles( $key, $roles, $network = false )
513
- {
514
  $option = $network ? get_site_option( $key ) : get_option( $key );
515
  $data = array();
516
-
517
  if ( ! empty( $option ) ) {
518
-
519
  if ( $network ) {
520
  delete_site_option( $key );
521
- }
522
- else {
523
  delete_option( $key );
524
  }
525
-
526
  $option = explode( ',', $option );
527
-
528
  foreach ( $roles as $role_key => $role_data ) {
529
-
530
  if ( ! isset( $role_data['capabilities']['edit_posts'] ) ) {
531
  continue;
532
  }
533
-
534
  $data[ $role_key ] = false;
535
-
536
  foreach ( $option as $cap ) {
537
-
538
  if ( isset( $role_data['capabilities'][ trim( $cap ) ] ) ) {
539
  $data[ $role_key ] = true;
540
  break;
541
- }
542
  }
543
  }
544
-
545
  }
546
-
547
  return $data;
548
  }
549
-
550
- /**
551
  * Convert old options to user access roles.
552
  *
553
  * @since 1.10
554
  * @access private
555
  * @return array
556
  */
557
- static private function v_1_10_convert_option_to_roles( $key, $roles, $network = false )
558
- {
559
  $option = $network ? get_site_option( $key ) : get_option( $key );
560
  $enabled = ! empty( $option ) && $option;
561
  $data = array();
562
-
563
  if ( ! empty( $option ) ) {
564
-
565
  if ( $network ) {
566
  delete_site_option( $key );
567
- }
568
- else {
569
  delete_option( $key );
570
  }
571
-
572
  foreach ( $roles as $role_key => $role_data ) {
573
-
574
  if ( ! isset( $role_data['capabilities']['edit_posts'] ) ) {
575
  continue;
576
  }
577
-
578
  $data[ $role_key ] = $enabled;
579
  }
580
  }
581
-
582
  return $data;
583
  }
584
  }
585
 
586
- FLBuilderUpdate::init();
1
  <?php
2
 
3
  /**
4
+ * Helper class for builder updates.
5
  *
6
  * @since 1.2.8
7
  */
8
  final class FLBuilderUpdate {
9
 
10
+ /**
11
  * Initialize hooks.
12
  *
13
  * @since 1.8
14
  * @return void
15
  */
16
+ static public function init() {
 
17
  add_action( 'init', __CLASS__ . '::maybe_run', 11 );
18
  }
19
 
20
+ /**
21
  * Checks to see if an update should be run. If it should,
22
  * the appropriate update method is run and the version
23
  * number is updated in the database.
25
  * @since 1.2.8
26
  * @return void
27
  */
28
+ static public function maybe_run() {
 
29
  // Make sure the user is logged in.
30
  if ( ! is_user_logged_in() ) {
31
  return;
32
  }
33
+
34
  // Don't update for dev copies.
35
  if ( FL_BUILDER_VERSION == '{FL_BUILDER_VERSION}' ) {
36
  return;
37
  }
38
+
39
+ // Get the saved version.
40
  $saved_version = get_site_option( '_fl_builder_version' );
41
+
42
  // No saved version number. This must be a fresh install.
43
  if ( ! $saved_version ) {
44
  update_site_option( '_fl_builder_version', FL_BUILDER_VERSION );
45
  return;
46
+ } // End if().
47
+ elseif ( ! version_compare( $saved_version, FL_BUILDER_VERSION, '=' ) ) {
48
+
 
49
  if ( is_multisite() ) {
50
  self::run_multisite( $saved_version );
51
+ } else {
52
+ self::run( $saved_version );
53
  }
54
+
 
 
 
55
  update_site_option( '_fl_builder_version', FL_BUILDER_VERSION );
56
  }
57
  }
58
 
59
+ /**
60
  * Runs the update for a specific version.
61
  *
62
  * @since 1.2.8
63
  * @access private
64
  * @return void
65
  */
66
+ static private function run( $saved_version ) {
 
67
  // Update to 1.2.8 or greater.
68
  if ( version_compare( $saved_version, '1.2.8', '<' ) ) {
69
  self::v_1_2_8();
70
  }
71
+
72
  // Update to 1.4.6 or greater.
73
  if ( version_compare( $saved_version, '1.4.6', '<' ) ) {
74
  self::v_1_4_6();
75
  }
76
+
77
  // Update to 1.6.3 or greater.
78
  if ( version_compare( $saved_version, '1.6.3', '<' ) ) {
79
  self::v_1_6_3();
80
  }
81
+
82
  // Update to 1.10 or greater.
83
  if ( version_compare( $saved_version, '1.10', '<' ) ) {
84
  self::v_1_10();
85
  }
86
+
87
  // Clear all asset cache.
88
  FLBuilderModel::delete_asset_cache_for_all_posts();
89
+
90
  // Flush the rewrite rules.
91
  flush_rewrite_rules();
92
  }
93
 
94
+ /**
95
  * Runs the update for all sites on a network install.
96
  *
97
  * @since 1.2.8
98
  * @access private
99
  * @return void
100
  */
101
+ static private function run_multisite( $saved_version ) {
 
102
  global $blog_id;
103
  global $wpdb;
104
+
105
  // Network update to 1.10 or greater.
106
  if ( version_compare( $saved_version, '1.10', '<' ) ) {
107
  self::v_1_10( true );
108
  }
109
+
110
  // Save the original blog id.
111
  $original_blog_id = $blog_id;
112
+
113
  // Get all blog ids.
114
  $blog_ids = $wpdb->get_col( "SELECT blog_id FROM $wpdb->blogs" );
115
+
116
  // Loop through the blog ids and run the update.
117
  foreach ( $blog_ids as $id ) {
118
  switch_to_blog( $id );
119
  self::run( $saved_version );
120
  }
121
+
122
  // Revert to the original blog.
123
  switch_to_blog( $original_blog_id );
124
  }
125
 
126
+ /**
127
  * Check for the fl_builder_nodes table that existed before 1.2.8.
128
  *
129
  * @since 1.2.8
130
  * @access private
131
  * @return bool
132
  */
133
+ static private function pre_1_2_8_table_exists() {
 
134
  global $wpdb;
135
 
136
  $table = $wpdb->prefix . 'fl_builder_nodes';
137
+ $results = $wpdb->get_results( $wpdb->prepare( 'SHOW TABLES LIKE %s', $table ) );
138
 
139
+ return count( $results ) > 0;
140
  }
141
 
142
  /**
147
  * @access private
148
  * @return bool
149
  */
150
+ static private function pre_1_2_8_table_is_empty() {
 
151
  global $wpdb;
152
 
153
+ if ( self::pre_1_2_8_table_exists() ) {
154
 
155
  $table = $wpdb->prefix . 'fl_builder_nodes';
156
+ $nodes = $wpdb->get_results( $wpdb->prepare( 'SELECT * FROM %s', $table ) );
157
 
158
+ return count( $nodes ) === 0;
159
  }
160
 
161
  return true;
168
  * @access private
169
  * @return void
170
  */
171
+ static private function pre_1_2_8_backup() {
 
172
  global $wpdb;
173
 
174
+ if ( self::pre_1_2_8_table_exists() ) {
175
 
176
  $cache_dir = FLBuilderModel::get_cache_dir();
177
  $table = $wpdb->prefix . 'fl_builder_nodes';
178
 
179
  // Get the data to backup.
180
+ $nodes = $wpdb->get_results( $wpdb->prepare( 'SELECT * FROM %s', $table ) );
181
+ $meta = $wpdb->get_results( "SELECT * FROM {$wpdb->postmeta} WHERE meta_key = '_fl_builder_layout'" );
182
 
183
  // Build the export object.
184
  $data = new StdClass();
185
  $data->version = FL_BUILDER_VERSION;
186
  $data->nodes = $nodes;
187
  $data->meta = $meta;
188
+
189
  // Save the backup.
190
+ file_put_contents( $cache_dir['path'] . 'backup.dat', serialize( $data ) );
191
  }
192
  }
193
 
194
+ /**
195
  * Restores a site to pre 1.2.8.
196
  *
197
  * @since 1.2.8
198
  * @access private
199
  * @return void
200
  */
201
+ static private function pre_1_2_8_restore() {
 
202
  global $wpdb;
203
+
204
+ if ( ! self::pre_1_2_8_table_exists() || self::pre_1_2_8_table_is_empty() ) {
205
+
206
  $cache_dir = FLBuilderModel::get_cache_dir();
207
  $backup_path = $cache_dir['path'] . 'backup.dat';
208
+
209
  // Install the database.
210
  FLBuilderModel::install_database();
211
+
212
+ // Check for the backup file.
213
+ if ( file_exists( $backup_path ) ) {
214
+
215
  // Get the backup data.
216
+ $backup = unserialize( file_get_contents( $backup_path ) );
217
+
218
  // Check for the correct backup data.
219
+ if ( ! isset( $backup->nodes ) || ! isset( $backup->meta ) ) {
220
  return;
221
  }
222
+
223
  // Restore the nodes.
224
+ foreach ( $backup->nodes as $node ) {
225
+
226
+ $wpdb->insert("{$wpdb->prefix}fl_builder_nodes",
227
  array(
228
  'node' => $node->node,
229
  'type' => $node->type,
231
  'parent' => $node->parent,
232
  'position' => $node->position,
233
  'settings' => $node->settings,
234
+ 'status' => $node->status,
235
+ ),
236
+ array( '%s', '%s', '%s', '%s', '%d', '%s', '%s' )
237
  );
238
  }
239
+
240
  // Restore the meta.
241
+ foreach ( $backup->meta as $meta ) {
242
+ update_post_meta( $meta->post_id, '_fl_builder_layout', $meta->meta_value );
243
  }
244
  }
245
+ }// End if().
246
  }
247
 
248
+ /**
249
  * Update to version 1.2.8 or later.
250
  *
251
  * @since 1.2.8
252
  * @access private
253
  * @return void
254
  */
255
+ static private function v_1_2_8() {
 
256
  global $wpdb;
257
 
258
+ if ( self::pre_1_2_8_table_exists() ) {
259
 
260
  $table = $wpdb->prefix . 'fl_builder_nodes';
261
+ $metas = $wpdb->get_results( "SELECT * FROM {$wpdb->postmeta} WHERE meta_key = '_fl_builder_layout'" );
262
  $cache_dir = FLBuilderModel::get_cache_dir();
263
 
264
  // Loop through the layout ids for each post.
265
+ foreach ( $metas as $meta ) {
266
 
267
  // Get the old layout nodes from the database.
268
  $published = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM %s WHERE layout = %s AND status = 'published'", $table, $meta->meta_value ) );
269
  $draft = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM %s WHERE layout = %s AND status = 'draft'", $table, $meta->meta_value ) );
270
 
271
  // Convert the old nodes to new ones.
272
+ $published = self::v_1_2_8_convert_nodes( $published );
273
+ $draft = self::v_1_2_8_convert_nodes( $draft );
274
 
275
  // Add the new layout post meta.
276
+ update_post_meta( $meta->post_id, '_fl_builder_data', $published );
277
+ update_post_meta( $meta->post_id, '_fl_builder_draft', $draft );
278
  }
279
 
280
  // Backup the old builder table.
281
  self::pre_1_2_8_backup();
282
 
283
  // Drop the old builder table.
284
+ if ( file_exists( $cache_dir['path'] . 'backup.dat' ) ) {
285
+ $wpdb->query( "DROP TABLE {$wpdb->prefix}fl_builder_nodes" );
286
  }
287
 
288
  // Delete old post meta.
289
+ delete_post_meta_by_key( '_fl_builder_layout' );
290
+ delete_post_meta_by_key( '_fl_builder_layout_export' );
291
+ delete_post_meta_by_key( '_fl_builder_css' );
292
+ delete_post_meta_by_key( '_fl_builder_css-draft' );
293
+ delete_post_meta_by_key( '_fl_builder_js' );
294
+ delete_post_meta_by_key( '_fl_builder_js-draft' );
295
+
296
  // Convert global settings.
297
  self::v_1_2_8_convert_global_settings();
298
+
299
  // Delete all asset cache.
300
  $css = glob( $cache_dir['path'] . '*.css' );
301
  $js = glob( $cache_dir['path'] . '*.js' );
302
+
303
  if ( is_array( $css ) ) {
304
  array_map( 'unlink', $css );
305
  }
306
  if ( is_array( $js ) ) {
307
  array_map( 'unlink', $js );
308
  }
309
+ }// End if().
310
  }
311
 
312
+ /**
313
  * Convert the global settings for 1.2.8 or later.
314
  *
315
  * @since 1.2.8
316
  * @access private
317
  * @return void
318
  */
319
+ static private function v_1_2_8_convert_global_settings() {
320
+ $settings = get_option( '_fl_builder_settings' );
321
+
322
+ if ( $settings && is_string( $settings ) ) {
323
+ update_option( '_fl_builder_settings', json_decode( $settings ) );
 
324
  }
325
  }
326
 
327
+ /**
328
  * Convert the nodes for 1.2.8 or earlier.
329
  *
330
  * @since 1.2.8
332
  * @param array $nodes An array of node data.
333
  * @return array
334
  */
335
+ static private function v_1_2_8_convert_nodes( $nodes ) {
 
336
  $new_nodes = array();
337
+
338
+ foreach ( $nodes as $node ) {
339
+
340
+ unset( $node->id );
341
+ unset( $node->layout );
342
+ unset( $node->status );
343
+
344
+ if ( 'row' == $node->type ) {
345
  $node->parent = null;
346
  }
347
+
348
+ $node->settings = self::v_1_2_8_json_decode_settings( $node->settings );
349
+ $new_nodes[ $node->node ] = $node;
350
  }
351
+
352
  return $new_nodes;
353
  }
354
 
355
+ /**
356
  * Convert a JSON encoded settings string for 1.2.8 or earlier.
357
  *
358
  * @since 1.2.8
360
  * @param object $settings The settings object.
361
  * @return object
362
  */
363
+ static private function v_1_2_8_json_decode_settings( $settings ) {
364
+ if ( ! $settings || empty( $settings ) ) {
365
+ return null;
 
366
  }
367
+
368
+ $settings = json_decode( $settings );
369
+
370
+ foreach ( $settings as $key => $val ) {
371
+
372
+ if ( is_string( $val ) ) {
373
+
374
+ $decoded = json_decode( $val );
375
+
376
+ if ( is_object( $decoded ) || is_array( $decoded ) ) {
377
+
378
  $settings->{$key} = $decoded;
379
  }
380
+ } elseif ( is_array( $val ) ) {
381
+
382
+ foreach ( $val as $sub_key => $sub_val ) {
383
+
384
+ if ( is_string( $sub_val ) ) {
385
+
386
+ $decoded = json_decode( $sub_val );
387
+
388
+ if ( is_object( $decoded ) || is_array( $decoded ) ) {
389
+
390
+ $settings->{$key}[ $sub_key ] = $decoded;
 
391
  }
392
  }
393
  }
394
  }
395
  }
396
+
397
  return $settings;
398
  }
399
+
400
+ /**
401
  * Update to version 1.4.6 or later.
402
  *
403
  * @since 1.4.6
404
  * @access private
405
  * @return void
406
  */
407
+ static private function v_1_4_6() {
 
408
  // Remove the old fl-builder uploads folder.
409
  $filesystem = FLBuilderUtils::get_filesystem();
410
  $upload_dir = wp_upload_dir();
411
  $path = trailingslashit( $upload_dir['basedir'] ) . 'fl-builder';
412
+
413
  if ( file_exists( $path ) ) {
414
  $filesystem->rmdir( $path, true );
415
  }
416
  }
417
+
418
+ /**
419
  * Update to version 1.6.3 or later.
420
  *
421
  * @since 1.6.3
422
  * @access private
423
  * @return void
424
  */
425
+ static private function v_1_6_3() {
 
426
  $posts = get_posts( array(
427
  'post_type' => 'fl-builder-template',
428
+ 'posts_per_page' => '-1',
429
  ) );
430
+
431
  foreach ( $posts as $post ) {
432
+
433
  $type = wp_get_post_terms( $post->ID, 'fl-builder-template-type' );
434
+
435
  if ( 0 === count( $type ) ) {
436
  wp_set_post_terms( $post->ID, 'layout', 'fl-builder-template-type' );
437
  }
438
  }
439
  }
440
+
441
+ /**
442
  * Update to version 1.10 or later.
443
  *
444
  * @since 1.10
445
  * @access private
446
  * @return void
447
  */
448
+ static private function v_1_10( $network = false ) {
 
449
  if ( ! function_exists( 'get_editable_roles' ) ) {
450
+ require_once( ABSPATH . 'wp-admin/includes/user.php' );
451
  }
452
+
453
  $roles = get_editable_roles();
454
  $user_access = array();
455
  $unrestricted = self::v_1_10_convert_cap_to_roles( '_fl_builder_editing_capability', $roles, $network );
456
  $global_templates = self::v_1_10_convert_cap_to_roles( '_fl_builder_global_templates_editing_capability', $roles, $network );
457
  $builder_admin = self::v_1_10_convert_option_to_roles( '_fl_builder_user_templates_admin', $roles, $network );
458
  $template_exporter = self::v_1_10_convert_option_to_roles( '_fl_builder_template_data_exporter', $roles, $network );
459
+
460
  if ( ! empty( $unrestricted ) ) {
461
+ $user_access['unrestricted_editing'] = $unrestricted;
462
  }
463
+
464
  if ( ! empty( $global_templates ) ) {
465
+ $user_access['global_node_editing'] = $global_templates;
466
  }
467
+
468
  if ( ! empty( $builder_admin ) ) {
469
+ $user_access['builder_admin'] = $builder_admin;
470
  }
471
+
472
  if ( ! empty( $template_exporter ) ) {
473
+ $user_access['template_data_exporter'] = $template_exporter;
474
  }
475
+
476
  if ( ! empty( $user_access ) ) {
477
+
478
  if ( $network ) {
479
  update_site_option( '_fl_builder_user_access', $user_access );
480
+ } else {
 
481
  update_option( '_fl_builder_user_access', $user_access );
482
  }
483
  }
484
  }
485
+
486
+ /**
487
  * Convert an old editing capability to a role settings.
488
  *
489
  * @since 1.10
490
  * @access private
491
  * @return array
492
  */
493
+ static private function v_1_10_convert_cap_to_roles( $key, $roles, $network = false ) {
 
494
  $option = $network ? get_site_option( $key ) : get_option( $key );
495
  $data = array();
496
+
497
  if ( ! empty( $option ) ) {
498
+
499
  if ( $network ) {
500
  delete_site_option( $key );
501
+ } else {
 
502
  delete_option( $key );
503
  }
504
+
505
  $option = explode( ',', $option );
506
+
507
  foreach ( $roles as $role_key => $role_data ) {
508
+
509
  if ( ! isset( $role_data['capabilities']['edit_posts'] ) ) {
510
  continue;
511
  }
512
+
513
  $data[ $role_key ] = false;
514
+
515
  foreach ( $option as $cap ) {
516
+
517
  if ( isset( $role_data['capabilities'][ trim( $cap ) ] ) ) {
518
  $data[ $role_key ] = true;
519
  break;
520
+ }
521
  }
522
  }
 
523
  }
524
+
525
  return $data;
526
  }
527
+
528
+ /**
529
  * Convert old options to user access roles.
530
  *
531
  * @since 1.10
532
  * @access private
533
  * @return array
534
  */
535
+ static private function v_1_10_convert_option_to_roles( $key, $roles, $network = false ) {
 
536
  $option = $network ? get_site_option( $key ) : get_option( $key );
537
  $enabled = ! empty( $option ) && $option;
538
  $data = array();
539
+
540
  if ( ! empty( $option ) ) {
541
+
542
  if ( $network ) {
543
  delete_site_option( $key );
544
+ } else {
 
545
  delete_option( $key );
546
  }
547
+
548
  foreach ( $roles as $role_key => $role_data ) {
549
+
550
  if ( ! isset( $role_data['capabilities']['edit_posts'] ) ) {
551
  continue;
552
  }
553
+
554
  $data[ $role_key ] = $enabled;
555
  }
556
  }
557
+
558
  return $data;
559
  }
560
  }
561
 
562
+ FLBuilderUpdate::init();
classes/class-fl-builder-user-access.php CHANGED
@@ -32,8 +32,7 @@ final class FLBuilderUserAccess {
32
  * @since 1.10
33
  * @return void
34
  */
35
- static public function init()
36
- {
37
  add_action( 'after_setup_theme', __CLASS__ . '::register_default_settings' );
38
  }
39
 
@@ -45,12 +44,11 @@ final class FLBuilderUserAccess {
45
  * @param array $data The setting data.
46
  * @return void
47
  */
48
- static public function register_setting( $key, $data )
49
- {
50
  if ( ! isset( $data['group'] ) ) {
51
  $data['group'] = __( 'Misc', 'fl-builder' );
52
  }
53
- if( ! isset( $data['order'] ) ) {
54
  $data['order'] = '10';
55
  }
56
  self::$registered_settings[ $key ] = $data;
@@ -63,8 +61,7 @@ final class FLBuilderUserAccess {
63
  * @since 1.10
64
  * @return array
65
  */
66
- static public function get_registered_settings()
67
- {
68
  return self::$registered_settings;
69
  }
70
 
@@ -75,8 +72,7 @@ final class FLBuilderUserAccess {
75
  * @since 1.10
76
  * @return array
77
  */
78
- static public function get_grouped_registered_settings()
79
- {
80
  $groups = array();
81
  $settings = self::$registered_settings;
82
 
@@ -84,7 +80,7 @@ final class FLBuilderUserAccess {
84
  * Sort the groups based on priority.
85
  * TODO update when were 5.3+ in PHP.
86
  */
87
- uasort($settings, create_function( '$a,$b', 'return $a["order"] > $b["order"];' ) );
88
 
89
  foreach ( $settings as $key => $data ) {
90
 
@@ -103,8 +99,7 @@ final class FLBuilderUserAccess {
103
  * @since 1.10
104
  * @return array
105
  */
106
- static public function get_saved_settings()
107
- {
108
  if ( self::$settings ) {
109
  return self::$settings;
110
  }
@@ -123,8 +118,7 @@ final class FLBuilderUserAccess {
123
  if ( ! isset( $settings[ $key ] ) ) {
124
  if ( $ms_support && isset( $ms_settings[ $key ] ) ) {
125
  $settings[ $key ] = $ms_settings[ $key ];
126
- }
127
- else{
128
  $settings[ $key ] = array();
129
  }
130
  }
@@ -135,17 +129,14 @@ final class FLBuilderUserAccess {
135
 
136
  if ( ! isset( $data['default'] ) || ! $data['default'] ) {
137
  $settings[ $key ][ $role_key ] = false;
138
- }
139
- else if ( is_array( $data['default'] ) ) {
140
 
141
  if ( in_array( $role_key, $data['default'] ) ) {
142
  $settings[ $key ][ $role_key ] = true;
143
- }
144
- else {
145
  $settings[ $key ][ $role_key ] = false;
146
  }
147
- }
148
- else {
149
  $settings[ $key ][ $role_key ] = true;
150
  }
151
  }
@@ -164,8 +155,7 @@ final class FLBuilderUserAccess {
164
  * @since 1.10
165
  * @return array
166
  */
167
- static public function get_raw_settings()
168
- {
169
  $settings = FLBuilderModel::get_admin_settings_option( '_fl_builder_user_access', true );
170
 
171
  if ( ! is_array( $settings ) ) {
@@ -182,8 +172,7 @@ final class FLBuilderUserAccess {
182
  * @param array $data The user access data to save.
183
  * @return void
184
  */
185
- static public function save_settings( $data = array() )
186
- {
187
  $roles = self::get_all_roles();
188
  $settings = array();
189
  $ms_support = FLBuilderAdminSettings::multisite_support();
@@ -220,18 +209,20 @@ final class FLBuilderUserAccess {
220
  * @since 1.10
221
  * @return array
222
  */
223
- static public function get_all_roles()
224
- {
225
  if ( ! function_exists( 'get_editable_roles' ) ) {
226
  require_once( ABSPATH . 'wp-admin/includes/user.php' );
227
  }
228
 
229
  $editable_roles = get_editable_roles();
230
  $roles = array();
 
231
 
232
  foreach ( $editable_roles as $role => $data ) {
233
- if ( isset( $data['capabilities']['edit_posts'] ) && 1 == $data['capabilities']['edit_posts'] ) {
234
- $roles[ $role ] = $data['name'];
 
 
235
  }
236
  }
237
 
@@ -247,13 +238,20 @@ final class FLBuilderUserAccess {
247
  * @param string $key The feature key to check.
248
  * @return bool
249
  */
250
- static public function current_user_can( $key )
251
- {
252
  $user = wp_get_current_user();
253
  $settings = self::get_saved_settings();
 
 
254
 
255
  // Return false for users that can't edit posts.
256
- if ( ! current_user_can( 'edit_posts' ) ) {
 
 
 
 
 
 
257
  return false;
258
  }
259
 
@@ -286,14 +284,13 @@ final class FLBuilderUserAccess {
286
  * @private
287
  * @return void
288
  */
289
- static function register_default_settings()
290
- {
291
  self::register_setting( 'unrestricted_editing', array(
292
  'default' => 'all',
293
  'group' => __( 'Frontend', 'fl-builder' ),
294
  'label' => __( 'Unrestricted Editing', 'fl-builder' ),
295
  'description' => __( 'The selected roles will have unrestricted access to all editing features.', 'fl-builder' ),
296
- 'order' => '1'
297
  ) );
298
  }
299
  }
32
  * @since 1.10
33
  * @return void
34
  */
35
+ static public function init() {
 
36
  add_action( 'after_setup_theme', __CLASS__ . '::register_default_settings' );
37
  }
38
 
44
  * @param array $data The setting data.
45
  * @return void
46
  */
47
+ static public function register_setting( $key, $data ) {
 
48
  if ( ! isset( $data['group'] ) ) {
49
  $data['group'] = __( 'Misc', 'fl-builder' );
50
  }
51
+ if ( ! isset( $data['order'] ) ) {
52
  $data['order'] = '10';
53
  }
54
  self::$registered_settings[ $key ] = $data;
61
  * @since 1.10
62
  * @return array
63
  */
64
+ static public function get_registered_settings() {
 
65
  return self::$registered_settings;
66
  }
67
 
72
  * @since 1.10
73
  * @return array
74
  */
75
+ static public function get_grouped_registered_settings() {
 
76
  $groups = array();
77
  $settings = self::$registered_settings;
78
 
80
  * Sort the groups based on priority.
81
  * TODO update when were 5.3+ in PHP.
82
  */
83
+ uasort( $settings, create_function( '$a,$b', 'return $a["order"] > $b["order"];' ) );
84
 
85
  foreach ( $settings as $key => $data ) {
86
 
99
  * @since 1.10
100
  * @return array
101
  */
102
+ static public function get_saved_settings() {
 
103
  if ( self::$settings ) {
104
  return self::$settings;
105
  }
118
  if ( ! isset( $settings[ $key ] ) ) {
119
  if ( $ms_support && isset( $ms_settings[ $key ] ) ) {
120
  $settings[ $key ] = $ms_settings[ $key ];
121
+ } else {
 
122
  $settings[ $key ] = array();
123
  }
124
  }
129
 
130
  if ( ! isset( $data['default'] ) || ! $data['default'] ) {
131
  $settings[ $key ][ $role_key ] = false;
132
+ } elseif ( is_array( $data['default'] ) ) {
 
133
 
134
  if ( in_array( $role_key, $data['default'] ) ) {
135
  $settings[ $key ][ $role_key ] = true;
136
+ } else {
 
137
  $settings[ $key ][ $role_key ] = false;
138
  }
139
+ } else {
 
140
  $settings[ $key ][ $role_key ] = true;
141
  }
142
  }
155
  * @since 1.10
156
  * @return array
157
  */
158
+ static public function get_raw_settings() {
 
159
  $settings = FLBuilderModel::get_admin_settings_option( '_fl_builder_user_access', true );
160
 
161
  if ( ! is_array( $settings ) ) {
172
  * @param array $data The user access data to save.
173
  * @return void
174
  */
175
+ static public function save_settings( $data = array() ) {
 
176
  $roles = self::get_all_roles();
177
  $settings = array();
178
  $ms_support = FLBuilderAdminSettings::multisite_support();
209
  * @since 1.10
210
  * @return array
211
  */
212
+ static public function get_all_roles() {
 
213
  if ( ! function_exists( 'get_editable_roles' ) ) {
214
  require_once( ABSPATH . 'wp-admin/includes/user.php' );
215
  }
216
 
217
  $editable_roles = get_editable_roles();
218
  $roles = array();
219
+ $caps = apply_filters( 'fl_builder_user_access_capabilities', array( 'edit_posts' ) );
220
 
221
  foreach ( $editable_roles as $role => $data ) {
222
+ foreach ( $caps as $cap ) {
223
+ if ( isset( $data['capabilities'][ $cap ] ) && 1 == $data['capabilities'][ $cap ] ) {
224
+ $roles[ $role ] = $data['name'];
225
+ }
226
  }
227
  }
228
 
238
  * @param string $key The feature key to check.
239
  * @return bool
240
  */
241
+ static public function current_user_can( $key ) {
 
242
  $user = wp_get_current_user();
243
  $settings = self::get_saved_settings();
244
+ $caps = apply_filters( 'fl_builder_user_access_capabilities', array( 'edit_posts' ) );
245
+ $user_can = false;
246
 
247
  // Return false for users that can't edit posts.
248
+ foreach ( $caps as $cap ) {
249
+ if ( current_user_can( $cap ) ) {
250
+ $user_can = true;
251
+ }
252
+ }
253
+
254
+ if ( ! $user_can ) {
255
  return false;
256
  }
257
 
284
  * @private
285
  * @return void
286
  */
287
+ static function register_default_settings() {
 
288
  self::register_setting( 'unrestricted_editing', array(
289
  'default' => 'all',
290
  'group' => __( 'Frontend', 'fl-builder' ),
291
  'label' => __( 'Unrestricted Editing', 'fl-builder' ),
292
  'description' => __( 'The selected roles will have unrestricted access to all editing features.', 'fl-builder' ),
293
+ 'order' => '1',
294
  ) );
295
  }
296
  }
classes/class-fl-builder-utils.php CHANGED
@@ -14,18 +14,17 @@ final class FLBuilderUtils {
14
  * @since 1.4.6
15
  * @return object A WP_Filesystem_Direct instance.
16
  */
17
- static public function get_filesystem()
18
- {
19
  global $wp_filesystem;
20
-
21
- require_once ABSPATH .'/wp-admin/includes/file.php';
22
-
23
- add_filter('filesystem_method', 'FLBuilderUtils::filesystem_method');
24
-
25
  WP_Filesystem();
26
-
27
- remove_filter('filesystem_method', 'FLBuilderUtils::filesystem_method');
28
-
29
  return $wp_filesystem;
30
  }
31
 
@@ -35,8 +34,7 @@ final class FLBuilderUtils {
35
  * @since 1.4.6
36
  * @return string
37
  */
38
- static public function filesystem_method()
39
- {
40
  return 'direct';
41
  }
42
 
@@ -49,34 +47,34 @@ final class FLBuilderUtils {
49
  * @param string $tail The trailing characters to append.
50
  * @return string
51
  */
52
- static public function snippetwop($text, $length = 64, $tail = "...")
53
- {
54
- $text = trim($text);
55
- $txtl = function_exists('mb_strlen') ? mb_strlen($text) : strlen($text);
56
-
57
- if($txtl > $length) {
58
-
59
- for($i=1;$text[$length-$i]!=" ";$i++) {
60
-
61
- if($i == $length) {
62
-
63
- if(function_exists('mb_substr')) {
64
- return mb_substr($text,0,$length) . $tail;
65
  }
66
-
67
- return substr($text,0,$length) . $tail;
68
  }
69
  }
70
-
71
- for(;$text[$length-$i]=="," || $text[$length-$i]=="." || $text[$length-$i]==" ";$i++) {;}
72
-
73
- if(function_exists('mb_substr')) {
74
- return mb_substr($text,0,$length-$i+1) . $tail;
 
75
  }
76
-
77
- return substr($text,0,$length-$i+1) . $tail;
78
  }
79
-
80
  return $text;
81
  }
82
 
@@ -87,13 +85,12 @@ final class FLBuilderUtils {
87
  * @param mixed $data The data to decode.
88
  * @return mixed The decoded data.
89
  */
90
- static public function json_decode_deep( $data )
91
- {
92
- // First check if we have a string and try to decode that.
93
  if ( is_string( $data ) ) {
94
  $data = json_decode( $data );
95
  }
96
-
97
  // Decode object properies or array values.
98
  if ( is_object( $data ) || is_array( $data ) ) {
99
 
@@ -108,8 +105,7 @@ final class FLBuilderUtils {
108
  if ( is_object( $decoded ) || is_array( $decoded ) ) {
109
  $new_val = $decoded;
110
  }
111
- }
112
- else if ( is_object( $val ) || is_array( $val ) ) {
113
  $new_val = self::json_decode_deep( $val );
114
  }
115
 
@@ -117,8 +113,7 @@ final class FLBuilderUtils {
117
 
118
  if ( is_object( $data ) ) {
119
  $data->{$key} = $new_val;
120
- }
121
- else if ( is_array( $data ) ) {
122
  $data[ $key ] = $new_val;
123
  }
124
  }
@@ -129,26 +124,23 @@ final class FLBuilderUtils {
129
  }
130
 
131
  /**
132
- * Base64 decode settings if our ModSecurity fix is enabled.
133
  *
134
  * @since 1.8.4
135
  * @return array
136
  */
137
- static public function modsec_fix_decode( $settings )
138
- {
139
  if ( defined( 'FL_BUILDER_MODSEC_FIX' ) && FL_BUILDER_MODSEC_FIX ) {
140
-
141
  if ( is_string( $settings ) ) {
142
  $settings = wp_slash( base64_decode( $settings ) );
143
- }
144
- else {
145
-
146
  foreach ( $settings as $key => $value ) {
147
-
148
  if ( is_string( $settings[ $key ] ) ) {
149
  $settings[ $key ] = wp_slash( base64_decode( $value ) );
150
- }
151
- else if ( is_array( $settings[ $key ] ) ) {
152
  $settings[ $key ] = self::modsec_fix_decode( $settings[ $key ] );
153
  }
154
  }
@@ -166,39 +158,40 @@ final class FLBuilderUtils {
166
  * @param string $type The type of video to check
167
  * @return array
168
  */
169
- static public function get_video_data( $url, $type = '' )
170
- {
171
- if ( empty($url) )
172
- return false;
173
 
174
  $y_matches = array();
175
  $vm_matches = array();
176
- $yt_pattern = '/^(?:(?:(?:https?:)?\/\/)?(?:www.)?(?:youtu(?:be.com|.be))\/(?:watch\?v\=|v\/|embed\/)?([\w\-]+))/is';
177
- $vm_pattern = '#(?:https?://)?(?:www.)?(?:player.)?vimeo.com/(?:[a-z]*/)*([0-9]{6,11})[?]?.*#';
178
- $video_data = array('type' => 'mp4', 'video_id' => '');
179
-
180
- preg_match($yt_pattern, $url, $yt_matches);
181
- preg_match($vm_pattern, $url, $vm_matches);
182
-
183
- if ( isset($yt_matches[1]) ) {
184
- $video_data['type'] = 'youtube';
185
- $video_data['video_id'] = $yt_matches[1];
186
- }
187
- else if (isset($vm_matches[1]) ) {
188
- $video_data['type'] = 'vimeo';
189
- $video_data['video_id'] = $vm_matches[1];
190
- }
191
-
192
- if ( !empty($type) ) {
193
- if ( $type === $video_data['type'] ) {
194
- return $video_data['video_id'];
195
- }
196
- else {
197
- return false;
198
- }
199
- }
200
-
201
- return $video_data;
 
202
  }
203
 
204
- }
14
  * @since 1.4.6
15
  * @return object A WP_Filesystem_Direct instance.
16
  */
17
+ static public function get_filesystem() {
 
18
  global $wp_filesystem;
19
+
20
+ require_once ABSPATH . '/wp-admin/includes/file.php';
21
+
22
+ add_filter( 'filesystem_method', 'FLBuilderUtils::filesystem_method' );
23
+
24
  WP_Filesystem();
25
+
26
+ remove_filter( 'filesystem_method', 'FLBuilderUtils::filesystem_method' );
27
+
28
  return $wp_filesystem;
29
  }
30
 
34
  * @since 1.4.6
35
  * @return string
36
  */
37
+ static public function filesystem_method() {
 
38
  return 'direct';
39
  }
40
 
47
  * @param string $tail The trailing characters to append.
48
  * @return string
49
  */
50
+ static public function snippetwop( $text, $length = 64, $tail = '...' ) {
51
+ $text = trim( $text );
52
+ $txtl = function_exists( 'mb_strlen' ) ? mb_strlen( $text ) : strlen( $text );
53
+
54
+ if ( $txtl > $length ) {
55
+
56
+ for ( $i = 1;' ' != $text[ $length -$i ];$i++ ) {
57
+
58
+ if ( $i == $length ) {
59
+
60
+ if ( function_exists( 'mb_substr' ) ) {
61
+ return mb_substr( $text,0,$length ) . $tail;
 
62
  }
63
+
64
+ return substr( $text,0,$length ) . $tail;
65
  }
66
  }
67
+
68
+ for ( ;',' == $text[ $length -$i ] || '.' == $text[ $length -$i ] || ' ' == $text[ $length -$i ];
69
+ $i++ ) {;}
70
+
71
+ if ( function_exists( 'mb_substr' ) ) {
72
+ return mb_substr( $text,0,$length -$i + 1 ) . $tail;
73
  }
74
+
75
+ return substr( $text,0,$length -$i + 1 ) . $tail;
76
  }
77
+
78
  return $text;
79
  }
80
 
85
  * @param mixed $data The data to decode.
86
  * @return mixed The decoded data.
87
  */
88
+ static public function json_decode_deep( $data ) {
89
+ // First check if we have a string and try to decode that.
 
90
  if ( is_string( $data ) ) {
91
  $data = json_decode( $data );
92
  }
93
+
94
  // Decode object properies or array values.
95
  if ( is_object( $data ) || is_array( $data ) ) {
96
 
105
  if ( is_object( $decoded ) || is_array( $decoded ) ) {
106
  $new_val = $decoded;
107
  }
108
+ } elseif ( is_object( $val ) || is_array( $val ) ) {
 
109
  $new_val = self::json_decode_deep( $val );
110
  }
111
 
113
 
114
  if ( is_object( $data ) ) {
115
  $data->{$key} = $new_val;
116
+ } elseif ( is_array( $data ) ) {
 
117
  $data[ $key ] = $new_val;
118
  }
119
  }
124
  }
125
 
126
  /**
127
+ * Base64 decode settings if our ModSecurity fix is enabled.
128
  *
129
  * @since 1.8.4
130
  * @return array
131
  */
132
+ static public function modsec_fix_decode( $settings ) {
 
133
  if ( defined( 'FL_BUILDER_MODSEC_FIX' ) && FL_BUILDER_MODSEC_FIX ) {
134
+
135
  if ( is_string( $settings ) ) {
136
  $settings = wp_slash( base64_decode( $settings ) );
137
+ } else {
138
+
 
139
  foreach ( $settings as $key => $value ) {
140
+
141
  if ( is_string( $settings[ $key ] ) ) {
142
  $settings[ $key ] = wp_slash( base64_decode( $value ) );
143
+ } elseif ( is_array( $settings[ $key ] ) ) {
 
144
  $settings[ $key ] = self::modsec_fix_decode( $settings[ $key ] );
145
  }
146
  }
158
  * @param string $type The type of video to check
159
  * @return array
160
  */
161
+ static public function get_video_data( $url, $type = '' ) {
162
+ if ( empty( $url ) ) {
163
+ return false;
164
+ }
165
 
166
  $y_matches = array();
167
  $vm_matches = array();
168
+ $yt_pattern = '/^(?:(?:(?:https?:)?\/\/)?(?:www.)?(?:youtu(?:be.com|.be))\/(?:watch\?v\=|v\/|embed\/)?([\w\-]+))/is';
169
+ $vm_pattern = '#(?:https?://)?(?:www.)?(?:player.)?vimeo.com/(?:[a-z]*/)*([0-9]{6,11})[?]?.*#';
170
+ $video_data = array(
171
+ 'type' => 'mp4',
172
+ 'video_id' => '',
173
+ );
174
+
175
+ preg_match( $yt_pattern, $url, $yt_matches );
176
+ preg_match( $vm_pattern, $url, $vm_matches );
177
+
178
+ if ( isset( $yt_matches[1] ) ) {
179
+ $video_data['type'] = 'youtube';
180
+ $video_data['video_id'] = $yt_matches[1];
181
+ } elseif ( isset( $vm_matches[1] ) ) {
182
+ $video_data['type'] = 'vimeo';
183
+ $video_data['video_id'] = $vm_matches[1];
184
+ }
185
+
186
+ if ( ! empty( $type ) ) {
187
+ if ( $type === $video_data['type'] ) {
188
+ return $video_data['video_id'];
189
+ } else {
190
+ return false;
191
+ }
192
+ }
193
+
194
+ return $video_data;
195
  }
196
 
197
+ }
classes/class-fl-builder-wpcli-command.php CHANGED
@@ -28,7 +28,7 @@ class FLbuilder_WPCLI_Command extends WP_CLI_Command {
28
  $network = false;
29
  $all = false;
30
 
31
- if ( isset( $assoc_args['network'] ) && $assoc_args['network'] == true && is_multisite() ) {
32
  $network = true;
33
  }
34
 
@@ -44,7 +44,7 @@ class FLbuilder_WPCLI_Command extends WP_CLI_Command {
44
 
45
  if ( class_exists( 'FLBuilderModel' ) ) {
46
 
47
- if ( $network == true ) {
48
 
49
  if ( function_exists( 'get_sites' ) ) {
50
  $blogs = get_sites();
28
  $network = false;
29
  $all = false;
30
 
31
+ if ( isset( $assoc_args['network'] ) && true == $assoc_args['network'] && is_multisite() ) {
32
  $network = true;
33
  }
34
 
44
 
45
  if ( class_exists( 'FLBuilderModel' ) ) {
46
 
47
+ if ( true == $network ) {
48
 
49
  if ( function_exists( 'get_sites' ) ) {
50
  $blogs = get_sites();
classes/class-fl-builder.php CHANGED
@@ -43,32 +43,31 @@ final class FLBuilder {
43
  * @since 1.8
44
  * @return void
45
  */
46
- static public function init()
47
- {
48
  /* Actions */
49
- add_action('plugins_loaded', __CLASS__ . '::load_plugin_textdomain');
50
- add_action('send_headers', __CLASS__ . '::no_cache_headers');
51
- add_action('wp', __CLASS__ . '::init_ui', 11);
52
- add_action('wp_enqueue_scripts', __CLASS__ . '::register_layout_styles_scripts');
53
- add_action('wp_enqueue_scripts', __CLASS__ . '::enqueue_ui_styles_scripts', 11);
54
- add_action('wp_enqueue_scripts', __CLASS__ . '::enqueue_all_layouts_styles_scripts');
55
- add_action('wp_head', __CLASS__ . '::render_custom_css_for_editing', 999);
56
- add_action('admin_bar_menu', __CLASS__ . '::admin_bar_menu', 999);
57
- add_action('wp_footer', __CLASS__ . '::include_jquery');
58
- add_action('wp_footer', __CLASS__ . '::render_ui');
59
- add_action('fl_builder_ui_panel_after_rows', __CLASS__ . '::render_ui_panel_row_templates');
60
- add_action('fl_builder_ui_panel_after_modules', __CLASS__ . '::render_ui_panel_modules_templates');
61
 
62
  /* Filters */
63
- add_filter('fl_builder_render_css', __CLASS__ . '::rewrite_css_cache_urls', 9999);
64
- add_filter('body_class', __CLASS__ . '::body_class');
65
- add_filter('wp_default_editor', __CLASS__ . '::default_editor');
66
- add_filter('mce_css', __CLASS__ . '::add_editor_css');
67
- add_filter('mce_buttons', __CLASS__ . '::editor_buttons');
68
- add_filter('mce_buttons_2', __CLASS__ . '::editor_buttons_2');
69
- add_filter('mce_external_plugins', __CLASS__ . '::editor_external_plugins', 9999);
70
- add_filter('tiny_mce_before_init', __CLASS__ . '::editor_font_sizes');
71
- add_filter('the_content', __CLASS__ . '::render_content');
72
  }
73
 
74
  /**
@@ -80,11 +79,10 @@ final class FLBuilder {
80
  * @since 1.4.4
81
  * @return string|bool The translation file path or false if none is found.
82
  */
83
- static public function load_plugin_textdomain()
84
- {
85
  // Traditional WordPress plugin locale filter
86
  // Uses get_user_locale() which was added in 4.7 so we need to check its available.
87
- if( function_exists( 'get_user_locale' ) ) {
88
  $locale = apply_filters( 'plugin_locale', get_user_locale(), 'fl-builder' );
89
  } else {
90
  $locale = apply_filters( 'plugin_locale', get_locale(), 'fl-builder' );
@@ -97,8 +95,7 @@ final class FLBuilder {
97
  if ( file_exists( $mofile_global ) ) {
98
  //Look in global /wp-content/languages/plugins/bb-plugin/ folder
99
  return load_textdomain( 'fl-builder', $mofile_global );
100
- }
101
- else if ( file_exists( $mofile_local ) ) {
102
  //Look in local /wp-content/plugins/bb-plugin/languages/ folder
103
  return load_textdomain( 'fl-builder', $mofile_local );
104
  }
@@ -114,8 +111,7 @@ final class FLBuilder {
114
  * @param sting $path The directory path to the template data file.
115
  * @return void
116
  */
117
- static public function register_templates( $path )
118
- {
119
  FLBuilderModel::register_templates( $path );
120
  }
121
 
@@ -127,9 +123,8 @@ final class FLBuilder {
127
  * @param array $form The module's settings form data.
128
  * @return void
129
  */
130
- static public function register_module($class, $form)
131
- {
132
- FLBuilderModel::register_module($class, $form);
133
  }
134
 
135
  /**
@@ -140,8 +135,7 @@ final class FLBuilder {
140
  * @param array $config The alias config.
141
  * @return void
142
  */
143
- static public function register_module_alias( $alias, $config )
144
- {
145
  FLBuilderModel::register_module_alias( $alias, $config );
146
  }
147
 
@@ -153,9 +147,8 @@ final class FLBuilder {
153
  * @param array $form The form data.
154
  * @return void
155
  */
156
- static public function register_settings_form($id, $form)
157
- {
158
- FLBuilderModel::register_settings_form($id, $form);
159
  }
160
 
161
  /**
@@ -164,14 +157,13 @@ final class FLBuilder {
164
  * @since 1.0
165
  * @return void
166
  */
167
- static public function no_cache_headers()
168
- {
169
- if(isset($_GET['fl_builder'])) {
170
- header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
171
- header('Cache-Control: no-store, no-cache, must-revalidate');
172
- header('Cache-Control: post-check=0, pre-check=0', false);
173
- header('Pragma: no-cache');
174
- header('Expires: Sat, 26 Jul 1997 05:00:00 GMT');
175
  }
176
  }
177
 
@@ -182,8 +174,7 @@ final class FLBuilder {
182
  * @param string $type The current default editor type.
183
  * @return string
184
  */
185
- static public function default_editor($type)
186
- {
187
  return FLBuilderModel::is_builder_active() ? 'tinymce' : $type;
188
  }
189
 
@@ -194,11 +185,10 @@ final class FLBuilder {
194
  * @param string $mce_css
195
  * @return string
196
  */
197
- static public function add_editor_css($mce_css)
198
- {
199
- if(FLBuilderModel::is_builder_active()) {
200
 
201
- if(!empty($mce_css)) {
202
  $mce_css .= ',';
203
  }
204
 
@@ -215,10 +205,9 @@ final class FLBuilder {
215
  * @param array $buttons The current buttons array.
216
  * @return array
217
  */
218
- static public function editor_buttons( $buttons )
219
- {
220
  if ( FLBuilderModel::is_builder_active() ) {
221
- if ( ( $key = array_search( 'wp_more', $buttons ) ) !== false ) {
222
  unset( $buttons[ $key ] );
223
  }
224
  }
@@ -233,8 +222,7 @@ final class FLBuilder {
233
  * @param array $buttons The current buttons array.
234
  * @return array
235
  */
236
- static public function editor_buttons_2( $buttons )
237
- {
238
  global $wp_version;
239
 
240
  if ( FLBuilderModel::is_builder_active() ) {
@@ -246,7 +234,7 @@ final class FLBuilder {
246
  array_unshift( $buttons, 'formatselect' );
247
  }
248
 
249
- if ( ( $key = array_search( 'wp_help', $buttons ) ) !== false ) {
250
  unset( $buttons[ $key ] );
251
  }
252
  }
@@ -261,8 +249,7 @@ final class FLBuilder {
261
  * @param array $init The TinyMCE init array.
262
  * @return array
263
  */
264
- static public function editor_font_sizes( $init )
265
- {
266
  if ( FLBuilderModel::is_builder_active() ) {
267
  $init['fontsize_formats'] = implode( ' ', array(
268
  '10px',
@@ -299,9 +286,8 @@ final class FLBuilder {
299
  * @param array $plugins The current editor plugins.
300
  * @return array
301
  */
302
- static public function editor_external_plugins($plugins)
303
- {
304
- if(FLBuilderModel::is_builder_active()) {
305
 
306
  $allowed = array(
307
  'anchor',
@@ -318,9 +304,9 @@ final class FLBuilder {
318
  'wptadv',
319
  );
320
 
321
- foreach($plugins as $key => $val) {
322
- if(!in_array($key, $allowed)) {
323
- unset($plugins[$key]);
324
  }
325
  }
326
  }
@@ -334,39 +320,38 @@ final class FLBuilder {
334
  * @since 1.7.4
335
  * @return void
336
  */
337
- static public function register_layout_styles_scripts()
338
- {
339
  $ver = FL_BUILDER_VERSION;
340
- $css_url = plugins_url('/css/', FL_BUILDER_FILE);
341
- $js_url = plugins_url('/js/', FL_BUILDER_FILE);
342
  $min = defined( 'WP_DEBUG' ) && WP_DEBUG ? '' : '.min';
343
 
344
  // Register additional CSS
345
- wp_register_style('fl-slideshow', $css_url . 'fl-slideshow.css', array('yui3'), $ver);
346
- wp_register_style('jquery-bxslider', $css_url . 'jquery.bxslider.css', array(), $ver);
347
- wp_register_style('jquery-magnificpopup', $css_url . 'jquery.magnificpopup.css', array(), $ver);
348
- wp_register_style('yui3', $css_url . 'yui3.css', array(), $ver);
349
 
350
  // Register icon CDN CSS
351
- wp_register_style('font-awesome', 'https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css', array(), $ver);
352
- wp_register_style('foundation-icons', 'https://cdnjs.cloudflare.com/ajax/libs/foundicons/3.0.0/foundation-icons.css', array(), $ver);
353
 
354
  // Register additional JS
355
- wp_register_script('fl-slideshow', $js_url . 'fl-slideshow' . $min . '.js', array('yui3'), $ver, true);
356
- wp_register_script('fl-gallery-grid', $js_url . 'fl-gallery-grid.js', array('jquery'), $ver, true);
357
- wp_register_script('jquery-bxslider', $js_url . 'jquery.bxslider.min.js', array('jquery-easing', 'jquery-fitvids'), $ver, true);
358
- wp_register_script('jquery-easing', $js_url . 'jquery.easing.1.3.js', array('jquery'), '1.3', true);
359
- wp_register_script('jquery-fitvids', $js_url . 'jquery.fitvids.js', array('jquery'), $ver, true);
360
- wp_register_script('jquery-imagesloaded', $js_url . 'jquery.imagesloaded.js', array('jquery'), $ver, true);
361
- wp_register_script('jquery-infinitescroll', $js_url . 'jquery.infinitescroll.js', array('jquery'), $ver, true);
362
- wp_register_script('jquery-magnificpopup', $js_url . 'jquery.magnificpopup.min.js', array('jquery'), $ver, true);
363
- wp_register_script('jquery-mosaicflow', $js_url . 'jquery.mosaicflow.min.js', array('jquery'), $ver, true);
364
- wp_register_script('jquery-waypoints', $js_url . 'jquery.waypoints.min.js', array('jquery'), $ver, true);
365
- wp_register_script('jquery-wookmark', $js_url . 'jquery.wookmark.min.js', array('jquery'), $ver, true);
366
- wp_register_script('yui3', $js_url . 'yui3.js', array(), $ver, true);
367
 
368
- wp_register_script('youtube-player', 'https://www.youtube.com/iframe_api', array(), $ver, true);
369
- wp_register_script('vimeo-player', 'https://player.vimeo.com/api/player.js', array(), $ver, true);
370
  }
371
 
372
  /**
@@ -376,8 +361,7 @@ final class FLBuilder {
376
  * @since 1.7.4
377
  * @return void
378
  */
379
- static public function enqueue_all_layouts_styles_scripts()
380
- {
381
  global $wp_query;
382
  global $post;
383
 
@@ -393,15 +377,15 @@ final class FLBuilder {
393
  // Enqueue assets for posts via the fl_builder_global_posts filter.
394
  $post_ids = FLBuilderModel::get_global_posts();
395
 
396
- if(count($post_ids) > 0) {
397
 
398
  $posts = get_posts(array(
399
  'post__in' => $post_ids,
400
  'post_type' => get_post_types(),
401
- 'posts_per_page' => -1
402
  ));
403
 
404
- foreach($posts as $post) {
405
  self::enqueue_layout_styles_scripts();
406
  }
407
  }
@@ -417,50 +401,47 @@ final class FLBuilder {
417
  * @param bool $rerender Whether to rerender the CSS and JS.
418
  * @return void
419
  */
420
- static public function enqueue_layout_styles_scripts( $rerender = false )
421
- {
422
- if(FLBuilderModel::is_builder_enabled()) {
423
 
424
  $nodes = FLBuilderModel::get_categorized_nodes();
425
 
426
  // Enqueue required row CSS and JS
427
- foreach($nodes['rows'] as $row) {
428
- if($row->settings->bg_type == 'slideshow') {
429
- wp_enqueue_script('yui3');
430
- wp_enqueue_script('fl-slideshow');
431
- wp_enqueue_style('fl-slideshow');
432
- }
433
- else if($row->settings->bg_type == 'video') {
434
- wp_enqueue_script('jquery-imagesloaded');
435
- if ( $row->settings->bg_video_source == 'video_service' ) {
436
-
437
- $video_data = FLBuilderUtils::get_video_data($row->settings->bg_video_service_url);
438
-
439
- if( $video_data['type'] == 'youtube' ) {
440
- wp_enqueue_script('youtube-player');
441
- }
442
- else if($video_data['type'] == 'vimeo') {
443
- wp_enqueue_script('vimeo-player');
444
  }
445
  }
446
  }
447
  }
448
 
449
  // Enqueue required module CSS and JS
450
- foreach($nodes['modules'] as $module) {
451
 
452
  $module->enqueue_icon_styles();
453
  $module->enqueue_font_styles();
454
  $module->enqueue_scripts();
455
 
456
- foreach($module->css as $handle => $props) {
457
- wp_enqueue_style($handle, $props[0], $props[1], $props[2], $props[3]);
458
  }
459
- foreach($module->js as $handle => $props) {
460
- wp_enqueue_script($handle, $props[0], $props[1], $props[2], $props[3]);
461
  }
462
- if(!empty($module->settings->animation)) {
463
- wp_enqueue_script('jquery-waypoints');
464
  }
465
  }
466
 
@@ -472,7 +453,7 @@ final class FLBuilder {
472
 
473
  // Enqueue layout JS
474
  self::enqueue_layout_cached_asset( 'js', $rerender );
475
- }
476
  }
477
 
478
  /**
@@ -483,8 +464,7 @@ final class FLBuilder {
483
  * @param int $post_id
484
  * @return void
485
  */
486
- static public function enqueue_layout_styles_scripts_by_id( $post_id )
487
- {
488
  FLBuilderModel::set_post_id( $post_id );
489
  FLBuilder::enqueue_layout_styles_scripts();
490
  FLBuilderModel::reset_post_id();
@@ -499,8 +479,7 @@ final class FLBuilder {
499
  * @param bool $rerender Whether to rerender the CSS or JS.
500
  * @return string
501
  */
502
- static private function enqueue_layout_cached_asset( $type = 'css', $rerender = false )
503
- {
504
  $post_id = FLBuilderModel::get_post_id();
505
  $asset_info = FLBuilderModel::get_asset_info();
506
  $asset_ver = FLBuilderModel::get_asset_version();
@@ -510,8 +489,7 @@ final class FLBuilder {
510
  $path = $asset_info[ $type . '_partial' ];
511
  $url = $asset_info[ $type . '_partial_url' ];
512
  $global = false;
513
- }
514
- else {
515
  $path = $asset_info[ $type ];
516
  $url = $asset_info[ $type . '_url' ];
517
  $global = true;
@@ -533,8 +511,7 @@ final class FLBuilder {
533
  $deps = apply_filters( 'fl_builder_layout_style_dependencies', array() );
534
  $media = apply_filters( 'fl_builder_layout_style_media', 'all' );
535
  wp_enqueue_style( 'fl-builder-layout-' . $post_id, $url, $deps, $asset_ver, $media );
536
- }
537
- else if ( 'js' == $type ) {
538
  wp_enqueue_script( 'fl-builder-layout-' . $post_id, $url, array( 'jquery' ), $asset_ver, true );
539
  }
540
  }
@@ -546,8 +523,7 @@ final class FLBuilder {
546
  * @since 1.10.2
547
  * @return void
548
  */
549
- static public function clear_enqueued_global_assets()
550
- {
551
  self::$enqueued_global_assets = array();
552
  }
553
 
@@ -557,103 +533,100 @@ final class FLBuilder {
557
  * @since 1.7.4
558
  * @return void
559
  */
560
- static public function enqueue_ui_styles_scripts()
561
- {
562
- if(FLBuilderModel::is_builder_active()) {
563
 
564
  $ver = FL_BUILDER_VERSION;
565
- $css_url = plugins_url('/css/', FL_BUILDER_FILE);
566
- $js_url = plugins_url('/js/', FL_BUILDER_FILE);
567
 
568
  /* Frontend builder styles */
569
- wp_enqueue_style('dashicons');
570
- wp_enqueue_style('font-awesome');
571
- wp_enqueue_style('foundation-icons');
572
- wp_enqueue_style('jquery-nanoscroller', $css_url . 'jquery.nanoscroller.css', array(), $ver);
573
- wp_enqueue_style('jquery-autosuggest', $css_url . 'jquery.autoSuggest.min.css', array(), $ver);
574
- wp_enqueue_style('jquery-tiptip', $css_url . 'jquery.tiptip.css', array(), $ver);
575
- wp_enqueue_style('bootstrap-tour', $css_url . 'bootstrap-tour-standalone.min.css', array(), $ver);
576
 
577
  // Enqueue individual builder styles if WP_DEBUG is on.
578
  if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
579
- wp_enqueue_style('fl-color-picker', $css_url . 'fl-color-picker.css', array(), $ver);
580
- wp_enqueue_style('fl-lightbox', $css_url . 'fl-lightbox.css', array(), $ver);
581
- wp_enqueue_style('fl-icon-selector', $css_url . 'fl-icon-selector.css', array(), $ver);
582
- wp_enqueue_style('fl-builder', $css_url . 'fl-builder.css', array(), $ver);
583
- }
584
- else {
585
- wp_enqueue_style('fl-builder-min', $css_url . 'fl-builder.min.css', array(), $ver);
586
  }
587
 
588
  /* Custom Icons */
589
  FLBuilderIcons::enqueue_all_custom_icons_styles();
590
 
591
  /* RTL Support */
592
- if(is_rtl()) {
593
- wp_enqueue_style('fl-builder-rtl', $css_url . 'fl-builder-rtl.css', array(), $ver);
594
  }
595
 
596
  /* We have a custom version of sortable that fixes a bug. */
597
- wp_deregister_script('jquery-ui-sortable');
598
 
599
  /* Frontend builder scripts */
600
  wp_enqueue_media();
601
- wp_enqueue_script('heartbeat');
602
- wp_enqueue_script('wpdialogs');
603
- wp_enqueue_script('wpdialogs-popup');
604
- wp_enqueue_script('wplink');
605
- wp_enqueue_script('editor');
606
- wp_enqueue_script('quicktags');
607
- wp_enqueue_script('json2');
608
- wp_enqueue_script('jquery-ui-droppable');
609
- wp_enqueue_script('jquery-ui-draggable');
610
- wp_enqueue_script('jquery-ui-slider');
611
- wp_enqueue_script('jquery-ui-widget');
612
- wp_enqueue_script('jquery-ui-position');
613
 
614
  do_action( 'fl_before_sortable_enqueue' );
615
 
616
- wp_enqueue_script('jquery-ui-sortable', $js_url . 'jquery.ui.sortable.js', array('jquery-ui-core', 'jquery-ui-widget', 'jquery-ui-mouse'), $ver);
617
- wp_enqueue_script('jquery-nanoscroller', $js_url . 'jquery.nanoscroller.min.js', array(), $ver);
618
- wp_enqueue_script('jquery-autosuggest', $js_url . 'jquery.autoSuggest.min.js', array(), $ver);
619
- wp_enqueue_script('jquery-tiptip', $js_url . 'jquery.tiptip.min.js', array(), $ver);
620
- wp_enqueue_script('jquery-simulate', $js_url . 'jquery.simulate.js', array(), $ver);
621
- wp_enqueue_script('jquery-validate', $js_url . 'jquery.validate.min.js', array(), $ver);
622
- wp_enqueue_script('bootstrap-tour', $js_url . 'bootstrap-tour-standalone.min.js', array(), $ver);
623
- wp_enqueue_script('ace', $js_url . 'ace/ace.js', array(), $ver);
624
- wp_enqueue_script('ace-language-tools', $js_url . 'ace/ext-language_tools.js', array(), $ver);
625
 
626
  // Enqueue individual builder scripts if WP_DEBUG is on.
627
  if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
628
- wp_enqueue_script('fl-color-picker', $js_url . 'fl-color-picker.js', array(), $ver);
629
- wp_enqueue_script('fl-lightbox', $js_url . 'fl-lightbox.js', array(), $ver);
630
- wp_enqueue_script('fl-icon-selector', $js_url . 'fl-icon-selector.js', array(), $ver);
631
- wp_enqueue_script('fl-stylesheet', $js_url . 'fl-stylesheet.js', array(), $ver);
632
- wp_enqueue_script('fl-builder', $js_url . 'fl-builder.js', array(), $ver);
633
- wp_enqueue_script('fl-builder-ajax-layout', $js_url . 'fl-builder-ajax-layout.js', array(), $ver);
634
- wp_enqueue_script('fl-builder-preview', $js_url . 'fl-builder-preview.js', array(), $ver);
635
- wp_enqueue_script('fl-builder-simulate-media-query', $js_url . 'fl-builder-simulate-media-query.js', array(), $ver);
636
- wp_enqueue_script('fl-builder-responsive-editing', $js_url . 'fl-builder-responsive-editing.js', array(), $ver);
637
- wp_enqueue_script('fl-builder-services', $js_url . 'fl-builder-services.js', array(), $ver);
638
- wp_enqueue_script('fl-builder-tour', $js_url . 'fl-builder-tour.js', array(), $ver);
639
- }
640
- else {
641
- wp_enqueue_script('fl-builder-min', $js_url . 'fl-builder.min.js', array(), $ver);
642
  }
643
 
644
  /* Additional module styles and scripts */
645
- foreach(FLBuilderModel::$modules as $module) {
646
 
647
  $module->enqueue_scripts();
648
 
649
- foreach($module->css as $handle => $props) {
650
- wp_enqueue_style($handle, $props[0], $props[1], $props[2], $props[3]);
651
  }
652
- foreach($module->js as $handle => $props) {
653
- wp_enqueue_script($handle, $props[0], $props[1], $props[2], $props[3]);
654
  }
655
  }
656
- }
657
  }
658
 
659
  /**
@@ -663,9 +636,8 @@ final class FLBuilder {
663
  * @since 1.0
664
  * @return void
665
  */
666
- static public function include_jquery()
667
- {
668
- if(FLBuilderModel::is_builder_enabled()) {
669
  include FL_BUILDER_DIR . 'includes/jquery.php';
670
  }
671
  }
@@ -677,17 +649,16 @@ final class FLBuilder {
677
  * @param array $classes An array of existing classes.
678
  * @return array
679
  */
680
- static public function body_class($classes)
681
- {
682
  $do_render = apply_filters( 'fl_builder_do_render_content', true, FLBuilderModel::get_post_id() );
683
 
684
- if($do_render && FLBuilderModel::is_builder_enabled() && !is_archive()) {
685
  $classes[] = 'fl-builder';
686
  }
687
- if(FLBuilderModel::is_builder_active()) {
688
  $classes[] = 'fl-builder-edit';
689
 
690
- if(!FLBuilderUserAccess::current_user_can('unrestricted_editing')) {
691
  $classes[] = 'fl-builder-simple';
692
  }
693
  }
@@ -702,8 +673,7 @@ final class FLBuilder {
702
  * @param object $wp_admin_bar An instance of the WordPress admin bar.
703
  * @return void
704
  */
705
- static public function admin_bar_menu($wp_admin_bar)
706
- {
707
  global $wp_the_query;
708
 
709
  if ( FLBuilderModel::is_post_editable() && is_object( $wp_the_query->post ) ) {
@@ -714,13 +684,12 @@ final class FLBuilder {
714
  $wp_admin_bar->add_node( array(
715
  'id' => 'fl-builder-frontend-edit-link',
716
  'title' => '<style> #wp-admin-bar-fl-builder-frontend-edit-link .ab-icon:before { content: "\f116" !important; top: 2px; margin-right: 3px; } </style><span class="ab-icon"></span>' . FLBuilderModel::get_branding() . $dot,
717
- 'href' => FLBuilderModel::get_edit_url( $wp_the_query->post->ID )
718
  ));
719
  }
720
  }
721
 
722
- static public function locate_template_file( $template_base, $slug )
723
- {
724
  $specific_template = $template_base . '-' . $slug . '.php';
725
  $general_template = $template_base . '.php';
726
  $default_dir = trailingslashit( FL_BUILDER_DIR ) . 'includes/';
@@ -729,7 +698,7 @@ final class FLBuilder {
729
 
730
  $locate_template_order = apply_filters( 'fl_builder_locate_template_order', array(
731
  self::$template_dir . $specific_template,
732
- self::$template_dir . $general_template
733
  ), self::$template_dir, $template_base, $slug );
734
 
735
  $template_path = locate_template( $locate_template_order );
@@ -737,8 +706,7 @@ final class FLBuilder {
737
  if ( ! $template_path ) {
738
  if ( file_exists( $default_dir . $specific_template ) ) {
739
  $template_path = $default_dir . $specific_template;
740
- }
741
- else if ( file_exists( $default_dir . $general_template ) ) {
742
  $template_path = $default_dir . $general_template;
743
  }
744
  }
@@ -753,8 +721,7 @@ final class FLBuilder {
753
  * @since 1.8 Method name changed from init to init_ui.
754
  * @return void
755
  */
756
- static public function init_ui()
757
- {
758
  // Enable editing if the builder is active.
759
  if ( FLBuilderModel::is_builder_active() && ! defined( 'DOING_AJAX' ) ) {
760
 
@@ -765,18 +732,17 @@ final class FLBuilder {
765
  add_filter( 'autoptimize_filter_noptimize', '__return_true' );
766
 
767
  // Remove 3rd party editor buttons.
768
- remove_all_actions('media_buttons', 999999);
769
- remove_all_actions('media_buttons_context', 999999);
770
 
771
  // Get the post.
772
  require_once ABSPATH . 'wp-admin/includes/post.php';
773
  $post_id = FLBuilderModel::get_post_id();
774
 
775
  // Check to see if the post is locked.
776
- if(wp_check_post_lock($post_id) !== false) {
777
- header('Location: ' . admin_url('/post.php?post=' . $post_id . '&action=edit'));
778
- }
779
- else {
780
  FLBuilderModel::enable_editing();
781
  }
782
  }
@@ -788,8 +754,7 @@ final class FLBuilder {
788
  * @since 1.0
789
  * @return void
790
  */
791
- static public function render_ui()
792
- {
793
  global $wp_the_query;
794
 
795
  if ( FLBuilderModel::is_builder_active() ) {
@@ -818,8 +783,7 @@ final class FLBuilder {
818
  * @since 1.6.3
819
  * @return void
820
  */
821
- static public function render_ui_bar_title()
822
- {
823
  // Get the bar title.
824
  $title = apply_filters( 'fl_builder_ui_bar_title', FLBuilderModel::get_branding() );
825
 
@@ -830,8 +794,7 @@ final class FLBuilder {
830
  echo $title;
831
  do_action( 'fl_builder_after_ui_bar_title' );
832
  echo '</div>';
833
- }
834
- else {
835
  echo '<div class="fl-builder-bar-title">';
836
  do_action( 'fl_builder_before_ui_bar_title' );
837
  echo '<img src="' . FLBuilderModel::get_branding_icon() . '" /> ';
@@ -847,40 +810,39 @@ final class FLBuilder {
847
  * @since 1.6.3
848
  * @return void
849
  */
850
- static public function render_ui_bar_buttons()
851
- {
852
  $help_button = FLBuilderModel::get_help_button_settings();
853
  $simple_ui = ! FLBuilderUserAccess::current_user_can( 'unrestricted_editing' );
854
 
855
  $buttons = apply_filters( 'fl_builder_ui_bar_buttons', array(
856
  'help' => array(
857
  'label' => '<i class="fa fa-question-circle"></i>',
858
- 'show' => $help_button['enabled'] && ! $simple_ui
859
  ),
860
  'upgrade' => array(
861
  'label' => __( 'Upgrade Today <i class="fa fa-external-link-square"></i>', 'fl-builder' ),
862
- 'show' => true === FL_BUILDER_LITE
863
  ),
864
  'buy' => array(
865
  'label' => __( 'Buy Now <i class="fa fa-external-link-square"></i>', 'fl-builder' ),
866
- 'show' => stristr( home_url(), 'demo.wpbeaverbuilder.com' )
867
  ),
868
  'done' => array(
869
  'label' => __( 'Done', 'fl-builder' ),
870
- 'class' => 'fl-builder-button-primary'
871
  ),
872
  'tools' => array(
873
  'label' => __( 'Tools', 'fl-builder' ),
874
- 'show' => ! $simple_ui
875
  ),
876
  'templates' => array(
877
  'label' => __( 'Templates', 'fl-builder' ),
878
- 'show' => ! $simple_ui
879
  ),
880
  'add-content' => array(
881
  'label' => __( 'Add Content', 'fl-builder' ),
882
- 'show' => ! $simple_ui
883
- )
884
  ) );
885
 
886
  echo '<div class="fl-builder-bar-actions">';
@@ -909,8 +871,7 @@ final class FLBuilder {
909
  * @since 1.8
910
  * @return void
911
  */
912
- static public function render_ui_panel_row_templates()
913
- {
914
  $is_row_template = FLBuilderModel::is_post_user_template( 'row' );
915
  $is_module_template = FLBuilderModel::is_post_user_template( 'module' );
916
  $has_editing_cap = FLBuilderUserAccess::current_user_can( 'unrestricted_editing' );
@@ -927,8 +888,7 @@ final class FLBuilder {
927
  * @since 1.8
928
  * @return void
929
  */
930
- static public function render_ui_panel_modules_templates()
931
- {
932
  $is_module_template = FLBuilderModel::is_post_user_template( 'module' );
933
  $has_editing_cap = FLBuilderUserAccess::current_user_can( 'unrestricted_editing' );
934
  $module_templates = FLBuilderModel::get_module_templates_data();
@@ -951,8 +911,7 @@ final class FLBuilder {
951
  * @param int $site_id The ID of a site on a network to pull the query from.
952
  * @return void
953
  */
954
- static public function render_query( $args, $site_id = null )
955
- {
956
  global $post;
957
  global $wp_query;
958
  $switched = false;
@@ -1022,8 +981,7 @@ final class FLBuilder {
1022
  * @param array $attrs An array of key/value attribute data for the content wrapper.
1023
  * @return void
1024
  */
1025
- static public function render_content_by_id( $post_id, $tag = 'div', $attrs = array() )
1026
- {
1027
  // Force the builder to use this post ID.
1028
  FLBuilderModel::set_post_id( $post_id );
1029
 
@@ -1083,8 +1041,7 @@ final class FLBuilder {
1083
  * @param string $content The existing content.
1084
  * @return string
1085
  */
1086
- static public function render_content( $content )
1087
- {
1088
  $post_id = FLBuilderModel::get_post_id();
1089
  $enabled = FLBuilderModel::is_builder_enabled();
1090
  $rendering = $post_id === self::$post_rendering;
@@ -1092,7 +1049,7 @@ final class FLBuilder {
1092
  $in_loop = in_the_loop();
1093
  $is_global = in_array( $post_id, FLBuilderModel::get_global_posts() );
1094
 
1095
- if( $enabled && ! $rendering && $do_render && ( $in_loop || $is_global ) ) {
1096
 
1097
  // Set the post rendering ID.
1098
  self::$post_rendering = $post_id;
@@ -1135,7 +1092,7 @@ final class FLBuilder {
1135
 
1136
  // Clear the post rendering ID.
1137
  self::$post_rendering = null;
1138
- }
1139
 
1140
  return $content;
1141
  }
@@ -1148,9 +1105,8 @@ final class FLBuilder {
1148
  * @param array $matches The existing content.
1149
  * @return string
1150
  */
1151
- static public function double_escape_shortcodes( $matches )
1152
- {
1153
- if ( $matches[1] == '[' && $matches[6] == ']' ) {
1154
  return '[' . $matches[0] . ']';
1155
  }
1156
 
@@ -1163,8 +1119,7 @@ final class FLBuilder {
1163
  * @since 1.6.4
1164
  * @return string
1165
  */
1166
- static public function render_content_classes()
1167
- {
1168
  global $wp_the_query;
1169
 
1170
  $post_id = FLBuilderModel::get_post_id();
@@ -1178,8 +1133,8 @@ final class FLBuilder {
1178
  }
1179
 
1180
  // Add browser specific classes.
1181
- if ( isset( $_SERVER[ 'HTTP_USER_AGENT' ] ) ) {
1182
- if ( stristr( $_SERVER[ 'HTTP_USER_AGENT' ], 'Trident/7.0' ) && stristr( $_SERVER[ 'HTTP_USER_AGENT' ], 'rv:11.0' ) ) {
1183
  $classes .= ' fl-builder-ie-11';
1184
  }
1185
  }
@@ -1193,8 +1148,7 @@ final class FLBuilder {
1193
  * @since 1.6.3
1194
  * @return void
1195
  */
1196
- static public function render_nodes()
1197
- {
1198
  do_action( 'fl_builder_before_render_nodes' );
1199
 
1200
  if ( apply_filters( 'fl_builder_render_nodes', true ) ) {
@@ -1211,25 +1165,22 @@ final class FLBuilder {
1211
  * @param array $attrs
1212
  * @return void
1213
  */
1214
- static public function render_node_attributes( $attrs )
1215
- {
1216
- foreach( $attrs as $attr_key => $attr_value ) {
1217
 
1218
  if ( empty( $attr_value ) ) {
1219
  continue;
1220
- }
1221
- else if ( is_string( $attr_value ) ) {
1222
  echo ' ' . $attr_key . '="' . $attr_value . '"';
1223
- }
1224
- else if ( is_array( $attr_value ) && ! empty( $attr_value ) ) {
1225
 
1226
  echo ' ' . $attr_key . '="';
1227
 
1228
- for( $i = 0; $i < count( $attr_value ); $i++ ) {
1229
 
1230
  echo $attr_value[ $i ];
1231
 
1232
- if ( $i < count( $attr_value ) - 1 ) {
1233
  echo ' ';
1234
  }
1235
  }
@@ -1247,22 +1198,21 @@ final class FLBuilder {
1247
  * @param string $content The existing content.
1248
  * @return string
1249
  */
1250
- static public function render_editor_content()
1251
- {
1252
- $rows = FLBuilderModel::get_nodes('row');
1253
 
1254
  ob_start();
1255
 
1256
  // Render the modules.
1257
- foreach($rows as $row) {
1258
 
1259
- $groups = FLBuilderModel::get_nodes('column-group', $row);
1260
 
1261
- foreach($groups as $group) {
1262
 
1263
- $cols = FLBuilderModel::get_nodes('column', $group);
1264
 
1265
- foreach($cols as $col) {
1266
 
1267
  $col_children = FLBuilderModel::get_nodes( null, $col );
1268
 
@@ -1275,14 +1225,13 @@ final class FLBuilder {
1275
  if ( $module && $module->editor_export ) {
1276
 
1277
  // Don't crop photos to ensure media library photos are rendered.
1278
- if($module->settings->type == 'photo') {
1279
  $module->settings->crop = false;
1280
  }
1281
 
1282
- FLBuilder::render_module_html($module->settings->type, $module->settings, $module);
1283
  }
1284
- }
1285
- else if ( 'column-group' == $col_child->type ) {
1286
 
1287
  $group_cols = FLBuilderModel::get_nodes( 'column', $col_child );
1288
 
@@ -1292,35 +1241,35 @@ final class FLBuilder {
1292
 
1293
  foreach ( $modules as $module ) {
1294
 
1295
- if($module->editor_export) {
1296
 
1297
  // Don't crop photos to ensure media library photos are rendered.
1298
- if($module->settings->type == 'photo') {
1299
  $module->settings->crop = false;
1300
  }
1301
 
1302
- FLBuilder::render_module_html($module->settings->type, $module->settings, $module);
1303
  }
1304
  }
1305
  }
1306
- }
1307
- }
1308
- }
1309
- }
1310
- }
1311
 
1312
  // Get the content.
1313
  $content = ob_get_clean();
1314
 
1315
  // Remove unnecessary tags.
1316
- $content = preg_replace('/<\/?div[^>]*\>/i', '', $content);
1317
- $content = preg_replace('/<\/?span[^>]*\>/i', '', $content);
1318
- $content = preg_replace('#<script(.*?)>(.*?)</script>#is', '', $content);
1319
- $content = preg_replace('/<i [^>]*><\\/i[^>]*>/', '', $content);
1320
- $content = preg_replace('/ class=".*?"/', '', $content);
1321
 
1322
  // Remove empty lines.
1323
- $content = preg_replace('/(^[\r\n]*|[\r\n]+)[\s\t]*[\r\n]+/', "\n", $content);
1324
 
1325
  return $content;
1326
  }
@@ -1333,8 +1282,7 @@ final class FLBuilder {
1333
  * @param object $settings The settings data.
1334
  * @return array
1335
  */
1336
- static public function render_settings($form = array(), $settings)
1337
- {
1338
  $defaults = array(
1339
  'class' => '',
1340
  'attrs' => '',
@@ -1342,7 +1290,7 @@ final class FLBuilder {
1342
  'badges' => array(),
1343
  'tabs' => array(),
1344
  'buttons' => array(),
1345
- 'resizable' => false
1346
  );
1347
 
1348
  $form = apply_filters( 'fl_builder_settings_form_config', array_merge( $defaults, $form ) );
@@ -1351,7 +1299,9 @@ final class FLBuilder {
1351
  include FL_BUILDER_DIR . 'includes/settings.php';
1352
  $html = ob_get_clean();
1353
 
1354
- return array( 'html' => $html );
 
 
1355
  }
1356
 
1357
  /**
@@ -1363,20 +1313,21 @@ final class FLBuilder {
1363
  * @param object $settings Form settings data object.
1364
  * @return void
1365
  */
1366
- static public function render_settings_field($name, $field, $settings = null)
1367
- {
1368
  $field = apply_filters( 'fl_builder_render_settings_field', $field, $name, $settings ); // Allow field settings filtering first
1369
  $i = null;
1370
- $is_multiple = isset($field['multiple']) && $field['multiple'] === true;
1371
- $supports_multiple = $field['type'] != 'editor' && $field['type'] != 'photo' && $field['type'] != 'service';
1372
  $settings = ! $settings ? new stdClass() : $settings;
1373
- $preview = isset($field['preview']) ? json_encode($field['preview']) : json_encode(array('type' => 'refresh'));
1374
- $row_class = isset($field['row_class']) ? ' ' . $field['row_class'] : '';
 
 
1375
  $responsive = false;
1376
  $responsive_fields = array( 'unit' );
1377
  $root_name = $name;
1378
  $global_settings = FLBuilderModel::get_global_settings();
1379
- $value = isset($settings->$name) ? $settings->$name : '';
1380
 
1381
  // Use a default value if not set in the settings.
1382
  if ( ! isset( $settings->$name ) && isset( $field['default'] ) ) {
@@ -1389,7 +1340,7 @@ final class FLBuilder {
1389
  }
1390
 
1391
  // Render the field.
1392
- if($is_multiple && $supports_multiple) {
1393
 
1394
  $values = $value;
1395
  $arr_name = $name;
@@ -1397,9 +1348,9 @@ final class FLBuilder {
1397
 
1398
  echo '<tbody class="fl-field fl-builder-field-multiples" data-type="form" data-preview=\'' . $preview . '\'>';
1399
 
1400
- for($i = 0; $i < count($values); $i++) {
1401
- $value = $values[$i];
1402
- echo '<tr class="fl-builder-field-multiple" data-field="'. $arr_name .'">';
1403
  include FL_BUILDER_DIR . 'includes/field.php';
1404
  echo '<td class="fl-builder-field-actions">';
1405
  echo '<i class="fl-builder-field-move fa fa-arrows"></i>';
@@ -1411,23 +1362,21 @@ final class FLBuilder {
1411
 
1412
  echo '<tr>';
1413
 
1414
- if(empty($field['label'])) {
1415
  echo '<td colspan="2">';
1416
- }
1417
- else {
1418
  echo '<td>&nbsp;</td><td>';
1419
  }
1420
 
1421
- echo '<a href="javascript:void(0);" onclick="return false;" class="fl-builder-field-add fl-builder-button" data-field="'. $arr_name .'">'. sprintf( _x( 'Add %s', 'Field name to add.', 'fl-builder' ), $field['label'] ) .'</a>';
1422
  echo '</td>';
1423
  echo '</tr>';
1424
  echo '</tbody>';
1425
- }
1426
- else {
1427
- echo '<tr id="fl-field-'. $name .'" class="fl-field' . $row_class . '" data-type="' . $field['type'] . '" data-preview=\'' . $preview . '\'>';
1428
  include FL_BUILDER_DIR . 'includes/field.php';
1429
  echo '</tr>';
1430
- }
1431
  }
1432
 
1433
  /**
@@ -1438,22 +1387,20 @@ final class FLBuilder {
1438
  * @param object $settings The settings data.
1439
  * @return array
1440
  */
1441
- static public function render_settings_form($type = null, $settings = null)
1442
- {
1443
  $form = FLBuilderModel::get_settings_form( $type );
1444
 
1445
- if(isset($settings) && !empty($settings)) {
1446
  $defaults = FLBuilderModel::get_settings_form_defaults( $type );
1447
- $settings = (object)array_merge((array)$defaults, (array)$settings);
1448
- }
1449
- else {
1450
  $settings = FLBuilderModel::get_settings_form_defaults( $type );
1451
  }
1452
 
1453
  return self::render_settings(array(
1454
  'title' => $form['title'],
1455
  'tabs' => $form['tabs'],
1456
- 'resizable' => true
1457
  ), $settings);
1458
  }
1459
 
@@ -1463,8 +1410,7 @@ final class FLBuilder {
1463
  * @since 1.8
1464
  * @return array
1465
  */
1466
- static public function render_layout_settings()
1467
- {
1468
  $settings = FLBuilderModel::get_layout_settings();
1469
  $form = FLBuilderModel::$settings_forms['layout'];
1470
 
@@ -1472,7 +1418,7 @@ final class FLBuilder {
1472
  'class' => 'fl-builder-layout-settings',
1473
  'title' => $form['title'],
1474
  'tabs' => $form['tabs'],
1475
- 'resizable' => true
1476
  ), $settings );
1477
  }
1478
 
@@ -1482,8 +1428,7 @@ final class FLBuilder {
1482
  * @since 1.0
1483
  * @return array
1484
  */
1485
- static public function render_global_settings()
1486
- {
1487
  $settings = FLBuilderModel::get_global_settings();
1488
  $form = FLBuilderModel::$settings_forms['global'];
1489
 
@@ -1491,7 +1436,7 @@ final class FLBuilder {
1491
  'class' => 'fl-builder-global-settings',
1492
  'title' => $form['title'],
1493
  'tabs' => $form['tabs'],
1494
- 'resizable' => true
1495
  ), $settings);
1496
  }
1497
 
@@ -1501,8 +1446,7 @@ final class FLBuilder {
1501
  * @since 1.0
1502
  * @return array
1503
  */
1504
- static public function render_template_selector()
1505
- {
1506
  $filter_data = FLBuilderModel::get_template_selector_filter_data();
1507
  $templates = FLBuilderModel::get_template_selector_data();
1508
 
@@ -1510,7 +1454,9 @@ final class FLBuilder {
1510
  include FL_BUILDER_DIR . 'includes/template-selector.php';
1511
  $html = ob_get_clean();
1512
 
1513
- return array( 'html' => $html );
 
 
1514
  }
1515
 
1516
  /**
@@ -1519,15 +1465,16 @@ final class FLBuilder {
1519
  * @since 1.0
1520
  * @return array
1521
  */
1522
- static public function render_icon_selector()
1523
- {
1524
  $icon_sets = FLBuilderIcons::get_sets();
1525
 
1526
  ob_start();
1527
  include FL_BUILDER_DIR . 'includes/icon-selector.php';
1528
  $html = ob_get_clean();
1529
 
1530
- return array( 'html' => $html );
 
 
1531
  }
1532
 
1533
  /**
@@ -1536,14 +1483,13 @@ final class FLBuilder {
1536
  * @since 1.0
1537
  * @return void
1538
  */
1539
- static public function render_rows()
1540
- {
1541
- $rows = FLBuilderModel::get_nodes('row');
1542
 
1543
  do_action( 'fl_builder_before_render_rows', $rows );
1544
 
1545
- foreach($rows as $row) {
1546
- self::render_row($row);
1547
  }
1548
 
1549
  do_action( 'fl_builder_after_render_rows', $rows );
@@ -1556,9 +1502,8 @@ final class FLBuilder {
1556
  * @param object $row The row to render.
1557
  * @return void
1558
  */
1559
- static public function render_row($row)
1560
- {
1561
- $groups = FLBuilderModel::get_nodes('column-group', $row);
1562
 
1563
  do_action( 'fl_builder_before_render_row', $row, $groups );
1564
 
@@ -1581,8 +1526,7 @@ final class FLBuilder {
1581
  * @param object $row A row node object.
1582
  * @return void
1583
  */
1584
- static public function render_row_attributes( $row )
1585
- {
1586
  $custom_class = apply_filters( 'fl_builder_row_custom_class', $row->settings->class, $row );
1587
  $overlay_bgs = array( 'photo', 'parallax', 'slideshow', 'video' );
1588
  $attrs = array(
@@ -1591,13 +1535,13 @@ final class FLBuilder {
1591
  'fl-row',
1592
  'fl-row-' . $row->settings->width . '-width',
1593
  'fl-row-bg-' . $row->settings->bg_type,
1594
- 'fl-node-' . $row->node
1595
  ),
1596
- 'data-node' => $row->node
1597
  );
1598
 
1599
  // Classes
1600
- if ( ! empty( $row->settings->full_height ) && $row->settings->full_height == 'full' ) {
1601
 
1602
  $attrs['class'][] = 'fl-row-full-height';
1603
 
@@ -1616,7 +1560,7 @@ final class FLBuilder {
1616
  }
1617
 
1618
  // Data
1619
- if ( $row->settings->bg_type == 'parallax' && ! empty( $row->settings->bg_parallax_image_src ) ) {
1620
  $attrs['data-parallax-speed'] = $row->settings->bg_parallax_speed;
1621
  $attrs['data-parallax-image'] = $row->settings->bg_parallax_image_src;
1622
  }
@@ -1631,15 +1575,14 @@ final class FLBuilder {
1631
  * @param object $row A row node object.
1632
  * @return void
1633
  */
1634
- static public function render_row_bg($row)
1635
- {
1636
  do_action( 'fl_builder_before_render_row_bg', $row );
1637
 
1638
- if($row->settings->bg_type == 'video') {
1639
 
1640
- $vid_data = FLBuilderModel::get_row_bg_data($row);
1641
 
1642
- if($vid_data || in_array($row->settings->bg_video_source, array('video_url', 'video_service'))) {
1643
  $template_file = self::locate_template_file(
1644
  apply_filters( 'fl_builder_row_video_bg_template_base', 'row-video', $row ),
1645
  apply_filters( 'fl_builder_row_video_bg_template_slug', '', $row )
@@ -1649,8 +1592,7 @@ final class FLBuilder {
1649
  include $template_file;
1650
  }
1651
  }
1652
- }
1653
- else if($row->settings->bg_type == 'slideshow') {
1654
  echo '<div class="fl-bg-slideshow"></div>';
1655
  }
1656
 
@@ -1664,8 +1606,7 @@ final class FLBuilder {
1664
  * @param object $row A row node object.
1665
  * @return void
1666
  */
1667
- static public function render_row_content_class($row)
1668
- {
1669
  echo 'fl-row-content';
1670
  echo ' fl-row-' . $row->settings->content_width . '-width';
1671
  echo ' fl-node-content';
@@ -1678,23 +1619,22 @@ final class FLBuilder {
1678
  * @param string $node_id A row node ID.
1679
  * @return array
1680
  */
1681
- static public function render_row_settings($node_id = null)
1682
- {
1683
- $node = FLBuilderModel::get_node($node_id);
1684
  $settings = $node->settings;
1685
  $form = FLBuilderModel::$settings_forms['row'];
1686
 
1687
  $rendered_settings = self::render_settings(array(
1688
  'class' => 'fl-builder-row-settings',
1689
- 'attrs' => 'data-node="'. $node->node .'"',
1690
  'title' => $form['title'],
1691
  'tabs' => $form['tabs'],
1692
- 'resizable' => true
1693
  ), $settings);
1694
 
1695
  return array(
1696
  'settings' => $rendered_settings['html'],
1697
- 'state' => FLBuilderAJAXLayout::render( $node_id )
1698
  );
1699
  }
1700
 
@@ -1705,9 +1645,8 @@ final class FLBuilder {
1705
  * @param object $group A column group node object.
1706
  * @return void
1707
  */
1708
- static public function render_column_group($group)
1709
- {
1710
- $cols = FLBuilderModel::get_nodes('column', $group);
1711
 
1712
  do_action( 'fl_builder_before_render_column_group', $group, $cols );
1713
 
@@ -1730,40 +1669,39 @@ final class FLBuilder {
1730
  * @param object $group
1731
  * @return void
1732
  */
1733
- static public function render_column_group_attributes( $group )
1734
- {
1735
  $cols = FLBuilderModel::get_nodes( 'column', $group );
1736
  $parent = FLBuilderModel::get_node_parent( $group );
1737
  $attrs = array(
1738
  'class' => array(
1739
  'fl-col-group',
1740
- 'fl-node-' . $group->node
1741
  ),
1742
- 'data-node' => $group->node
1743
  );
1744
 
1745
  if ( 'column' == $parent->type ) {
1746
  $attrs['class'][] = 'fl-col-group-nested';
1747
  }
1748
 
1749
- foreach( $cols as $col ) {
1750
 
1751
- if( isset( $col->settings->equal_height ) && $col->settings->equal_height == 'yes' ) {
1752
  if ( ! in_array( 'fl-col-group-equal-height', $attrs['class'] ) ) {
1753
  $attrs['class'][] = 'fl-col-group-equal-height';
1754
  }
1755
- if( isset( $col->settings->content_alignment ) ) {
1756
  if ( ! in_array( 'fl-col-group-align-' . $col->settings->content_alignment, $attrs['class'] ) ) {
1757
  $attrs['class'][] = 'fl-col-group-align-' . $col->settings->content_alignment;
1758
  }
1759
  }
1760
  }
1761
- if( isset( $col->settings->responsive_size ) && $col->settings->responsive_size == 'custom' ) {
1762
  if ( ! in_array( 'fl-col-group-custom-width', $attrs['class'] ) ) {
1763
  $attrs['class'][] = 'fl-col-group-custom-width';
1764
  }
1765
  }
1766
- if( isset( $col->settings->responsive_order ) && $col->settings->responsive_order == 'reversed' ) {
1767
  if ( ! in_array( 'fl-col-group-responsive-reversed', $attrs['class'] ) ) {
1768
  $attrs['class'][] = 'fl-col-group-responsive-reversed';
1769
  }
@@ -1780,8 +1718,7 @@ final class FLBuilder {
1780
  * @param string|object $col_id A column ID or object.
1781
  * @return void
1782
  */
1783
- static public function render_column( $col_id = null )
1784
- {
1785
  $col = is_object( $col_id ) ? $col_id : FLBuilderModel::get_node( $col_id );
1786
 
1787
  if ( FLBuilderModel::is_node_visible( $col ) ) {
@@ -1796,23 +1733,22 @@ final class FLBuilder {
1796
  * @param string $node_id A column node ID.
1797
  * @return array
1798
  */
1799
- static public function render_column_settings($node_id = null)
1800
- {
1801
- $node = FLBuilderModel::get_node($node_id);
1802
  $settings = $node->settings;
1803
  $form = FLBuilderModel::$settings_forms['col'];
1804
 
1805
  $rendered_settings = self::render_settings(array(
1806
  'class' => 'fl-builder-col-settings',
1807
- 'attrs' => 'data-node="'. $node->node .'"',
1808
  'title' => $form['title'],
1809
  'tabs' => $form['tabs'],
1810
- 'resizable' => true
1811
  ), $settings);
1812
 
1813
  return array(
1814
  'settings' => $rendered_settings['html'],
1815
- 'state' => FLBuilderAJAXLayout::render( $node->parent )
1816
  );
1817
  }
1818
 
@@ -1823,8 +1759,7 @@ final class FLBuilder {
1823
  * @param object $col A column node object.
1824
  * @return void
1825
  */
1826
- static public function render_column_attributes( $col )
1827
- {
1828
  $custom_class = apply_filters( 'fl_builder_column_custom_class', $col->settings->class, $col );
1829
  $overlay_bgs = array( 'photo' );
1830
  $nested = FLBuilderModel::get_nodes( 'column-group', $col );
@@ -1832,10 +1767,10 @@ final class FLBuilder {
1832
  'id' => $col->settings->id,
1833
  'class' => array(
1834
  'fl-col',
1835
- 'fl-node-' . $col->node
1836
  ),
1837
  'data-node' => $col->node,
1838
- 'style' => array()
1839
  );
1840
 
1841
  // Classes
@@ -1871,8 +1806,7 @@ final class FLBuilder {
1871
  * @param string|object $col_id A column ID or object.
1872
  * @return void
1873
  */
1874
- static public function render_modules( $col_id = null )
1875
- {
1876
  $nodes = FLBuilderModel::get_nodes( null, $col_id );
1877
 
1878
  do_action( 'fl_builder_before_render_modules', $nodes, $col_id );
@@ -1881,8 +1815,7 @@ final class FLBuilder {
1881
 
1882
  if ( 'module' == $node->type && FLBuilderModel::is_module_registered( $node->settings->type ) ) {
1883
  self::render_module( $node );
1884
- }
1885
- else if ( 'column-group' == $node->type ) {
1886
  self::render_column_group( $node );
1887
  }
1888
  }
@@ -1897,8 +1830,7 @@ final class FLBuilder {
1897
  * @param string|object $module_id A module ID or object.
1898
  * @return void
1899
  */
1900
- static public function render_module( $module_id = null )
1901
- {
1902
  $module = FLBuilderModel::get_module( $module_id );
1903
  $settings = $module->settings;
1904
  $id = $module->node;
@@ -1927,26 +1859,24 @@ final class FLBuilder {
1927
  * @param bool $render_state Whether to render the preview state or not.
1928
  * @return array
1929
  */
1930
- static public function render_module_settings($node_id = null, $type = null, $parent_id = null, $render_state = true)
1931
- {
1932
  $assets = '';
1933
 
1934
  // Get the module and settings.
1935
- if($node_id) {
1936
- $module = FLBuilderModel::get_module($node_id);
1937
  $settings = $module->settings;
1938
- }
1939
- else {
1940
- $module = FLBuilderModel::$modules[$type];
1941
- $settings = FLBuilderModel::get_module_defaults($type);
1942
  }
1943
 
1944
  // Render the settings CSS/JS assets.
1945
- if(file_exists($module->dir .'css/settings.css')) {
1946
- $assets .= '<link class="fl-builder-settings-css" rel="stylesheet" href="'. $module->url .'css/settings.css" />';
1947
  }
1948
- if(file_exists($module->dir .'js/settings.js')) {
1949
- $assets .= '<script class="fl-builder-settings-js" src="'. $module->url .'js/settings.js"></script>';
1950
  }
1951
 
1952
  // Allow developers to hook in from a plugin and add further assets
@@ -1954,17 +1884,17 @@ final class FLBuilder {
1954
 
1955
  // Render the form.
1956
  $rendered_settings = self::render_settings(array(
1957
- 'class' => 'fl-builder-module-settings fl-builder-'. $type .'-settings',
1958
- 'attrs' => 'data-node="'. $node_id .'" data-parent="'. $parent_id .'" data-type="'. $type .'"',
1959
  'title' => sprintf( __( '%s Settings', 'fl-builder' ), $module->name ),
1960
  'tabs' => apply_filters( 'fl_builder_render_module_settings', $module->form, $module ),
1961
- 'resizable' => true
1962
  ), $settings);
1963
 
1964
  // Return the HTML.
1965
  return array(
1966
  'settings' => $assets . $rendered_settings['html'],
1967
- 'state' => $render_state ? FLBuilderAJAXLayout::render( $node_id ) : null
1968
  );
1969
  }
1970
 
@@ -1979,21 +1909,20 @@ final class FLBuilder {
1979
  * @param object $module Optional. An existing module object to use.
1980
  * @return void
1981
  */
1982
- static public function render_module_html($type, $settings, $module = null)
1983
- {
1984
  // Settings
1985
- $defaults = FLBuilderModel::get_module_defaults($type);
1986
- $settings = (object)array_merge((array)$defaults, (array)$settings);
1987
 
1988
  // Module
1989
- $class = get_class(FLBuilderModel::$modules[$type]);
1990
  $module = new $class();
1991
  $module->settings = $settings;
1992
 
1993
  // Shorthand reference to the module's id.
1994
  $id = $module->node;
1995
 
1996
- include $module->dir .'includes/frontend.php';
1997
  }
1998
 
1999
  /**
@@ -2003,15 +1932,14 @@ final class FLBuilder {
2003
  * @param object $module A module node object.
2004
  * @return void
2005
  */
2006
- static public function render_module_attributes( $module )
2007
- {
2008
  $custom_class = apply_filters( 'fl_builder_module_custom_class', $module->settings->class, $module );
2009
  $attrs = array(
2010
  'id' => esc_attr( $module->settings->id ),
2011
  'class' => array(
2012
  'fl-module',
2013
  'fl-module-' . $module->settings->type,
2014
- 'fl-node-' . $module->node
2015
  ),
2016
  'data-node' => $module->node,
2017
  );
@@ -2048,19 +1976,18 @@ final class FLBuilder {
2048
  * @param object $settings A module settings object.
2049
  * @return void
2050
  */
2051
- static public function render_module_css($type, $id, $settings)
2052
- {
2053
  // Settings
2054
  $global_settings = FLBuilderModel::get_global_settings();
2055
- $defaults = FLBuilderModel::get_module_defaults($type);
2056
- $settings = (object)array_merge((array)$defaults, (array)$settings);
2057
 
2058
  // Module
2059
- $class = get_class(FLBuilderModel::$modules[$type]);
2060
  $module = new $class();
2061
  $module->settings = $settings;
2062
 
2063
- include $module->dir .'includes/frontend.css.php';
2064
  }
2065
 
2066
  /**
@@ -2069,8 +1996,7 @@ final class FLBuilder {
2069
  * @since 1.7
2070
  * @return void
2071
  */
2072
- static public function render_assets()
2073
- {
2074
  self::render_css();
2075
  self::render_js();
2076
  }
@@ -2082,8 +2008,7 @@ final class FLBuilder {
2082
  * @since 1.7
2083
  * @return void
2084
  */
2085
- static public function render_custom_css_for_editing()
2086
- {
2087
  if ( ! FLBuilderModel::is_builder_active() ) {
2088
  return;
2089
  }
@@ -2102,15 +2027,14 @@ final class FLBuilder {
2102
  * @param bool $include_global
2103
  * @return string
2104
  */
2105
- static public function render_css( $include_global = true )
2106
- {
2107
  // Get info on the new file.
2108
  $nodes = FLBuilderModel::get_categorized_nodes();
2109
  $node_status = FLBuilderModel::get_node_status();
2110
  $global_settings = FLBuilderModel::get_global_settings();
2111
  $asset_info = FLBuilderModel::get_asset_info();
2112
  $post_id = FLBuilderModel::get_post_id();
2113
- $post = get_post($post_id);
2114
  $css = '';
2115
  $path = $include_global ? $asset_info['css'] : $asset_info['css_partial'];
2116
 
@@ -2120,7 +2044,7 @@ final class FLBuilder {
2120
  }
2121
 
2122
  // Loop through rows
2123
- foreach($nodes['rows'] as $row) {
2124
 
2125
  // Instance row css
2126
  ob_start();
@@ -2128,17 +2052,17 @@ final class FLBuilder {
2128
  $css .= ob_get_clean();
2129
 
2130
  // Instance row margins
2131
- $css .= self::render_row_margins($row);
2132
 
2133
  // Instance row padding
2134
- $css .= self::render_row_padding($row);
2135
 
2136
  // Instance row border
2137
- $css .= self::render_row_border($row);
2138
  }
2139
 
2140
  // Loop through the columns.
2141
- foreach($nodes['columns'] as $col) {
2142
 
2143
  // Instance column css
2144
  ob_start();
@@ -2146,40 +2070,40 @@ final class FLBuilder {
2146
  $css .= ob_get_clean();
2147
 
2148
  // Instance column margins
2149
- $css .= self::render_column_margins($col);
2150
 
2151
  // Instance column padding
2152
- $css .= self::render_column_padding($col);
2153
 
2154
  // Instance column border
2155
- $css .= self::render_column_border($col);
2156
 
2157
  // Get the modules in this column.
2158
- $modules = FLBuilderModel::get_modules($col);
2159
  }
2160
 
2161
  // Loop through the modules.
2162
- foreach($nodes['modules'] as $module) {
2163
 
2164
  // Global module css
2165
  $file = $module->dir . 'css/frontend.css';
2166
  $file_responsive = $module->dir . 'css/frontend.responsive.css';
2167
 
2168
  // Only include global module css that hasn't been included yet.
2169
- if(!in_array($module->settings->type . '-module-css', self::$enqueued_global_assets)) {
2170
 
2171
  // Add to the compiled array so we don't include it again.
2172
  self::$enqueued_global_assets[] = $module->settings->type . '-module-css';
2173
 
2174
  // Get the standard module css.
2175
- if(file_exists($file)) {
2176
- $css .= file_get_contents($file);
2177
  }
2178
 
2179
  // Get the responsive module css.
2180
- if($global_settings->responsive_enabled && file_exists($file_responsive)) {
2181
- $css .= '@media (max-width: '. $global_settings->responsive_breakpoint .'px) { ';
2182
- $css .= file_get_contents($file_responsive);
2183
  $css .= ' }';
2184
  }
2185
  }
@@ -2189,19 +2113,19 @@ final class FLBuilder {
2189
  $settings = $module->settings;
2190
  $id = $module->node;
2191
 
2192
- if(file_exists($file)) {
2193
  ob_start();
2194
  include $file;
2195
  $css .= ob_get_clean();
2196
  }
2197
 
2198
  // Instance module margins
2199
- $css .= self::render_module_margins($module);
2200
 
2201
  if ( ! isset( $global_settings->auto_spacing ) || $global_settings->auto_spacing ) {
2202
- $css .= self::render_responsive_module_margins($module);
2203
  }
2204
- }
2205
 
2206
  // Custom Global CSS (included here for proper specificity)
2207
  if ( 'published' == $node_status && $include_global ) {
@@ -2220,8 +2144,8 @@ final class FLBuilder {
2220
  $css = apply_filters( 'fl_builder_render_css', $css, $nodes, $global_settings, $include_global );
2221
 
2222
  if ( ! defined( 'WP_DEBUG' ) || ! WP_DEBUG ) {
2223
- $css = preg_replace('!/\*[^*]*\*+([^/][^*]*\*+)*/!', '', $css);
2224
- $css = str_replace(array("\r\n", "\r", "\n", "\t", ' ', ' ', ' '), '', $css);
2225
  }
2226
 
2227
  file_put_contents( $path, $css );
@@ -2241,13 +2165,12 @@ final class FLBuilder {
2241
  * @since 1.8.2
2242
  * @return string
2243
  */
2244
- static public function render_global_css()
2245
- {
2246
  // Get info on the new file.
2247
  $global_settings = FLBuilderModel::get_global_settings();
2248
 
2249
  // Core layout css
2250
- $css = file_get_contents(FL_BUILDER_DIR . '/css/fl-builder-layout.css');
2251
 
2252
  // Core button defaults
2253
  if ( ! defined( 'FL_THEME_VERSION' ) ) {
@@ -2255,8 +2178,8 @@ final class FLBuilder {
2255
  }
2256
 
2257
  // Core layout RTL css
2258
- if(is_rtl()) {
2259
- $css .= file_get_contents(FL_BUILDER_DIR . '/css/fl-builder-layout-rtl.css');
2260
  }
2261
 
2262
  // Global node css
@@ -2264,7 +2187,7 @@ final class FLBuilder {
2264
  array( 'row_margins', '.fl-row-content-wrap { margin: ' ),
2265
  array( 'row_padding', '.fl-row-content-wrap { padding: ' ),
2266
  array( 'row_width', '.fl-row-fixed-width { max-width: ' ),
2267
- array( 'module_margins', '.fl-module-content { margin: ' )
2268
  ) as $data ) {
2269
  if ( '' !== $global_settings->{ $data[0] } ) {
2270
  $value = preg_replace( self::regex( 'css_unit' ), '', strtolower( $global_settings->{ $data[0] } ) );
@@ -2277,52 +2200,52 @@ final class FLBuilder {
2277
  if ( $global_settings->responsive_enabled ) {
2278
 
2279
  // Medium devices
2280
- $css .= '@media (max-width: '. $global_settings->medium_breakpoint .'px) { ';
2281
 
2282
  // Core medium layout css
2283
- $css .= file_get_contents(FL_BUILDER_DIR . '/css/fl-builder-layout-medium.css');
2284
 
2285
  // Global node medium css
2286
- foreach ( array(
2287
  array( 'row_margins_medium', '.fl-row[data-node] > .fl-row-content-wrap { margin: ' ),
2288
  array( 'row_padding_medium', '.fl-row[data-node] > .fl-row-content-wrap { padding: ' ),
2289
- array( 'module_margins_medium', '.fl-module[data-node] > .fl-module-content { margin: ' )
2290
  ) as $data ) {
2291
- if ( '' !== $global_settings->{ $data[0] } ) {
2292
- $value = preg_replace( self::regex( 'css_unit' ), '', strtolower( $global_settings->{ $data[0] } ) );
2293
- $css .= $data[1] . esc_attr( $value );
2294
- $css .= ( is_numeric( $value ) ) ? ( 'px; }' ) : ( '; }' );
2295
- }
2296
  }
 
2297
 
2298
  $css .= ' }';
2299
 
2300
  // Responsive devices
2301
- $css .= '@media (max-width: '. $global_settings->responsive_breakpoint .'px) { ';
2302
 
2303
  // Core responsive layout css
2304
- $css .= file_get_contents(FL_BUILDER_DIR . '/css/fl-builder-layout-responsive.css');
2305
 
2306
  // Auto spacing
2307
- if ( ! isset( $global_settings->auto_spacing ) || $global_settings->auto_spacing ) {
2308
- $css .= file_get_contents(FL_BUILDER_DIR . '/css/fl-builder-layout-auto-spacing.css');
2309
- }
2310
 
2311
  // Global node responsive css
2312
- foreach ( array(
2313
  array( 'row_margins_responsive', '.fl-row[data-node] > .fl-row-content-wrap { margin: ' ),
2314
  array( 'row_padding_responsive', '.fl-row[data-node] > .fl-row-content-wrap { padding: ' ),
2315
- array( 'module_margins_responsive', '.fl-module[data-node] > .fl-module-content { margin: ' )
2316
  ) as $data ) {
2317
- if ( '' !== $global_settings->{ $data[0] } ) {
2318
- $value = preg_replace( self::regex( 'css_unit' ), '', strtolower( $global_settings->{ $data[0] } ) );
2319
- $css .= $data[1] . esc_attr( $value );
2320
- $css .= ( is_numeric( $value ) ) ? ( 'px; }' ) : ( '; }' );
2321
- }
2322
  }
 
2323
 
2324
  $css .= ' }';
2325
- }
2326
 
2327
  // Default page heading
2328
  if ( ! $global_settings->show_default_heading && ! empty( $global_settings->default_heading_selector ) ) {
@@ -2348,8 +2271,7 @@ final class FLBuilder {
2348
  * @param string $content A string where the URLs will be modified.
2349
  * @return string String with SSL ready URLs.
2350
  */
2351
- static public function rewrite_css_cache_urls( $content )
2352
- {
2353
  if ( FLBuilderModel::is_ssl() ) {
2354
  $content = str_ireplace( 'http:', 'https:', $content );
2355
  }
@@ -2364,8 +2286,7 @@ final class FLBuilder {
2364
  * @param string $scope What regular expression to return?
2365
  * @return string Regular expression.
2366
  */
2367
- static public function regex( $scope )
2368
- {
2369
  $regex = array(
2370
  'css_unit' => '/[^a-z0-9%.\-]/',
2371
  );
@@ -2381,8 +2302,7 @@ final class FLBuilder {
2381
  * @param string $selector_prefix Optional CSS selector prefix for better overrides.
2382
  * @return string A CSS string.
2383
  */
2384
- static public function render_node_spacing( $node = null, $prop_type = '', $selector_prefix = '' )
2385
- {
2386
  // Exit early if incorrect parameters
2387
  if ( ! is_object( $node ) || empty( $prop_type ) ) {
2388
  return;
@@ -2433,8 +2353,7 @@ final class FLBuilder {
2433
 
2434
  if ( empty( $settings->border_type ) ) {
2435
  continue;
2436
- }
2437
- else {
2438
  $prop .= '-width';
2439
  }
2440
  }
@@ -2452,8 +2371,7 @@ final class FLBuilder {
2452
  // Build the selector
2453
  if ( 'default' !== $breakpoint ) {
2454
  $selector = $selector_prefix . '.fl-' . str_replace( 'column', 'col', $node->type ) . $selector_suffix;
2455
- }
2456
- else {
2457
  $selector = $selector_prefix . $selector_suffix;
2458
  }
2459
 
@@ -2467,7 +2385,7 @@ final class FLBuilder {
2467
 
2468
  $css .= $breakpoint_css;
2469
  }
2470
- }
2471
 
2472
  return $css;
2473
  }
@@ -2479,8 +2397,7 @@ final class FLBuilder {
2479
  * @param object $row A row node object.
2480
  * @return string The row CSS margins string.
2481
  */
2482
- static public function render_row_margins($row)
2483
- {
2484
  return self::render_node_spacing( $row, 'margin' );
2485
  }
2486
 
@@ -2491,8 +2408,7 @@ final class FLBuilder {
2491
  * @param object $row A row node object.
2492
  * @return string The row CSS padding string.
2493
  */
2494
- static public function render_row_padding($row)
2495
- {
2496
  return self::render_node_spacing( $row, 'padding' );
2497
  }
2498
 
@@ -2503,8 +2419,7 @@ final class FLBuilder {
2503
  * @param object $row A row node object.
2504
  * @return string The row CSS border-width string.
2505
  */
2506
- static public function render_row_border($row)
2507
- {
2508
  return self::render_node_spacing( $row, 'border' );
2509
  }
2510
 
@@ -2515,8 +2430,7 @@ final class FLBuilder {
2515
  * @param object $col A column node object.
2516
  * @return string The column CSS margins string.
2517
  */
2518
- static public function render_column_margins($col)
2519
- {
2520
  return self::render_node_spacing( $col, 'margin' );
2521
  }
2522
 
@@ -2527,8 +2441,7 @@ final class FLBuilder {
2527
  * @param object $col A column node object.
2528
  * @return string The column CSS padding string.
2529
  */
2530
- static public function render_column_padding($col)
2531
- {
2532
  return self::render_node_spacing( $col, 'padding' );
2533
  }
2534
 
@@ -2539,8 +2452,7 @@ final class FLBuilder {
2539
  * @param object $col A column node object.
2540
  * @return string The column CSS border-width string.
2541
  */
2542
- static public function render_column_border($col)
2543
- {
2544
  return self::render_node_spacing( $col, 'border', '.fl-builder-content' );
2545
  }
2546
 
@@ -2551,8 +2463,7 @@ final class FLBuilder {
2551
  * @param object $module A module node object.
2552
  * @return string The module CSS margins string.
2553
  */
2554
- static public function render_module_margins($module)
2555
- {
2556
  return self::render_node_spacing( $module, 'margin' );
2557
  }
2558
 
@@ -2563,8 +2474,7 @@ final class FLBuilder {
2563
  * @param object $module A module node object.
2564
  * @return string The module CSS margins string.
2565
  */
2566
- static public function render_responsive_module_margins($module)
2567
- {
2568
  $global_settings = FLBuilderModel::get_global_settings();
2569
  $settings = $module->settings;
2570
  $margins = '';
@@ -2578,8 +2488,7 @@ final class FLBuilder {
2578
  // Get the global default margin value to use.
2579
  if ( '' != $global_settings->module_margins_medium ) {
2580
  $default = trim( $global_settings->module_margins_medium );
2581
- }
2582
- else {
2583
  $default = trim( $global_settings->module_margins );
2584
  }
2585
 
@@ -2617,13 +2526,12 @@ final class FLBuilder {
2617
  * @param bool $include_global
2618
  * @return string
2619
  */
2620
- static public function render_js( $include_global = true )
2621
- {
2622
  // Get info on the new file.
2623
  $nodes = FLBuilderModel::get_categorized_nodes();
2624
  $global_settings = FLBuilderModel::get_global_settings();
2625
  $layout_settings = FLBuilderModel::get_layout_settings();
2626
- $rows = FLBuilderModel::get_nodes('row');
2627
  $asset_info = FLBuilderModel::get_asset_info();
2628
  $js = '';
2629
  $path = $include_global ? $asset_info['js'] : $asset_info['js_partial'];
@@ -2634,12 +2542,12 @@ final class FLBuilder {
2634
  }
2635
 
2636
  // Loop through the rows.
2637
- foreach($nodes['rows'] as $row) {
2638
  $js .= self::render_row_js( $row );
2639
  }
2640
 
2641
  // Loop through the modules.
2642
- foreach($nodes['modules'] as $module) {
2643
  $js .= self::render_module_js( $module );
2644
  }
2645
 
@@ -2648,12 +2556,12 @@ final class FLBuilder {
2648
  $js .= is_array( $layout_settings->js ) ? json_encode( $layout_settings->js ) : $layout_settings->js;
2649
 
2650
  // Call the FLBuilder._renderLayoutComplete method if we're currently editing.
2651
- if(stristr($asset_info['js'], '-draft.js') || stristr($asset_info['js'], '-preview.js')) {
2652
  $js .= "; if(typeof FLBuilder !== 'undefined' && typeof FLBuilder._renderLayoutComplete !== 'undefined') FLBuilder._renderLayoutComplete();";
2653
  }
2654
 
2655
  // Include FLJSMin
2656
- if(!class_exists('FLJSMin')) {
2657
  include FL_BUILDER_DIR . 'classes/class-fl-jsmin.php';
2658
  }
2659
 
@@ -2661,15 +2569,15 @@ final class FLBuilder {
2661
  $js = apply_filters( 'fl_builder_render_js', $js, $nodes, $global_settings, $include_global );
2662
 
2663
  // Save the JS.
2664
- if(!empty($js)) {
2665
 
2666
  if ( ! defined( 'WP_DEBUG' ) || ! WP_DEBUG ) {
2667
  try {
2668
- $min = FLJSMin::minify( $js );
2669
- } catch (Exception $e) {}
2670
 
2671
  if ( $min ) {
2672
- $js = $min;
2673
  }
2674
  }
2675
 
@@ -2691,13 +2599,12 @@ final class FLBuilder {
2691
  * @since 1.8.2
2692
  * @return string
2693
  */
2694
- static public function render_global_js()
2695
- {
2696
  $global_settings = FLBuilderModel::get_global_settings();
2697
  $js = '';
2698
 
2699
  // Add the path legacy vars (FLBuilderLayoutConfig.paths should be used instead).
2700
- $js .= "var wpAjaxUrl = '" . admin_url('admin-ajax.php') . "';";
2701
  $js .= "var flBuilderUrl = '" . FL_BUILDER_URL . "';";
2702
 
2703
  // Layout config object.
@@ -2706,7 +2613,7 @@ final class FLBuilder {
2706
  $js .= ob_get_clean();
2707
 
2708
  // Core layout JS.
2709
- $js .= file_get_contents(FL_BUILDER_DIR . 'js/fl-builder-layout.js');
2710
 
2711
  // Add the global settings JS.
2712
  $js .= $global_settings->js;
@@ -2721,8 +2628,7 @@ final class FLBuilder {
2721
  * @param string|object $row_id A row ID or object.
2722
  * @return string
2723
  */
2724
- static public function render_row_js( $row_id )
2725
- {
2726
  $row = is_object( $row_id ) ? $row_id : FLBuilderModel::get_node( $row_id );
2727
  $settings = $row->settings;
2728
  $id = $row->node;
@@ -2739,19 +2645,18 @@ final class FLBuilder {
2739
  * @param string|object $row_id A row ID or object.
2740
  * @return string
2741
  */
2742
- static public function render_row_modules_js( $row_id )
2743
- {
2744
  $row = is_object( $row_id ) ? $row_id : FLBuilderModel::get_node( $row_id );
2745
  $nodes = FLBuilderModel::get_categorized_nodes();
2746
  $template_post_id = FLBuilderModel::is_node_global( $row );
2747
  $js = '';
2748
 
2749
  // Render the JS.
2750
- foreach( $nodes['groups'] as $group ) {
2751
  if ( $row->node == $group->parent || ( $template_post_id && $row->template_node_id == $group->parent ) ) {
2752
- foreach( $nodes['columns'] as $column ) {
2753
  if ( $group->node == $column->parent ) {
2754
- foreach( $nodes['modules'] as $module ) {
2755
  if ( $column->node == $module->parent ) {
2756
  $js .= self::render_module_js( $module );
2757
  }
@@ -2772,14 +2677,13 @@ final class FLBuilder {
2772
  * @param string|object $col_id A column ID or object.
2773
  * @return string
2774
  */
2775
- static public function render_column_modules_js( $col_id )
2776
- {
2777
  $col = is_object( $col_id ) ? $col_id : FLBuilderModel::get_node( $col_id );
2778
  $nodes = FLBuilderModel::get_categorized_nodes();
2779
  $js = '';
2780
 
2781
  // Render the JS.
2782
- foreach( $nodes['modules'] as $module ) {
2783
  if ( $col->node == $module->parent ) {
2784
  $js .= self::render_module_js( $module );
2785
  }
@@ -2796,8 +2700,7 @@ final class FLBuilder {
2796
  * @param string|object $module_id A module ID or object.
2797
  * @return string
2798
  */
2799
- static public function render_module_js( $module_id )
2800
- {
2801
  $module = is_object( $module_id ) ? $module_id : FLBuilderModel::get_module( $module_id );
2802
  $global_settings = FLBuilderModel::get_global_settings();
2803
  $js = '';
@@ -2830,8 +2733,7 @@ final class FLBuilder {
2830
  *
2831
  * @since 1.7
2832
  */
2833
- static public function render_global_nodes_custom_code( $type = 'css' )
2834
- {
2835
  $code = '';
2836
  $rendered = array();
2837
 
@@ -2840,7 +2742,7 @@ final class FLBuilder {
2840
  $nodes = FLBuilderModel::get_layout_data();
2841
  $node_status = FLBuilderModel::get_node_status();
2842
 
2843
- foreach( $nodes as $node_id => $node ) {
2844
 
2845
  $template_post_id = FLBuilderModel::is_node_global( $node );
2846
 
@@ -2861,8 +2763,7 @@ final class FLBuilder {
2861
  * @since 1.0
2862
  * @return void
2863
  */
2864
- static public function log()
2865
- {
2866
  foreach ( func_get_args() as $arg ) {
2867
  ob_start();
2868
  print_r( $arg );
@@ -2874,8 +2775,7 @@ final class FLBuilder {
2874
  * @since 1.0
2875
  * @deprecated 1.7.4
2876
  */
2877
- static public function layout_styles_scripts( $post_id )
2878
- {
2879
  _deprecated_function( __METHOD__, '1.7.4', __CLASS__ . '::enqueue_layout_styles_scripts()' );
2880
 
2881
  self::enqueue_layout_styles_scripts();
@@ -2885,8 +2785,7 @@ final class FLBuilder {
2885
  * @since 1.0
2886
  * @deprecated 1.7.4
2887
  */
2888
- static public function styles_scripts()
2889
- {
2890
  _deprecated_function( __METHOD__, '1.7.4', __CLASS__ . '::enqueue_ui_styles_scripts()' );
2891
 
2892
  self::enqueue_ui_styles_scripts();
@@ -2896,8 +2795,7 @@ final class FLBuilder {
2896
  * @since 1.0
2897
  * @deprecated 1.8
2898
  */
2899
- static public function register_templates_post_type()
2900
- {
2901
  _deprecated_function( __METHOD__, '1.8', 'FLBuilderUserTemplates::register_post_type()' );
2902
 
2903
  if ( class_exists( 'FLBuilderUserTemplates' ) ) {
@@ -2909,8 +2807,7 @@ final class FLBuilder {
2909
  * @since 1.0
2910
  * @deprecated 1.8
2911
  */
2912
- static public function render_template( $template )
2913
- {
2914
  _deprecated_function( __METHOD__, '1.8', 'FLBuilderUserTemplates::template_include()' );
2915
 
2916
  if ( class_exists( 'FLBuilderUserTemplates' ) ) {
@@ -2922,8 +2819,7 @@ final class FLBuilder {
2922
  * @since 1.6.3
2923
  * @deprecated 1.8
2924
  */
2925
- static public function render_ui_panel_node_templates()
2926
- {
2927
  _deprecated_function( __METHOD__, '1.8', 'FLBuilderUserTemplates::render_ui_panel_node_templates()' );
2928
 
2929
  if ( class_exists( 'FLBuilderUserTemplates' ) ) {
@@ -2935,8 +2831,7 @@ final class FLBuilder {
2935
  * @since 1.0
2936
  * @deprecated 1.8
2937
  */
2938
- static public function render_user_template_settings()
2939
- {
2940
  _deprecated_function( __METHOD__, '1.8', 'FLBuilderUserTemplates::render_settings()' );
2941
 
2942
  if ( class_exists( 'FLBuilderUserTemplates' ) ) {
@@ -2948,8 +2843,7 @@ final class FLBuilder {
2948
  * @since 1.6.3
2949
  * @deprecated 1.8
2950
  */
2951
- static public function render_node_template_settings( $node_id = null )
2952
- {
2953
  _deprecated_function( __METHOD__, '1.8', 'FLBuilderUserTemplates::render_node_settings()' );
2954
 
2955
  if ( class_exists( 'FLBuilderUserTemplates' ) ) {
43
  * @since 1.8
44
  * @return void
45
  */
46
+ static public function init() {
 
47
  /* Actions */
48
+ add_action( 'plugins_loaded', __CLASS__ . '::load_plugin_textdomain' );
49
+ add_action( 'send_headers', __CLASS__ . '::no_cache_headers' );
50
+ add_action( 'wp', __CLASS__ . '::init_ui', 11 );
51
+ add_action( 'wp_enqueue_scripts', __CLASS__ . '::register_layout_styles_scripts' );
52
+ add_action( 'wp_enqueue_scripts', __CLASS__ . '::enqueue_ui_styles_scripts', 11 );
53
+ add_action( 'wp_enqueue_scripts', __CLASS__ . '::enqueue_all_layouts_styles_scripts' );
54
+ add_action( 'wp_head', __CLASS__ . '::render_custom_css_for_editing', 999 );
55
+ add_action( 'admin_bar_menu', __CLASS__ . '::admin_bar_menu', 999 );
56
+ add_action( 'wp_footer', __CLASS__ . '::include_jquery' );
57
+ add_action( 'wp_footer', __CLASS__ . '::render_ui' );
58
+ add_action( 'fl_builder_ui_panel_after_rows', __CLASS__ . '::render_ui_panel_row_templates' );
59
+ add_action( 'fl_builder_ui_panel_after_modules', __CLASS__ . '::render_ui_panel_modules_templates' );
60
 
61
  /* Filters */
62
+ add_filter( 'fl_builder_render_css', __CLASS__ . '::rewrite_css_cache_urls', 9999 );
63
+ add_filter( 'body_class', __CLASS__ . '::body_class' );
64
+ add_filter( 'wp_default_editor', __CLASS__ . '::default_editor' );
65
+ add_filter( 'mce_css', __CLASS__ . '::add_editor_css' );
66
+ add_filter( 'mce_buttons', __CLASS__ . '::editor_buttons' );
67
+ add_filter( 'mce_buttons_2', __CLASS__ . '::editor_buttons_2' );
68
+ add_filter( 'mce_external_plugins', __CLASS__ . '::editor_external_plugins', 9999 );
69
+ add_filter( 'tiny_mce_before_init', __CLASS__ . '::editor_font_sizes' );
70
+ add_filter( 'the_content', __CLASS__ . '::render_content' );
71
  }
72
 
73
  /**
79
  * @since 1.4.4
80
  * @return string|bool The translation file path or false if none is found.
81
  */
82
+ static public function load_plugin_textdomain() {
 
83
  // Traditional WordPress plugin locale filter
84
  // Uses get_user_locale() which was added in 4.7 so we need to check its available.
85
+ if ( function_exists( 'get_user_locale' ) ) {
86
  $locale = apply_filters( 'plugin_locale', get_user_locale(), 'fl-builder' );
87
  } else {
88
  $locale = apply_filters( 'plugin_locale', get_locale(), 'fl-builder' );
95
  if ( file_exists( $mofile_global ) ) {
96
  //Look in global /wp-content/languages/plugins/bb-plugin/ folder
97
  return load_textdomain( 'fl-builder', $mofile_global );
98
+ } elseif ( file_exists( $mofile_local ) ) {
 
99
  //Look in local /wp-content/plugins/bb-plugin/languages/ folder
100
  return load_textdomain( 'fl-builder', $mofile_local );
101
  }
111
  * @param sting $path The directory path to the template data file.
112
  * @return void
113
  */
114
+ static public function register_templates( $path ) {
 
115
  FLBuilderModel::register_templates( $path );
116
  }
117
 
123
  * @param array $form The module's settings form data.
124
  * @return void
125
  */
126
+ static public function register_module( $class, $form ) {
127
+ FLBuilderModel::register_module( $class, $form );
 
128
  }
129
 
130
  /**
135
  * @param array $config The alias config.
136
  * @return void
137
  */
138
+ static public function register_module_alias( $alias, $config ) {
 
139
  FLBuilderModel::register_module_alias( $alias, $config );
140
  }
141
 
147
  * @param array $form The form data.
148
  * @return void
149
  */
150
+ static public function register_settings_form( $id, $form ) {
151
+ FLBuilderModel::register_settings_form( $id, $form );
 
152
  }
153
 
154
  /**
157
  * @since 1.0
158
  * @return void
159
  */
160
+ static public function no_cache_headers() {
161
+ if ( isset( $_GET['fl_builder'] ) ) {
162
+ header( 'Last-Modified: ' . gmdate( 'D, d M Y H:i:s' ) . ' GMT' );
163
+ header( 'Cache-Control: no-store, no-cache, must-revalidate' );
164
+ header( 'Cache-Control: post-check=0, pre-check=0', false );
165
+ header( 'Pragma: no-cache' );
166
+ header( 'Expires: Sat, 26 Jul 1997 05:00:00 GMT' );
 
167
  }
168
  }
169
 
174
  * @param string $type The current default editor type.
175
  * @return string
176
  */
177
+ static public function default_editor( $type ) {
 
178
  return FLBuilderModel::is_builder_active() ? 'tinymce' : $type;
179
  }
180
 
185
  * @param string $mce_css
186
  * @return string
187
  */
188
+ static public function add_editor_css( $mce_css ) {
189
+ if ( FLBuilderModel::is_builder_active() ) {
 
190
 
191
+ if ( ! empty( $mce_css ) ) {
192
  $mce_css .= ',';
193
  }
194
 
205
  * @param array $buttons The current buttons array.
206
  * @return array
207
  */
208
+ static public function editor_buttons( $buttons ) {
 
209
  if ( FLBuilderModel::is_builder_active() ) {
210
+ if ( ( $key = array_search( 'wp_more', $buttons ) ) !== false ) { // @codingStandardsIgnoreLine
211
  unset( $buttons[ $key ] );
212
  }
213
  }
222
  * @param array $buttons The current buttons array.
223
  * @return array
224
  */
225
+ static public function editor_buttons_2( $buttons ) {
 
226
  global $wp_version;
227
 
228
  if ( FLBuilderModel::is_builder_active() ) {
234
  array_unshift( $buttons, 'formatselect' );
235
  }
236
 
237
+ if ( ( $key = array_search( 'wp_help', $buttons ) ) !== false ) { // @codingStandardsIgnoreLine
238
  unset( $buttons[ $key ] );
239
  }
240
  }
249
  * @param array $init The TinyMCE init array.
250
  * @return array
251
  */
252
+ static public function editor_font_sizes( $init ) {
 
253
  if ( FLBuilderModel::is_builder_active() ) {
254
  $init['fontsize_formats'] = implode( ' ', array(
255
  '10px',
286
  * @param array $plugins The current editor plugins.
287
  * @return array
288
  */
289
+ static public function editor_external_plugins( $plugins ) {
290
+ if ( FLBuilderModel::is_builder_active() ) {
 
291
 
292
  $allowed = array(
293
  'anchor',
304
  'wptadv',
305
  );
306
 
307
+ foreach ( $plugins as $key => $val ) {
308
+ if ( ! in_array( $key, $allowed ) ) {
309
+ unset( $plugins[ $key ] );
310
  }
311
  }
312
  }
320
  * @since 1.7.4
321
  * @return void
322
  */
323
+ static public function register_layout_styles_scripts() {
 
324
  $ver = FL_BUILDER_VERSION;
325
+ $css_url = plugins_url( '/css/', FL_BUILDER_FILE );
326
+ $js_url = plugins_url( '/js/', FL_BUILDER_FILE );
327
  $min = defined( 'WP_DEBUG' ) && WP_DEBUG ? '' : '.min';
328
 
329
  // Register additional CSS
330
+ wp_register_style( 'fl-slideshow', $css_url . 'fl-slideshow.css', array( 'yui3' ), $ver );
331
+ wp_register_style( 'jquery-bxslider', $css_url . 'jquery.bxslider.css', array(), $ver );
332
+ wp_register_style( 'jquery-magnificpopup', $css_url . 'jquery.magnificpopup.css', array(), $ver );
333
+ wp_register_style( 'yui3', $css_url . 'yui3.css', array(), $ver );
334
 
335
  // Register icon CDN CSS
336
+ wp_register_style( 'font-awesome', 'https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css', array(), $ver );
337
+ wp_register_style( 'foundation-icons', 'https://cdnjs.cloudflare.com/ajax/libs/foundicons/3.0.0/foundation-icons.css', array(), $ver );
338
 
339
  // Register additional JS
340
+ wp_register_script( 'fl-slideshow', $js_url . 'fl-slideshow' . $min . '.js', array( 'yui3' ), $ver, true );
341
+ wp_register_script( 'fl-gallery-grid', $js_url . 'fl-gallery-grid.js', array( 'jquery' ), $ver, true );
342
+ wp_register_script( 'jquery-bxslider', $js_url . 'jquery.bxslider.min.js', array( 'jquery-easing', 'jquery-fitvids' ), $ver, true );
343
+ wp_register_script( 'jquery-easing', $js_url . 'jquery.easing.1.3.js', array( 'jquery' ), '1.3', true );
344
+ wp_register_script( 'jquery-fitvids', $js_url . 'jquery.fitvids.js', array( 'jquery' ), $ver, true );
345
+ wp_register_script( 'jquery-imagesloaded', $js_url . 'jquery.imagesloaded.js', array( 'jquery' ), $ver, true );
346
+ wp_register_script( 'jquery-infinitescroll', $js_url . 'jquery.infinitescroll.js', array( 'jquery' ), $ver, true );
347
+ wp_register_script( 'jquery-magnificpopup', $js_url . 'jquery.magnificpopup.min.js', array( 'jquery' ), $ver, true );
348
+ wp_register_script( 'jquery-mosaicflow', $js_url . 'jquery.mosaicflow.min.js', array( 'jquery' ), $ver, true );
349
+ wp_register_script( 'jquery-waypoints', $js_url . 'jquery.waypoints.min.js', array( 'jquery' ), $ver, true );
350
+ wp_register_script( 'jquery-wookmark', $js_url . 'jquery.wookmark.min.js', array( 'jquery' ), $ver, true );
351
+ wp_register_script( 'yui3', $js_url . 'yui3.js', array(), $ver, true );
352
 
353
+ wp_register_script( 'youtube-player', 'https://www.youtube.com/iframe_api', array(), $ver, true );
354
+ wp_register_script( 'vimeo-player', 'https://player.vimeo.com/api/player.js', array(), $ver, true );
355
  }
356
 
357
  /**
361
  * @since 1.7.4
362
  * @return void
363
  */
364
+ static public function enqueue_all_layouts_styles_scripts() {
 
365
  global $wp_query;
366
  global $post;
367
 
377
  // Enqueue assets for posts via the fl_builder_global_posts filter.
378
  $post_ids = FLBuilderModel::get_global_posts();
379
 
380
+ if ( count( $post_ids ) > 0 ) {
381
 
382
  $posts = get_posts(array(
383
  'post__in' => $post_ids,
384
  'post_type' => get_post_types(),
385
+ 'posts_per_page' => -1,
386
  ));
387
 
388
+ foreach ( $posts as $post ) {
389
  self::enqueue_layout_styles_scripts();
390
  }
391
  }
401
  * @param bool $rerender Whether to rerender the CSS and JS.
402
  * @return void
403
  */
404
+ static public function enqueue_layout_styles_scripts( $rerender = false ) {
405
+ if ( FLBuilderModel::is_builder_enabled() ) {
 
406
 
407
  $nodes = FLBuilderModel::get_categorized_nodes();
408
 
409
  // Enqueue required row CSS and JS
410
+ foreach ( $nodes['rows'] as $row ) {
411
+ if ( 'slideshow' == $row->settings->bg_type ) {
412
+ wp_enqueue_script( 'yui3' );
413
+ wp_enqueue_script( 'fl-slideshow' );
414
+ wp_enqueue_style( 'fl-slideshow' );
415
+ } elseif ( 'video' == $row->settings->bg_type ) {
416
+ wp_enqueue_script( 'jquery-imagesloaded' );
417
+ if ( 'video_service' == $row->settings->bg_video_source ) {
418
+
419
+ $video_data = FLBuilderUtils::get_video_data( $row->settings->bg_video_service_url );
420
+
421
+ if ( 'youtube' == $video_data['type'] ) {
422
+ wp_enqueue_script( 'youtube-player' );
423
+ } elseif ( 'vimeo' == $video_data['type'] ) {
424
+ wp_enqueue_script( 'vimeo-player' );
 
 
425
  }
426
  }
427
  }
428
  }
429
 
430
  // Enqueue required module CSS and JS
431
+ foreach ( $nodes['modules'] as $module ) {
432
 
433
  $module->enqueue_icon_styles();
434
  $module->enqueue_font_styles();
435
  $module->enqueue_scripts();
436
 
437
+ foreach ( $module->css as $handle => $props ) {
438
+ wp_enqueue_style( $handle, $props[0], $props[1], $props[2], $props[3] );
439
  }
440
+ foreach ( $module->js as $handle => $props ) {
441
+ wp_enqueue_script( $handle, $props[0], $props[1], $props[2], $props[3] );
442
  }
443
+ if ( ! empty( $module->settings->animation ) ) {
444
+ wp_enqueue_script( 'jquery-waypoints' );
445
  }
446
  }
447
 
453
 
454
  // Enqueue layout JS
455
  self::enqueue_layout_cached_asset( 'js', $rerender );
456
+ }// End if().
457
  }
458
 
459
  /**
464
  * @param int $post_id
465
  * @return void
466
  */
467
+ static public function enqueue_layout_styles_scripts_by_id( $post_id ) {
 
468
  FLBuilderModel::set_post_id( $post_id );
469
  FLBuilder::enqueue_layout_styles_scripts();
470
  FLBuilderModel::reset_post_id();
479
  * @param bool $rerender Whether to rerender the CSS or JS.
480
  * @return string
481
  */
482
+ static private function enqueue_layout_cached_asset( $type = 'css', $rerender = false ) {
 
483
  $post_id = FLBuilderModel::get_post_id();
484
  $asset_info = FLBuilderModel::get_asset_info();
485
  $asset_ver = FLBuilderModel::get_asset_version();
489
  $path = $asset_info[ $type . '_partial' ];
490
  $url = $asset_info[ $type . '_partial_url' ];
491
  $global = false;
492
+ } else {
 
493
  $path = $asset_info[ $type ];
494
  $url = $asset_info[ $type . '_url' ];
495
  $global = true;
511
  $deps = apply_filters( 'fl_builder_layout_style_dependencies', array() );
512
  $media = apply_filters( 'fl_builder_layout_style_media', 'all' );
513
  wp_enqueue_style( 'fl-builder-layout-' . $post_id, $url, $deps, $asset_ver, $media );
514
+ } elseif ( 'js' == $type ) {
 
515
  wp_enqueue_script( 'fl-builder-layout-' . $post_id, $url, array( 'jquery' ), $asset_ver, true );
516
  }
517
  }
523
  * @since 1.10.2
524
  * @return void
525
  */
526
+ static public function clear_enqueued_global_assets() {
 
527
  self::$enqueued_global_assets = array();
528
  }
529
 
533
  * @since 1.7.4
534
  * @return void
535
  */
536
+ static public function enqueue_ui_styles_scripts() {
537
+ if ( FLBuilderModel::is_builder_active() ) {
 
538
 
539
  $ver = FL_BUILDER_VERSION;
540
+ $css_url = plugins_url( '/css/', FL_BUILDER_FILE );
541
+ $js_url = plugins_url( '/js/', FL_BUILDER_FILE );
542
 
543
  /* Frontend builder styles */
544
+ wp_enqueue_style( 'dashicons' );
545
+ wp_enqueue_style( 'font-awesome' );
546
+ wp_enqueue_style( 'foundation-icons' );
547
+ wp_enqueue_style( 'jquery-nanoscroller', $css_url . 'jquery.nanoscroller.css', array(), $ver );
548
+ wp_enqueue_style( 'jquery-autosuggest', $css_url . 'jquery.autoSuggest.min.css', array(), $ver );
549
+ wp_enqueue_style( 'jquery-tiptip', $css_url . 'jquery.tiptip.css', array(), $ver );
550
+ wp_enqueue_style( 'bootstrap-tour', $css_url . 'bootstrap-tour-standalone.min.css', array(), $ver );
551
 
552
  // Enqueue individual builder styles if WP_DEBUG is on.
553
  if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
554
+ wp_enqueue_style( 'fl-color-picker', $css_url . 'fl-color-picker.css', array(), $ver );
555
+ wp_enqueue_style( 'fl-lightbox', $css_url . 'fl-lightbox.css', array(), $ver );
556
+ wp_enqueue_style( 'fl-icon-selector', $css_url . 'fl-icon-selector.css', array(), $ver );
557
+ wp_enqueue_style( 'fl-builder', $css_url . 'fl-builder.css', array(), $ver );
558
+ } else {
559
+ wp_enqueue_style( 'fl-builder-min', $css_url . 'fl-builder.min.css', array(), $ver );
 
560
  }
561
 
562
  /* Custom Icons */
563
  FLBuilderIcons::enqueue_all_custom_icons_styles();
564
 
565
  /* RTL Support */
566
+ if ( is_rtl() ) {
567
+ wp_enqueue_style( 'fl-builder-rtl', $css_url . 'fl-builder-rtl.css', array(), $ver );
568
  }
569
 
570
  /* We have a custom version of sortable that fixes a bug. */
571
+ wp_deregister_script( 'jquery-ui-sortable' );
572
 
573
  /* Frontend builder scripts */
574
  wp_enqueue_media();
575
+ wp_enqueue_script( 'heartbeat' );
576
+ wp_enqueue_script( 'wpdialogs' );
577
+ wp_enqueue_script( 'wpdialogs-popup' );
578
+ wp_enqueue_script( 'wplink' );
579
+ wp_enqueue_script( 'editor' );
580
+ wp_enqueue_script( 'quicktags' );
581
+ wp_enqueue_script( 'json2' );
582
+ wp_enqueue_script( 'jquery-ui-droppable' );
583
+ wp_enqueue_script( 'jquery-ui-draggable' );
584
+ wp_enqueue_script( 'jquery-ui-slider' );
585
+ wp_enqueue_script( 'jquery-ui-widget' );
586
+ wp_enqueue_script( 'jquery-ui-position' );
587
 
588
  do_action( 'fl_before_sortable_enqueue' );
589
 
590
+ wp_enqueue_script( 'jquery-ui-sortable', $js_url . 'jquery.ui.sortable.js', array( 'jquery-ui-core', 'jquery-ui-widget', 'jquery-ui-mouse' ), $ver );
591
+ wp_enqueue_script( 'jquery-nanoscroller', $js_url . 'jquery.nanoscroller.min.js', array(), $ver );
592
+ wp_enqueue_script( 'jquery-autosuggest', $js_url . 'jquery.autoSuggest.min.js', array(), $ver );
593
+ wp_enqueue_script( 'jquery-tiptip', $js_url . 'jquery.tiptip.min.js', array(), $ver );
594
+ wp_enqueue_script( 'jquery-simulate', $js_url . 'jquery.simulate.js', array(), $ver );
595
+ wp_enqueue_script( 'jquery-validate', $js_url . 'jquery.validate.min.js', array(), $ver );
596
+ wp_enqueue_script( 'bootstrap-tour', $js_url . 'bootstrap-tour-standalone.min.js', array(), $ver );
597
+ wp_enqueue_script( 'ace', $js_url . 'ace/ace.js', array(), $ver );
598
+ wp_enqueue_script( 'ace-language-tools', $js_url . 'ace/ext-language_tools.js', array(), $ver );
599
 
600
  // Enqueue individual builder scripts if WP_DEBUG is on.
601
  if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
602
+ wp_enqueue_script( 'fl-color-picker', $js_url . 'fl-color-picker.js', array(), $ver );
603
+ wp_enqueue_script( 'fl-lightbox', $js_url . 'fl-lightbox.js', array(), $ver );
604
+ wp_enqueue_script( 'fl-icon-selector', $js_url . 'fl-icon-selector.js', array(), $ver );
605
+ wp_enqueue_script( 'fl-stylesheet', $js_url . 'fl-stylesheet.js', array(), $ver );
606
+ wp_enqueue_script( 'fl-builder', $js_url . 'fl-builder.js', array(), $ver );
607
+ wp_enqueue_script( 'fl-builder-ajax-layout', $js_url . 'fl-builder-ajax-layout.js', array(), $ver );
608
+ wp_enqueue_script( 'fl-builder-preview', $js_url . 'fl-builder-preview.js', array(), $ver );
609
+ wp_enqueue_script( 'fl-builder-simulate-media-query', $js_url . 'fl-builder-simulate-media-query.js', array(), $ver );
610
+ wp_enqueue_script( 'fl-builder-responsive-editing', $js_url . 'fl-builder-responsive-editing.js', array(), $ver );
611
+ wp_enqueue_script( 'fl-builder-services', $js_url . 'fl-builder-services.js', array(), $ver );
612
+ wp_enqueue_script( 'fl-builder-tour', $js_url . 'fl-builder-tour.js', array(), $ver );
613
+ } else {
614
+ wp_enqueue_script( 'fl-builder-min', $js_url . 'fl-builder.min.js', array(), $ver );
 
615
  }
616
 
617
  /* Additional module styles and scripts */
618
+ foreach ( FLBuilderModel::$modules as $module ) {
619
 
620
  $module->enqueue_scripts();
621
 
622
+ foreach ( $module->css as $handle => $props ) {
623
+ wp_enqueue_style( $handle, $props[0], $props[1], $props[2], $props[3] );
624
  }
625
+ foreach ( $module->js as $handle => $props ) {
626
+ wp_enqueue_script( $handle, $props[0], $props[1], $props[2], $props[3] );
627
  }
628
  }
629
+ }// End if().
630
  }
631
 
632
  /**
636
  * @since 1.0
637
  * @return void
638
  */
639
+ static public function include_jquery() {
640
+ if ( FLBuilderModel::is_builder_enabled() ) {
 
641
  include FL_BUILDER_DIR . 'includes/jquery.php';
642
  }
643
  }
649
  * @param array $classes An array of existing classes.
650
  * @return array
651
  */
652
+ static public function body_class( $classes ) {
 
653
  $do_render = apply_filters( 'fl_builder_do_render_content', true, FLBuilderModel::get_post_id() );
654
 
655
+ if ( $do_render && FLBuilderModel::is_builder_enabled() && ! is_archive() ) {
656
  $classes[] = 'fl-builder';
657
  }
658
+ if ( FLBuilderModel::is_builder_active() ) {
659
  $classes[] = 'fl-builder-edit';
660
 
661
+ if ( ! FLBuilderUserAccess::current_user_can( 'unrestricted_editing' ) ) {
662
  $classes[] = 'fl-builder-simple';
663
  }
664
  }
673
  * @param object $wp_admin_bar An instance of the WordPress admin bar.
674
  * @return void
675
  */
676
+ static public function admin_bar_menu( $wp_admin_bar ) {
 
677
  global $wp_the_query;
678
 
679
  if ( FLBuilderModel::is_post_editable() && is_object( $wp_the_query->post ) ) {
684
  $wp_admin_bar->add_node( array(
685
  'id' => 'fl-builder-frontend-edit-link',
686
  'title' => '<style> #wp-admin-bar-fl-builder-frontend-edit-link .ab-icon:before { content: "\f116" !important; top: 2px; margin-right: 3px; } </style><span class="ab-icon"></span>' . FLBuilderModel::get_branding() . $dot,
687
+ 'href' => FLBuilderModel::get_edit_url( $wp_the_query->post->ID ),
688
  ));
689
  }
690
  }
691
 
692
+ static public function locate_template_file( $template_base, $slug ) {
 
693
  $specific_template = $template_base . '-' . $slug . '.php';
694
  $general_template = $template_base . '.php';
695
  $default_dir = trailingslashit( FL_BUILDER_DIR ) . 'includes/';
698
 
699
  $locate_template_order = apply_filters( 'fl_builder_locate_template_order', array(
700
  self::$template_dir . $specific_template,
701
+ self::$template_dir . $general_template,
702
  ), self::$template_dir, $template_base, $slug );
703
 
704
  $template_path = locate_template( $locate_template_order );
706
  if ( ! $template_path ) {
707
  if ( file_exists( $default_dir . $specific_template ) ) {
708
  $template_path = $default_dir . $specific_template;
709
+ } elseif ( file_exists( $default_dir . $general_template ) ) {
 
710
  $template_path = $default_dir . $general_template;
711
  }
712
  }
721
  * @since 1.8 Method name changed from init to init_ui.
722
  * @return void
723
  */
724
+ static public function init_ui() {
 
725
  // Enable editing if the builder is active.
726
  if ( FLBuilderModel::is_builder_active() && ! defined( 'DOING_AJAX' ) ) {
727
 
732
  add_filter( 'autoptimize_filter_noptimize', '__return_true' );
733
 
734
  // Remove 3rd party editor buttons.
735
+ remove_all_actions( 'media_buttons', 999999 );
736
+ remove_all_actions( 'media_buttons_context', 999999 );
737
 
738
  // Get the post.
739
  require_once ABSPATH . 'wp-admin/includes/post.php';
740
  $post_id = FLBuilderModel::get_post_id();
741
 
742
  // Check to see if the post is locked.
743
+ if ( wp_check_post_lock( $post_id ) !== false ) {
744
+ header( 'Location: ' . admin_url( '/post.php?post=' . $post_id . '&action=edit' ) );
745
+ } else {
 
746
  FLBuilderModel::enable_editing();
747
  }
748
  }
754
  * @since 1.0
755
  * @return void
756
  */
757
+ static public function render_ui() {
 
758
  global $wp_the_query;
759
 
760
  if ( FLBuilderModel::is_builder_active() ) {
783
  * @since 1.6.3
784
  * @return void
785
  */
786
+ static public function render_ui_bar_title() {
 
787
  // Get the bar title.
788
  $title = apply_filters( 'fl_builder_ui_bar_title', FLBuilderModel::get_branding() );
789
 
794
  echo $title;
795
  do_action( 'fl_builder_after_ui_bar_title' );
796
  echo '</div>';
797
+ } else {
 
798
  echo '<div class="fl-builder-bar-title">';
799
  do_action( 'fl_builder_before_ui_bar_title' );
800
  echo '<img src="' . FLBuilderModel::get_branding_icon() . '" /> ';
810
  * @since 1.6.3
811
  * @return void
812
  */
813
+ static public function render_ui_bar_buttons() {
 
814
  $help_button = FLBuilderModel::get_help_button_settings();
815
  $simple_ui = ! FLBuilderUserAccess::current_user_can( 'unrestricted_editing' );
816
 
817
  $buttons = apply_filters( 'fl_builder_ui_bar_buttons', array(
818
  'help' => array(
819
  'label' => '<i class="fa fa-question-circle"></i>',
820
+ 'show' => $help_button['enabled'] && ! $simple_ui,
821
  ),
822
  'upgrade' => array(
823
  'label' => __( 'Upgrade Today <i class="fa fa-external-link-square"></i>', 'fl-builder' ),
824
+ 'show' => true === FL_BUILDER_LITE,
825
  ),
826
  'buy' => array(
827
  'label' => __( 'Buy Now <i class="fa fa-external-link-square"></i>', 'fl-builder' ),
828
+ 'show' => stristr( home_url(), 'demo.wpbeaverbuilder.com' ),
829
  ),
830
  'done' => array(
831
  'label' => __( 'Done', 'fl-builder' ),
832
+ 'class' => 'fl-builder-button-primary',
833
  ),
834
  'tools' => array(
835
  'label' => __( 'Tools', 'fl-builder' ),
836
+ 'show' => ! $simple_ui,
837
  ),
838
  'templates' => array(
839
  'label' => __( 'Templates', 'fl-builder' ),
840
+ 'show' => ! $simple_ui,
841
  ),
842
  'add-content' => array(
843
  'label' => __( 'Add Content', 'fl-builder' ),
844
+ 'show' => ! $simple_ui,
845
+ ),
846
  ) );
847
 
848
  echo '<div class="fl-builder-bar-actions">';
871
  * @since 1.8
872
  * @return void
873
  */
874
+ static public function render_ui_panel_row_templates() {
 
875
  $is_row_template = FLBuilderModel::is_post_user_template( 'row' );
876
  $is_module_template = FLBuilderModel::is_post_user_template( 'module' );
877
  $has_editing_cap = FLBuilderUserAccess::current_user_can( 'unrestricted_editing' );
888
  * @since 1.8
889
  * @return void
890
  */
891
+ static public function render_ui_panel_modules_templates() {
 
892
  $is_module_template = FLBuilderModel::is_post_user_template( 'module' );
893
  $has_editing_cap = FLBuilderUserAccess::current_user_can( 'unrestricted_editing' );
894
  $module_templates = FLBuilderModel::get_module_templates_data();
911
  * @param int $site_id The ID of a site on a network to pull the query from.
912
  * @return void
913
  */
914
+ static public function render_query( $args, $site_id = null ) {
 
915
  global $post;
916
  global $wp_query;
917
  $switched = false;
981
  * @param array $attrs An array of key/value attribute data for the content wrapper.
982
  * @return void
983
  */
984
+ static public function render_content_by_id( $post_id, $tag = 'div', $attrs = array() ) {
 
985
  // Force the builder to use this post ID.
986
  FLBuilderModel::set_post_id( $post_id );
987
 
1041
  * @param string $content The existing content.
1042
  * @return string
1043
  */
1044
+ static public function render_content( $content ) {
 
1045
  $post_id = FLBuilderModel::get_post_id();
1046
  $enabled = FLBuilderModel::is_builder_enabled();
1047
  $rendering = $post_id === self::$post_rendering;
1049
  $in_loop = in_the_loop();
1050
  $is_global = in_array( $post_id, FLBuilderModel::get_global_posts() );
1051
 
1052
+ if ( $enabled && ! $rendering && $do_render && ( $in_loop || $is_global ) ) {
1053
 
1054
  // Set the post rendering ID.
1055
  self::$post_rendering = $post_id;
1092
 
1093
  // Clear the post rendering ID.
1094
  self::$post_rendering = null;
1095
+ }// End if().
1096
 
1097
  return $content;
1098
  }
1105
  * @param array $matches The existing content.
1106
  * @return string
1107
  */
1108
+ static public function double_escape_shortcodes( $matches ) {
1109
+ if ( '[' == $matches[1] && ']' == $matches[6] ) {
 
1110
  return '[' . $matches[0] . ']';
1111
  }
1112
 
1119
  * @since 1.6.4
1120
  * @return string
1121
  */
1122
+ static public function render_content_classes() {
 
1123
  global $wp_the_query;
1124
 
1125
  $post_id = FLBuilderModel::get_post_id();
1133
  }
1134
 
1135
  // Add browser specific classes.
1136
+ if ( isset( $_SERVER['HTTP_USER_AGENT'] ) ) {
1137
+ if ( stristr( $_SERVER['HTTP_USER_AGENT'], 'Trident/7.0' ) && stristr( $_SERVER['HTTP_USER_AGENT'], 'rv:11.0' ) ) {
1138
  $classes .= ' fl-builder-ie-11';
1139
  }
1140
  }
1148
  * @since 1.6.3
1149
  * @return void
1150
  */
1151
+ static public function render_nodes() {
 
1152
  do_action( 'fl_builder_before_render_nodes' );
1153
 
1154
  if ( apply_filters( 'fl_builder_render_nodes', true ) ) {
1165
  * @param array $attrs
1166
  * @return void
1167
  */
1168
+ static public function render_node_attributes( $attrs ) {
1169
+ foreach ( $attrs as $attr_key => $attr_value ) {
 
1170
 
1171
  if ( empty( $attr_value ) ) {
1172
  continue;
1173
+ } elseif ( is_string( $attr_value ) ) {
 
1174
  echo ' ' . $attr_key . '="' . $attr_value . '"';
1175
+ } elseif ( is_array( $attr_value ) && ! empty( $attr_value ) ) {
 
1176
 
1177
  echo ' ' . $attr_key . '="';
1178
 
1179
+ for ( $i = 0; $i < count( $attr_value ); $i++ ) {
1180
 
1181
  echo $attr_value[ $i ];
1182
 
1183
+ if ( $i < count( $attr_value ) - 1 ) {
1184
  echo ' ';
1185
  }
1186
  }
1198
  * @param string $content The existing content.
1199
  * @return string
1200
  */
1201
+ static public function render_editor_content() {
1202
+ $rows = FLBuilderModel::get_nodes( 'row' );
 
1203
 
1204
  ob_start();
1205
 
1206
  // Render the modules.
1207
+ foreach ( $rows as $row ) {
1208
 
1209
+ $groups = FLBuilderModel::get_nodes( 'column-group', $row );
1210
 
1211
+ foreach ( $groups as $group ) {
1212
 
1213
+ $cols = FLBuilderModel::get_nodes( 'column', $group );
1214
 
1215
+ foreach ( $cols as $col ) {
1216
 
1217
  $col_children = FLBuilderModel::get_nodes( null, $col );
1218
 
1225
  if ( $module && $module->editor_export ) {
1226
 
1227
  // Don't crop photos to ensure media library photos are rendered.
1228
+ if ( 'photo' == $module->settings->type ) {
1229
  $module->settings->crop = false;
1230
  }
1231
 
1232
+ FLBuilder::render_module_html( $module->settings->type, $module->settings, $module );
1233
  }
1234
+ } elseif ( 'column-group' == $col_child->type ) {
 
1235
 
1236
  $group_cols = FLBuilderModel::get_nodes( 'column', $col_child );
1237
 
1241
 
1242
  foreach ( $modules as $module ) {
1243
 
1244
+ if ( $module->editor_export ) {
1245
 
1246
  // Don't crop photos to ensure media library photos are rendered.
1247
+ if ( 'photo' == $module->settings->type ) {
1248
  $module->settings->crop = false;
1249
  }
1250
 
1251
+ FLBuilder::render_module_html( $module->settings->type, $module->settings, $module );
1252
  }
1253
  }
1254
  }
1255
+ }// End if().
1256
+ }// End foreach().
1257
+ }// End foreach().
1258
+ }// End foreach().
1259
+ }// End foreach().
1260
 
1261
  // Get the content.
1262
  $content = ob_get_clean();
1263
 
1264
  // Remove unnecessary tags.
1265
+ $content = preg_replace( '/<\/?div[^>]*\>/i', '', $content );
1266
+ $content = preg_replace( '/<\/?span[^>]*\>/i', '', $content );
1267
+ $content = preg_replace( '#<script(.*?)>(.*?)</script>#is', '', $content );
1268
+ $content = preg_replace( '/<i [^>]*><\\/i[^>]*>/', '', $content );
1269
+ $content = preg_replace( '/ class=".*?"/', '', $content );
1270
 
1271
  // Remove empty lines.
1272
+ $content = preg_replace( '/(^[\r\n]*|[\r\n]+)[\s\t]*[\r\n]+/', "\n", $content );
1273
 
1274
  return $content;
1275
  }
1282
  * @param object $settings The settings data.
1283
  * @return array
1284
  */
1285
+ static public function render_settings( $form = array(), $settings ) {
 
1286
  $defaults = array(
1287
  'class' => '',
1288
  'attrs' => '',
1290
  'badges' => array(),
1291
  'tabs' => array(),
1292
  'buttons' => array(),
1293
+ 'resizable' => false,
1294
  );
1295
 
1296
  $form = apply_filters( 'fl_builder_settings_form_config', array_merge( $defaults, $form ) );
1299
  include FL_BUILDER_DIR . 'includes/settings.php';
1300
  $html = ob_get_clean();
1301
 
1302
+ return array(
1303
+ 'html' => $html,
1304
+ );
1305
  }
1306
 
1307
  /**
1313
  * @param object $settings Form settings data object.
1314
  * @return void
1315
  */
1316
+ static public function render_settings_field( $name, $field, $settings = null ) {
 
1317
  $field = apply_filters( 'fl_builder_render_settings_field', $field, $name, $settings ); // Allow field settings filtering first
1318
  $i = null;
1319
+ $is_multiple = isset( $field['multiple'] ) && true === $field['multiple'];
1320
+ $supports_multiple = 'editor' != $field['type'] && 'photo' != $field['type'] && 'service' != $field['type'];
1321
  $settings = ! $settings ? new stdClass() : $settings;
1322
+ $preview = isset( $field['preview'] ) ? json_encode( $field['preview'] ) : json_encode( array(
1323
+ 'type' => 'refresh',
1324
+ ) );
1325
+ $row_class = isset( $field['row_class'] ) ? ' ' . $field['row_class'] : '';
1326
  $responsive = false;
1327
  $responsive_fields = array( 'unit' );
1328
  $root_name = $name;
1329
  $global_settings = FLBuilderModel::get_global_settings();
1330
+ $value = isset( $settings->$name ) ? $settings->$name : '';
1331
 
1332
  // Use a default value if not set in the settings.
1333
  if ( ! isset( $settings->$name ) && isset( $field['default'] ) ) {
1340
  }
1341
 
1342
  // Render the field.
1343
+ if ( $is_multiple && $supports_multiple ) {
1344
 
1345
  $values = $value;
1346
  $arr_name = $name;
1348
 
1349
  echo '<tbody class="fl-field fl-builder-field-multiples" data-type="form" data-preview=\'' . $preview . '\'>';
1350
 
1351
+ for ( $i = 0; $i < count( $values ); $i++ ) {
1352
+ $value = $values[ $i ];
1353
+ echo '<tr class="fl-builder-field-multiple" data-field="' . $arr_name . '">';
1354
  include FL_BUILDER_DIR . 'includes/field.php';
1355
  echo '<td class="fl-builder-field-actions">';
1356
  echo '<i class="fl-builder-field-move fa fa-arrows"></i>';
1362
 
1363
  echo '<tr>';
1364
 
1365
+ if ( empty( $field['label'] ) ) {
1366
  echo '<td colspan="2">';
1367
+ } else {
 
1368
  echo '<td>&nbsp;</td><td>';
1369
  }
1370
 
1371
+ echo '<a href="javascript:void(0);" onclick="return false;" class="fl-builder-field-add fl-builder-button" data-field="' . $arr_name . '">' . sprintf( _x( 'Add %s', 'Field name to add.', 'fl-builder' ), $field['label'] ) . '</a>';
1372
  echo '</td>';
1373
  echo '</tr>';
1374
  echo '</tbody>';
1375
+ } else {
1376
+ echo '<tr id="fl-field-' . $name . '" class="fl-field' . $row_class . '" data-type="' . $field['type'] . '" data-preview=\'' . $preview . '\'>';
 
1377
  include FL_BUILDER_DIR . 'includes/field.php';
1378
  echo '</tr>';
1379
+ }// End if().
1380
  }
1381
 
1382
  /**
1387
  * @param object $settings The settings data.
1388
  * @return array
1389
  */
1390
+ static public function render_settings_form( $type = null, $settings = null ) {
 
1391
  $form = FLBuilderModel::get_settings_form( $type );
1392
 
1393
+ if ( isset( $settings ) && ! empty( $settings ) ) {
1394
  $defaults = FLBuilderModel::get_settings_form_defaults( $type );
1395
+ $settings = (object) array_merge( (array) $defaults, (array) $settings );
1396
+ } else {
 
1397
  $settings = FLBuilderModel::get_settings_form_defaults( $type );
1398
  }
1399
 
1400
  return self::render_settings(array(
1401
  'title' => $form['title'],
1402
  'tabs' => $form['tabs'],
1403
+ 'resizable' => true,
1404
  ), $settings);
1405
  }
1406
 
1410
  * @since 1.8
1411
  * @return array
1412
  */
1413
+ static public function render_layout_settings() {
 
1414
  $settings = FLBuilderModel::get_layout_settings();
1415
  $form = FLBuilderModel::$settings_forms['layout'];
1416
 
1418
  'class' => 'fl-builder-layout-settings',
1419
  'title' => $form['title'],
1420
  'tabs' => $form['tabs'],
1421
+ 'resizable' => true,
1422
  ), $settings );
1423
  }
1424
 
1428
  * @since 1.0
1429
  * @return array
1430
  */
1431
+ static public function render_global_settings() {
 
1432
  $settings = FLBuilderModel::get_global_settings();
1433
  $form = FLBuilderModel::$settings_forms['global'];
1434
 
1436
  'class' => 'fl-builder-global-settings',
1437
  'title' => $form['title'],
1438
  'tabs' => $form['tabs'],
1439
+ 'resizable' => true,
1440
  ), $settings);
1441
  }
1442
 
1446
  * @since 1.0
1447
  * @return array
1448
  */
1449
+ static public function render_template_selector() {
 
1450
  $filter_data = FLBuilderModel::get_template_selector_filter_data();
1451
  $templates = FLBuilderModel::get_template_selector_data();
1452
 
1454
  include FL_BUILDER_DIR . 'includes/template-selector.php';
1455
  $html = ob_get_clean();
1456
 
1457
+ return array(
1458
+ 'html' => $html,
1459
+ );
1460
  }
1461
 
1462
  /**
1465
  * @since 1.0
1466
  * @return array
1467
  */
1468
+ static public function render_icon_selector() {
 
1469
  $icon_sets = FLBuilderIcons::get_sets();
1470
 
1471
  ob_start();
1472
  include FL_BUILDER_DIR . 'includes/icon-selector.php';
1473
  $html = ob_get_clean();
1474
 
1475
+ return array(
1476
+ 'html' => $html,
1477
+ );
1478
  }
1479
 
1480
  /**
1483
  * @since 1.0
1484
  * @return void
1485
  */
1486
+ static public function render_rows() {
1487
+ $rows = FLBuilderModel::get_nodes( 'row' );
 
1488
 
1489
  do_action( 'fl_builder_before_render_rows', $rows );
1490
 
1491
+ foreach ( $rows as $row ) {
1492
+ self::render_row( $row );
1493
  }
1494
 
1495
  do_action( 'fl_builder_after_render_rows', $rows );
1502
  * @param object $row The row to render.
1503
  * @return void
1504
  */
1505
+ static public function render_row( $row ) {
1506
+ $groups = FLBuilderModel::get_nodes( 'column-group', $row );
 
1507
 
1508
  do_action( 'fl_builder_before_render_row', $row, $groups );
1509
 
1526
  * @param object $row A row node object.
1527
  * @return void
1528
  */
1529
+ static public function render_row_attributes( $row ) {
 
1530
  $custom_class = apply_filters( 'fl_builder_row_custom_class', $row->settings->class, $row );
1531
  $overlay_bgs = array( 'photo', 'parallax', 'slideshow', 'video' );
1532
  $attrs = array(
1535
  'fl-row',
1536
  'fl-row-' . $row->settings->width . '-width',
1537
  'fl-row-bg-' . $row->settings->bg_type,
1538
+ 'fl-node-' . $row->node,
1539
  ),
1540
+ 'data-node' => $row->node,
1541
  );
1542
 
1543
  // Classes
1544
+ if ( ! empty( $row->settings->full_height ) && 'full' == $row->settings->full_height ) {
1545
 
1546
  $attrs['class'][] = 'fl-row-full-height';
1547
 
1560
  }
1561
 
1562
  // Data
1563
+ if ( 'parallax' == $row->settings->bg_type && ! empty( $row->settings->bg_parallax_image_src ) ) {
1564
  $attrs['data-parallax-speed'] = $row->settings->bg_parallax_speed;
1565
  $attrs['data-parallax-image'] = $row->settings->bg_parallax_image_src;
1566
  }
1575
  * @param object $row A row node object.
1576
  * @return void
1577
  */
1578
+ static public function render_row_bg( $row ) {
 
1579
  do_action( 'fl_builder_before_render_row_bg', $row );
1580
 
1581
+ if ( 'video' == $row->settings->bg_type ) {
1582
 
1583
+ $vid_data = FLBuilderModel::get_row_bg_data( $row );
1584
 
1585
+ if ( $vid_data || in_array( $row->settings->bg_video_source, array( 'video_url', 'video_service' ) ) ) {
1586
  $template_file = self::locate_template_file(
1587
  apply_filters( 'fl_builder_row_video_bg_template_base', 'row-video', $row ),
1588
  apply_filters( 'fl_builder_row_video_bg_template_slug', '', $row )
1592
  include $template_file;
1593
  }
1594
  }
1595
+ } elseif ( 'slideshow' == $row->settings->bg_type ) {
 
1596
  echo '<div class="fl-bg-slideshow"></div>';
1597
  }
1598
 
1606
  * @param object $row A row node object.
1607
  * @return void
1608
  */
1609
+ static public function render_row_content_class( $row ) {
 
1610
  echo 'fl-row-content';
1611
  echo ' fl-row-' . $row->settings->content_width . '-width';
1612
  echo ' fl-node-content';
1619
  * @param string $node_id A row node ID.
1620
  * @return array
1621
  */
1622
+ static public function render_row_settings( $node_id = null ) {
1623
+ $node = FLBuilderModel::get_node( $node_id );
 
1624
  $settings = $node->settings;
1625
  $form = FLBuilderModel::$settings_forms['row'];
1626
 
1627
  $rendered_settings = self::render_settings(array(
1628
  'class' => 'fl-builder-row-settings',
1629
+ 'attrs' => 'data-node="' . $node->node . '"',
1630
  'title' => $form['title'],
1631
  'tabs' => $form['tabs'],
1632
+ 'resizable' => true,
1633
  ), $settings);
1634
 
1635
  return array(
1636
  'settings' => $rendered_settings['html'],
1637
+ 'state' => FLBuilderAJAXLayout::render( $node_id ),
1638
  );
1639
  }
1640
 
1645
  * @param object $group A column group node object.
1646
  * @return void
1647
  */
1648
+ static public function render_column_group( $group ) {
1649
+ $cols = FLBuilderModel::get_nodes( 'column', $group );
 
1650
 
1651
  do_action( 'fl_builder_before_render_column_group', $group, $cols );
1652
 
1669
  * @param object $group
1670
  * @return void
1671
  */
1672
+ static public function render_column_group_attributes( $group ) {
 
1673
  $cols = FLBuilderModel::get_nodes( 'column', $group );
1674
  $parent = FLBuilderModel::get_node_parent( $group );
1675
  $attrs = array(
1676
  'class' => array(
1677
  'fl-col-group',
1678
+ 'fl-node-' . $group->node,
1679
  ),
1680
+ 'data-node' => $group->node,
1681
  );
1682
 
1683
  if ( 'column' == $parent->type ) {
1684
  $attrs['class'][] = 'fl-col-group-nested';
1685
  }
1686
 
1687
+ foreach ( $cols as $col ) {
1688
 
1689
+ if ( isset( $col->settings->equal_height ) && 'yes' == $col->settings->equal_height ) {
1690
  if ( ! in_array( 'fl-col-group-equal-height', $attrs['class'] ) ) {
1691
  $attrs['class'][] = 'fl-col-group-equal-height';
1692
  }
1693
+ if ( isset( $col->settings->content_alignment ) ) {
1694
  if ( ! in_array( 'fl-col-group-align-' . $col->settings->content_alignment, $attrs['class'] ) ) {
1695
  $attrs['class'][] = 'fl-col-group-align-' . $col->settings->content_alignment;
1696
  }
1697
  }
1698
  }
1699
+ if ( isset( $col->settings->responsive_size ) && 'custom' == $col->settings->responsive_size ) {
1700
  if ( ! in_array( 'fl-col-group-custom-width', $attrs['class'] ) ) {
1701
  $attrs['class'][] = 'fl-col-group-custom-width';
1702
  }
1703
  }
1704
+ if ( isset( $col->settings->responsive_order ) && 'reversed' == $col->settings->responsive_order ) {
1705
  if ( ! in_array( 'fl-col-group-responsive-reversed', $attrs['class'] ) ) {
1706
  $attrs['class'][] = 'fl-col-group-responsive-reversed';
1707
  }
1718
  * @param string|object $col_id A column ID or object.
1719
  * @return void
1720
  */
1721
+ static public function render_column( $col_id = null ) {
 
1722
  $col = is_object( $col_id ) ? $col_id : FLBuilderModel::get_node( $col_id );
1723
 
1724
  if ( FLBuilderModel::is_node_visible( $col ) ) {
1733
  * @param string $node_id A column node ID.
1734
  * @return array
1735
  */
1736
+ static public function render_column_settings( $node_id = null ) {
1737
+ $node = FLBuilderModel::get_node( $node_id );
 
1738
  $settings = $node->settings;
1739
  $form = FLBuilderModel::$settings_forms['col'];
1740
 
1741
  $rendered_settings = self::render_settings(array(
1742
  'class' => 'fl-builder-col-settings',
1743
+ 'attrs' => 'data-node="' . $node->node . '"',
1744
  'title' => $form['title'],
1745
  'tabs' => $form['tabs'],
1746
+ 'resizable' => true,
1747
  ), $settings);
1748
 
1749
  return array(
1750
  'settings' => $rendered_settings['html'],
1751
+ 'state' => FLBuilderAJAXLayout::render( $node->parent ),
1752
  );
1753
  }
1754
 
1759
  * @param object $col A column node object.
1760
  * @return void
1761
  */
1762
+ static public function render_column_attributes( $col ) {
 
1763
  $custom_class = apply_filters( 'fl_builder_column_custom_class', $col->settings->class, $col );
1764
  $overlay_bgs = array( 'photo' );
1765
  $nested = FLBuilderModel::get_nodes( 'column-group', $col );
1767
  'id' => $col->settings->id,
1768
  'class' => array(
1769
  'fl-col',
1770
+ 'fl-node-' . $col->node,
1771
  ),
1772
  'data-node' => $col->node,
1773
+ 'style' => array(),
1774
  );
1775
 
1776
  // Classes
1806
  * @param string|object $col_id A column ID or object.
1807
  * @return void
1808
  */
1809
+ static public function render_modules( $col_id = null ) {
 
1810
  $nodes = FLBuilderModel::get_nodes( null, $col_id );
1811
 
1812
  do_action( 'fl_builder_before_render_modules', $nodes, $col_id );
1815
 
1816
  if ( 'module' == $node->type && FLBuilderModel::is_module_registered( $node->settings->type ) ) {
1817
  self::render_module( $node );
1818
+ } elseif ( 'column-group' == $node->type ) {
 
1819
  self::render_column_group( $node );
1820
  }
1821
  }
1830
  * @param string|object $module_id A module ID or object.
1831
  * @return void
1832
  */
1833
+ static public function render_module( $module_id = null ) {
 
1834
  $module = FLBuilderModel::get_module( $module_id );
1835
  $settings = $module->settings;
1836
  $id = $module->node;
1859
  * @param bool $render_state Whether to render the preview state or not.
1860
  * @return array
1861
  */
1862
+ static public function render_module_settings( $node_id = null, $type = null, $parent_id = null, $render_state = true ) {
 
1863
  $assets = '';
1864
 
1865
  // Get the module and settings.
1866
+ if ( $node_id ) {
1867
+ $module = FLBuilderModel::get_module( $node_id );
1868
  $settings = $module->settings;
1869
+ } else {
1870
+ $module = FLBuilderModel::$modules[ $type ];
1871
+ $settings = FLBuilderModel::get_module_defaults( $type );
 
1872
  }
1873
 
1874
  // Render the settings CSS/JS assets.
1875
+ if ( file_exists( $module->dir . 'css/settings.css' ) ) {
1876
+ $assets .= '<link class="fl-builder-settings-css" rel="stylesheet" href="' . $module->url . 'css/settings.css" />';
1877
  }
1878
+ if ( file_exists( $module->dir . 'js/settings.js' ) ) {
1879
+ $assets .= '<script class="fl-builder-settings-js" src="' . $module->url . 'js/settings.js"></script>';
1880
  }
1881
 
1882
  // Allow developers to hook in from a plugin and add further assets
1884
 
1885
  // Render the form.
1886
  $rendered_settings = self::render_settings(array(
1887
+ 'class' => 'fl-builder-module-settings fl-builder-' . $type . '-settings',
1888
+ 'attrs' => 'data-node="' . $node_id . '" data-parent="' . $parent_id . '" data-type="' . $type . '"',
1889
  'title' => sprintf( __( '%s Settings', 'fl-builder' ), $module->name ),
1890
  'tabs' => apply_filters( 'fl_builder_render_module_settings', $module->form, $module ),
1891
+ 'resizable' => true,
1892
  ), $settings);
1893
 
1894
  // Return the HTML.
1895
  return array(
1896
  'settings' => $assets . $rendered_settings['html'],
1897
+ 'state' => $render_state ? FLBuilderAJAXLayout::render( $node_id ) : null,
1898
  );
1899
  }
1900
 
1909
  * @param object $module Optional. An existing module object to use.
1910
  * @return void
1911
  */
1912
+ static public function render_module_html( $type, $settings, $module = null ) {
 
1913
  // Settings
1914
+ $defaults = FLBuilderModel::get_module_defaults( $type );
1915
+ $settings = (object) array_merge( (array) $defaults, (array) $settings );
1916
 
1917
  // Module
1918
+ $class = get_class( FLBuilderModel::$modules[ $type ] );
1919
  $module = new $class();
1920
  $module->settings = $settings;
1921
 
1922
  // Shorthand reference to the module's id.
1923
  $id = $module->node;
1924
 
1925
+ include $module->dir . 'includes/frontend.php';
1926
  }
1927
 
1928
  /**
1932
  * @param object $module A module node object.
1933
  * @return void
1934
  */
1935
+ static public function render_module_attributes( $module ) {
 
1936
  $custom_class = apply_filters( 'fl_builder_module_custom_class', $module->settings->class, $module );
1937
  $attrs = array(
1938
  'id' => esc_attr( $module->settings->id ),
1939
  'class' => array(
1940
  'fl-module',
1941
  'fl-module-' . $module->settings->type,
1942
+ 'fl-node-' . $module->node,
1943
  ),
1944
  'data-node' => $module->node,
1945
  );
1976
  * @param object $settings A module settings object.
1977
  * @return void
1978
  */
1979
+ static public function render_module_css( $type, $id, $settings ) {
 
1980
  // Settings
1981
  $global_settings = FLBuilderModel::get_global_settings();
1982
+ $defaults = FLBuilderModel::get_module_defaults( $type );
1983
+ $settings = (object) array_merge( (array) $defaults, (array) $settings );
1984
 
1985
  // Module
1986
+ $class = get_class( FLBuilderModel::$modules[ $type ] );
1987
  $module = new $class();
1988
  $module->settings = $settings;
1989
 
1990
+ include $module->dir . 'includes/frontend.css.php';
1991
  }
1992
 
1993
  /**
1996
  * @since 1.7
1997
  * @return void
1998
  */
1999
+ static public function render_assets() {
 
2000
  self::render_css();
2001
  self::render_js();
2002
  }
2008
  * @since 1.7
2009
  * @return void
2010
  */
2011
+ static public function render_custom_css_for_editing() {
 
2012
  if ( ! FLBuilderModel::is_builder_active() ) {
2013
  return;
2014
  }
2027
  * @param bool $include_global
2028
  * @return string
2029
  */
2030
+ static public function render_css( $include_global = true ) {
 
2031
  // Get info on the new file.
2032
  $nodes = FLBuilderModel::get_categorized_nodes();
2033
  $node_status = FLBuilderModel::get_node_status();
2034
  $global_settings = FLBuilderModel::get_global_settings();
2035
  $asset_info = FLBuilderModel::get_asset_info();
2036
  $post_id = FLBuilderModel::get_post_id();
2037
+ $post = get_post( $post_id );
2038
  $css = '';
2039
  $path = $include_global ? $asset_info['css'] : $asset_info['css_partial'];
2040
 
2044
  }
2045
 
2046
  // Loop through rows
2047
+ foreach ( $nodes['rows'] as $row ) {
2048
 
2049
  // Instance row css
2050
  ob_start();
2052
  $css .= ob_get_clean();
2053
 
2054
  // Instance row margins
2055
+ $css .= self::render_row_margins( $row );
2056
 
2057
  // Instance row padding
2058
+ $css .= self::render_row_padding( $row );
2059
 
2060
  // Instance row border
2061
+ $css .= self::render_row_border( $row );
2062
  }
2063
 
2064
  // Loop through the columns.
2065
+ foreach ( $nodes['columns'] as $col ) {
2066
 
2067
  // Instance column css
2068
  ob_start();
2070
  $css .= ob_get_clean();
2071
 
2072
  // Instance column margins
2073
+ $css .= self::render_column_margins( $col );
2074
 
2075
  // Instance column padding
2076
+ $css .= self::render_column_padding( $col );
2077
 
2078
  // Instance column border
2079
+ $css .= self::render_column_border( $col );
2080
 
2081
  // Get the modules in this column.
2082
+ $modules = FLBuilderModel::get_modules( $col );
2083
  }
2084
 
2085
  // Loop through the modules.
2086
+ foreach ( $nodes['modules'] as $module ) {
2087
 
2088
  // Global module css
2089
  $file = $module->dir . 'css/frontend.css';
2090
  $file_responsive = $module->dir . 'css/frontend.responsive.css';
2091
 
2092
  // Only include global module css that hasn't been included yet.
2093
+ if ( ! in_array( $module->settings->type . '-module-css', self::$enqueued_global_assets ) ) {
2094
 
2095
  // Add to the compiled array so we don't include it again.
2096
  self::$enqueued_global_assets[] = $module->settings->type . '-module-css';
2097
 
2098
  // Get the standard module css.
2099
+ if ( file_exists( $file ) ) {
2100
+ $css .= file_get_contents( $file );
2101
  }
2102
 
2103
  // Get the responsive module css.
2104
+ if ( $global_settings->responsive_enabled && file_exists( $file_responsive ) ) {
2105
+ $css .= '@media (max-width: ' . $global_settings->responsive_breakpoint . 'px) { ';
2106
+ $css .= file_get_contents( $file_responsive );
2107
  $css .= ' }';
2108
  }
2109
  }
2113
  $settings = $module->settings;
2114
  $id = $module->node;
2115
 
2116
+ if ( file_exists( $file ) ) {
2117
  ob_start();
2118
  include $file;
2119
  $css .= ob_get_clean();
2120
  }
2121
 
2122
  // Instance module margins
2123
+ $css .= self::render_module_margins( $module );
2124
 
2125
  if ( ! isset( $global_settings->auto_spacing ) || $global_settings->auto_spacing ) {
2126
+ $css .= self::render_responsive_module_margins( $module );
2127
  }
2128
+ }// End foreach().
2129
 
2130
  // Custom Global CSS (included here for proper specificity)
2131
  if ( 'published' == $node_status && $include_global ) {
2144
  $css = apply_filters( 'fl_builder_render_css', $css, $nodes, $global_settings, $include_global );
2145
 
2146
  if ( ! defined( 'WP_DEBUG' ) || ! WP_DEBUG ) {
2147
+ $css = preg_replace( '!/\*[^*]*\*+([^/][^*]*\*+)*/!', '', $css );
2148
+ $css = str_replace( array( "\r\n", "\r", "\n", "\t", ' ', ' ', ' ' ), '', $css );
2149
  }
2150
 
2151
  file_put_contents( $path, $css );
2165
  * @since 1.8.2
2166
  * @return string
2167
  */
2168
+ static public function render_global_css() {
 
2169
  // Get info on the new file.
2170
  $global_settings = FLBuilderModel::get_global_settings();
2171
 
2172
  // Core layout css
2173
+ $css = file_get_contents( FL_BUILDER_DIR . '/css/fl-builder-layout.css' );
2174
 
2175
  // Core button defaults
2176
  if ( ! defined( 'FL_THEME_VERSION' ) ) {
2178
  }
2179
 
2180
  // Core layout RTL css
2181
+ if ( is_rtl() ) {
2182
+ $css .= file_get_contents( FL_BUILDER_DIR . '/css/fl-builder-layout-rtl.css' );
2183
  }
2184
 
2185
  // Global node css
2187
  array( 'row_margins', '.fl-row-content-wrap { margin: ' ),
2188
  array( 'row_padding', '.fl-row-content-wrap { padding: ' ),
2189
  array( 'row_width', '.fl-row-fixed-width { max-width: ' ),
2190
+ array( 'module_margins', '.fl-module-content { margin: ' ),
2191
  ) as $data ) {
2192
  if ( '' !== $global_settings->{ $data[0] } ) {
2193
  $value = preg_replace( self::regex( 'css_unit' ), '', strtolower( $global_settings->{ $data[0] } ) );
2200
  if ( $global_settings->responsive_enabled ) {
2201
 
2202
  // Medium devices
2203
+ $css .= '@media (max-width: ' . $global_settings->medium_breakpoint . 'px) { ';
2204
 
2205
  // Core medium layout css
2206
+ $css .= file_get_contents( FL_BUILDER_DIR . '/css/fl-builder-layout-medium.css' );
2207
 
2208
  // Global node medium css
2209
+ foreach ( array(
2210
  array( 'row_margins_medium', '.fl-row[data-node] > .fl-row-content-wrap { margin: ' ),
2211
  array( 'row_padding_medium', '.fl-row[data-node] > .fl-row-content-wrap { padding: ' ),
2212
+ array( 'module_margins_medium', '.fl-module[data-node] > .fl-module-content { margin: ' ),
2213
  ) as $data ) {
2214
+ if ( '' !== $global_settings->{ $data[0] } ) {
2215
+ $value = preg_replace( self::regex( 'css_unit' ), '', strtolower( $global_settings->{ $data[0] } ) );
2216
+ $css .= $data[1] . esc_attr( $value );
2217
+ $css .= ( is_numeric( $value ) ) ? ( 'px; }' ) : ( '; }' );
 
2218
  }
2219
+ }
2220
 
2221
  $css .= ' }';
2222
 
2223
  // Responsive devices
2224
+ $css .= '@media (max-width: ' . $global_settings->responsive_breakpoint . 'px) { ';
2225
 
2226
  // Core responsive layout css
2227
+ $css .= file_get_contents( FL_BUILDER_DIR . '/css/fl-builder-layout-responsive.css' );
2228
 
2229
  // Auto spacing
2230
+ if ( ! isset( $global_settings->auto_spacing ) || $global_settings->auto_spacing ) {
2231
+ $css .= file_get_contents( FL_BUILDER_DIR . '/css/fl-builder-layout-auto-spacing.css' );
2232
+ }
2233
 
2234
  // Global node responsive css
2235
+ foreach ( array(
2236
  array( 'row_margins_responsive', '.fl-row[data-node] > .fl-row-content-wrap { margin: ' ),
2237
  array( 'row_padding_responsive', '.fl-row[data-node] > .fl-row-content-wrap { padding: ' ),
2238
+ array( 'module_margins_responsive', '.fl-module[data-node] > .fl-module-content { margin: ' ),
2239
  ) as $data ) {
2240
+ if ( '' !== $global_settings->{ $data[0] } ) {
2241
+ $value = preg_replace( self::regex( 'css_unit' ), '', strtolower( $global_settings->{ $data[0] } ) );
2242
+ $css .= $data[1] . esc_attr( $value );
2243
+ $css .= ( is_numeric( $value ) ) ? ( 'px; }' ) : ( '; }' );
 
2244
  }
2245
+ }
2246
 
2247
  $css .= ' }';
2248
+ }// End if().
2249
 
2250
  // Default page heading
2251
  if ( ! $global_settings->show_default_heading && ! empty( $global_settings->default_heading_selector ) ) {
2271
  * @param string $content A string where the URLs will be modified.
2272
  * @return string String with SSL ready URLs.
2273
  */
2274
+ static public function rewrite_css_cache_urls( $content ) {
 
2275
  if ( FLBuilderModel::is_ssl() ) {
2276
  $content = str_ireplace( 'http:', 'https:', $content );
2277
  }
2286
  * @param string $scope What regular expression to return?
2287
  * @return string Regular expression.
2288
  */
2289
+ static public function regex( $scope ) {
 
2290
  $regex = array(
2291
  'css_unit' => '/[^a-z0-9%.\-]/',
2292
  );
2302
  * @param string $selector_prefix Optional CSS selector prefix for better overrides.
2303
  * @return string A CSS string.
2304
  */
2305
+ static public function render_node_spacing( $node = null, $prop_type = '', $selector_prefix = '' ) {
 
2306
  // Exit early if incorrect parameters
2307
  if ( ! is_object( $node ) || empty( $prop_type ) ) {
2308
  return;
2353
 
2354
  if ( empty( $settings->border_type ) ) {
2355
  continue;
2356
+ } else {
 
2357
  $prop .= '-width';
2358
  }
2359
  }
2371
  // Build the selector
2372
  if ( 'default' !== $breakpoint ) {
2373
  $selector = $selector_prefix . '.fl-' . str_replace( 'column', 'col', $node->type ) . $selector_suffix;
2374
+ } else {
 
2375
  $selector = $selector_prefix . $selector_suffix;
2376
  }
2377
 
2385
 
2386
  $css .= $breakpoint_css;
2387
  }
2388
+ }// End foreach().
2389
 
2390
  return $css;
2391
  }
2397
  * @param object $row A row node object.
2398
  * @return string The row CSS margins string.
2399
  */
2400
+ static public function render_row_margins( $row ) {
 
2401
  return self::render_node_spacing( $row, 'margin' );
2402
  }
2403
 
2408
  * @param object $row A row node object.
2409
  * @return string The row CSS padding string.
2410
  */
2411
+ static public function render_row_padding( $row ) {
 
2412
  return self::render_node_spacing( $row, 'padding' );
2413
  }
2414
 
2419
  * @param object $row A row node object.
2420
  * @return string The row CSS border-width string.
2421
  */
2422
+ static public function render_row_border( $row ) {
 
2423
  return self::render_node_spacing( $row, 'border' );
2424
  }
2425
 
2430
  * @param object $col A column node object.
2431
  * @return string The column CSS margins string.
2432
  */
2433
+ static public function render_column_margins( $col ) {
 
2434
  return self::render_node_spacing( $col, 'margin' );
2435
  }
2436
 
2441
  * @param object $col A column node object.
2442
  * @return string The column CSS padding string.
2443
  */
2444
+ static public function render_column_padding( $col ) {
 
2445
  return self::render_node_spacing( $col, 'padding' );
2446
  }
2447
 
2452
  * @param object $col A column node object.
2453
  * @return string The column CSS border-width string.
2454
  */
2455
+ static public function render_column_border( $col ) {
 
2456
  return self::render_node_spacing( $col, 'border', '.fl-builder-content' );
2457
  }
2458
 
2463
  * @param object $module A module node object.
2464
  * @return string The module CSS margins string.
2465
  */
2466
+ static public function render_module_margins( $module ) {
 
2467
  return self::render_node_spacing( $module, 'margin' );
2468
  }
2469
 
2474
  * @param object $module A module node object.
2475
  * @return string The module CSS margins string.
2476
  */
2477
+ static public function render_responsive_module_margins( $module ) {
 
2478
  $global_settings = FLBuilderModel::get_global_settings();
2479
  $settings = $module->settings;
2480
  $margins = '';
2488
  // Get the global default margin value to use.
2489
  if ( '' != $global_settings->module_margins_medium ) {
2490
  $default = trim( $global_settings->module_margins_medium );
2491
+ } else {
 
2492
  $default = trim( $global_settings->module_margins );
2493
  }
2494
 
2526
  * @param bool $include_global
2527
  * @return string
2528
  */
2529
+ static public function render_js( $include_global = true ) {
 
2530
  // Get info on the new file.
2531
  $nodes = FLBuilderModel::get_categorized_nodes();
2532
  $global_settings = FLBuilderModel::get_global_settings();
2533
  $layout_settings = FLBuilderModel::get_layout_settings();
2534
+ $rows = FLBuilderModel::get_nodes( 'row' );
2535
  $asset_info = FLBuilderModel::get_asset_info();
2536
  $js = '';
2537
  $path = $include_global ? $asset_info['js'] : $asset_info['js_partial'];
2542
  }
2543
 
2544
  // Loop through the rows.
2545
+ foreach ( $nodes['rows'] as $row ) {
2546
  $js .= self::render_row_js( $row );
2547
  }
2548
 
2549
  // Loop through the modules.
2550
+ foreach ( $nodes['modules'] as $module ) {
2551
  $js .= self::render_module_js( $module );
2552
  }
2553
 
2556
  $js .= is_array( $layout_settings->js ) ? json_encode( $layout_settings->js ) : $layout_settings->js;
2557
 
2558
  // Call the FLBuilder._renderLayoutComplete method if we're currently editing.
2559
+ if ( stristr( $asset_info['js'], '-draft.js' ) || stristr( $asset_info['js'], '-preview.js' ) ) {
2560
  $js .= "; if(typeof FLBuilder !== 'undefined' && typeof FLBuilder._renderLayoutComplete !== 'undefined') FLBuilder._renderLayoutComplete();";
2561
  }
2562
 
2563
  // Include FLJSMin
2564
+ if ( ! class_exists( 'FLJSMin' ) ) {
2565
  include FL_BUILDER_DIR . 'classes/class-fl-jsmin.php';
2566
  }
2567
 
2569
  $js = apply_filters( 'fl_builder_render_js', $js, $nodes, $global_settings, $include_global );
2570
 
2571
  // Save the JS.
2572
+ if ( ! empty( $js ) ) {
2573
 
2574
  if ( ! defined( 'WP_DEBUG' ) || ! WP_DEBUG ) {
2575
  try {
2576
+ $min = FLJSMin::minify( $js );
2577
+ } catch ( Exception $e ) {}
2578
 
2579
  if ( $min ) {
2580
+ $js = $min;
2581
  }
2582
  }
2583
 
2599
  * @since 1.8.2
2600
  * @return string
2601
  */
2602
+ static public function render_global_js() {
 
2603
  $global_settings = FLBuilderModel::get_global_settings();
2604
  $js = '';
2605
 
2606
  // Add the path legacy vars (FLBuilderLayoutConfig.paths should be used instead).
2607
+ $js .= "var wpAjaxUrl = '" . admin_url( 'admin-ajax.php' ) . "';";
2608
  $js .= "var flBuilderUrl = '" . FL_BUILDER_URL . "';";
2609
 
2610
  // Layout config object.
2613
  $js .= ob_get_clean();
2614
 
2615
  // Core layout JS.
2616
+ $js .= file_get_contents( FL_BUILDER_DIR . 'js/fl-builder-layout.js' );
2617
 
2618
  // Add the global settings JS.
2619
  $js .= $global_settings->js;
2628
  * @param string|object $row_id A row ID or object.
2629
  * @return string
2630
  */
2631
+ static public function render_row_js( $row_id ) {
 
2632
  $row = is_object( $row_id ) ? $row_id : FLBuilderModel::get_node( $row_id );
2633
  $settings = $row->settings;
2634
  $id = $row->node;
2645
  * @param string|object $row_id A row ID or object.
2646
  * @return string
2647
  */
2648
+ static public function render_row_modules_js( $row_id ) {
 
2649
  $row = is_object( $row_id ) ? $row_id : FLBuilderModel::get_node( $row_id );
2650
  $nodes = FLBuilderModel::get_categorized_nodes();
2651
  $template_post_id = FLBuilderModel::is_node_global( $row );
2652
  $js = '';
2653
 
2654
  // Render the JS.
2655
+ foreach ( $nodes['groups'] as $group ) {
2656
  if ( $row->node == $group->parent || ( $template_post_id && $row->template_node_id == $group->parent ) ) {
2657
+ foreach ( $nodes['columns'] as $column ) {
2658
  if ( $group->node == $column->parent ) {
2659
+ foreach ( $nodes['modules'] as $module ) {
2660
  if ( $column->node == $module->parent ) {
2661
  $js .= self::render_module_js( $module );
2662
  }
2677
  * @param string|object $col_id A column ID or object.
2678
  * @return string
2679
  */
2680
+ static public function render_column_modules_js( $col_id ) {
 
2681
  $col = is_object( $col_id ) ? $col_id : FLBuilderModel::get_node( $col_id );
2682
  $nodes = FLBuilderModel::get_categorized_nodes();
2683
  $js = '';
2684
 
2685
  // Render the JS.
2686
+ foreach ( $nodes['modules'] as $module ) {
2687
  if ( $col->node == $module->parent ) {
2688
  $js .= self::render_module_js( $module );
2689
  }
2700
  * @param string|object $module_id A module ID or object.
2701
  * @return string
2702
  */
2703
+ static public function render_module_js( $module_id ) {
 
2704
  $module = is_object( $module_id ) ? $module_id : FLBuilderModel::get_module( $module_id );
2705
  $global_settings = FLBuilderModel::get_global_settings();
2706
  $js = '';
2733
  *
2734
  * @since 1.7
2735
  */
2736
+ static public function render_global_nodes_custom_code( $type = 'css' ) {
 
2737
  $code = '';
2738
  $rendered = array();
2739
 
2742
  $nodes = FLBuilderModel::get_layout_data();
2743
  $node_status = FLBuilderModel::get_node_status();
2744
 
2745
+ foreach ( $nodes as $node_id => $node ) {
2746
 
2747
  $template_post_id = FLBuilderModel::is_node_global( $node );
2748
 
2763
  * @since 1.0
2764
  * @return void
2765
  */
2766
+ static public function log() {
 
2767
  foreach ( func_get_args() as $arg ) {
2768
  ob_start();
2769
  print_r( $arg );
2775
  * @since 1.0
2776
  * @deprecated 1.7.4
2777
  */
2778
+ static public function layout_styles_scripts( $post_id ) {
 
2779
  _deprecated_function( __METHOD__, '1.7.4', __CLASS__ . '::enqueue_layout_styles_scripts()' );
2780
 
2781
  self::enqueue_layout_styles_scripts();
2785
  * @since 1.0
2786
  * @deprecated 1.7.4
2787
  */
2788
+ static public function styles_scripts() {
 
2789
  _deprecated_function( __METHOD__, '1.7.4', __CLASS__ . '::enqueue_ui_styles_scripts()' );
2790
 
2791
  self::enqueue_ui_styles_scripts();
2795
  * @since 1.0
2796
  * @deprecated 1.8
2797
  */
2798
+ static public function register_templates_post_type() {
 
2799
  _deprecated_function( __METHOD__, '1.8', 'FLBuilderUserTemplates::register_post_type()' );
2800
 
2801
  if ( class_exists( 'FLBuilderUserTemplates' ) ) {
2807
  * @since 1.0
2808
  * @deprecated 1.8
2809
  */
2810
+ static public function render_template( $template ) {
 
2811
  _deprecated_function( __METHOD__, '1.8', 'FLBuilderUserTemplates::template_include()' );
2812
 
2813
  if ( class_exists( 'FLBuilderUserTemplates' ) ) {
2819
  * @since 1.6.3
2820
  * @deprecated 1.8
2821
  */
2822
+ static public function render_ui_panel_node_templates() {
 
2823
  _deprecated_function( __METHOD__, '1.8', 'FLBuilderUserTemplates::render_ui_panel_node_templates()' );
2824
 
2825
  if ( class_exists( 'FLBuilderUserTemplates' ) ) {
2831
  * @since 1.0
2832
  * @deprecated 1.8
2833
  */
2834
+ static public function render_user_template_settings() {
 
2835
  _deprecated_function( __METHOD__, '1.8', 'FLBuilderUserTemplates::render_settings()' );
2836
 
2837
  if ( class_exists( 'FLBuilderUserTemplates' ) ) {
2843
  * @since 1.6.3
2844
  * @deprecated 1.8
2845
  */
2846
+ static public function render_node_template_settings( $node_id = null ) {
 
2847
  _deprecated_function( __METHOD__, '1.8', 'FLBuilderUserTemplates::render_node_settings()' );
2848
 
2849
  if ( class_exists( 'FLBuilderUserTemplates' ) ) {
classes/class-fl-jsmin.php CHANGED
@@ -1,4 +1,5 @@
1
  <?php
 
2
  /**
3
  * FLJSMin.php - Renamed original class to avoid conflicts.
4
  *
@@ -61,42 +62,42 @@ class FLJSMin {
61
 
62
  // -- Public Static Methods --------------------------------------------------
63
 
64
- public static function minify($js) {
65
- $jsmin = new FLJSMin($js);
66
  return $jsmin->min();
67
  }
68
 
69
  // -- Public Instance Methods ------------------------------------------------
70
 
71
- public function __construct($input) {
72
- $this->input = str_replace("\r\n", "\n", $input);
73
- $this->inputLength = strlen($this->input);
74
  }
75
 
76
  // -- Protected Instance Methods ---------------------------------------------
77
 
78
- protected function action($d) {
79
- switch($d) {
80
  case 1:
81
  $this->output .= $this->a;
82
 
83
  case 2:
84
  $this->a = $this->b;
85
 
86
- if ($this->a === "'" || $this->a === '"') {
87
- for (;;) {
88
  $this->output .= $this->a;
89
  $this->a = $this->get();
90
 
91
- if ($this->a === $this->b) {
92
  break;
93
  }
94
 
95
- if (ord($this->a) <= self::ORD_LF) {
96
- throw new FLJSMinException('Unterminated string literal.');
97
  }
98
 
99
- if ($this->a === '\\') {
100
  $this->output .= $this->a;
101
  $this->a = $this->get();
102
  }
@@ -106,23 +107,23 @@ class FLJSMin {
106
  case 3:
107
  $this->b = $this->next();
108
 
109
- if ($this->b === '/' && (
110
  $this->a === '(' || $this->a === ',' || $this->a === '=' ||
111
  $this->a === ':' || $this->a === '[' || $this->a === '!' ||
112
- $this->a === '&' || $this->a === '|' || $this->a === '?')) {
113
 
114
  $this->output .= $this->a . $this->b;
115
 
116
- for (;;) {
117
  $this->a = $this->get();
118
 
119
- if ($this->a === '/') {
120
  break;
121
- } elseif ($this->a === '\\') {
122
  $this->output .= $this->a;
123
  $this->a = $this->get();
124
- } elseif (ord($this->a) <= self::ORD_LF) {
125
- throw new FLJSMinException('Unterminated regular expression literal.');
126
  }
127
 
128
  $this->output .= $this->a;
@@ -130,88 +131,87 @@ class FLJSMin {
130
 
131
  $this->b = $this->next();
132
  }
133
- }
134
  }
135
 
136
  protected function get() {
137
  $c = $this->lookAhead;
138
  $this->lookAhead = null;
139
 
140
- if ($c === null) {
141
- if ($this->inputIndex < $this->inputLength) {
142
- $c = substr($this->input, $this->inputIndex, 1);
143
  $this->inputIndex += 1;
144
  } else {
145
  $c = null;
146
  }
147
  }
148
 
149
- if ($c === "\r") {
150
  return "\n";
151
  }
152
 
153
- if ($c === null || $c === "\n" || ord($c) >= self::ORD_SPACE) {
154
  return $c;
155
  }
156
 
157
  return ' ';
158
  }
159
 
160
- protected function isAlphaNum($c) {
161
- return ord($c) > 126 || $c === '\\' || preg_match('/^[\w\$]$/', $c) === 1;
162
  }
163
 
164
  protected function min() {
165
  $this->a = "\n";
166
- $this->action(3);
167
 
168
- while ($this->a !== null) {
169
- switch ($this->a) {
170
  case ' ':
171
- if ($this->isAlphaNum($this->b)) {
172
- $this->action(1);
173
  } else {
174
- $this->action(2);
175
  }
176
  break;
177
 
178
  case "\n":
179
- switch ($this->b) {
180
  case '{':
181
  case '[':
182
  case '(':
183
  case '+':
184
  case '-':
185
- $this->action(1);
186
  break;
187
 
188
  case ' ':
189
- $this->action(3);
190
  break;
191
 
192
  default:
193
- if ($this->isAlphaNum($this->b)) {
194
- $this->action(1);
195
- }
196
- else {
197
- $this->action(2);
198
  }
199
  }
200
  break;
201
 
202
  default:
203
- switch ($this->b) {
204
  case ' ':
205
- if ($this->isAlphaNum($this->a)) {
206
- $this->action(1);
207
  break;
208
  }
209
 
210
- $this->action(3);
211
  break;
212
 
213
  case "\n":
214
- switch ($this->a) {
215
  case '}':
216
  case ']':
217
  case ')':
@@ -219,25 +219,24 @@ class FLJSMin {
219
  case '-':
220
  case '"':
221
  case "'":
222
- $this->action(1);
223
  break;
224
 
225
  default:
226
- if ($this->isAlphaNum($this->a)) {
227
- $this->action(1);
228
- }
229
- else {
230
- $this->action(3);
231
  }
232
  }
233
  break;
234
 
235
  default:
236
- $this->action(1);
237
  break;
238
- }
239
- }
240
- }
241
 
242
  return $this->output;
243
  }
@@ -245,13 +244,13 @@ class FLJSMin {
245
  protected function next() {
246
  $c = $this->get();
247
 
248
- if ($c === '/') {
249
- switch($this->peek()) {
250
  case '/':
251
- for (;;) {
252
  $c = $this->get();
253
 
254
- if (ord($c) <= self::ORD_LF) {
255
  return $c;
256
  }
257
  }
@@ -259,17 +258,17 @@ class FLJSMin {
259
  case '*':
260
  $this->get();
261
 
262
- for (;;) {
263
- switch($this->get()) {
264
  case '*':
265
- if ($this->peek() === '/') {
266
  $this->get();
267
  return ' ';
268
  }
269
  break;
270
 
271
  case null:
272
- throw new FLJSMinException('Unterminated comment.');
273
  }
274
  }
275
 
@@ -289,4 +288,3 @@ class FLJSMin {
289
 
290
  // -- Exceptions ---------------------------------------------------------------
291
  class FLJSMinException extends Exception {}
292
-
1
  <?php
2
+ // @codingStandardsIgnoreFile
3
  /**
4
  * FLJSMin.php - Renamed original class to avoid conflicts.
5
  *
62
 
63
  // -- Public Static Methods --------------------------------------------------
64
 
65
+ public static function minify( $js ) {
66
+ $jsmin = new FLJSMin( $js );
67
  return $jsmin->min();
68
  }
69
 
70
  // -- Public Instance Methods ------------------------------------------------
71
 
72
+ public function __construct( $input ) {
73
+ $this->input = str_replace( "\r\n", "\n", $input );
74
+ $this->inputLength = strlen( $this->input );
75
  }
76
 
77
  // -- Protected Instance Methods ---------------------------------------------
78
 
79
+ protected function action( $d ) {
80
+ switch ( $d ) {
81
  case 1:
82
  $this->output .= $this->a;
83
 
84
  case 2:
85
  $this->a = $this->b;
86
 
87
+ if ( $this->a === "'" || $this->a === '"' ) {
88
+ for ( ;; ) {
89
  $this->output .= $this->a;
90
  $this->a = $this->get();
91
 
92
+ if ( $this->a === $this->b ) {
93
  break;
94
  }
95
 
96
+ if ( ord( $this->a ) <= self::ORD_LF ) {
97
+ throw new FLJSMinException( 'Unterminated string literal.' );
98
  }
99
 
100
+ if ( $this->a === '\\' ) {
101
  $this->output .= $this->a;
102
  $this->a = $this->get();
103
  }
107
  case 3:
108
  $this->b = $this->next();
109
 
110
+ if ( $this->b === '/' && (
111
  $this->a === '(' || $this->a === ',' || $this->a === '=' ||
112
  $this->a === ':' || $this->a === '[' || $this->a === '!' ||
113
+ $this->a === '&' || $this->a === '|' || $this->a === '?') ) {
114
 
115
  $this->output .= $this->a . $this->b;
116
 
117
+ for ( ;; ) {
118
  $this->a = $this->get();
119
 
120
+ if ( $this->a === '/' ) {
121
  break;
122
+ } elseif ( $this->a === '\\' ) {
123
  $this->output .= $this->a;
124
  $this->a = $this->get();
125
+ } elseif ( ord( $this->a ) <= self::ORD_LF ) {
126
+ throw new FLJSMinException( 'Unterminated regular expression literal.' );
127
  }
128
 
129
  $this->output .= $this->a;
131
 
132
  $this->b = $this->next();
133
  }
134
+ }// End switch().
135
  }
136
 
137
  protected function get() {
138
  $c = $this->lookAhead;
139
  $this->lookAhead = null;
140
 
141
+ if ( $c === null ) {
142
+ if ( $this->inputIndex < $this->inputLength ) {
143
+ $c = substr( $this->input, $this->inputIndex, 1 );
144
  $this->inputIndex += 1;
145
  } else {
146
  $c = null;
147
  }
148
  }
149
 
150
+ if ( $c === "\r" ) {
151
  return "\n";
152
  }
153
 
154
+ if ( $c === null || $c === "\n" || ord( $c ) >= self::ORD_SPACE ) {
155
  return $c;
156
  }
157
 
158
  return ' ';
159
  }
160
 
161
+ protected function isAlphaNum( $c ) {
162
+ return ord( $c ) > 126 || $c === '\\' || preg_match( '/^[\w\$]$/', $c ) === 1;
163
  }
164
 
165
  protected function min() {
166
  $this->a = "\n";
167
+ $this->action( 3 );
168
 
169
+ while ( $this->a !== null ) {
170
+ switch ( $this->a ) {
171
  case ' ':
172
+ if ( $this->isAlphaNum( $this->b ) ) {
173
+ $this->action( 1 );
174
  } else {
175
+ $this->action( 2 );
176
  }
177
  break;
178
 
179
  case "\n":
180
+ switch ( $this->b ) {
181
  case '{':
182
  case '[':
183
  case '(':
184
  case '+':
185
  case '-':
186
+ $this->action( 1 );
187
  break;
188
 
189
  case ' ':
190
+ $this->action( 3 );
191
  break;
192
 
193
  default:
194
+ if ( $this->isAlphaNum( $this->b ) ) {
195
+ $this->action( 1 );
196
+ } else {
197
+ $this->action( 2 );
 
198
  }
199
  }
200
  break;
201
 
202
  default:
203
+ switch ( $this->b ) {
204
  case ' ':
205
+ if ( $this->isAlphaNum( $this->a ) ) {
206
+ $this->action( 1 );
207
  break;
208
  }
209
 
210
+ $this->action( 3 );
211
  break;
212
 
213
  case "\n":
214
+ switch ( $this->a ) {
215
  case '}':
216
  case ']':
217
  case ')':
219
  case '-':
220
  case '"':
221
  case "'":
222
+ $this->action( 1 );
223
  break;
224
 
225
  default:
226
+ if ( $this->isAlphaNum( $this->a ) ) {
227
+ $this->action( 1 );
228
+ } else {
229
+ $this->action( 3 );
 
230
  }
231
  }
232
  break;
233
 
234
  default:
235
+ $this->action( 1 );
236
  break;
237
+ }// End switch().
238
+ }// End switch().
239
+ }// End while().
240
 
241
  return $this->output;
242
  }
244
  protected function next() {
245
  $c = $this->get();
246
 
247
+ if ( $c === '/' ) {
248
+ switch ( $this->peek() ) {
249
  case '/':
250
+ for ( ;; ) {
251
  $c = $this->get();
252
 
253
+ if ( ord( $c ) <= self::ORD_LF ) {
254
  return $c;
255
  }
256
  }
258
  case '*':
259
  $this->get();
260
 
261
+ for ( ;; ) {
262
+ switch ( $this->get() ) {
263
  case '*':
264
+ if ( $this->peek() === '/' ) {
265
  $this->get();
266
  return ' ';
267
  }
268
  break;
269
 
270
  case null:
271
+ throw new FLJSMinException( 'Unterminated comment.' );
272
  }
273
  }
274
 
288
 
289
  // -- Exceptions ---------------------------------------------------------------
290
  class FLJSMinException extends Exception {}
 
extensions/fl-builder-multisite/classes/class-fl-builder-multisite.php CHANGED
@@ -13,12 +13,11 @@ final class FLBuilderMultisite {
13
  * @since 1.0
14
  * @return void
15
  */
16
- static public function init()
17
- {
18
- add_action('wpmu_new_blog', __CLASS__ . '::install_for_new_blog', 10, 6);
19
- add_filter('wpmu_drop_tables', __CLASS__ . '::uninstall_on_delete_blog');
20
- add_filter('fl_builder_activate', __CLASS__ . '::activate');
21
- add_filter('fl_builder_uninstall', __CLASS__ . '::uninstall');
22
  }
23
 
24
  /**
@@ -27,17 +26,15 @@ final class FLBuilderMultisite {
27
  * @since 1.8
28
  * @return void
29
  */
30
- static public function activate( $activate )
31
- {
32
  if ( is_network_admin() ) {
33
  FLBuilderMultisite::install();
34
- }
35
- else {
36
  FLBuilderAdmin::install();
37
  }
38
-
39
  FLBuilderAdmin::trigger_activate_notice();
40
-
41
  return false;
42
  }
43
 
@@ -47,20 +44,19 @@ final class FLBuilderMultisite {
47
  * @since 1.0
48
  * @return void
49
  */
50
- static public function install()
51
- {
52
  global $blog_id;
53
  global $wpdb;
54
-
55
  $original_blog_id = $blog_id;
56
- $blog_ids = $wpdb->get_col("SELECT blog_id FROM $wpdb->blogs");
57
-
58
- foreach($blog_ids as $id) {
59
- switch_to_blog($id);
60
  FLBuilderAdmin::install();
61
  }
62
-
63
- switch_to_blog($original_blog_id);
64
  }
65
 
66
  /**
@@ -75,12 +71,11 @@ final class FLBuilderMultisite {
75
  * @param array $meta
76
  * @return void
77
  */
78
- static public function install_for_new_blog($blog_id, $user_id, $domain, $path, $site_id, $meta)
79
- {
80
  global $wpdb;
81
-
82
- if(is_plugin_active_for_network(FLBuilderModel::plugin_basename())) {
83
- switch_to_blog($blog_id);
84
  FLBuilderAdmin::install();
85
  restore_current_blog();
86
  }
@@ -93,21 +88,20 @@ final class FLBuilderMultisite {
93
  * @since 1.0
94
  * @return void
95
  */
96
- static public function uninstall( $uninstall )
97
- {
98
  global $blog_id;
99
  global $wpdb;
100
-
101
  $original_blog_id = $blog_id;
102
- $blog_ids = $wpdb->get_col("SELECT blog_id FROM $wpdb->blogs");
103
-
104
- foreach($blog_ids as $id) {
105
- switch_to_blog($id);
106
  FLBuilderAdmin::uninstall();
107
  }
108
-
109
- switch_to_blog($original_blog_id);
110
-
111
  return false;
112
  }
113
 
@@ -117,26 +111,23 @@ final class FLBuilderMultisite {
117
  * @since 1.0
118
  * @return array
119
  */
120
- static public function uninstall_on_delete_blog($tables)
121
- {
122
  return $tables;
123
  }
124
-
125
- /**
126
  * Checks if a blog on the network exists.
127
  *
128
  * @since 1.5.7
129
  * @param $blog_id The blog ID to check.
130
  * @return bool
131
  */
132
- static public function blog_exists( $blog_id )
133
- {
134
  global $wpdb;
135
-
136
  if ( method_exists( $wpdb, 'esc_like' ) ) {
137
  $like = esc_sql( $wpdb->esc_like( $blog_id ) );
138
- }
139
- else {
140
  $like = like_escape( esc_sql( $blog_id ) );
141
  }
142
 
13
  * @since 1.0
14
  * @return void
15
  */
16
+ static public function init() {
17
+ add_action( 'wpmu_new_blog', __CLASS__ . '::install_for_new_blog', 10, 6 );
18
+ add_filter( 'wpmu_drop_tables', __CLASS__ . '::uninstall_on_delete_blog' );
19
+ add_filter( 'fl_builder_activate', __CLASS__ . '::activate' );
20
+ add_filter( 'fl_builder_uninstall', __CLASS__ . '::uninstall' );
 
21
  }
22
 
23
  /**
26
  * @since 1.8
27
  * @return void
28
  */
29
+ static public function activate( $activate ) {
 
30
  if ( is_network_admin() ) {
31
  FLBuilderMultisite::install();
32
+ } else {
 
33
  FLBuilderAdmin::install();
34
  }
35
+
36
  FLBuilderAdmin::trigger_activate_notice();
37
+
38
  return false;
39
  }
40
 
44
  * @since 1.0
45
  * @return void
46
  */
47
+ static public function install() {
 
48
  global $blog_id;
49
  global $wpdb;
50
+
51
  $original_blog_id = $blog_id;
52
+ $blog_ids = $wpdb->get_col( "SELECT blog_id FROM $wpdb->blogs" );
53
+
54
+ foreach ( $blog_ids as $id ) {
55
+ switch_to_blog( $id );
56
  FLBuilderAdmin::install();
57
  }
58
+
59
+ switch_to_blog( $original_blog_id );
60
  }
61
 
62
  /**
71
  * @param array $meta
72
  * @return void
73
  */
74
+ static public function install_for_new_blog( $blog_id, $user_id, $domain, $path, $site_id, $meta ) {
 
75
  global $wpdb;
76
+
77
+ if ( is_plugin_active_for_network( FLBuilderModel::plugin_basename() ) ) {
78
+ switch_to_blog( $blog_id );
79
  FLBuilderAdmin::install();
80
  restore_current_blog();
81
  }
88
  * @since 1.0
89
  * @return void
90
  */
91
+ static public function uninstall( $uninstall ) {
 
92
  global $blog_id;
93
  global $wpdb;
94
+
95
  $original_blog_id = $blog_id;
96
+ $blog_ids = $wpdb->get_col( "SELECT blog_id FROM $wpdb->blogs" );
97
+
98
+ foreach ( $blog_ids as $id ) {
99
+ switch_to_blog( $id );
100
  FLBuilderAdmin::uninstall();
101
  }
102
+
103
+ switch_to_blog( $original_blog_id );
104
+
105
  return false;
106
  }
107
 
111
  * @since 1.0
112
  * @return array
113
  */
114
+ static public function uninstall_on_delete_blog( $tables ) {
 
115
  return $tables;
116
  }
117
+
118
+ /**
119
  * Checks if a blog on the network exists.
120
  *
121
  * @since 1.5.7
122
  * @param $blog_id The blog ID to check.
123
  * @return bool
124
  */
125
+ static public function blog_exists( $blog_id ) {
 
126
  global $wpdb;
127
+
128
  if ( method_exists( $wpdb, 'esc_like' ) ) {
129
  $like = esc_sql( $wpdb->esc_like( $blog_id ) );
130
+ } else {
 
131
  $like = like_escape( esc_sql( $blog_id ) );
132
  }
133
 
extensions/fl-builder-multisite/fl-builder-multisite.php CHANGED
@@ -2,7 +2,7 @@
2
 
3
  // Only load for multisite installs.
4
  if ( ! is_multisite() ) {
5
- return;
6
  }
7
 
8
  // Defines
@@ -10,4 +10,4 @@ define( 'FL_BUILDER_MULTISITE_DIR', FL_BUILDER_DIR . 'extensions/fl-builder-mult
10
  define( 'FL_BUILDER_MULTISITE_URL', FL_BUILDER_URL . 'extensions/fl-builder-multisite/' );
11
 
12
  // Classes
13
- require_once FL_BUILDER_MULTISITE_DIR . 'classes/class-fl-builder-multisite.php';
2
 
3
  // Only load for multisite installs.
4
  if ( ! is_multisite() ) {
5
+ return;
6
  }
7
 
8
  // Defines
10
  define( 'FL_BUILDER_MULTISITE_URL', FL_BUILDER_URL . 'extensions/fl-builder-multisite/' );
11
 
12
  // Classes
13
+ require_once FL_BUILDER_MULTISITE_DIR . 'classes/class-fl-builder-multisite.php';
fl-builder.php CHANGED
@@ -3,7 +3,7 @@
3
  * Plugin Name: Beaver Builder Plugin (Lite Version)
4
  * Plugin URI: https://www.wpbeaverbuilder.com/?utm_medium=bb&utm_source=plugins-admin-page&utm_campaign=plugins-admin-uri
5
  * Description: A drag and drop frontend WordPress page builder plugin that works with almost any theme!
6
- * Version: 1.10.6.5
7
  * Author: The Beaver Builder Team
8
  * Author URI: https://www.wpbeaverbuilder.com/?utm_medium=bb&utm_source=plugins-admin-page&utm_campaign=plugins-admin-author
9
  * Copyright: (c) 2014 Beaver Builder
3
  * Plugin Name: Beaver Builder Plugin (Lite Version)
4
  * Plugin URI: https://www.wpbeaverbuilder.com/?utm_medium=bb&utm_source=plugins-admin-page&utm_campaign=plugins-admin-uri
5
  * Description: A drag and drop frontend WordPress page builder plugin that works with almost any theme!
6
+ * Version: 1.10.7
7
  * Author: The Beaver Builder Team
8
  * Author URI: https://www.wpbeaverbuilder.com/?utm_medium=bb&utm_source=plugins-admin-page&utm_campaign=plugins-admin-author
9
  * Copyright: (c) 2014 Beaver Builder
includes/admin-posts.php CHANGED
@@ -1,7 +1,7 @@
1
  <div class="fl-builder-admin">
2
  <div class="fl-builder-admin-tabs">
3
- <a href="javascript:void(0);" onclick="return false;" class="fl-enable-editor<?php if(!$enabled) echo ' fl-active'; ?>"><?php _e('Text Editor', 'fl-builder'); ?></a>
4
- <a href="javascript:void(0);" onclick="return false;" class="fl-enable-builder<?php if($enabled) echo ' fl-active'; ?>"><?php echo FLBuilderModel::get_branding(); ?></a>
5
  </div>
6
  <div class="fl-builder-admin-ui">
7
  <h3><?php printf( _x( '%1$s is currently active for this %2$s.', 'The first %s stands for custom branded "Page Builder" name. The second %s stands for the post type name.', 'fl-builder' ), FLBuilderModel::get_branding(), $post_type_name ); ?></h3>
1
  <div class="fl-builder-admin">
2
  <div class="fl-builder-admin-tabs">
3
+ <a href="javascript:void(0);" onclick="return false;" class="fl-enable-editor<?php if ( ! $enabled ) { echo ' fl-active';} ?>"><?php _e( 'Text Editor', 'fl-builder' ); ?></a>
4
+ <a href="javascript:void(0);" onclick="return false;" class="fl-enable-builder<?php if ( $enabled ) { echo ' fl-active';} ?>"><?php echo FLBuilderModel::get_branding(); ?></a>
5
  </div>
6
  <div class="fl-builder-admin-ui">
7
  <h3><?php printf( _x( '%1$s is currently active for this %2$s.', 'The first %s stands for custom branded "Page Builder" name. The second %s stands for the post type name.', 'fl-builder' ), FLBuilderModel::get_branding(), $post_type_name ); ?></h3>
includes/admin-settings-js-config.php CHANGED
@@ -6,13 +6,13 @@ FLBuilderAdminSettingsConfig = {
6
  };
7
 
8
  FLBuilderAdminSettingsStrings = {
9
- deselectAll: '<?php esc_attr_e('Deselect All', 'fl-builder'); ?>',
10
- noneSelected: '<?php esc_attr_e('None Selected', 'fl-builder'); ?>',
11
- select: '<?php esc_attr_e('Select...', 'fl-builder'); ?>',
12
- selected: '<?php esc_attr_e('Selected', 'fl-builder'); ?>',
13
- selectAll: '<?php esc_attr_e('Select All', 'fl-builder'); ?>',
14
- selectFile: '<?php esc_attr_e('Select File', 'fl-builder'); ?>',
15
- uninstall: '<?php esc_attr_e('Please type "uninstall" in the box below to confirm that you really want to uninstall the page builder and all of its data.', 'fl-builder'); ?>'
16
  };
17
 
18
- </script>
6
  };
7
 
8
  FLBuilderAdminSettingsStrings = {
9
+ deselectAll: '<?php esc_attr_e( 'Deselect All', 'fl-builder' ); ?>',
10
+ noneSelected: '<?php esc_attr_e( 'None Selected', 'fl-builder' ); ?>',
11
+ select: '<?php esc_attr_e( 'Select...', 'fl-builder' ); ?>',
12
+ selected: '<?php esc_attr_e( 'Selected', 'fl-builder' ); ?>',
13
+ selectAll: '<?php esc_attr_e( 'Select All', 'fl-builder' ); ?>',
14
+ selectFile: '<?php esc_attr_e( 'Select File', 'fl-builder' ); ?>',
15
+ uninstall: '<?php esc_attr_e( 'Please type "uninstall" in the box below to confirm that you really want to uninstall the page builder and all of its data.', 'fl-builder' ); ?>'
16
  };
17
 
18
+ </script>
includes/admin-settings-modules.php CHANGED
@@ -1,24 +1,24 @@
1
  <div id="fl-modules-form" class="fl-settings-form">
2
 
3
- <h3 class="fl-settings-form-header"><?php _e('Enabled Modules', 'fl-builder'); ?></h3>
4
 
5
  <form id="modules-form" action="<?php FLBuilderAdminSettings::render_form_action( 'modules' ); ?>" method="post">
6
 
7
  <?php if ( FLBuilderAdminSettings::multisite_support() && ! is_network_admin() ) : ?>
8
  <label>
9
- <input class="fl-override-ms-cb" type="checkbox" name="fl-override-ms" value="1" <?php if(get_option('_fl_builder_enabled_modules')) echo 'checked="checked"'; ?> />
10
- <?php _e('Override network settings?', 'fl-builder'); ?>
11
  </label>
12
  <?php endif; ?>
13
-
14
  <div class="fl-settings-form-content">
15
 
16
- <p><?php _e('Check or uncheck modules below to enable or disable them.', 'fl-builder'); ?></p>
17
  <?php
18
 
19
  $categories = FLBuilderModel::get_categorized_modules( true );
20
  $enabled_modules = FLBuilderModel::get_enabled_modules();
21
- $checked = in_array('all', $enabled_modules) ? 'checked' : '';
22
 
23
  ?>
24
  <label>
@@ -28,11 +28,11 @@
28
  <?php foreach ( $categories as $title => $modules ) : ?>
29
  <h3><?php echo $title; ?></h3>
30
  <?php
31
-
32
- if ( $title == __( 'WordPress Widgets', 'fl-builder') ) :
33
-
34
- $checked = in_array('widget', $enabled_modules) ? 'checked' : '';
35
-
36
  ?>
37
  <p>
38
  <label>
@@ -41,15 +41,15 @@
41
  </label>
42
  </p>
43
  <?php
44
-
45
  continue;
46
-
47
  endif;
48
-
49
  foreach ( $modules as $module ) :
50
-
51
- $checked = in_array($module->slug, $enabled_modules) ? 'checked' : '';
52
-
53
  ?>
54
  <p>
55
  <label>
@@ -62,7 +62,7 @@
62
  </div>
63
  <p class="submit">
64
  <input type="submit" name="update" class="button-primary" value="<?php esc_attr_e( 'Save Module Settings', 'fl-builder' ); ?>" />
65
- <?php wp_nonce_field('modules', 'fl-modules-nonce'); ?>
66
  </p>
67
  </form>
68
- </div>
1
  <div id="fl-modules-form" class="fl-settings-form">
2
 
3
+ <h3 class="fl-settings-form-header"><?php _e( 'Enabled Modules', 'fl-builder' ); ?></h3>
4
 
5
  <form id="modules-form" action="<?php FLBuilderAdminSettings::render_form_action( 'modules' ); ?>" method="post">
6
 
7
  <?php if ( FLBuilderAdminSettings::multisite_support() && ! is_network_admin() ) : ?>
8
  <label>
9
+ <input class="fl-override-ms-cb" type="checkbox" name="fl-override-ms" value="1" <?php if ( get_option( '_fl_builder_enabled_modules' ) ) { echo 'checked="checked"';} ?> />
10
+ <?php _e( 'Override network settings?', 'fl-builder' ); ?>
11
  </label>
12
  <?php endif; ?>
13
+
14
  <div class="fl-settings-form-content">
15
 
16
+ <p><?php _e( 'Check or uncheck modules below to enable or disable them.', 'fl-builder' ); ?></p>
17
  <?php
18
 
19
  $categories = FLBuilderModel::get_categorized_modules( true );
20
  $enabled_modules = FLBuilderModel::get_enabled_modules();
21
+ $checked = in_array( 'all', $enabled_modules ) ? 'checked' : '';
22
 
23
  ?>
24
  <label>
28
  <?php foreach ( $categories as $title => $modules ) : ?>
29
  <h3><?php echo $title; ?></h3>
30
  <?php
31
+
32
+ if ( __( 'WordPress Widgets', 'fl-builder' ) == $title ) :
33
+
34
+ $checked = in_array( 'widget', $enabled_modules ) ? 'checked' : '';
35
+
36
  ?>
37
  <p>
38
  <label>
41
  </label>
42
  </p>
43
  <?php
44
+
45
  continue;
46
+
47
  endif;
48
+
49
  foreach ( $modules as $module ) :
50
+
51
+ $checked = in_array( $module->slug, $enabled_modules ) ? 'checked' : '';
52
+
53
  ?>
54
  <p>
55
  <label>
62
  </div>
63
  <p class="submit">
64
  <input type="submit" name="update" class="button-primary" value="<?php esc_attr_e( 'Save Module Settings', 'fl-builder' ); ?>" />
65
+ <?php wp_nonce_field( 'modules', 'fl-modules-nonce' ); ?>
66
  </p>
67
  </form>
68
+ </div>
includes/admin-settings-post-types.php CHANGED
@@ -1,60 +1,62 @@
1
  <div id="fl-post-types-form" class="fl-settings-form">
2
 
3
- <h3 class="fl-settings-form-header"><?php _e('Post Types', 'fl-builder'); ?></h3>
4
 
5
  <form id="post-types-form" action="<?php FLBuilderAdminSettings::render_form_action( 'post-types' ); ?>" method="post">
6
 
7
  <?php if ( FLBuilderAdminSettings::multisite_support() && ! is_network_admin() ) : ?>
8
  <label>
9
- <input class="fl-override-ms-cb" type="checkbox" name="fl-override-ms" value="1" <?php if(get_option('_fl_builder_post_types')) echo 'checked="checked"'; ?> />
10
- <?php _e('Override network settings?', 'fl-builder'); ?>
11
  </label>
12
  <?php endif; ?>
13
-
14
  <div class="fl-settings-form-content">
15
-
16
  <?php if ( is_network_admin() ) : ?>
17
-
18
- <p><?php _e('Enter a comma separated list of the post types you would like the builder to work with.', 'fl-builder'); ?></p>
19
- <p><?php _e('NOTE: Not all custom post types may be supported.', 'fl-builder'); ?></p>
20
  <?php
21
-
22
  $saved_post_types = FLBuilderModel::get_post_types();
23
-
24
- foreach($saved_post_types as $key => $post_type) {
25
- if($post_type == 'fl-builder-template') {
26
- unset($saved_post_types[$key]);
27
  }
28
  }
29
-
30
- $saved_post_types = implode(', ', $saved_post_types);
31
-
32
  ?>
33
- <input type="text" name="fl-post-types" value="<?php echo esc_html($saved_post_types); ?>" class="regular-text" />
34
- <p class="description"><?php _e('Example: page, post, product', 'fl-builder'); ?></p>
35
-
36
  <?php else : ?>
37
-
38
- <p><?php _e('Select the post types you would like the builder to work with.', 'fl-builder'); ?></p>
39
- <p><?php _e('NOTE: Not all custom post types may be supported.', 'fl-builder'); ?></p>
40
-
41
  <?php
42
-
43
  $saved_post_types = FLBuilderModel::get_post_types();
44
- $post_types = get_post_types( array( 'public' => true ), 'objects' );
 
 
45
  $post_types = apply_filters( 'fl_builder_admin_settings_post_types', $post_types );
46
-
47
- foreach($post_types as $post_type) :
48
-
49
- $checked = in_array($post_type->name, $saved_post_types) ? 'checked' : '';
50
-
51
- if($post_type->name == 'attachment') {
52
  continue;
53
  }
54
- if($post_type->name == 'fl-builder-template') {
55
  continue;
56
  }
57
-
58
  ?>
59
  <p>
60
  <label>
@@ -63,13 +65,13 @@
63
  </label>
64
  </p>
65
  <?php endforeach; ?>
66
-
67
  <?php endif; ?>
68
-
69
  </div>
70
  <p class="submit">
71
  <input type="submit" name="update" class="button-primary" value="<?php esc_attr_e( 'Save Post Types', 'fl-builder' ); ?>" />
72
- <?php wp_nonce_field('post-types', 'fl-post-types-nonce'); ?>
73
  </p>
74
  </form>
75
- </div>
1
  <div id="fl-post-types-form" class="fl-settings-form">
2
 
3
+ <h3 class="fl-settings-form-header"><?php _e( 'Post Types', 'fl-builder' ); ?></h3>
4
 
5
  <form id="post-types-form" action="<?php FLBuilderAdminSettings::render_form_action( 'post-types' ); ?>" method="post">
6
 
7
  <?php if ( FLBuilderAdminSettings::multisite_support() && ! is_network_admin() ) : ?>
8
  <label>
9
+ <input class="fl-override-ms-cb" type="checkbox" name="fl-override-ms" value="1" <?php if ( get_option( '_fl_builder_post_types' ) ) { echo 'checked="checked"';} ?> />
10
+ <?php _e( 'Override network settings?', 'fl-builder' ); ?>
11
  </label>
12
  <?php endif; ?>
13
+
14
  <div class="fl-settings-form-content">
15
+
16
  <?php if ( is_network_admin() ) : ?>
17
+
18
+ <p><?php _e( 'Enter a comma separated list of the post types you would like the builder to work with.', 'fl-builder' ); ?></p>
19
+ <p><?php _e( 'NOTE: Not all custom post types may be supported.', 'fl-builder' ); ?></p>
20
  <?php
21
+
22
  $saved_post_types = FLBuilderModel::get_post_types();
23
+
24
+ foreach ( $saved_post_types as $key => $post_type ) {
25
+ if ( 'fl-builder-template' == $post_type ) {
26
+ unset( $saved_post_types[ $key ] );
27
  }
28
  }
29
+
30
+ $saved_post_types = implode( ', ', $saved_post_types );
31
+
32
  ?>
33
+ <input type="text" name="fl-post-types" value="<?php echo esc_html( $saved_post_types ); ?>" class="regular-text" />
34
+ <p class="description"><?php _e( 'Example: page, post, product', 'fl-builder' ); ?></p>
35
+
36
  <?php else : ?>
37
+
38
+ <p><?php _e( 'Select the post types you would like the builder to work with.', 'fl-builder' ); ?></p>
39
+ <p><?php _e( 'NOTE: Not all custom post types may be supported.', 'fl-builder' ); ?></p>
40
+
41
  <?php
42
+
43
  $saved_post_types = FLBuilderModel::get_post_types();
44
+ $post_types = get_post_types( array(
45
+ 'public' => true,
46
+ ), 'objects' );
47
  $post_types = apply_filters( 'fl_builder_admin_settings_post_types', $post_types );
48
+
49
+ foreach ( $post_types as $post_type ) :
50
+
51
+ $checked = in_array( $post_type->name, $saved_post_types ) ? 'checked' : '';
52
+
53
+ if ( 'attachment' == $post_type->name ) {
54
  continue;
55
  }
56
+ if ( 'fl-builder-template' == $post_type->name ) {
57
  continue;
58
  }
59
+
60
  ?>
61
  <p>
62
  <label>
65
  </label>
66
  </p>
67
  <?php endforeach; ?>
68
+
69
  <?php endif; ?>
70
+
71
  </div>
72
  <p class="submit">
73
  <input type="submit" name="update" class="button-primary" value="<?php esc_attr_e( 'Save Post Types', 'fl-builder' ); ?>" />
74
+ <?php wp_nonce_field( 'post-types', 'fl-post-types-nonce' ); ?>
75
  </p>
76
  </form>
77
+ </div>
includes/admin-settings-tools.php CHANGED
@@ -1,20 +1,20 @@
1
  <div id="fl-tools-form" class="fl-settings-form">
2
 
3
- <h3 class="fl-settings-form-header"><?php _e('Cache', 'fl-builder'); ?></h3>
4
 
5
  <form id="cache-form" action="<?php FLBuilderAdminSettings::render_form_action( 'cache' ); ?>" method="post">
6
  <div class="fl-settings-form-content">
7
  <p><?php _e( 'A CSS and JavaScript file is dynamically generated and cached each time you create a new layout. Sometimes the cache needs to be refreshed when you migrate your site to another server or update to the latest version. If you are running into any issues, please try clearing the cache by clicking the button below.', 'fl-builder' ); ?></p>
8
  <?php if ( is_network_admin() ) : ?>
9
- <p><strong><?php _e( 'NOTE:', 'fl-builder' ); ?></strong> <?php _e('This applies to all sites on the network.', 'fl-builder'); ?></p>
10
  <?php elseif ( ! is_network_admin() && is_multisite() ) : ?>
11
- <p><strong><?php _e( 'NOTE:', 'fl-builder' ); ?></strong> <?php _e('This only applies to this site. Please visit the Network Admin Settings to clear the cache for all sites on the network.', 'fl-builder'); ?></p>
12
  <?php endif; ?>
13
 
14
  </div>
15
  <p class="submit">
16
  <input type="submit" name="update" class="button-primary" value="<?php esc_attr_e( 'Clear Cache', 'fl-builder' ); ?>" />
17
- <?php wp_nonce_field('cache', 'fl-cache-nonce'); ?>
18
  </p>
19
  </form>
20
 
@@ -22,22 +22,22 @@
22
 
23
  <hr />
24
 
25
- <h3 class="fl-settings-form-header"><?php _e('Uninstall', 'fl-builder'); ?></h3>
26
 
27
  <div class="fl-settings-form-content">
28
- <p><?php _e('Clicking the button below will uninstall the page builder plugin and delete all of the data associated with it. You can uninstall or deactivate the page builder from the plugins page instead if you do not wish to delete the data.', 'fl-builder'); ?></p>
29
  <p><strong><?php _e( 'NOTE:', 'fl-builder' ); ?></strong> <?php _e( 'The builder does not delete the post meta <code>_fl_builder_data</code>, <code>_fl_builder_draft</code> and <code>_fl_builder_enabled</code> in case you want to reinstall it later. If you do, the builder will rebuild all of its data using those meta values.', 'fl-builder' ); ?></p>
30
- <?php if(is_multisite()) : ?>
31
- <p><strong><?php _e( 'NOTE:', 'fl-builder' ); ?></strong> <?php _e('This applies to all sites on the network.', 'fl-builder'); ?></p>
32
  <?php endif; ?>
33
  <form id="uninstall-form" action="<?php FLBuilderAdminSettings::render_form_action( 'uninstall' ); ?>" method="post">
34
  <p class="submit">
35
- <input type="submit" name="uninstall-submit" class="button button-primary" value="<?php _e('Uninstall', 'fl-builder'); ?>">
36
- <?php wp_nonce_field('uninstall', 'fl-uninstall'); ?>
37
  </p>
38
  </form>
39
  </div>
40
 
41
  <?php endif; ?>
42
 
43
- </div>
1
  <div id="fl-tools-form" class="fl-settings-form">
2
 
3
+ <h3 class="fl-settings-form-header"><?php _e( 'Cache', 'fl-builder' ); ?></h3>
4
 
5
  <form id="cache-form" action="<?php FLBuilderAdminSettings::render_form_action( 'cache' ); ?>" method="post">
6
  <div class="fl-settings-form-content">
7
  <p><?php _e( 'A CSS and JavaScript file is dynamically generated and cached each time you create a new layout. Sometimes the cache needs to be refreshed when you migrate your site to another server or update to the latest version. If you are running into any issues, please try clearing the cache by clicking the button below.', 'fl-builder' ); ?></p>
8
  <?php if ( is_network_admin() ) : ?>
9
+ <p><strong><?php _e( 'NOTE:', 'fl-builder' ); ?></strong> <?php _e( 'This applies to all sites on the network.', 'fl-builder' ); ?></p>
10
  <?php elseif ( ! is_network_admin() && is_multisite() ) : ?>
11
+ <p><strong><?php _e( 'NOTE:', 'fl-builder' ); ?></strong> <?php _e( 'This only applies to this site. Please visit the Network Admin Settings to clear the cache for all sites on the network.', 'fl-builder' ); ?></p>
12
  <?php endif; ?>
13
 
14
  </div>
15
  <p class="submit">
16
  <input type="submit" name="update" class="button-primary" value="<?php esc_attr_e( 'Clear Cache', 'fl-builder' ); ?>" />
17
+ <?php wp_nonce_field( 'cache', 'fl-cache-nonce' ); ?>
18
  </p>
19
  </form>
20
 
22
 
23
  <hr />
24
 
25
+ <h3 class="fl-settings-form-header"><?php _e( 'Uninstall', 'fl-builder' ); ?></h3>
26
 
27
  <div class="fl-settings-form-content">
28
+ <p><?php _e( 'Clicking the button below will uninstall the page builder plugin and delete all of the data associated with it. You can uninstall or deactivate the page builder from the plugins page instead if you do not wish to delete the data.', 'fl-builder' ); ?></p>
29
  <p><strong><?php _e( 'NOTE:', 'fl-builder' ); ?></strong> <?php _e( 'The builder does not delete the post meta <code>_fl_builder_data</code>, <code>_fl_builder_draft</code> and <code>_fl_builder_enabled</code> in case you want to reinstall it later. If you do, the builder will rebuild all of its data using those meta values.', 'fl-builder' ); ?></p>
30
+ <?php if ( is_multisite() ) : ?>
31
+ <p><strong><?php _e( 'NOTE:', 'fl-builder' ); ?></strong> <?php _e( 'This applies to all sites on the network.', 'fl-builder' ); ?></p>
32
  <?php endif; ?>
33
  <form id="uninstall-form" action="<?php FLBuilderAdminSettings::render_form_action( 'uninstall' ); ?>" method="post">
34
  <p class="submit">
35
+ <input type="submit" name="uninstall-submit" class="button button-primary" value="<?php _e( 'Uninstall', 'fl-builder' ); ?>">
36
+ <?php wp_nonce_field( 'uninstall', 'fl-uninstall' ); ?>
37
  </p>
38
  </form>
39
  </div>
40
 
41
  <?php endif; ?>
42
 
43
+ </div>
includes/admin-settings-upgrade.php CHANGED
@@ -1,21 +1,25 @@
1
  <div id="fl-upgrade-form" class="fl-settings-form fl-upgrade-page-content">
2
 
3
- <h3 class="fl-settings-form-header"><?php _e('Get More Features', 'fl-builder'); ?></h3>
4
 
5
- <p><?php _e('Along with access to our expert support team, the premium versions of Beaver Builder are packed with more features to save you time and make building websites easier!', 'fl-builder'); ?></p>
6
 
7
- <h4><?php _e('Premium Features', 'fl-builder'); ?></h4>
8
 
9
  <ul>
10
- <li><?php _e('Additional modules: Contact Form, Tabs, Slider, Pricing Table, Map, Blog Posts, Subscribe Form, Social Icons, and many more.', 'fl-builder'); ?></li>
11
- <li><?php _e('Expert support from our world-class support team.', 'fl-builder'); ?></li>
12
- <li><?php _e('Beautiful pre-made layout templates.', 'fl-builder'); ?></li>
13
- <li><?php _e('Save, export, and reuse full-page layouts, rows, and modules.', 'fl-builder'); ?></li>
14
- <li><?php _e('Build your own custom modules.', 'fl-builder'); ?></li>
15
  </ul>
16
 
17
- <p><?php _e('Come by the Beaver Builder Homepage to learn more about what our premium features can do for you!', 'fl-builder'); ?></p>
18
 
19
- <input type="button" class="button button-primary" value="<?php _e('Learn More', 'fl-builder'); ?>" onclick="window.open('<?php echo FLBuilderModel::get_store_url( '', array( 'utm_medium' => 'bb-lite', 'utm_source' => 'upgrade-settings-page', 'utm_campaign' => 'settings-upgrade-button' ) ); ?>');" style="margin-right: 10px;">
 
 
 
 
20
 
21
  </div>
1
  <div id="fl-upgrade-form" class="fl-settings-form fl-upgrade-page-content">
2
 
3
+ <h3 class="fl-settings-form-header"><?php _e( 'Get More Features', 'fl-builder' ); ?></h3>
4
 
5
+ <p><?php _e( 'Along with access to our expert support team, the premium versions of Beaver Builder are packed with more features to save you time and make building websites easier!', 'fl-builder' ); ?></p>
6
 
7
+ <h4><?php _e( 'Premium Features', 'fl-builder' ); ?></h4>
8
 
9
  <ul>
10
+ <li><?php _e( 'Additional modules: Contact Form, Tabs, Slider, Pricing Table, Map, Blog Posts, Subscribe Form, Social Icons, and many more.', 'fl-builder' ); ?></li>
11
+ <li><?php _e( 'Expert support from our world-class support team.', 'fl-builder' ); ?></li>
12
+ <li><?php _e( 'Beautiful pre-made layout templates.', 'fl-builder' ); ?></li>
13
+ <li><?php _e( 'Save, export, and reuse full-page layouts, rows, and modules.', 'fl-builder' ); ?></li>
14
+ <li><?php _e( 'Build your own custom modules.', 'fl-builder' ); ?></li>
15
  </ul>
16
 
17
+ <p><?php _e( 'Come by the Beaver Builder Homepage to learn more about what our premium features can do for you!', 'fl-builder' ); ?></p>
18
 
19
+ <input type="button" class="button button-primary" value="<?php _e( 'Learn More', 'fl-builder' ); ?>" onclick="window.open('<?php echo FLBuilderModel::get_store_url( '', array(
20
+ 'utm_medium' => 'bb-lite',
21
+ 'utm_source' => 'upgrade-settings-page',
22
+ 'utm_campaign' => 'settings-upgrade-button',
23
+ ) ); ?>');" style="margin-right: 10px;">
24
 
25
  </div>
includes/admin-settings-user-access.php CHANGED
@@ -1,13 +1,13 @@
1
  <?php $raw_settings = FLBuilderUserAccess::get_raw_settings(); ?>
2
  <div id="fl-user-access-form" class="fl-settings-form">
3
 
4
- <h3 class="fl-settings-form-header"><?php _e('User Access Settings', 'fl-builder'); ?></h3>
5
  <p><?php _e( 'Use these settings to limit which builder features users can access.', 'fl-builder' ); ?></p>
6
-
7
  <form id="editing-form" action="<?php FLBuilderAdminSettings::render_form_action( 'user-access' ); ?>" method="post">
8
  <div class="fl-settings-form-content">
9
  <?php foreach ( FLBuilderUserAccess::get_grouped_registered_settings() as $group => $group_data ) : ?>
10
-
11
  <div class="fl-user-access-group">
12
  <h3><?php echo $group; ?></h3>
13
  <?php $i = 1; foreach ( $group_data as $cap => $cap_data ) : ?>
@@ -15,23 +15,24 @@
15
  <h4><?php echo $cap_data['label']; ?><i class="dashicons dashicons-editor-help" title="<?php echo esc_html( $cap_data['description'] ); ?>"></i></h4>
16
  <?php if ( FLBuilderAdminSettings::multisite_support() && ! is_network_admin() ) : ?>
17
  <label class="fl-ua-override-ms-label">
18
- <input class="fl-ua-override-ms-cb" type="checkbox" name="fl_ua_override_ms[<?php echo $cap; ?>]" value="1" <?php if ( isset( $raw_settings[ $cap ] ) ) echo 'checked'; ?> />
19
- <?php _e('Override network settings?', 'fl-builder'); ?>
20
  </label>
21
  <?php endif; ?>
22
  <select name="fl_user_access[<?php echo $cap; ?>][]" class="fl-user-access-select" multiple></select>
23
  </div>
24
- <?php if ( 0 === $i % 2 || $i == count( $group_data ) ) : ?>
25
  <div class="clear"></div>
26
  <?php endif; ?>
27
- <?php $i++; endforeach; ?>
 
28
  </div>
29
-
30
  <?php endforeach; ?>
31
  </div>
32
  <p class="submit">
33
  <input type="submit" name="update" class="button-primary" value="<?php esc_attr_e( 'Save User Access Settings', 'fl-builder' ); ?>" />
34
- <?php wp_nonce_field('user-access', 'fl-user-access-nonce'); ?>
35
  </p>
36
  </form>
37
- </div>
1
  <?php $raw_settings = FLBuilderUserAccess::get_raw_settings(); ?>
2
  <div id="fl-user-access-form" class="fl-settings-form">
3
 
4
+ <h3 class="fl-settings-form-header"><?php _e( 'User Access Settings', 'fl-builder' ); ?></h3>
5
  <p><?php _e( 'Use these settings to limit which builder features users can access.', 'fl-builder' ); ?></p>
6
+
7
  <form id="editing-form" action="<?php FLBuilderAdminSettings::render_form_action( 'user-access' ); ?>" method="post">
8
  <div class="fl-settings-form-content">
9
  <?php foreach ( FLBuilderUserAccess::get_grouped_registered_settings() as $group => $group_data ) : ?>
10
+
11
  <div class="fl-user-access-group">
12
  <h3><?php echo $group; ?></h3>
13
  <?php $i = 1; foreach ( $group_data as $cap => $cap_data ) : ?>
15
  <h4><?php echo $cap_data['label']; ?><i class="dashicons dashicons-editor-help" title="<?php echo esc_html( $cap_data['description'] ); ?>"></i></h4>
16
  <?php if ( FLBuilderAdminSettings::multisite_support() && ! is_network_admin() ) : ?>
17
  <label class="fl-ua-override-ms-label">
18
+ <input class="fl-ua-override-ms-cb" type="checkbox" name="fl_ua_override_ms[<?php echo $cap; ?>]" value="1" <?php if ( isset( $raw_settings[ $cap ] ) ) { echo 'checked';} ?> />
19
+ <?php _e( 'Override network settings?', 'fl-builder' ); ?>
20
  </label>
21
  <?php endif; ?>
22
  <select name="fl_user_access[<?php echo $cap; ?>][]" class="fl-user-access-select" multiple></select>
23
  </div>
24
+ <?php if ( 0 === $i % 2 || count( $group_data ) == $i ) : ?>
25
  <div class="clear"></div>
26
  <?php endif; ?>
27
+ <?php $i++;
28
+ endforeach; ?>
29
  </div>
30
+
31
  <?php endforeach; ?>
32
  </div>
33
  <p class="submit">
34
  <input type="submit" name="update" class="button-primary" value="<?php esc_attr_e( 'Save User Access Settings', 'fl-builder' ); ?>" />
35
+ <?php wp_nonce_field( 'user-access', 'fl-user-access-nonce' ); ?>
36
  </p>
37
  </form>
38
+ </div>
includes/admin-settings-welcome.php CHANGED
@@ -4,11 +4,11 @@ function fl_welcome_utm( $campaign ) {
4
  return array(
5
  'utm_medium' => true === FL_BUILDER_LITE ? 'bb-lite' : 'bb-pro',
6
  'utm_source' => 'welcome-settings-page',
7
- 'utm_campaign' => $campaign
8
  );
9
  }
10
 
11
- $blog_post_url = FLBuilderModel::get_store_url( 'beaver-builder-1-9-shasta', fl_welcome_utm('settings-welcome-blog-post' ) );
12
  $change_logs_url = FLBuilderModel::get_store_url( 'change-logs', fl_welcome_utm( 'settings-welcome-change-logs' ) );
13
  $upgrade_url = FLBuilderModel::get_store_url( '', fl_welcome_utm( 'settings-welcome-upgrade' ) );
14
  $support_url = FLBuilderModel::get_store_url( 'beaver-builder-support', fl_welcome_utm( 'settings-welcome-support' ) );
@@ -19,40 +19,40 @@ $docs_url = 'http://kb.wpbeaverbuilder.com/';
19
  ?>
20
  <div id="fl-welcome-form" class="fl-settings-form">
21
 
22
- <h3 class="fl-settings-form-header"><?php _e('Welcome to Beaver Builder!', 'fl-builder'); ?></h3>
23
 
24
  <div class="fl-settings-form-content fl-welcome-page-content">
25
 
26
- <p><?php _e('Thank you for choosing Beaver Builder and welcome to the colony! Find some helpful information below. Also, to the left are the Page Builder settings options.', 'fl-builder'); ?>
27
 
28
- <?php if (true === FL_BUILDER_LITE) : ?>
29
- <?php printf( __('For more time-saving features and access to our expert support team, <a href="%s" target="_blank">upgrade today</a>.', 'fl-builder'), $upgrade_url ); ?>
30
- <?php else: ?>
31
- <?php _e('Be sure to add your license key for access to updates and new features.', 'fl-builder'); ?>
32
  <?php endif; ?>
33
 
34
  </p>
35
 
36
- <h4><?php _e('Getting Started - Building your first page.', 'fl-builder'); ?></h4>
37
 
38
  <div class="fl-welcome-col-wrap">
39
 
40
  <div class="fl-welcome-col">
41
 
42
- <p><a href="<?php echo admin_url(); ?>post-new.php?post_type=page" class="fl-welcome-big-link"><?php _e('Pages → Add New', 'fl-builder'); ?></a></p>
43
 
44
- <p><?php _e('Ready to start building? Add a new page and jump into Beaver Builder by clicking the Page Builder tab shown on the image.', 'fl-builder'); ?></p>
45
 
46
- <h4><?php _e('Join the Community', 'fl-builder'); ?></h4>
47
 
48
- <p><?php _e('There\'s a wonderful community of "Beaver Builders" out there and we\'d love it if <em>you</em> joined us!', 'fl-builder'); ?></p>
49
 
50
  <ul>
51
  <li><?php _e( '<a href="https://www.wpbeaverbuilder.com/go/bb-facebook" target="_blank">Join the Beaver Builder\'s Group on Facebook</a>', 'fl-builder' ); ?></li>
52
- <li><?php _e( '<a href="https://www.wpbeaverbuilder.com/go/bb-slack" target="_blank">Join the Beaver Builder\'s Group on Slack</a>', 'fl-builder'); ?></li>
53
  </ul>
54
 
55
- <p><?php _e('Come by and share a project, ask a question, or just say hi! For news about new features and updates, like our <a href="https://www.facebook.com/wpbeaverbuilder/" target="_blank">Facebook Page</a> or follow us <a href="https://twitter.com/beaverbuilder" target="_blank">on Twitter</a>.', 'fl-builder'); ?></p>
56
 
57
  </div>
58
 
@@ -68,35 +68,35 @@ $docs_url = 'http://kb.wpbeaverbuilder.com/';
68
 
69
  <div class="fl-welcome-col">
70
 
71
- <h4><?php _e('What\'s New in Beaver Builder 1.9 Shasta', 'fl-builder'); ?></h4>
72
 
73
- <p><?php _e('Beaver Builder 1.9 is out and it has some epic new features:', 'fl-builder'); ?></p>
74
 
75
  <ul>
76
- <li><?php _e('The ability to drag, drop and nest columns.', 'fl-builder'); ?></li>
77
- <li><?php _e('A revamped editor with more accurate dragging and dropping.', 'fl-builder'); ?></li>
78
- <li><?php _e('Responsive settings for margins, paddings and borders.', 'fl-builder'); ?></li>
79
- <li><?php _e('New content page templates available in the template selector.', 'fl-builder'); ?></li>
80
  </ul>
81
 
82
- <p><?php printf( __('There\'s a whole lot more, too! Read about everything else on our <a href="%1$s" target="_blank">update post</a> or <a href="%2$s" target="_blank">change logs</a>.', 'fl-builder'), $blog_post_url, $change_logs_url ); ?></p>
83
 
84
  </div>
85
 
86
  <div class="fl-welcome-col">
87
 
88
- <h4><?php _e('Need Some Help?', 'fl-builder'); ?></h4>
89
 
90
- <p><?php _e('We take pride in offering outstanding support.', 'fl-builder'); ?></p>
91
 
92
- <p><?php _e('The fastest way to find an answer to a question is to see if someone\'s already answered it!', 'fl-builder'); ?></p>
93
 
94
- <p><?php printf( __('For that, check our <a href="%1$s" target="_blank">Knowledge Base</a>, <a href="%2$s" target="_blank">FAQ page</a>, or search our legacy <a href="%3$s" target="_blank">support forum.</a>', 'fl-builder'), $docs_url, $faqs_url, $forums_url ); ?></p>
95
 
96
- <?php if (true === FL_BUILDER_LITE) : ?>
97
- <p><?php printf( __('If you can\'t find an answer, consider upgrading to a premium version of Beaver Builder. Our expert support team is waiting to answer your questions and help you build your website. <a href="%s" target="_blank">Learn More</a>.', 'fl-builder'), $upgrade_url ); ?></p>
98
- <?php else: ?>
99
- <p><?php printf( __('If you can\'t find an answer, feel free to <a href="%s" target="_blank">send us a message with your question.</a>', 'fl-builder'), $support_url ); ?></p>
100
  <?php endif; ?>
101
  </div>
102
 
4
  return array(
5
  'utm_medium' => true === FL_BUILDER_LITE ? 'bb-lite' : 'bb-pro',
6
  'utm_source' => 'welcome-settings-page',
7
+ 'utm_campaign' => $campaign,
8
  );
9
  }
10
 
11
+ $blog_post_url = FLBuilderModel::get_store_url( 'beaver-builder-1-9-shasta', fl_welcome_utm( 'settings-welcome-blog-post' ) );
12
  $change_logs_url = FLBuilderModel::get_store_url( 'change-logs', fl_welcome_utm( 'settings-welcome-change-logs' ) );
13
  $upgrade_url = FLBuilderModel::get_store_url( '', fl_welcome_utm( 'settings-welcome-upgrade' ) );
14
  $support_url = FLBuilderModel::get_store_url( 'beaver-builder-support', fl_welcome_utm( 'settings-welcome-support' ) );
19
  ?>
20
  <div id="fl-welcome-form" class="fl-settings-form">
21
 
22
+ <h3 class="fl-settings-form-header"><?php _e( 'Welcome to Beaver Builder!', 'fl-builder' ); ?></h3>
23
 
24
  <div class="fl-settings-form-content fl-welcome-page-content">
25
 
26
+ <p><?php _e( 'Thank you for choosing Beaver Builder and welcome to the colony! Find some helpful information below. Also, to the left are the Page Builder settings options.', 'fl-builder' ); ?>
27
 
28
+ <?php if ( true === FL_BUILDER_LITE ) : ?>
29
+ <?php printf( __( 'For more time-saving features and access to our expert support team, <a href="%s" target="_blank">upgrade today</a>.', 'fl-builder' ), $upgrade_url ); ?>
30
+ <?php else : ?>
31
+ <?php _e( 'Be sure to add your license key for access to updates and new features.', 'fl-builder' ); ?>
32
  <?php endif; ?>
33
 
34
  </p>
35
 
36
+ <h4><?php _e( 'Getting Started - Building your first page.', 'fl-builder' ); ?></h4>
37
 
38
  <div class="fl-welcome-col-wrap">
39
 
40
  <div class="fl-welcome-col">
41
 
42
+ <p><a href="<?php echo admin_url(); ?>post-new.php?post_type=page" class="fl-welcome-big-link"><?php _e( 'Pages → Add New', 'fl-builder' ); ?></a></p>
43
 
44
+ <p><?php _e( 'Ready to start building? Add a new page and jump into Beaver Builder by clicking the Page Builder tab shown on the image.', 'fl-builder' ); ?></p>
45
 
46
+ <h4><?php _e( 'Join the Community', 'fl-builder' ); ?></h4>
47
 
48
+ <p><?php _e( 'There\'s a wonderful community of "Beaver Builders" out there and we\'d love it if <em>you</em> joined us!', 'fl-builder' ); ?></p>
49
 
50
  <ul>
51
  <li><?php _e( '<a href="https://www.wpbeaverbuilder.com/go/bb-facebook" target="_blank">Join the Beaver Builder\'s Group on Facebook</a>', 'fl-builder' ); ?></li>
52
+ <li><?php _e( '<a href="https://www.wpbeaverbuilder.com/go/bb-slack" target="_blank">Join the Beaver Builder\'s Group on Slack</a>', 'fl-builder' ); ?></li>
53
  </ul>
54
 
55
+ <p><?php _e( 'Come by and share a project, ask a question, or just say hi! For news about new features and updates, like our <a href="https://www.facebook.com/wpbeaverbuilder/" target="_blank">Facebook Page</a> or follow us <a href="https://twitter.com/beaverbuilder" target="_blank">on Twitter</a>.', 'fl-builder' ); ?></p>
56
 
57
  </div>
58
 
68
 
69
  <div class="fl-welcome-col">
70
 
71
+ <h4><?php _e( 'What\'s New in Beaver Builder 1.9 Shasta', 'fl-builder' ); ?></h4>
72
 
73
+ <p><?php _e( 'Beaver Builder 1.9 is out and it has some epic new features:', 'fl-builder' ); ?></p>
74
 
75
  <ul>
76
+ <li><?php _e( 'The ability to drag, drop and nest columns.', 'fl-builder' ); ?></li>
77
+ <li><?php _e( 'A revamped editor with more accurate dragging and dropping.', 'fl-builder' ); ?></li>
78
+ <li><?php _e( 'Responsive settings for margins, paddings and borders.', 'fl-builder' ); ?></li>
79
+ <li><?php _e( 'New content page templates available in the template selector.', 'fl-builder' ); ?></li>
80
  </ul>
81
 
82
+ <p><?php printf( __( 'There\'s a whole lot more, too! Read about everything else on our <a href="%1$s" target="_blank">update post</a> or <a href="%2$s" target="_blank">change logs</a>.', 'fl-builder' ), $blog_post_url, $change_logs_url ); ?></p>
83
 
84
  </div>
85
 
86
  <div class="fl-welcome-col">
87
 
88
+ <h4><?php _e( 'Need Some Help?', 'fl-builder' ); ?></h4>
89
 
90
+ <p><?php _e( 'We take pride in offering outstanding support.', 'fl-builder' ); ?></p>
91
 
92
+ <p><?php _e( 'The fastest way to find an answer to a question is to see if someone\'s already answered it!', 'fl-builder' ); ?></p>
93
 
94
+ <p><?php printf( __( 'For that, check our <a href="%1$s" target="_blank">Knowledge Base</a>, <a href="%2$s" target="_blank">FAQ page</a>, or search our legacy <a href="%3$s" target="_blank">support forum.</a>', 'fl-builder' ), $docs_url, $faqs_url, $forums_url ); ?></p>
95
 
96
+ <?php if ( true === FL_BUILDER_LITE ) : ?>
97
+ <p><?php printf( __( 'If you can\'t find an answer, consider upgrading to a premium version of Beaver Builder. Our expert support team is waiting to answer your questions and help you build your website. <a href="%s" target="_blank">Learn More</a>.', 'fl-builder' ), $upgrade_url ); ?></p>
98
+ <?php else : ?>
99
+ <p><?php printf( __( 'If you can\'t find an answer, feel free to <a href="%s" target="_blank">send us a message with your question.</a>', 'fl-builder' ), $support_url ); ?></p>
100
  <?php endif; ?>
101
  </div>
102
 
includes/admin-settings.php CHANGED
@@ -15,4 +15,4 @@
15
  <div class="fl-settings-content">
16
  <?php FLBuilderAdminSettings::render_forms(); ?>
17
  </div>
18
- </div>
15
  <div class="fl-settings-content">
16
  <?php FLBuilderAdminSettings::render_forms(); ?>
17
  </div>
18
+ </div>
includes/column-css.php CHANGED
@@ -2,7 +2,7 @@
2
  width: <?php echo $col->settings->size; ?>%;
3
  }
4
 
5
- <?php if(!empty($col->settings->text_color)) : // Text Color ?>
6
  .fl-node-<?php echo $col->node; ?> {
7
  color: #<?php echo $col->settings->text_color; ?>;
8
  }
@@ -11,27 +11,27 @@
11
  }
12
  <?php endif; ?>
13
 
14
- <?php if(!empty($col->settings->link_color)) : // Link Color ?>
15
  .fl-builder-content .fl-node-<?php echo $col->node; ?> a {
16
  color: #<?php echo $col->settings->link_color; ?>;
17
  }
18
- <?php elseif(!empty($col->settings->text_color)) : ?>
19
  .fl-builder-content .fl-node-<?php echo $col->node; ?> a {
20
  color: #<?php echo $col->settings->text_color; ?>;
21
  }
22
  <?php endif; ?>
23
 
24
- <?php if(!empty($col->settings->hover_color)) : // Link Hover Color ?>
25
  .fl-builder-content .fl-node-<?php echo $col->node; ?> a:hover {
26
  color: #<?php echo $col->settings->hover_color; ?>;
27
  }
28
- <?php elseif(!empty($col->settings->text_color)) : ?>
29
  .fl-builder-content .fl-node-<?php echo $col->node; ?> a:hover {
30
  color: #<?php echo $col->settings->text_color; ?>;
31
  }
32
  <?php endif; ?>
33
 
34
- <?php if(!empty($col->settings->heading_color)) : // Heading Color ?>
35
  .fl-builder-content .fl-node-<?php echo $col->node; ?> h1,
36
  .fl-builder-content .fl-node-<?php echo $col->node; ?> h2,
37
  .fl-builder-content .fl-node-<?php echo $col->node; ?> h3,
@@ -46,7 +46,7 @@
46
  .fl-builder-content .fl-node-<?php echo $col->node; ?> h6 a {
47
  color: #<?php echo $col->settings->heading_color; ?>;
48
  }
49
- <?php elseif(!empty($col->settings->text_color)) : ?>
50
  .fl-builder-content .fl-node-<?php echo $col->node; ?> h1,
51
  .fl-builder-content .fl-node-<?php echo $col->node; ?> h2,
52
  .fl-builder-content .fl-node-<?php echo $col->node; ?> h3,
@@ -63,14 +63,14 @@
63
  }
64
  <?php endif; ?>
65
 
66
- <?php if($col->settings->bg_type == 'color' && !empty($col->settings->bg_color)) : // Background Color ?>
67
  .fl-node-<?php echo $col->node; ?> > .fl-col-content {
68
  background-color: #<?php echo $col->settings->bg_color; ?>;
69
- background-color: rgba(<?php echo implode(',', FLBuilderColor::hex_to_rgb($col->settings->bg_color)) ?>, <?php echo $col->settings->bg_opacity/100; ?>);
70
  }
71
  <?php endif; ?>
72
 
73
- <?php if($col->settings->bg_type == 'photo' && !empty($col->settings->bg_image)) : // Background Image ?>
74
  .fl-node-<?php echo $col->node; ?> > .fl-col-content {
75
  background-image: url(<?php echo $col->settings->bg_image_src; ?>);
76
  background-repeat: <?php echo $col->settings->bg_repeat; ?>;
@@ -80,27 +80,27 @@
80
  }
81
  <?php endif; ?>
82
 
83
- <?php if( in_array( $col->settings->bg_type, array('photo') ) && ! empty( $col->settings->bg_overlay_color ) ) : // Background Overlay Color ?>
84
  .fl-node-<?php echo $col->node; ?> > .fl-col-content:after {
85
  background-color: #<?php echo $col->settings->bg_overlay_color; ?>;
86
- background-color: rgba(<?php echo implode( ',', FLBuilderColor::hex_to_rgb( $col->settings->bg_overlay_color ) ) ?>, <?php echo $col->settings->bg_overlay_opacity/100; ?>);
87
  }
88
  <?php endif; ?>
89
 
90
- <?php if(!empty($col->settings->border_type)) : // Border ?>
91
  .fl-builder-content .fl-node-<?php echo $col->node; ?> > .fl-col-content {
92
  border-style: <?php echo $col->settings->border_type; ?>;
93
  border-width: 0;
94
- <?php if(!empty($col->settings->border_color)) : ?>
95
  border-color: #<?php echo $col->settings->border_color; ?>;
96
- border-color: rgba(<?php echo implode(',', FLBuilderColor::hex_to_rgb($col->settings->border_color)) ?>, <?php echo $col->settings->border_opacity/100; ?>);
97
  <?php endif; ?>
98
  }
99
  <?php endif; ?>
100
 
101
- <?php if($global_settings->responsive_enabled) : // Responsive Sizes ?>
102
 
103
- <?php if($col->settings->medium_size == 'custom') : ?>
104
  @media(max-width: <?php echo $global_settings->medium_breakpoint; ?>px) {
105
  .fl-builder-content .fl-node-<?php echo $col->node; ?> {
106
  max-width: none;
@@ -108,8 +108,8 @@
108
  }
109
  }
110
  <?php endif; ?>
111
-
112
- <?php if($col->settings->responsive_size == 'custom') : ?>
113
  @media(max-width: <?php echo $global_settings->responsive_breakpoint; ?>px) {
114
  .fl-builder-content .fl-node-<?php echo $col->node; ?> {
115
  clear: none;
@@ -119,5 +119,5 @@
119
  }
120
  }
121
  <?php endif; ?>
122
-
123
- <?php endif; ?>
2
  width: <?php echo $col->settings->size; ?>%;
3
  }
4
 
5
+ <?php if ( ! empty( $col->settings->text_color ) ) : // Text Color ?>
6
  .fl-node-<?php echo $col->node; ?> {
7
  color: #<?php echo $col->settings->text_color; ?>;
8
  }
11
  }
12
  <?php endif; ?>
13
 
14
+ <?php if ( ! empty( $col->settings->link_color ) ) : // Link Color ?>
15
  .fl-builder-content .fl-node-<?php echo $col->node; ?> a {
16
  color: #<?php echo $col->settings->link_color; ?>;
17
  }
18
+ <?php elseif ( ! empty( $col->settings->text_color ) ) : ?>
19
  .fl-builder-content .fl-node-<?php echo $col->node; ?> a {
20
  color: #<?php echo $col->settings->text_color; ?>;
21
  }
22
  <?php endif; ?>
23
 
24
+ <?php if ( ! empty( $col->settings->hover_color ) ) : // Link Hover Color ?>
25
  .fl-builder-content .fl-node-<?php echo $col->node; ?> a:hover {
26
  color: #<?php echo $col->settings->hover_color; ?>;
27
  }
28
+ <?php elseif ( ! empty( $col->settings->text_color ) ) : ?>
29
  .fl-builder-content .fl-node-<?php echo $col->node; ?> a:hover {
30
  color: #<?php echo $col->settings->text_color; ?>;
31
  }
32
  <?php endif; ?>
33
 
34
+ <?php if ( ! empty( $col->settings->heading_color ) ) : // Heading Color ?>
35
  .fl-builder-content .fl-node-<?php echo $col->node; ?> h1,
36
  .fl-builder-content .fl-node-<?php echo $col->node; ?> h2,
37
  .fl-builder-content .fl-node-<?php echo $col->node; ?> h3,
46
  .fl-builder-content .fl-node-<?php echo $col->node; ?> h6 a {
47
  color: #<?php echo $col->settings->heading_color; ?>;
48
  }
49
+ <?php elseif ( ! empty( $col->settings->text_color ) ) : ?>
50
  .fl-builder-content .fl-node-<?php echo $col->node; ?> h1,
51
  .fl-builder-content .fl-node-<?php echo $col->node; ?> h2,
52
  .fl-builder-content .fl-node-<?php echo $col->node; ?> h3,
63
  }
64
  <?php endif; ?>
65
 
66
+ <?php if ( 'color' == $col->settings->bg_type && ! empty( $col->settings->bg_color ) ) : // Background Color ?>
67
  .fl-node-<?php echo $col->node; ?> > .fl-col-content {
68
  background-color: #<?php echo $col->settings->bg_color; ?>;
69
+ background-color: rgba(<?php echo implode( ',', FLBuilderColor::hex_to_rgb( $col->settings->bg_color ) ) ?>, <?php echo $col->settings->bg_opacity / 100; ?>);
70
  }
71
  <?php endif; ?>
72
 
73
+ <?php if ( 'photo' == $col->settings->bg_type && ! empty( $col->settings->bg_image ) ) : // Background Image ?>
74
  .fl-node-<?php echo $col->node; ?> > .fl-col-content {
75
  background-image: url(<?php echo $col->settings->bg_image_src; ?>);
76
  background-repeat: <?php echo $col->settings->bg_repeat; ?>;
80
  }
81
  <?php endif; ?>
82
 
83
+ <?php if ( in_array( $col->settings->bg_type, array( 'photo' ) ) && ! empty( $col->settings->bg_overlay_color ) ) : // Background Overlay Color ?>
84
  .fl-node-<?php echo $col->node; ?> > .fl-col-content:after {
85
  background-color: #<?php echo $col->settings->bg_overlay_color; ?>;
86
+ background-color: rgba(<?php echo implode( ',', FLBuilderColor::hex_to_rgb( $col->settings->bg_overlay_color ) ) ?>, <?php echo $col->settings->bg_overlay_opacity / 100; ?>);
87
  }
88
  <?php endif; ?>
89
 
90
+ <?php if ( ! empty( $col->settings->border_type ) ) : // Border ?>
91
  .fl-builder-content .fl-node-<?php echo $col->node; ?> > .fl-col-content {
92
  border-style: <?php echo $col->settings->border_type; ?>;
93
  border-width: 0;
94
+ <?php if ( ! empty( $col->settings->border_color ) ) : ?>
95
  border-color: #<?php echo $col->settings->border_color; ?>;
96
+ border-color: rgba(<?php echo implode( ',', FLBuilderColor::hex_to_rgb( $col->settings->border_color ) ) ?>, <?php echo $col->settings->border_opacity / 100; ?>);
97
  <?php endif; ?>
98
  }
99
  <?php endif; ?>
100
 
101
+ <?php if ( $global_settings->responsive_enabled ) : // Responsive Sizes ?>
102
 
103
+ <?php if ( 'custom' == $col->settings->medium_size ) : ?>
104
  @media(max-width: <?php echo $global_settings->medium_breakpoint; ?>px) {
105
  .fl-builder-content .fl-node-<?php echo $col->node; ?> {
106
  max-width: none;
108
  }
109
  }
110
  <?php endif; ?>
111
+
112
+ <?php if ( 'custom' == $col->settings->responsive_size ) : ?>
113
  @media(max-width: <?php echo $global_settings->responsive_breakpoint; ?>px) {
114
  .fl-builder-content .fl-node-<?php echo $col->node; ?> {
115
  clear: none;
119
  }
120
  }
121
  <?php endif; ?>
122
+
123
+ <?php endif; ?>
includes/column-group.php CHANGED
@@ -1,6 +1,6 @@
1
 
2
  <div<?php FLBuilder::render_column_group_attributes( $group ); ?>>
3
- <?php
4
  // $cols received as a magic variable from template loader
5
  foreach ( $cols as $col ) :
6
  ?>
1
 
2
  <div<?php FLBuilder::render_column_group_attributes( $group ); ?>>
3
+ <?php
4
  // $cols received as a magic variable from template loader
5
  foreach ( $cols as $col ) :
6
  ?>
includes/column-settings.php CHANGED
@@ -1,29 +1,29 @@
1
  <?php
2
 
3
  FLBuilder::register_settings_form('col', array(
4
- 'title' => __('Column Settings', 'fl-builder'),
5
  'tabs' => array(
6
  'style' => array(
7
- 'title' => __('Style', 'fl-builder'),
8
  'sections' => array(
9
  'general' => array(
10
  'title' => '',
11
  'fields' => array(
12
  'size' => array(
13
  'type' => 'text',
14
- 'label' => __('Column Width', 'fl-builder'),
15
  'default' => '',
16
  'description' => '%',
17
  'maxlength' => '5',
18
  'size' => '6',
19
  'preview' => array(
20
- 'type' => 'none'
21
- )
22
  ),
23
  'equal_height' => array(
24
  'type' => 'select',
25
- 'label' => __('Equalize Column Heights', 'fl-builder'),
26
- 'help' => __('Setting this to yes will make all of the columns in this group the same height regardless of how much content is in each of them.', 'fl-builder'),
27
  'default' => 'no',
28
  'options' => array(
29
  'no' => __( 'No', 'fl-builder' ),
@@ -31,16 +31,16 @@ FLBuilder::register_settings_form('col', array(
31
  ),
32
  'toggle' => array(
33
  'yes' => array(
34
- 'fields' => array('content_alignment')
35
- )
36
  ),
37
  'preview' => array(
38
- 'type' => 'none'
39
- )
40
  ),
41
  'content_alignment' => array(
42
  'type' => 'select',
43
- 'label' => __('Content Alignment', 'fl-builder'),
44
  'default' => 'top',
45
  'options' => array(
46
  'top' => __( 'Top', 'fl-builder' ),
@@ -48,54 +48,54 @@ FLBuilder::register_settings_form('col', array(
48
  'bottom' => __( 'Bottom', 'fl-builder' ),
49
  ),
50
  'preview' => array(
51
- 'type' => 'none'
52
- )
53
- )
54
- )
55
  ),
56
  'text' => array(
57
- 'title' => __('Text', 'fl-builder'),
58
  'fields' => array(
59
  'text_color' => array(
60
  'type' => 'color',
61
- 'label' => __('Color', 'fl-builder'),
62
  'show_reset' => true,
63
  'preview' => array(
64
- 'type' => 'none'
65
- )
66
  ),
67
  'link_color' => array(
68
  'type' => 'color',
69
- 'label' => __('Link Color', 'fl-builder'),
70
  'show_reset' => true,
71
  'preview' => array(
72
- 'type' => 'none'
73
- )
74
  ),
75
  'hover_color' => array(
76
  'type' => 'color',
77
- 'label' => __('Link Hover Color', 'fl-builder'),
78
  'show_reset' => true,
79
  'preview' => array(
80
- 'type' => 'none'
81
- )
82
  ),
83
  'heading_color' => array(
84
  'type' => 'color',
85
- 'label' => __('Heading Color', 'fl-builder'),
86
  'show_reset' => true,
87
  'preview' => array(
88
- 'type' => 'none'
89
- )
90
- )
91
- )
92
  ),
93
  'background' => array(
94
- 'title' => __('Background', 'fl-builder'),
95
  'fields' => array(
96
  'bg_type' => array(
97
  'type' => 'select',
98
- 'label' => __('Type', 'fl-builder'),
99
  'default' => 'color',
100
  'options' => array(
101
  'none' => _x( 'None', 'Background type.', 'fl-builder' ),
@@ -104,195 +104,195 @@ FLBuilder::register_settings_form('col', array(
104
  ),
105
  'toggle' => array(
106
  'color' => array(
107
- 'sections' => array('bg_color')
108
  ),
109
  'photo' => array(
110
- 'sections' => array('bg_photo', 'bg_overlay')
111
  ),
112
  ),
113
  'preview' => array(
114
- 'type' => 'none'
115
- )
116
- )
117
- )
118
  ),
119
  'bg_color' => array(
120
- 'title' => __('Background Color', 'fl-builder'),
121
  'fields' => array(
122
  'bg_color' => array(
123
  'type' => 'color',
124
- 'label' => __('Color', 'fl-builder'),
125
  'show_reset' => true,
126
  'preview' => array(
127
- 'type' => 'none'
128
- )
129
  ),
130
  'bg_opacity' => array(
131
  'type' => 'text',
132
- 'label' => __('Opacity', 'fl-builder'),
133
  'default' => '100',
134
  'description' => '%',
135
  'maxlength' => '3',
136
  'size' => '5',
137
  'preview' => array(
138
- 'type' => 'none'
139
- )
140
- )
141
- )
142
  ),
143
  'bg_photo' => array(
144
- 'title' => __('Background Photo', 'fl-builder'),
145
  'fields' => array(
146
  'bg_image' => array(
147
  'type' => 'photo',
148
- 'label' => __('Photo', 'fl-builder'),
149
  'preview' => array(
150
- 'type' => 'none'
151
  ),
152
- 'connections' => array( 'photo' )
153
  ),
154
  'bg_repeat' => array(
155
  'type' => 'select',
156
- 'label' => __('Repeat', 'fl-builder'),
157
  'default' => 'none',
158
  'options' => array(
159
  'no-repeat' => _x( 'None', 'Background repeat.', 'fl-builder' ),
160
  'repeat' => _x( 'Tile', 'Background repeat.', 'fl-builder' ),
161
  'repeat-x' => _x( 'Horizontal', 'Background repeat.', 'fl-builder' ),
162
- 'repeat-y' => _x( 'Vertical', 'Background repeat.', 'fl-builder' )
163
  ),
164
- 'help' => __('Repeat applies to how the image should display in the background. Choosing none will display the image as uploaded. Tile will repeat the image as many times as needed to fill the background horizontally and vertically. You can also specify the image to only repeat horizontally or vertically.', 'fl-builder'),
165
  'preview' => array(
166
- 'type' => 'none'
167
- )
168
  ),
169
  'bg_position' => array(
170
  'type' => 'select',
171
- 'label' => __('Position', 'fl-builder'),
172
  'default' => 'center center',
173
  'options' => array(
174
- 'left top' => __('Left Top', 'fl-builder'),
175
- 'left center' => __('Left Center', 'fl-builder'),
176
- 'left bottom' => __('Left Bottom', 'fl-builder'),
177
- 'right top' => __('Right Top', 'fl-builder'),
178
- 'right center' => __('Right Center', 'fl-builder'),
179
- 'right bottom' => __('Right Bottom', 'fl-builder'),
180
- 'center top' => __('Center Top', 'fl-builder'),
181
  'center center' => __( 'Center', 'fl-builder' ),
182
- 'center bottom' => __('Center Bottom', 'fl-builder')
183
  ),
184
- 'help' => __('Position will tell the image where it should sit in the background.', 'fl-builder'),
185
  'preview' => array(
186
- 'type' => 'none'
187
- )
188
  ),
189
  'bg_attachment' => array(
190
  'type' => 'select',
191
- 'label' => __('Attachment', 'fl-builder'),
192
  'default' => 'scroll',
193
  'options' => array(
194
  'scroll' => __( 'Scroll', 'fl-builder' ),
195
- 'fixed' => __( 'Fixed', 'fl-builder' )
196
  ),
197
- 'help' => __('Attachment will specify how the image reacts when scrolling a page. When scrolling is selected, the image will scroll with page scrolling. This is the default setting. Fixed will allow the image to scroll within the background if fill is selected in the scale setting.', 'fl-builder'),
198
  'preview' => array(
199
- 'type' => 'none'
200
- )
201
  ),
202
  'bg_size' => array(
203
  'type' => 'select',
204
- 'label' => __('Scale', 'fl-builder'),
205
  'default' => 'cover',
206
  'options' => array(
207
  'auto' => _x( 'None', 'Background scale.', 'fl-builder' ),
208
- 'contain' => __( 'Fit', 'fl-builder'),
209
- 'cover' => __( 'Fill', 'fl-builder')
210
  ),
211
- 'help' => __('Scale applies to how the image should display in the background. You can select either fill or fit to the background.', 'fl-builder'),
212
  'preview' => array(
213
- 'type' => 'none'
214
- )
215
- )
216
- )
217
  ),
218
  'bg_overlay' => array(
219
- 'title' => __('Background Overlay', 'fl-builder'),
220
  'fields' => array(
221
  'bg_overlay_color' => array(
222
  'type' => 'color',
223
- 'label' => __('Overlay Color', 'fl-builder'),
224
  'show_reset' => true,
225
  'preview' => array(
226
- 'type' => 'none'
227
- )
228
  ),
229
  'bg_overlay_opacity' => array(
230
  'type' => 'text',
231
- 'label' => __('Overlay Opacity', 'fl-builder'),
232
  'default' => '50',
233
  'description' => '%',
234
  'maxlength' => '3',
235
  'size' => '5',
236
  'preview' => array(
237
- 'type' => 'none'
238
- )
239
- )
240
- )
241
  ),
242
  'border' => array(
243
- 'title' => __('Border', 'fl-builder'),
244
  'fields' => array(
245
  'border_type' => array(
246
  'type' => 'select',
247
- 'label' => __('Type', 'fl-builder'),
248
  'default' => '',
249
- 'help' => __('The type of border to use. Double borders must have a width of at least 3px to render properly.', 'fl-builder'),
250
  'options' => array(
251
  '' => _x( 'None', 'Border type.', 'fl-builder' ),
252
  'solid' => _x( 'Solid', 'Border type.', 'fl-builder' ),
253
  'dashed' => _x( 'Dashed', 'Border type.', 'fl-builder' ),
254
  'dotted' => _x( 'Dotted', 'Border type.', 'fl-builder' ),
255
- 'double' => _x( 'Double', 'Border type.', 'fl-builder' )
256
  ),
257
  'toggle' => array(
258
  '' => array(
259
- 'fields' => array()
260
  ),
261
  'solid' => array(
262
- 'fields' => array('border_color', 'border_opacity', 'border_top', 'border_bottom', 'border_left', 'border_right')
263
  ),
264
  'dashed' => array(
265
- 'fields' => array('border_color', 'border_opacity', 'border_top', 'border_bottom', 'border_left', 'border_right')
266
  ),
267
  'dotted' => array(
268
- 'fields' => array('border_color', 'border_opacity', 'border_top', 'border_bottom', 'border_left', 'border_right')
269
  ),
270
  'double' => array(
271
- 'fields' => array('border_color', 'border_opacity', 'border_top', 'border_bottom', 'border_left', 'border_right')
272
- )
273
  ),
274
  'preview' => array(
275
- 'type' => 'none'
276
- )
277
  ),
278
  'border_color' => array(
279
  'type' => 'color',
280
- 'label' => __('Color', 'fl-builder'),
281
  'show_reset' => true,
282
  'preview' => array(
283
- 'type' => 'none'
284
- )
285
  ),
286
  'border_opacity' => array(
287
  'type' => 'text',
288
- 'label' => __('Opacity', 'fl-builder'),
289
  'default' => '100',
290
  'description' => '%',
291
  'maxlength' => '3',
292
  'size' => '5',
293
  'preview' => array(
294
- 'type' => 'none'
295
- )
296
  ),
297
  'border_top' => array(
298
  'type' => 'unit',
@@ -307,8 +307,8 @@ FLBuilder::register_settings_form('col', array(
307
  'default' => '0',
308
  'medium' => '',
309
  'responsive' => '',
310
- )
311
- )
312
  ),
313
  'border_bottom' => array(
314
  'type' => 'unit',
@@ -323,8 +323,8 @@ FLBuilder::register_settings_form('col', array(
323
  'default' => '0',
324
  'medium' => '',
325
  'responsive' => '',
326
- )
327
- )
328
  ),
329
  'border_left' => array(
330
  'type' => 'unit',
@@ -339,8 +339,8 @@ FLBuilder::register_settings_form('col', array(
339
  'default' => '0',
340
  'medium' => '',
341
  'responsive' => '',
342
- )
343
- )
344
  ),
345
  'border_right' => array(
346
  'type' => 'unit',
@@ -355,18 +355,18 @@ FLBuilder::register_settings_form('col', array(
355
  'default' => '0',
356
  'medium' => '',
357
  'responsive' => '',
358
- )
359
- )
360
  ),
361
  ),
362
  ),
363
- )
364
  ),
365
  'advanced' => array(
366
- 'title' => __('Advanced', 'fl-builder'),
367
  'sections' => array(
368
  'margins' => array(
369
- 'title' => __('Margins', 'fl-builder'),
370
  'fields' => array(
371
  'margin_top' => array(
372
  'type' => 'unit',
@@ -376,7 +376,7 @@ FLBuilder::register_settings_form('col', array(
376
  'type' => 'none',
377
  ),
378
  'placeholder' => '0',
379
- 'responsive' => true
380
  ),
381
  'margin_bottom' => array(
382
  'type' => 'unit',
@@ -386,7 +386,7 @@ FLBuilder::register_settings_form('col', array(
386
  'type' => 'none',
387
  ),
388
  'placeholder' => '0',
389
- 'responsive' => true
390
  ),
391
  'margin_left' => array(
392
  'type' => 'unit',
@@ -396,7 +396,7 @@ FLBuilder::register_settings_form('col', array(
396
  'type' => 'none',
397
  ),
398
  'placeholder' => '0',
399
- 'responsive' => true
400
  ),
401
  'margin_right' => array(
402
  'type' => 'unit',
@@ -406,12 +406,12 @@ FLBuilder::register_settings_form('col', array(
406
  'type' => 'none',
407
  ),
408
  'placeholder' => '0',
409
- 'responsive' => true
410
  ),
411
  ),
412
  ),
413
  'padding' => array(
414
- 'title' => __('Padding', 'fl-builder'),
415
  'fields' => array(
416
  'padding_top' => array(
417
  'type' => 'unit',
@@ -421,7 +421,7 @@ FLBuilder::register_settings_form('col', array(
421
  'type' => 'none',
422
  ),
423
  'placeholder' => '0',
424
- 'responsive' => true
425
  ),
426
  'padding_bottom' => array(
427
  'type' => 'unit',
@@ -431,7 +431,7 @@ FLBuilder::register_settings_form('col', array(
431
  'type' => 'none',
432
  ),
433
  'placeholder' => '0',
434
- 'responsive' => true
435
  ),
436
  'padding_left' => array(
437
  'type' => 'unit',
@@ -441,7 +441,7 @@ FLBuilder::register_settings_form('col', array(
441
  'type' => 'none',
442
  ),
443
  'placeholder' => '0',
444
- 'responsive' => true
445
  ),
446
  'padding_right' => array(
447
  'type' => 'unit',
@@ -451,73 +451,73 @@ FLBuilder::register_settings_form('col', array(
451
  'type' => 'none',
452
  ),
453
  'placeholder' => '0',
454
- 'responsive' => true
455
  ),
456
  ),
457
  ),
458
  'responsive' => array(
459
- 'title' => __('Responsive Layout', 'fl-builder'),
460
  'fields' => array(
461
  'responsive_display' => array(
462
  'type' => 'select',
463
- 'label' => __('Display', 'fl-builder'),
464
  'options' => array(
465
- '' => __('Always', 'fl-builder'),
466
- 'desktop' => __('Large Devices Only', 'fl-builder'),
467
- 'desktop-medium' => __('Large &amp; Medium Devices Only', 'fl-builder'),
468
- 'medium' => __('Medium Devices Only', 'fl-builder'),
469
- 'medium-mobile' => __('Medium &amp; Small Devices Only', 'fl-builder'),
470
- 'mobile' => __('Small Devices Only', 'fl-builder'),
471
  ),
472
  'help' => __( 'Choose whether to show or hide this column at different device sizes.', 'fl-builder' ),
473
  'preview' => array(
474
- 'type' => 'none'
475
- )
476
  ),
477
  'medium_size' => array(
478
  'type' => 'select',
479
- 'label' => __('Medium Device Width', 'fl-builder'),
480
  'help' => __( 'The width of this column on medium devices such as tablets.', 'fl-builder' ),
481
  'options' => array(
482
- 'default' => __('Default', 'fl-builder'),
483
- 'custom' => __('Custom', 'fl-builder'),
484
  ),
485
  'toggle' => array(
486
  'custom' => array(
487
- 'fields' => array('custom_medium_size')
488
- )
489
  ),
490
  'preview' => array(
491
- 'type' => 'none'
492
- )
493
  ),
494
  'custom_medium_size' => array(
495
  'type' => 'text',
496
- 'label' => __('Custom Medium Device Width', 'fl-builder'),
497
  'default' => '100',
498
  'description' => '%',
499
  'maxlength' => '5',
500
  'size' => '6',
501
  'preview' => array(
502
- 'type' => 'none'
503
- )
504
  ),
505
  'responsive_size' => array(
506
  'type' => 'select',
507
- 'label' => __('Small Device Width', 'fl-builder'),
508
  'help' => __( 'The width of this column on small devices such as phones.', 'fl-builder' ),
509
  'options' => array(
510
- 'default' => __('Default', 'fl-builder'),
511
- 'custom' => __('Custom', 'fl-builder'),
512
  ),
513
  'toggle' => array(
514
  'custom' => array(
515
- 'fields' => array('custom_responsive_size')
516
- )
517
  ),
518
  'preview' => array(
519
- 'type' => 'none'
520
- )
521
  ),
522
  'custom_responsive_size' => array(
523
  'type' => 'text',
@@ -527,77 +527,77 @@ FLBuilder::register_settings_form('col', array(
527
  'maxlength' => '5',
528
  'size' => '6',
529
  'preview' => array(
530
- 'type' => 'none'
531
- )
532
  ),
533
  'responsive_order' => array(
534
  'type' => 'select',
535
- 'label' => __('Stacking Order', 'fl-builder'),
536
  'help' => __( 'The order of the columns in this group when they are stacked for small devices.', 'fl-builder' ),
537
  'default' => 'default',
538
  'options' => array(
539
- 'default' => __('Default', 'fl-builder'),
540
- 'reversed' => __('Reversed', 'fl-builder'),
541
  ),
542
  'preview' => array(
543
- 'type' => 'none'
544
- )
545
- )
546
- )
547
  ),
548
  'visibility' => array(
549
- 'title' => __('Visibility', 'fl-builder'),
550
  'fields' => array(
551
  'visibility_display' => array(
552
  'type' => 'select',
553
- 'label' => __('Display', 'fl-builder'),
554
  'options' => array(
555
- '' => __('Always', 'fl-builder'),
556
- 'logged_out' => __('Logged Out User', 'fl-builder'),
557
- 'logged_in' => __('Logged In User', 'fl-builder'),
558
- '0' => __('Never', 'fl-builder'),
559
  ),
560
  'toggle' => array(
561
  'logged_in' => array(
562
- 'fields' => array('visibility_user_capability')
563
- )
564
  ),
565
  'preview' => array(
566
- 'type' => 'none'
567
- )
568
  ),
569
  'visibility_user_capability' => array(
570
  'type' => 'text',
571
- 'label' => __('User Capability', 'fl-builder'),
572
  'description' => sprintf( __( 'Optional. Set the <a%s>capability</a> required for users to view this column.', 'fl-builder' ), ' href="http://codex.wordpress.org/Roles_and_Capabilities#Capability_vs._Role_Table" target="_blank"' ),
573
  'preview' => array(
574
- 'type' => 'none'
575
  ),
576
- )
577
- )
578
  ),
579
  'css_selectors' => array(
580
- 'title' => __('HTML Element', 'fl-builder'),
581
  'fields' => array(
582
  'id' => array(
583
  'type' => 'text',
584
- 'label' => __('ID', 'fl-builder'),
585
  'help' => __( "A unique ID that will be applied to this column's HTML. Must start with a letter and only contain dashes, underscores, letters or numbers. No spaces.", 'fl-builder' ),
586
  'preview' => array(
587
- 'type' => 'none'
588
- )
589
  ),
590
  'class' => array(
591
  'type' => 'text',
592
- 'label' => __('CSS Class', 'fl-builder'),
593
  'help' => __( "A class that will be applied to this column's HTML. Must start with a letter and only contain dashes, underscores, letters or numbers. Separate multiple classes with spaces.", 'fl-builder' ),
594
  'preview' => array(
595
- 'type' => 'none'
596
- )
597
- )
598
- )
599
- )
600
- )
601
- )
602
- )
603
  ));
1
  <?php
2
 
3
  FLBuilder::register_settings_form('col', array(
4
+ 'title' => __( 'Column Settings', 'fl-builder' ),
5
  'tabs' => array(
6
  'style' => array(
7
+ 'title' => __( 'Style', 'fl-builder' ),
8
  'sections' => array(
9
  'general' => array(
10
  'title' => '',
11
  'fields' => array(
12
  'size' => array(
13
  'type' => 'text',
14
+ 'label' => __( 'Column Width', 'fl-builder' ),
15
  'default' => '',
16
  'description' => '%',
17
  'maxlength' => '5',
18
  'size' => '6',
19
  'preview' => array(
20
+ 'type' => 'none',
21
+ ),
22
  ),
23
  'equal_height' => array(
24
  'type' => 'select',
25
+ 'label' => __( 'Equalize Column Heights', 'fl-builder' ),
26
+ 'help' => __( 'Setting this to yes will make all of the columns in this group the same height regardless of how much content is in each of them.', 'fl-builder' ),
27
  'default' => 'no',
28
  'options' => array(
29
  'no' => __( 'No', 'fl-builder' ),
31
  ),
32
  'toggle' => array(
33
  'yes' => array(
34
+ 'fields' => array( 'content_alignment' ),
35
+ ),
36
  ),
37
  'preview' => array(
38
+ 'type' => 'none',
39
+ ),
40
  ),
41
  'content_alignment' => array(
42
  'type' => 'select',
43
+ 'label' => __( 'Content Alignment', 'fl-builder' ),
44
  'default' => 'top',
45
  'options' => array(
46
  'top' => __( 'Top', 'fl-builder' ),
48
  'bottom' => __( 'Bottom', 'fl-builder' ),
49
  ),
50
  'preview' => array(
51
+ 'type' => 'none',
52
+ ),
53
+ ),
54
+ ),
55
  ),
56
  'text' => array(
57
+ 'title' => __( 'Text', 'fl-builder' ),
58
  'fields' => array(
59
  'text_color' => array(
60
  'type' => 'color',
61
+ 'label' => __( 'Color', 'fl-builder' ),
62
  'show_reset' => true,
63
  'preview' => array(
64
+ 'type' => 'none',
65
+ ),
66
  ),
67
  'link_color' => array(
68
  'type' => 'color',
69
+ 'label' => __( 'Link Color', 'fl-builder' ),
70
  'show_reset' => true,
71
  'preview' => array(
72
+ 'type' => 'none',
73
+ ),
74
  ),
75
  'hover_color' => array(
76
  'type' => 'color',
77
+ 'label' => __( 'Link Hover Color', 'fl-builder' ),
78
  'show_reset' => true,
79
  'preview' => array(
80
+ 'type' => 'none',
81
+ ),
82
  ),
83
  'heading_color' => array(
84
  'type' => 'color',
85
+ 'label' => __( 'Heading Color', 'fl-builder' ),
86
  'show_reset' => true,
87
  'preview' => array(
88
+ 'type' => 'none',
89
+ ),
90
+ ),
91
+ ),
92
  ),
93
  'background' => array(
94
+ 'title' => __( 'Background', 'fl-builder' ),
95
  'fields' => array(
96
  'bg_type' => array(
97
  'type' => 'select',
98
+ 'label' => __( 'Type', 'fl-builder' ),
99
  'default' => 'color',
100
  'options' => array(
101
  'none' => _x( 'None', 'Background type.', 'fl-builder' ),
104
  ),
105
  'toggle' => array(
106
  'color' => array(
107
+ 'sections' => array( 'bg_color' ),
108
  ),
109
  'photo' => array(
110
+ 'sections' => array( 'bg_photo', 'bg_overlay' ),
111
  ),
112
  ),
113
  'preview' => array(
114
+ 'type' => 'none',
115
+ ),
116
+ ),
117
+ ),
118
  ),
119
  'bg_color' => array(
120
+ 'title' => __( 'Background Color', 'fl-builder' ),
121
  'fields' => array(
122
  'bg_color' => array(
123
  'type' => 'color',
124
+ 'label' => __( 'Color', 'fl-builder' ),
125
  'show_reset' => true,
126
  'preview' => array(
127
+ 'type' => 'none',
128
+ ),
129
  ),
130
  'bg_opacity' => array(
131
  'type' => 'text',
132
+ 'label' => __( 'Opacity', 'fl-builder' ),
133
  'default' => '100',
134
  'description' => '%',
135
  'maxlength' => '3',
136
  'size' => '5',
137
  'preview' => array(
138
+ 'type' => 'none',
139
+ ),
140
+ ),
141
+ ),
142
  ),
143
  'bg_photo' => array(
144
+ 'title' => __( 'Background Photo', 'fl-builder' ),
145
  'fields' => array(
146
  'bg_image' => array(
147
  'type' => 'photo',
148
+ 'label' => __( 'Photo', 'fl-builder' ),
149
  'preview' => array(
150
+ 'type' => 'none',
151
  ),
152
+ 'connections' => array( 'photo' ),
153
  ),
154
  'bg_repeat' => array(
155
  'type' => 'select',
156
+ 'label' => __( 'Repeat', 'fl-builder' ),
157
  'default' => 'none',
158
  'options' => array(
159
  'no-repeat' => _x( 'None', 'Background repeat.', 'fl-builder' ),
160
  'repeat' => _x( 'Tile', 'Background repeat.', 'fl-builder' ),
161
  'repeat-x' => _x( 'Horizontal', 'Background repeat.', 'fl-builder' ),
162
+ 'repeat-y' => _x( 'Vertical', 'Background repeat.', 'fl-builder' ),
163
  ),
164
+ 'help' => __( 'Repeat applies to how the image should display in the background. Choosing none will display the image as uploaded. Tile will repeat the image as many times as needed to fill the background horizontally and vertically. You can also specify the image to only repeat horizontally or vertically.', 'fl-builder' ),
165
  'preview' => array(
166
+ 'type' => 'none',
167
+ ),
168
  ),
169
  'bg_position' => array(
170
  'type' => 'select',
171
+ 'label' => __( 'Position', 'fl-builder' ),
172
  'default' => 'center center',
173
  'options' => array(
174
+ 'left top' => __( 'Left Top', 'fl-builder' ),
175
+ 'left center' => __( 'Left Center', 'fl-builder' ),
176
+ 'left bottom' => __( 'Left Bottom', 'fl-builder' ),
177
+ 'right top' => __( 'Right Top', 'fl-builder' ),
178
+ 'right center' => __( 'Right Center', 'fl-builder' ),
179
+ 'right bottom' => __( 'Right Bottom', 'fl-builder' ),
180
+ 'center top' => __( 'Center Top', 'fl-builder' ),
181
  'center center' => __( 'Center', 'fl-builder' ),
182
+ 'center bottom' => __( 'Center Bottom', 'fl-builder' ),
183
  ),
184
+ 'help' => __( 'Position will tell the image where it should sit in the background.', 'fl-builder' ),
185
  'preview' => array(
186
+ 'type' => 'none',
187
+ ),
188
  ),
189
  'bg_attachment' => array(
190
  'type' => 'select',
191
+ 'label' => __( 'Attachment', 'fl-builder' ),
192
  'default' => 'scroll',
193
  'options' => array(
194
  'scroll' => __( 'Scroll', 'fl-builder' ),
195
+ 'fixed' => __( 'Fixed', 'fl-builder' ),
196
  ),
197
+ 'help' => __( 'Attachment will specify how the image reacts when scrolling a page. When scrolling is selected, the image will scroll with page scrolling. This is the default setting. Fixed will allow the image to scroll within the background if fill is selected in the scale setting.', 'fl-builder' ),
198
  'preview' => array(
199
+ 'type' => 'none',
200
+ ),
201
  ),
202
  'bg_size' => array(
203
  'type' => 'select',
204
+ 'label' => __( 'Scale', 'fl-builder' ),
205
  'default' => 'cover',
206
  'options' => array(
207
  'auto' => _x( 'None', 'Background scale.', 'fl-builder' ),
208
+ 'contain' => __( 'Fit', 'fl-builder' ),
209
+ 'cover' => __( 'Fill', 'fl-builder' ),
210
  ),
211
+ 'help' => __( 'Scale applies to how the image should display in the background. You can select either fill or fit to the background.', 'fl-builder' ),
212
  'preview' => array(
213
+ 'type' => 'none',
214
+ ),
215
+ ),
216
+ ),
217
  ),
218
  'bg_overlay' => array(
219
+ 'title' => __( 'Background Overlay', 'fl-builder' ),
220
  'fields' => array(
221
  'bg_overlay_color' => array(
222
  'type' => 'color',
223
+ 'label' => __( 'Overlay Color', 'fl-builder' ),
224
  'show_reset' => true,
225
  'preview' => array(
226
+ 'type' => 'none',
227
+ ),
228
  ),
229
  'bg_overlay_opacity' => array(
230
  'type' => 'text',
231
+ 'label' => __( 'Overlay Opacity', 'fl-builder' ),
232
  'default' => '50',
233
  'description' => '%',
234
  'maxlength' => '3',
235
  'size' => '5',
236
  'preview' => array(
237
+ 'type' => 'none',
238
+ ),
239
+ ),
240
+ ),
241
  ),
242
  'border' => array(
243
+ 'title' => __( 'Border', 'fl-builder' ),
244
  'fields' => array(
245
  'border_type' => array(
246
  'type' => 'select',
247
+ 'label' => __( 'Type', 'fl-builder' ),
248
  'default' => '',
249
+ 'help' => __( 'The type of border to use. Double borders must have a width of at least 3px to render properly.', 'fl-builder' ),
250
  'options' => array(
251
  '' => _x( 'None', 'Border type.', 'fl-builder' ),
252
  'solid' => _x( 'Solid', 'Border type.', 'fl-builder' ),
253
  'dashed' => _x( 'Dashed', 'Border type.', 'fl-builder' ),
254
  'dotted' => _x( 'Dotted', 'Border type.', 'fl-builder' ),
255
+ 'double' => _x( 'Double', 'Border type.', 'fl-builder' ),
256
  ),
257
  'toggle' => array(
258
  '' => array(
259
+ 'fields' => array(),
260
  ),
261
  'solid' => array(
262
+ 'fields' => array( 'border_color', 'border_opacity', 'border_top', 'border_bottom', 'border_left', 'border_right' ),
263
  ),
264
  'dashed' => array(
265
+ 'fields' => array( 'border_color', 'border_opacity', 'border_top', 'border_bottom', 'border_left', 'border_right' ),
266
  ),
267
  'dotted' => array(
268
+ 'fields' => array( 'border_color', 'border_opacity', 'border_top', 'border_bottom', 'border_left', 'border_right' ),
269
  ),
270
  'double' => array(
271
+ 'fields' => array( 'border_color', 'border_opacity', 'border_top', 'border_bottom', 'border_left', 'border_right' ),
272
+ ),
273
  ),
274
  'preview' => array(
275
+ 'type' => 'none',
276
+ ),
277
  ),
278
  'border_color' => array(
279
  'type' => 'color',
280
+ 'label' => __( 'Color', 'fl-builder' ),
281
  'show_reset' => true,
282
  'preview' => array(
283
+ 'type' => 'none',
284
+ ),
285
  ),
286
  'border_opacity' => array(
287
  'type' => 'text',
288
+ 'label' => __( 'Opacity', 'fl-builder' ),
289
  'default' => '100',
290
  'description' => '%',
291
  'maxlength' => '3',
292
  'size' => '5',
293
  'preview' => array(
294
+ 'type' => 'none',
295
+ ),
296
  ),
297
  'border_top' => array(
298
  'type' => 'unit',
307
  'default' => '0',
308
  'medium' => '',
309
  'responsive' => '',
310
+ ),
311
+ ),
312
  ),
313
  'border_bottom' => array(
314
  'type' => 'unit',
323
  'default' => '0',
324
  'medium' => '',
325
  'responsive' => '',
326
+ ),
327
+ ),
328
  ),
329
  'border_left' => array(
330
  'type' => 'unit',
339
  'default' => '0',
340
  'medium' => '',
341
  'responsive' => '',
342
+ ),
343
+ ),
344
  ),
345
  'border_right' => array(
346
  'type' => 'unit',
355
  'default' => '0',
356
  'medium' => '',
357
  'responsive' => '',
358
+ ),
359
+ ),
360
  ),
361
  ),
362
  ),
363
+ ),
364
  ),
365
  'advanced' => array(
366
+ 'title' => __( 'Advanced', 'fl-builder' ),
367
  'sections' => array(
368
  'margins' => array(
369
+ 'title' => __( 'Margins', 'fl-builder' ),
370
  'fields' => array(
371
  'margin_top' => array(
372
  'type' => 'unit',
376
  'type' => 'none',
377
  ),
378
  'placeholder' => '0',
379
+ 'responsive' => true,
380
  ),
381
  'margin_bottom' => array(
382
  'type' => 'unit',
386
  'type' => 'none',
387
  ),
388
  'placeholder' => '0',
389
+ 'responsive' => true,
390
  ),
391
  'margin_left' => array(
392
  'type' => 'unit',
396
  'type' => 'none',
397
  ),
398
  'placeholder' => '0',
399
+ 'responsive' => true,
400
  ),
401
  'margin_right' => array(
402
  'type' => 'unit',
406
  'type' => 'none',
407
  ),
408
  'placeholder' => '0',
409
+ 'responsive' => true,
410
  ),
411
  ),
412
  ),
413
  'padding' => array(
414
+ 'title' => __( 'Padding', 'fl-builder' ),
415
  'fields' => array(
416
  'padding_top' => array(
417
  'type' => 'unit',
421
  'type' => 'none',
422
  ),
423
  'placeholder' => '0',
424
+ 'responsive' => true,
425
  ),
426
  'padding_bottom' => array(
427
  'type' => 'unit',
431
  'type' => 'none',
432
  ),
433
  'placeholder' => '0',
434
+ 'responsive' => true,
435
  ),
436
  'padding_left' => array(
437
  'type' => 'unit',
441
  'type' => 'none',
442
  ),
443
  'placeholder' => '0',
444
+ 'responsive' => true,
445
  ),
446
  'padding_right' => array(
447
  'type' => 'unit',
451
  'type' => 'none',
452
  ),
453
  'placeholder' => '0',
454
+ 'responsive' => true,
455
  ),
456
  ),
457
  ),
458
  'responsive' => array(
459
+ 'title' => __( 'Responsive Layout', 'fl-builder' ),
460
  'fields' => array(
461
  'responsive_display' => array(
462
  'type' => 'select',
463
+ 'label' => __( 'Display', 'fl-builder' ),
464
  'options' => array(
465
+ '' => __( 'Always', 'fl-builder' ),
466
+ 'desktop' => __( 'Large Devices Only', 'fl-builder' ),
467
+ 'desktop-medium' => __( 'Large &amp; Medium Devices Only', 'fl-builder' ),
468
+ 'medium' => __( 'Medium Devices Only', 'fl-builder' ),
469
+ 'medium-mobile' => __( 'Medium &amp; Small Devices Only', 'fl-builder' ),
470
+ 'mobile' => __( 'Small Devices Only', 'fl-builder' ),
471
  ),
472
  'help' => __( 'Choose whether to show or hide this column at different device sizes.', 'fl-builder' ),
473
  'preview' => array(
474
+ 'type' => 'none',
475
+ ),
476
  ),
477
  'medium_size' => array(
478
  'type' => 'select',
479
+ 'label' => __( 'Medium Device Width', 'fl-builder' ),
480
  'help' => __( 'The width of this column on medium devices such as tablets.', 'fl-builder' ),
481
  'options' => array(
482
+ 'default' => __( 'Default', 'fl-builder' ),
483
+ 'custom' => __( 'Custom', 'fl-builder' ),
484
  ),
485
  'toggle' => array(
486
  'custom' => array(
487
+ 'fields' => array( 'custom_medium_size' ),
488
+ ),
489
  ),
490
  'preview' => array(
491
+ 'type' => 'none',
492
+ ),
493
  ),
494
  'custom_medium_size' => array(
495
  'type' => 'text',
496
+ 'label' => __( 'Custom Medium Device Width', 'fl-builder' ),
497
  'default' => '100',
498
  'description' => '%',
499
  'maxlength' => '5',
500
  'size' => '6',
501
  'preview' => array(
502
+ 'type' => 'none',
503
+ ),
504
  ),
505
  'responsive_size' => array(
506
  'type' => 'select',
507
+ 'label' => __( 'Small Device Width', 'fl-builder' ),
508
  'help' => __( 'The width of this column on small devices such as phones.', 'fl-builder' ),
509
  'options' => array(
510
+ 'default' => __( 'Default', 'fl-builder' ),
511
+ 'custom' => __( 'Custom', 'fl-builder' ),
512
  ),
513
  'toggle' => array(
514
  'custom' => array(
515
+ 'fields' => array( 'custom_responsive_size' ),
516
+ ),
517
  ),
518
  'preview' => array(
519
+ 'type' => 'none',
520
+ ),
521
  ),
522
  'custom_responsive_size' => array(
523
  'type' => 'text',
527
  'maxlength' => '5',
528
  'size' => '6',
529
  'preview' => array(
530
+ 'type' => 'none',
531
+ ),
532
  ),
533
  'responsive_order' => array(
534
  'type' => 'select',
535
+ 'label' => __( 'Stacking Order', 'fl-builder' ),
536
  'help' => __( 'The order of the columns in this group when they are stacked for small devices.', 'fl-builder' ),
537
  'default' => 'default',
538
  'options' => array(
539
+ 'default' => __( 'Default', 'fl-builder' ),
540
+ 'reversed' => __( 'Reversed', 'fl-builder' ),
541
  ),
542
  'preview' => array(
543
+ 'type' => 'none',
544
+ ),
545
+ ),
546
+ ),
547
  ),
548
  'visibility' => array(
549
+ 'title' => __( 'Visibility', 'fl-builder' ),
550
  'fields' => array(
551
  'visibility_display' => array(
552
  'type' => 'select',
553
+ 'label' => __( 'Display', 'fl-builder' ),
554
  'options' => array(
555
+ '' => __( 'Always', 'fl-builder' ),
556
+ 'logged_out' => __( 'Logged Out User', 'fl-builder' ),
557
+ 'logged_in' => __( 'Logged In User', 'fl-builder' ),
558
+ '0' => __( 'Never', 'fl-builder' ),
559
  ),
560
  'toggle' => array(
561
  'logged_in' => array(
562
+ 'fields' => array( 'visibility_user_capability' ),
563
+ ),
564
  ),
565
  'preview' => array(
566
+ 'type' => 'none',
567
+ ),
568
  ),
569
  'visibility_user_capability' => array(
570
  'type' => 'text',
571
+ 'label' => __( 'User Capability', 'fl-builder' ),
572
  'description' => sprintf( __( 'Optional. Set the <a%s>capability</a> required for users to view this column.', 'fl-builder' ), ' href="http://codex.wordpress.org/Roles_and_Capabilities#Capability_vs._Role_Table" target="_blank"' ),
573
  'preview' => array(
574
+ 'type' => 'none',
575
  ),
576
+ ),
577
+ ),
578
  ),
579
  'css_selectors' => array(
580
+ 'title' => __( 'HTML Element', 'fl-builder' ),
581
  'fields' => array(
582
  'id' => array(
583
  'type' => 'text',
584
+ 'label' => __( 'ID', 'fl-builder' ),
585
  'help' => __( "A unique ID that will be applied to this column's HTML. Must start with a letter and only contain dashes, underscores, letters or numbers. No spaces.", 'fl-builder' ),
586
  'preview' => array(
587
+ 'type' => 'none',
588
+ ),
589
  ),
590
  'class' => array(
591
  'type' => 'text',
592
+ 'label' => __( 'CSS Class', 'fl-builder' ),
593
  'help' => __( "A class that will be applied to this column's HTML. Must start with a letter and only contain dashes, underscores, letters or numbers. Separate multiple classes with spaces.", 'fl-builder' ),
594
  'preview' => array(
595
+ 'type' => 'none',
596
+ ),
597
+ ),
598
+ ),
599
+ ),
600
+ ),
601
+ ),
602
+ ),
603
  ));
includes/column.php CHANGED
@@ -2,4 +2,4 @@
2
  <div class="fl-col-content fl-node-content">
3
  <?php FLBuilder::render_modules( $col ); ?>
4
  </div>
5
- </div>
2
  <div class="fl-col-content fl-node-content">
3
  <?php FLBuilder::render_modules( $col ); ?>
4
  </div>
5
+ </div>
includes/compatibility.php CHANGED
@@ -12,14 +12,14 @@
12
  function fl_builder_tinypng_support( $cropped_path ) {
13
 
14
  if ( class_exists( 'Tiny_Settings' ) ) {
15
- try{
16
  $settings = new Tiny_Settings();
17
  $settings->xmlrpc_init();
18
  $compressor = $settings->get_compressor();
19
  if ( $compressor ) {
20
  $compressor->compress_file( $cropped_path['path'], false, false );
21
  }
22
- } catch( Exception $e ) {
23
  //
24
  }
25
  }
@@ -42,9 +42,8 @@ function fl_builder_wc_memberships_support() {
42
  // check if user has access to restricted content
43
  if ( ! current_user_can( 'wc_memberships_view_restricted_post_content', $post_id ) ) {
44
  $do_render = false;
45
- }
46
- // check if user has access to delayed content
47
- else if ( ! current_user_can( 'wc_memberships_view_delayed_post_content', $post_id ) ) {
48
  $do_render = false;
49
  }
50
  }
@@ -65,33 +64,33 @@ add_action( 'plugins_loaded', 'fl_builder_wc_memberships_support', 11 );
65
  */
66
  function fl_builder_option_tree_support() {
67
 
68
- if ( !function_exists( 'ot_get_media_post_ID' ) ) {
69
 
70
- function ot_get_media_post_ID() {
71
 
72
  // Option ID
73
  $option_id = 'ot_media_post_ID';
74
 
75
  // Get the media post ID
76
- $post_ID = get_option( $option_id, false );
77
 
78
  // Add $post_ID to the DB
79
- if ( $post_ID === false ) {
80
 
81
  global $wpdb;
82
 
83
  // Get the media post ID
84
- $post_ID = $wpdb->get_var( "SELECT ID FROM $wpdb->posts WHERE `post_title` = 'Media' AND `post_type` = 'option-tree' AND `post_status` = 'private'" );
85
 
86
  // Add to the DB
87
- add_option( $option_id, $post_ID );
88
  }
89
 
90
- return $post_ID;
91
  }
92
  }
93
  }
94
- add_action('after_setup_theme', 'fl_builder_option_tree_support');
95
 
96
  /**
97
  * If FORCE_SSL_ADMIN is enabled but the frontend is not SSL fixes a CORS error when trying to upload a photo.
@@ -100,9 +99,9 @@ add_action('after_setup_theme', 'fl_builder_option_tree_support');
100
  * @since 1.10.2
101
  */
102
  function fl_admin_ssl_upload_fix() {
103
- if( defined( 'FORCE_SSL_ADMIN' ) && ! is_ssl() && is_admin() && defined( 'DOING_AJAX' ) && DOING_AJAX ) {
104
- if( isset( $_POST['action'] ) && 'upload-attachment' === $_POST['action'] && true === apply_filters( 'fl_admin_ssl_upload_fix', true ) ) {
105
- force_ssl_admin(false);
106
  }
107
  }
108
  }
@@ -115,10 +114,10 @@ add_action( 'plugins_loaded', 'fl_admin_ssl_upload_fix', 11 );
115
  * @param $post The post to check from
116
  * @return bool
117
  */
118
- function fl_builder_bp_pages_support( $is_editable, $post = false ){
119
 
120
  // Frontend check
121
- if ( !is_admin() && class_exists( 'BuddyPress' ) && ! bp_is_blog_page() ) {
122
  $is_editable = false;
123
  }
124
 
@@ -127,7 +126,7 @@ function fl_builder_bp_pages_support( $is_editable, $post = false ){
127
 
128
  $bp = buddypress();
129
  if ( $bp->pages ) {
130
- foreach( $bp->pages as $page ) {
131
  if ( $post->ID == $page->id ) {
132
  $is_editable = false;
133
  break;
@@ -151,10 +150,9 @@ function fl_photo_photon_exception( $val, $src, $tag ) {
151
  if ( false !== strpos( $src, 'bb-plugin/cache' ) ) {
152
 
153
  // now make sure its a circle cropped image.
154
- if( false !== strpos( basename( $src ), '-circle' ) ) {
155
  return apply_filters( 'fl_photo_photon_exception', true );
156
  }
157
-
158
  }
159
  // return original val
160
  return $val;
@@ -166,14 +164,14 @@ add_filter( 'jetpack_photon_skip_image', 'fl_photo_photon_exception', 10, 3 );
166
  */
167
  function fl_before_sortable_enqueue_callback() {
168
 
169
- if(version_compare( get_bloginfo( 'version' ), '4.5', '<') ) {
170
- wp_deregister_script( 'jquery-ui-widget' );
171
- wp_deregister_script( 'jquery-ui-mouse' );
172
- wp_deregister_script( 'jquery-ui-core' );
173
- wp_enqueue_script( 'jquery-ui-core', site_url( '/wp-includes/js/jquery/ui/core.min.js' ), array('jquery'), '1.8.12' );
174
- wp_enqueue_script( 'jquery-ui-widget', site_url( '/wp-includes/js/jquery/ui/widget.min.js' ), array('jquery'), '1.8.12' );
175
- wp_enqueue_script( 'jquery-ui-mouse', site_url( '/wp-includes/js/jquery/ui/mouse.min.js' ), array('jquery'), '1.8.12' );
176
- }
177
  }
178
  add_action( 'fl_before_sortable_enqueue', 'fl_before_sortable_enqueue_callback' );
179
 
@@ -189,7 +187,7 @@ function fl_maybe_fix_unserialize( $data ) {
189
  // @codingStandardsIgnoreStart
190
  $unserialized = @unserialize( $data );
191
  // @codingStandardsIgnoreEnd
192
- if( ! $unserialized ) {
193
  $unserialized = unserialize( preg_replace_callback( '!s:(\d+):"(.*?)";!', 'fl_maybe_fix_unserialize_callback', $data ) );
194
  }
195
  return $unserialized;
@@ -201,5 +199,19 @@ function fl_maybe_fix_unserialize( $data ) {
201
  * @since 1.10.6
202
  */
203
  function fl_maybe_fix_unserialize_callback( $match ) {
204
- return ($match[1] == strlen($match[2])) ? $match[0] : 's:' . strlen($match[2]) . ':"' . $match[2] . '";';
205
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12
  function fl_builder_tinypng_support( $cropped_path ) {
13
 
14
  if ( class_exists( 'Tiny_Settings' ) ) {
15
+ try {
16
  $settings = new Tiny_Settings();
17
  $settings->xmlrpc_init();
18
  $compressor = $settings->get_compressor();
19
  if ( $compressor ) {
20
  $compressor->compress_file( $cropped_path['path'], false, false );
21
  }
22
+ } catch ( Exception $e ) {
23
  //
24
  }
25
  }
42
  // check if user has access to restricted content
43
  if ( ! current_user_can( 'wc_memberships_view_restricted_post_content', $post_id ) ) {
44
  $do_render = false;
45
+ } // End if().
46
+ elseif ( ! current_user_can( 'wc_memberships_view_delayed_post_content', $post_id ) ) {
 
47
  $do_render = false;
48
  }
49
  }
64
  */
65
  function fl_builder_option_tree_support() {
66
 
67
+ if ( ! function_exists( 'ot_get_media_post_ID' ) ) {
68
 
69
+ function ot_get_media_post_ID() { // @codingStandardsIgnoreLine
70
 
71
  // Option ID
72
  $option_id = 'ot_media_post_ID';
73
 
74
  // Get the media post ID
75
+ $post_id = get_option( $option_id, false );
76
 
77
  // Add $post_ID to the DB
78
+ if ( false === $post_id ) {
79
 
80
  global $wpdb;
81
 
82
  // Get the media post ID
83
+ $post_id = $wpdb->get_var( "SELECT ID FROM $wpdb->posts WHERE `post_title` = 'Media' AND `post_type` = 'option-tree' AND `post_status` = 'private'" );
84
 
85
  // Add to the DB
86
+ add_option( $option_id, $post_id );
87
  }
88
 
89
+ return $post_id;
90
  }
91
  }
92
  }
93
+ add_action( 'after_setup_theme', 'fl_builder_option_tree_support' );
94
 
95
  /**
96
  * If FORCE_SSL_ADMIN is enabled but the frontend is not SSL fixes a CORS error when trying to upload a photo.
99
  * @since 1.10.2
100
  */
101
  function fl_admin_ssl_upload_fix() {
102
+ if ( defined( 'FORCE_SSL_ADMIN' ) && ! is_ssl() && is_admin() && defined( 'DOING_AJAX' ) && DOING_AJAX ) {
103
+ if ( isset( $_POST['action'] ) && 'upload-attachment' === $_POST['action'] && true === apply_filters( 'fl_admin_ssl_upload_fix', true ) ) {
104
+ force_ssl_admin( false );
105
  }
106
  }
107
  }
114
  * @param $post The post to check from
115
  * @return bool
116
  */
117
+ function fl_builder_bp_pages_support( $is_editable, $post = false ) {
118
 
119
  // Frontend check
120
+ if ( ! is_admin() && class_exists( 'BuddyPress' ) && ! bp_is_blog_page() ) {
121
  $is_editable = false;
122
  }
123
 
126
 
127
  $bp = buddypress();
128
  if ( $bp->pages ) {
129
+ foreach ( $bp->pages as $page ) {
130
  if ( $post->ID == $page->id ) {
131
  $is_editable = false;
132
  break;
150
  if ( false !== strpos( $src, 'bb-plugin/cache' ) ) {
151
 
152
  // now make sure its a circle cropped image.
153
+ if ( false !== strpos( basename( $src ), '-circle' ) ) {
154
  return apply_filters( 'fl_photo_photon_exception', true );
155
  }
 
156
  }
157
  // return original val
158
  return $val;
164
  */
165
  function fl_before_sortable_enqueue_callback() {
166
 
167
+ if ( version_compare( get_bloginfo( 'version' ), '4.5', '<' ) ) {
168
+ wp_deregister_script( 'jquery-ui-widget' );
169
+ wp_deregister_script( 'jquery-ui-mouse' );
170
+ wp_deregister_script( 'jquery-ui-core' );
171
+ wp_enqueue_script( 'jquery-ui-core', site_url( '/wp-includes/js/jquery/ui/core.min.js' ), array( 'jquery' ), '1.8.12' );
172
+ wp_enqueue_script( 'jquery-ui-widget', site_url( '/wp-includes/js/jquery/ui/widget.min.js' ), array( 'jquery' ), '1.8.12' );
173
+ wp_enqueue_script( 'jquery-ui-mouse', site_url( '/wp-includes/js/jquery/ui/mouse.min.js' ), array( 'jquery' ), '1.8.12' );
174
+ }
175
  }
176
  add_action( 'fl_before_sortable_enqueue', 'fl_before_sortable_enqueue_callback' );
177
 
187
  // @codingStandardsIgnoreStart
188
  $unserialized = @unserialize( $data );
189
  // @codingStandardsIgnoreEnd
190
+ if ( ! $unserialized ) {
191
  $unserialized = unserialize( preg_replace_callback( '!s:(\d+):"(.*?)";!', 'fl_maybe_fix_unserialize_callback', $data ) );
192
  }
193
  return $unserialized;
199
  * @since 1.10.6
200
  */
201
  function fl_maybe_fix_unserialize_callback( $match ) {
202
+ return ( strlen( $match[2] ) == $match[1] ) ? $match[0] : 's:' . strlen( $match[2] ) . ':"' . $match[2] . '";';
203
  }
204
+
205
+ /**
206
+ * Filter rendered module content and if safemode is active safely display a message.
207
+ * @since 1.10.7
208
+ */
209
+ function fl_builder_render_module_content_filter( $contents, $module ) {
210
+ if ( isset( $_GET['safemode'] ) && FLBuilderModel::is_builder_active() ) {
211
+ return sprintf( '<h3>[%1$s] %2$s %3$s</h3>', __( 'SAFEMODE', 'fl-builder' ), $module->name, __( 'module', 'fl-builder' ) );
212
+ } else {
213
+ return $contents;
214
+ }
215
+ }
216
+
217
+ add_filter( 'fl_builder_render_module_content', 'fl_builder_render_module_content_filter', 10, 2 );
includes/export-filters.php CHANGED
@@ -5,4 +5,4 @@
5
  </select>
6
  <span class="spinner"></span>
7
  <div id="fl-builder-template-export-posts"></div>
8
- </div>
5
  </select>
6
  <span class="spinner"></span>
7
  <div id="fl-builder-template-export-posts"></div>
8
+ </div>
includes/export.php CHANGED
@@ -19,7 +19,7 @@
19
  */
20
  function fl_export_wp( $post_ids = array() ) {
21
  global $wpdb, $post;
22
-
23
  if ( empty( $post_ids ) ) {
24
  return;
25
  }
@@ -72,11 +72,11 @@ function fl_export_wp( $post_ids = array() ) {
72
  */
73
  function wxr_site_url() {
74
  // Multisite: the base URL.
75
- if ( is_multisite() )
76
  return network_home_url();
77
- // WordPress (single site): the blog URL.
78
- else
79
- return get_bloginfo_rss( 'url' );
80
  }
81
 
82
  /**
@@ -87,8 +87,9 @@ function fl_export_wp( $post_ids = array() ) {
87
  * @param object $category Category Object
88
  */
89
  function wxr_cat_name( $category ) {
90
- if ( empty( $category->name ) )
91
  return;
 
92
 
93
  echo '<wp:cat_name>' . wxr_cdata( $category->name ) . '</wp:cat_name>';
94
  }
@@ -101,8 +102,9 @@ function fl_export_wp( $post_ids = array() ) {
101
  * @param object $category Category Object
102
  */
103
  function wxr_category_description( $category ) {
104
- if ( empty( $category->description ) )
105
  return;
 
106
 
107
  echo '<wp:category_description>' . wxr_cdata( $category->description ) . '</wp:category_description>';
108
  }
@@ -115,8 +117,9 @@ function fl_export_wp( $post_ids = array() ) {
115
  * @param object $tag Tag Object
116
  */
117
  function wxr_tag_name( $tag ) {
118
- if ( empty( $tag->name ) )
119
  return;
 
120
 
121
  echo '<wp:tag_name>' . wxr_cdata( $tag->name ) . '</wp:tag_name>';
122
  }
@@ -129,8 +132,9 @@ function fl_export_wp( $post_ids = array() ) {
129
  * @param object $tag Tag Object
130
  */
131
  function wxr_tag_description( $tag ) {
132
- if ( empty( $tag->description ) )
133
  return;
 
134
 
135
  echo '<wp:tag_description>' . wxr_cdata( $tag->description ) . '</wp:tag_description>';
136
  }
@@ -143,8 +147,9 @@ function fl_export_wp( $post_ids = array() ) {
143
  * @param object $term Term Object
144
  */
145
  function wxr_term_name( $term ) {
146
- if ( empty( $term->name ) )
147
  return;
 
148
 
149
  echo '<wp:term_name>' . wxr_cdata( $term->name ) . '</wp:term_name>';
150
  }
@@ -157,8 +162,9 @@ function fl_export_wp( $post_ids = array() ) {
157
  * @param object $term Term Object
158
  */
159
  function wxr_term_description( $term ) {
160
- if ( empty( $term->description ) )
161
  return;
 
162
 
163
  echo '<wp:term_description>' . wxr_cdata( $term->description ) . '</wp:term_description>';
164
  }
@@ -175,7 +181,7 @@ function fl_export_wp( $post_ids = array() ) {
175
  function wxr_authors_list( array $post_ids = null ) {
176
  global $wpdb;
177
 
178
- if ( !empty( $post_ids ) ) {
179
  $post_ids = array_map( 'absint', $post_ids );
180
  $and = 'AND ID IN ( ' . implode( ', ', $post_ids ) . ')';
181
  } else {
@@ -186,8 +192,9 @@ function fl_export_wp( $post_ids = array() ) {
186
  // @codingStandardsIgnoreStart
187
  $results = $wpdb->get_results( "SELECT DISTINCT post_author FROM $wpdb->posts WHERE post_status != 'auto-draft' $and" );
188
  // @codingStandardsIgnoreEnd
189
- foreach ( (array) $results as $result )
190
  $authors[] = get_userdata( $result->post_author );
 
191
 
192
  $authors = array_filter( $authors );
193
 
@@ -210,8 +217,9 @@ function fl_export_wp( $post_ids = array() ) {
210
  */
211
  function wxr_nav_menu_terms() {
212
  $nav_menus = wp_get_nav_menus();
213
- if ( empty( $nav_menus ) || ! is_array( $nav_menus ) )
214
  return;
 
215
 
216
  foreach ( $nav_menus as $menu ) {
217
  echo "\t<wp:term>";
@@ -232,8 +240,9 @@ function fl_export_wp( $post_ids = array() ) {
232
  $post = get_post();
233
 
234
  $taxonomies = get_object_taxonomies( $post->post_type );
235
- if ( empty( $taxonomies ) )
236
  return;
 
237
  $terms = wp_get_object_terms( $post->ID, $taxonomies );
238
 
239
  foreach ( (array) $terms as $term ) {
@@ -248,13 +257,14 @@ function fl_export_wp( $post_ids = array() ) {
248
  * @return bool
249
  */
250
  function wxr_filter_postmeta( $return_me, $meta_key ) {
251
- if ( '_edit_lock' == $meta_key )
252
  $return_me = true;
 
253
  return $return_me;
254
  }
255
  add_filter( 'wxr_export_skip_postmeta', 'wxr_filter_postmeta', 10, 2 );
256
 
257
- echo '<?xml version="1.0" encoding="' . get_bloginfo('charset') . "\" ?>\n";
258
 
259
  ?>
260
  <!-- This is a WordPress eXtended RSS file generated by WordPress as an export of your site. -->
@@ -311,17 +321,17 @@ function fl_export_wp( $post_ids = array() ) {
311
 
312
  // Fetch 20 posts at a time rather than loading the entire table into memory.
313
  while ( $next_posts = array_splice( $post_ids, 0, 20 ) ) {
314
- $where = 'WHERE ID IN (' . join( ',', $next_posts ) . ')';
315
  // @codingStandardsIgnoreStart
316
  $posts = $wpdb->get_results( "SELECT * FROM {$wpdb->posts} $where" );
317
  // @codingStandardsIgnoreEnd
318
 
319
- // Begin Loop.
320
- foreach ( $posts as $post ) {
321
- setup_postdata( $post );
322
- $is_sticky = is_sticky( $post->ID ) ? 1 : 0;
323
- ?>
324
- <item>
325
  <title><?php
326
  /** This filter is documented in wp-includes/feed.php */
327
  echo apply_filters( 'the_title_rss', $post->post_title );
@@ -363,11 +373,11 @@ function fl_export_wp( $post_ids = array() ) {
363
  <wp:post_type><?php echo wxr_cdata( $post->post_type ); ?></wp:post_type>
364
  <wp:post_password><?php echo wxr_cdata( $post->post_password ); ?></wp:post_password>
365
  <wp:is_sticky><?php echo intval( $is_sticky ); ?></wp:is_sticky>
366
- <?php if ( $post->post_type == 'attachment' ) : ?>
367
  <wp:attachment_url><?php echo wxr_cdata( wp_get_attachment_url( $post->ID ) ); ?></wp:attachment_url>
368
- <?php endif; ?>
369
- <?php wxr_post_taxonomy(); ?>
370
- <?php $postmeta = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM $wpdb->postmeta WHERE post_id = %d", $post->ID ) );
371
  foreach ( $postmeta as $meta ) :
372
  /**
373
  * Filter whether to selectively skip post meta used for WXR exports.
@@ -381,12 +391,13 @@ function fl_export_wp( $post_ids = array() ) {
381
  * @param string $meta_key Current meta key.
382
  * @param object $meta Current meta object.
383
  */
384
- if ( apply_filters( 'wxr_export_skip_postmeta', false, $meta->meta_key, $meta ) )
385
  continue;
 
386
  ?>
387
  <wp:postmeta>
388
- <wp:meta_key><?php echo wxr_cdata( $meta->meta_key ); ?></wp:meta_key>
389
- <wp:meta_value><?php echo wxr_cdata( $meta->meta_value ); ?></wp:meta_value>
390
  </wp:postmeta>
391
  <?php endforeach;
392
 
@@ -407,8 +418,8 @@ function fl_export_wp( $post_ids = array() ) {
407
  <wp:comment_parent><?php echo intval( $c->comment_parent ); ?></wp:comment_parent>
408
  <wp:comment_user_id><?php echo intval( $c->user_id ); ?></wp:comment_user_id>
409
  <?php $c_meta = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM $wpdb->commentmeta WHERE comment_id = %d", $c->comment_ID ) );
410
- foreach ( $c_meta as $meta ) :
411
- /**
412
  * Filter whether to selectively skip comment meta used for WXR exports.
413
  *
414
  * Returning a truthy value to the filter will skip the current meta
@@ -420,22 +431,23 @@ function fl_export_wp( $post_ids = array() ) {
420
  * @param string $meta_key Current meta key.
421
  * @param object $meta Current meta object.
422
  */
423
- if ( apply_filters( 'wxr_export_skip_commentmeta', false, $meta->meta_key, $meta ) ) {
424
- continue;
425
- }
426
- ?>
427
- <wp:commentmeta>
428
- <wp:meta_key><?php echo wxr_cdata( $meta->meta_key ); ?></wp:meta_key>
429
- <wp:meta_value><?php echo wxr_cdata( $meta->meta_value ); ?></wp:meta_value>
430
- </wp:commentmeta>
431
  <?php endforeach; ?>
432
  </wp:comment>
433
  <?php endforeach; ?>
434
- </item>
435
- <?php
436
- }
437
- }
438
- } ?>
 
439
  </channel>
440
  </rss>
441
  <?php
19
  */
20
  function fl_export_wp( $post_ids = array() ) {
21
  global $wpdb, $post;
22
+
23
  if ( empty( $post_ids ) ) {
24
  return;
25
  }
72
  */
73
  function wxr_site_url() {
74
  // Multisite: the base URL.
75
+ if ( is_multisite() ) {
76
  return network_home_url();
77
+ } // End if().
78
+ else { return get_bloginfo_rss( 'url' );
79
+ }
80
  }
81
 
82
  /**
87
  * @param object $category Category Object
88
  */
89
  function wxr_cat_name( $category ) {
90
+ if ( empty( $category->name ) ) {
91
  return;
92
+ }
93
 
94
  echo '<wp:cat_name>' . wxr_cdata( $category->name ) . '</wp:cat_name>';
95
  }
102
  * @param object $category Category Object
103
  */
104
  function wxr_category_description( $category ) {
105
+ if ( empty( $category->description ) ) {
106
  return;
107
+ }
108
 
109
  echo '<wp:category_description>' . wxr_cdata( $category->description ) . '</wp:category_description>';
110
  }
117
  * @param object $tag Tag Object
118
  */
119
  function wxr_tag_name( $tag ) {
120
+ if ( empty( $tag->name ) ) {
121
  return;
122
+ }
123
 
124
  echo '<wp:tag_name>' . wxr_cdata( $tag->name ) . '</wp:tag_name>';
125
  }
132
  * @param object $tag Tag Object
133
  */
134
  function wxr_tag_description( $tag ) {
135
+ if ( empty( $tag->description ) ) {
136
  return;
137
+ }
138
 
139
  echo '<wp:tag_description>' . wxr_cdata( $tag->description ) . '</wp:tag_description>';
140
  }
147
  * @param object $term Term Object
148
  */
149
  function wxr_term_name( $term ) {
150
+ if ( empty( $term->name ) ) {
151
  return;
152
+ }
153
 
154
  echo '<wp:term_name>' . wxr_cdata( $term->name ) . '</wp:term_name>';
155
  }
162
  * @param object $term Term Object
163
  */
164
  function wxr_term_description( $term ) {
165
+ if ( empty( $term->description ) ) {
166
  return;
167
+ }
168
 
169
  echo '<wp:term_description>' . wxr_cdata( $term->description ) . '</wp:term_description>';
170
  }
181
  function wxr_authors_list( array $post_ids = null ) {
182
  global $wpdb;
183
 
184
+ if ( ! empty( $post_ids ) ) {
185
  $post_ids = array_map( 'absint', $post_ids );
186
  $and = 'AND ID IN ( ' . implode( ', ', $post_ids ) . ')';
187
  } else {
192
  // @codingStandardsIgnoreStart
193
  $results = $wpdb->get_results( "SELECT DISTINCT post_author FROM $wpdb->posts WHERE post_status != 'auto-draft' $and" );
194
  // @codingStandardsIgnoreEnd
195
+ foreach ( (array) $results as $result ) {
196
  $authors[] = get_userdata( $result->post_author );
197
+ }
198
 
199
  $authors = array_filter( $authors );
200
 
217
  */
218
  function wxr_nav_menu_terms() {
219
  $nav_menus = wp_get_nav_menus();
220
+ if ( empty( $nav_menus ) || ! is_array( $nav_menus ) ) {
221
  return;
222
+ }
223
 
224
  foreach ( $nav_menus as $menu ) {
225
  echo "\t<wp:term>";
240
  $post = get_post();
241
 
242
  $taxonomies = get_object_taxonomies( $post->post_type );
243
+ if ( empty( $taxonomies ) ) {
244
  return;
245
+ }
246
  $terms = wp_get_object_terms( $post->ID, $taxonomies );
247
 
248
  foreach ( (array) $terms as $term ) {
257
  * @return bool
258
  */
259
  function wxr_filter_postmeta( $return_me, $meta_key ) {
260
+ if ( '_edit_lock' == $meta_key ) {
261
  $return_me = true;
262
+ }
263
  return $return_me;
264
  }
265
  add_filter( 'wxr_export_skip_postmeta', 'wxr_filter_postmeta', 10, 2 );
266
 
267
+ echo '<?xml version="1.0" encoding="' . get_bloginfo( 'charset' ) . "\" ?>\n";
268
 
269
  ?>
270
  <!-- This is a WordPress eXtended RSS file generated by WordPress as an export of your site. -->
321
 
322
  // Fetch 20 posts at a time rather than loading the entire table into memory.
323
  while ( $next_posts = array_splice( $post_ids, 0, 20 ) ) {
324
+ $where = 'WHERE ID IN (' . join( ',', $next_posts ) . ')';
325
  // @codingStandardsIgnoreStart
326
  $posts = $wpdb->get_results( "SELECT * FROM {$wpdb->posts} $where" );
327
  // @codingStandardsIgnoreEnd
328
 
329
+ // Begin Loop.
330
+ foreach ( $posts as $post ) {
331
+ setup_postdata( $post );
332
+ $is_sticky = is_sticky( $post->ID ) ? 1 : 0;
333
+ ?>
334
+ <item>
335
  <title><?php
336
  /** This filter is documented in wp-includes/feed.php */
337
  echo apply_filters( 'the_title_rss', $post->post_title );
373
  <wp:post_type><?php echo wxr_cdata( $post->post_type ); ?></wp:post_type>
374
  <wp:post_password><?php echo wxr_cdata( $post->post_password ); ?></wp:post_password>
375
  <wp:is_sticky><?php echo intval( $is_sticky ); ?></wp:is_sticky>
376
+ <?php if ( 'attachment' == $post->post_type ) : ?>
377
  <wp:attachment_url><?php echo wxr_cdata( wp_get_attachment_url( $post->ID ) ); ?></wp:attachment_url>
378
+ <?php endif; ?>
379
+ <?php wxr_post_taxonomy(); ?>
380
+ <?php $postmeta = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM $wpdb->postmeta WHERE post_id = %d", $post->ID ) );
381
  foreach ( $postmeta as $meta ) :
382
  /**
383
  * Filter whether to selectively skip post meta used for WXR exports.
391
  * @param string $meta_key Current meta key.
392
  * @param object $meta Current meta object.
393
  */
394
+ if ( apply_filters( 'wxr_export_skip_postmeta', false, $meta->meta_key, $meta ) ) {
395
  continue;
396
+ }
397
  ?>
398
  <wp:postmeta>
399
+ <wp:meta_key><?php echo wxr_cdata( $meta->meta_key ); ?></wp:meta_key>
400
+ <wp:meta_value><?php echo wxr_cdata( $meta->meta_value ); ?></wp:meta_value>
401
  </wp:postmeta>
402
  <?php endforeach;
403
 
418
  <wp:comment_parent><?php echo intval( $c->comment_parent ); ?></wp:comment_parent>
419
  <wp:comment_user_id><?php echo intval( $c->user_id ); ?></wp:comment_user_id>
420
  <?php $c_meta = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM $wpdb->commentmeta WHERE comment_id = %d", $c->comment_ID ) );
421
+ foreach ( $c_meta as $meta ) :
422
+ /**
423
  * Filter whether to selectively skip comment meta used for WXR exports.
424
  *
425
  * Returning a truthy value to the filter will skip the current meta
431
  * @param string $meta_key Current meta key.
432
  * @param object $meta Current meta object.
433
  */
434
+ if ( apply_filters( 'wxr_export_skip_commentmeta', false, $meta->meta_key, $meta ) ) {
435
+ continue;
436
+ }
437
+ ?>
438
+ <wp:commentmeta>
439
+ <wp:meta_key><?php echo wxr_cdata( $meta->meta_key ); ?></wp:meta_key>
440
+ <wp:meta_value><?php echo wxr_cdata( $meta->meta_value ); ?></wp:meta_value>
441
+ </wp:commentmeta>
442
  <?php endforeach; ?>
443
  </wp:comment>
444
  <?php endforeach; ?>
445
+ </item>
446
+ <?php
447
+ }// End foreach().
448
+ }// End while().
449
+ }// End if().
450
+ ?>
451
  </channel>
452
  </rss>
453
  <?php
includes/field-button.php CHANGED
@@ -1 +1 @@
1
- <span class="fl-builder-button<?php if ( isset( $field['class'] ) ) echo ' '. $field['class']; ?>" href="javascript:void(0);" onclick="return false;"><?php echo $field['label']; ?></span>
1
+ <span class="fl-builder-button<?php if ( isset( $field['class'] ) ) { echo ' ' . $field['class'];} ?>" href="javascript:void(0);" onclick="return false;"><?php echo $field['label']; ?></span>
includes/field-code.php CHANGED
@@ -1,21 +1,22 @@
1
  <div class="fl-code-field">
2
- <?php
3
-
4
- $editor_id = 'flcode' . time() . '_' . $name;
5
  $value = is_array( $value ) ? htmlspecialchars( json_encode( $value ) ) : htmlspecialchars( $value );
6
-
7
  ?>
8
- <textarea id="<?php echo $editor_id; ?>" name="<?php echo $name; ?>" data-editor="<?php echo $field['editor']; ?>" <?php if(isset($field['class'])) echo ' class="'. $field['class'] .'"'; if(isset($field['rows'])) echo ' rows="'. $field['rows'] .'"'; ?>><?php echo $value; ?></textarea>
 
9
  <script>
10
-
11
  jQuery(function(){
12
-
13
- var textarea = jQuery('#<?php echo $editor_id; ?>'),
14
- mode = textarea.data('editor'),
15
  editDiv = jQuery('<div>', {
16
  position: 'absolute',
17
  height: parseInt(textarea.attr('rows'), 10) * 20
18
- }),
19
  editor = null;
20
 
21
  editDiv.insertBefore(textarea);
@@ -25,25 +26,25 @@
25
  editor.$blockScrolling = Infinity;
26
  editor.getSession().setValue(textarea.val());
27
  editor.getSession().setMode('ace/mode/' + mode);
28
-
29
- <?php if ( isset( $field['wrap'] ) && $field['wrap'] === true ) : ?>
30
  editor.getSession().setUseWrapMode(true);
31
  <?php endif; ?>
32
-
33
  editor.setOptions({
34
- enableBasicAutocompletion: true,
35
- enableLiveAutocompletion: true,
36
- enableSnippets: false,
37
- showLineNumbers: false,
38
- showFoldWidgets: false
39
- });
40
-
41
- editor.getSession().on('change', function(e) {
42
  textarea.val(editor.getSession().getValue()).trigger('change');
43
  });
44
-
45
  textarea.closest( '.fl-field' ).data( 'editor', editor );
46
  });
47
-
48
  </script>
49
- </div>
1
  <div class="fl-code-field">
2
+ <?php
3
+
4
+ $editor_id = 'flcode' . time() . '_' . $name;
5
  $value = is_array( $value ) ? htmlspecialchars( json_encode( $value ) ) : htmlspecialchars( $value );
6
+
7
  ?>
8
+ <textarea id="<?php echo $editor_id; ?>" name="<?php echo $name; ?>" data-editor="<?php echo $field['editor']; ?>" <?php if ( isset( $field['class'] ) ) { echo ' class="' . $field['class'] . '"';
9
+ } if ( isset( $field['rows'] ) ) { echo ' rows="' . $field['rows'] . '"';} ?>><?php echo $value; ?></textarea>
10
  <script>
11
+
12
  jQuery(function(){
13
+
14
+ var textarea = jQuery('#<?php echo $editor_id; ?>'),
15
+ mode = textarea.data('editor'),
16
  editDiv = jQuery('<div>', {
17
  position: 'absolute',
18
  height: parseInt(textarea.attr('rows'), 10) * 20
19
+ }),
20
  editor = null;
21
 
22
  editDiv.insertBefore(textarea);
26
  editor.$blockScrolling = Infinity;
27
  editor.getSession().setValue(textarea.val());
28
  editor.getSession().setMode('ace/mode/' + mode);
29
+
30
+ <?php if ( isset( $field['wrap'] ) && true === $field['wrap'] ) : ?>
31
  editor.getSession().setUseWrapMode(true);
32
  <?php endif; ?>
33
+
34
  editor.setOptions({
35
+ enableBasicAutocompletion: true,
36
+ enableLiveAutocompletion: true,
37
+ enableSnippets: false,
38
+ showLineNumbers: false,
39
+ showFoldWidgets: false
40
+ });
41
+
42
+ editor.getSession().on('change', function(e) {
43
  textarea.val(editor.getSession().getValue()).trigger('change');
44
  });
45
+
46
  textarea.closest( '.fl-field' ).data( 'editor', editor );
47
  });
48
+
49
  </script>
50
+ </div>
includes/field-color.php CHANGED
@@ -1,6 +1,6 @@
1
- <div class="fl-color-picker<?php if(isset($field['class'])) echo ' ' . $field['class']; ?>">
2
- <div class="fl-color-picker-color<?php if( empty( $value ) ) echo ' fl-color-picker-empty' ?><?php if( isset($field['show_alpha']) && $field['show_alpha']) echo ' fl-color-picker-alpha-enabled' ?>"></div>
3
- <?php if(isset($field['show_reset']) && $field['show_reset']) : ?>
4
  <div class="fl-color-picker-clear"><div class="fl-color-picker-icon-remove"></div></div>
5
  <?php endif; ?>
6
  <input name="<?php echo $name; ?>" type="hidden" value="<?php echo $value; ?>" class="fl-color-picker-value" />
1
+ <div class="fl-color-picker<?php if ( isset( $field['class'] ) ) { echo ' ' . $field['class'];} ?>">
2
+ <div class="fl-color-picker-color<?php if ( empty( $value ) ) { echo ' fl-color-picker-empty'; } ?><?php if ( isset( $field['show_alpha'] ) && $field['show_alpha'] ) { echo ' fl-color-picker-alpha-enabled'; } ?>"></div>
3
+ <?php if ( isset( $field['show_reset'] ) && $field['show_reset'] ) : ?>
4
  <div class="fl-color-picker-clear"><div class="fl-color-picker-icon-remove"></div></div>
5
  <?php endif; ?>
6
  <input name="<?php echo $name; ?>" type="hidden" value="<?php echo $value; ?>" class="fl-color-picker-value" />
includes/field-editor.php CHANGED
@@ -2,69 +2,69 @@
2
 
3
  if ( ! isset( $field['wpautop'] ) || $field['wpautop'] ) {
4
  $wpautop = ' data-wpautop="1"';
5
- }
6
- else {
7
  $wpautop = ' data-wpautop="0"';
8
  }
9
-
10
  ?>
11
  <div class="fl-editor-field" id="<?php echo $name; ?>"<?php echo $wpautop; ?>>
12
- <?php
13
 
14
  // Remove 3rd party editor buttons.
15
- remove_all_actions('media_buttons', 999999);
16
- remove_all_actions('media_buttons_context', 999999);
17
- remove_all_filters('mce_external_plugins', 999999);
18
-
19
  global $wp_version;
20
 
21
  $editor_id = 'flrich' . time() . '_' . $name;
22
-
23
  wp_editor($value, $editor_id, array(
24
- 'media_buttons' => isset($field['media_buttons']) ? $field['media_buttons'] : true,
25
- 'textarea_rows' => isset($field['rows']) ? $field['rows'] : 16,
26
- 'wpautop' => true
27
- ));
28
-
29
  ?>
30
  <script type="text/javascript">
31
-
32
- <?php if(version_compare($wp_version, '3.8.9', '<=')) : // Pre 3.9 editor init. ?>
33
- jQuery(function()
34
  {
35
  var editorId = '<?php echo $editor_id; ?>';
36
-
37
  quicktags({id : editorId});
38
  QTags._buttonsInit();
39
-
40
  if(typeof tinymce != 'undefined') {
41
  tinymce.execCommand('mceAddControl', true, editorId);
42
  }
43
-
44
  FLBuilder.initEditorField(editorId);
45
  });
46
  <?php else : // 3.9 and above editor init. ?>
47
- jQuery(function()
48
  {
49
  var editorId = '<?php echo $editor_id; ?>',
50
  hiddenEditor = tinyMCEPreInit.mceInit['flhiddeneditor'],
51
  editorProps = null;
52
-
53
  if(typeof tinymce != 'undefined') {
54
  editorProps = tinymce.extend({}, hiddenEditor);
55
  editorProps.selector = '#' + editorId;
56
  editorProps.body_class = editorProps.body_class.replace('flhiddeneditor', editorId);
57
  tinyMCEPreInit.mceInit[editorId] = editorProps;
58
  tinymce.init(editorProps);
 
59
  }
60
- if(typeof quicktags != 'undefined') {
61
  quicktags({id : editorId, buttons : 'strong,em,link,block,del,ins,img,ul,ol,li,code,close'});
62
  QTags._buttonsInit();
63
  }
64
-
65
  window.wpActiveEditor = editorId;
66
  });
67
  <?php endif; ?>
68
-
69
  </script>
70
- </div>
2
 
3
  if ( ! isset( $field['wpautop'] ) || $field['wpautop'] ) {
4
  $wpautop = ' data-wpautop="1"';
5
+ } else {
 
6
  $wpautop = ' data-wpautop="0"';
7
  }
8
+
9
  ?>
10
  <div class="fl-editor-field" id="<?php echo $name; ?>"<?php echo $wpautop; ?>>
11
+ <?php
12
 
13
  // Remove 3rd party editor buttons.
14
+ remove_all_actions( 'media_buttons', 999999 );
15
+ remove_all_actions( 'media_buttons_context', 999999 );
16
+ remove_all_filters( 'mce_external_plugins', 999999 );
17
+
18
  global $wp_version;
19
 
20
  $editor_id = 'flrich' . time() . '_' . $name;
21
+
22
  wp_editor($value, $editor_id, array(
23
+ 'media_buttons' => isset( $field['media_buttons'] ) ? $field['media_buttons'] : true,
24
+ 'textarea_rows' => isset( $field['rows'] ) ? $field['rows'] : 16,
25
+ 'wpautop' => true,
26
+ ));
27
+
28
  ?>
29
  <script type="text/javascript">
30
+
31
+ <?php if ( version_compare( $wp_version, '3.8.9', '<=' ) ) : // Pre 3.9 editor init. ?>
32
+ jQuery(function()
33
  {
34
  var editorId = '<?php echo $editor_id; ?>';
35
+
36
  quicktags({id : editorId});
37
  QTags._buttonsInit();
38
+
39
  if(typeof tinymce != 'undefined') {
40
  tinymce.execCommand('mceAddControl', true, editorId);
41
  }
42
+
43
  FLBuilder.initEditorField(editorId);
44
  });
45
  <?php else : // 3.9 and above editor init. ?>
46
+ jQuery(function()
47
  {
48
  var editorId = '<?php echo $editor_id; ?>',
49
  hiddenEditor = tinyMCEPreInit.mceInit['flhiddeneditor'],
50
  editorProps = null;
51
+
52
  if(typeof tinymce != 'undefined') {
53
  editorProps = tinymce.extend({}, hiddenEditor);
54
  editorProps.selector = '#' + editorId;
55
  editorProps.body_class = editorProps.body_class.replace('flhiddeneditor', editorId);
56
  tinyMCEPreInit.mceInit[editorId] = editorProps;
57
  tinymce.init(editorProps);
58
+ tinymce.ui.FloatPanel.zIndex = 100100; // Fix z-index issue in wp 4.8.1
59
  }
60
+ if(typeof quicktags != 'undefined') {
61
  quicktags({id : editorId, buttons : 'strong,em,link,block,del,ins,img,ul,ol,li,code,close'});
62
  QTags._buttonsInit();
63
  }
64
+
65
  window.wpActiveEditor = editorId;
66
  });
67
  <?php endif; ?>
68
+
69
  </script>
70
+ </div>
includes/field-font.php CHANGED
@@ -1,4 +1,4 @@
1
- <?php $value = ( array ) $value; // Make sure we have an array and not an object. ?>
2
  <div class="fl-font-field">
3
  <select name="<?php echo $name . '[][family]'; ?>" class="fl-font-field-font">
4
  <?php FLBuilderFonts::display_select_font( $value['family'] ) ?>
@@ -6,4 +6,4 @@
6
  <select name="<?php echo $name . '[][weight]'; ?>" class="fl-font-field-weight">
7
  <?php FLBuilderFonts::display_select_weight( $value['family'], $value['weight'] ) ?>
8
  </select>
9
- </div>
1
+ <?php $value = (array) $value; // Make sure we have an array and not an object. ?>
2
  <div class="fl-font-field">
3
  <select name="<?php echo $name . '[][family]'; ?>" class="fl-font-field-font">
4
  <?php FLBuilderFonts::display_select_font( $value['family'] ) ?>
6
  <select name="<?php echo $name . '[][weight]'; ?>" class="fl-font-field-weight">
7
  <?php FLBuilderFonts::display_select_weight( $value['family'], $value['weight'] ) ?>
8
  </select>
9
+ </div>
includes/field-form.php CHANGED
@@ -1,32 +1,30 @@
1
  <?php
2
  // Allow filtering of preview text output of a field
3
- $preview_text = apply_filters('fl_builder_form_field_preview_text', $field['preview_text'], $name, $field, $i);
4
  ?>
5
- <div class="fl-form-field fl-builder-custom-field"<?php if ( isset( $preview_text ) ) echo ' data-preview-text="'. $preview_text .'"'; ?>>
6
  <div class="fl-form-field-preview-text">
7
  <?php
8
 
9
  if ( isset( $preview_text ) && is_object( $value ) ) {
10
-
11
  $form = FLBuilderModel::get_settings_form( $field['form'] );
12
  $form_fields = FLBuilderModel::get_settings_form_fields( $form['tabs'] );
13
-
14
  if ( isset( $form_fields[ $preview_text ] ) ) {
15
-
16
  $preview_field = $form_fields[ $preview_text ];
17
-
18
  if ( 'icon' == $preview_field['type'] ) {
19
  echo '<i class="' . $value->$preview_text . '"></i>';
20
- }
21
- else if ( 'select' == $preview_field['type'] ) {
22
  echo $preview_field['options'][ $value->$preview_text ];
23
- }
24
- else if ( ! empty( $value->{$preview_text} ) ) {
25
  echo FLBuilderUtils::snippetwop( strip_tags( str_replace( '&#39;', "'", $value->{$preview_text} ) ), 35 );
26
  }
27
  }
28
  }
29
-
30
  // JSON encode the value and fix encoding conflicts.
31
  if ( ! empty( $value ) ) {
32
  $value = str_replace( "'", '&#39;', json_encode( $value ) );
@@ -37,4 +35,4 @@ $preview_text = apply_filters('fl_builder_form_field_preview_text', $field['prev
37
  </div>
38
  <a class="fl-form-field-edit" href="javascript:void(0);" onclick="return false;" data-type="<?php echo $field['form']; ?>"><?php printf( _x( 'Edit %s', '%s stands for form field label.', 'fl-builder' ), $field['label'] ); ?></a>
39
  <input name="<?php echo $name; ?>" type="hidden" value='<?php echo $value; ?>' />
40
- </div>
1
  <?php
2
  // Allow filtering of preview text output of a field
3
+ $preview_text = apply_filters( 'fl_builder_form_field_preview_text', $field['preview_text'], $name, $field, $i );
4
  ?>
5
+ <div class="fl-form-field fl-builder-custom-field"<?php if ( isset( $preview_text ) ) { echo ' data-preview-text="' . $preview_text . '"';} ?>>
6
  <div class="fl-form-field-preview-text">
7
  <?php
8
 
9
  if ( isset( $preview_text ) && is_object( $value ) ) {
10
+
11
  $form = FLBuilderModel::get_settings_form( $field['form'] );
12
  $form_fields = FLBuilderModel::get_settings_form_fields( $form['tabs'] );
13
+
14
  if ( isset( $form_fields[ $preview_text ] ) ) {
15
+
16
  $preview_field = $form_fields[ $preview_text ];
17
+
18
  if ( 'icon' == $preview_field['type'] ) {
19
  echo '<i class="' . $value->$preview_text . '"></i>';
20
+ } elseif ( 'select' == $preview_field['type'] ) {
 
21
  echo $preview_field['options'][ $value->$preview_text ];
22
+ } elseif ( ! empty( $value->{$preview_text} ) ) {
 
23
  echo FLBuilderUtils::snippetwop( strip_tags( str_replace( '&#39;', "'", $value->{$preview_text} ) ), 35 );
24
  }
25
  }
26
  }
27
+
28
  // JSON encode the value and fix encoding conflicts.
29
  if ( ! empty( $value ) ) {
30
  $value = str_replace( "'", '&#39;', json_encode( $value ) );
35
  </div>
36
  <a class="fl-form-field-edit" href="javascript:void(0);" onclick="return false;" data-type="<?php echo $field['form']; ?>"><?php printf( _x( 'Edit %s', '%s stands for form field label.', 'fl-builder' ), $field['label'] ); ?></a>
37
  <input name="<?php echo $name; ?>" type="hidden" value='<?php echo $value; ?>' />
38
+ </div>
includes/field-icon.php CHANGED
@@ -1,11 +1,12 @@
1
- <div class="fl-icon-field fl-builder-custom-field<?php if(empty($value)) echo ' fl-icon-empty'; if(isset($field['class'])) echo ' ' . $field['class']; ?>">
2
- <a class="fl-icon-select" href="javascript:void(0);" onclick="return false;"><?php _e('Select Icon', 'fl-builder'); ?></a>
 
3
  <div class="fl-icon-preview">
4
  <i class="<?php echo $value; ?>" data-icon="<?php echo $value; ?>"></i>
5
- <a class="fl-icon-replace" href="javascript:void(0);" onclick="return false;"><?php _e('Replace', 'fl-builder'); ?></a>
6
- <?php if(isset($field['show_remove']) && $field['show_remove']) : ?>
7
- <a class="fl-icon-remove" href="javascript:void(0);" onclick="return false;"><?php _e('Remove', 'fl-builder'); ?></a>
8
  <?php endif; ?>
9
  </div>
10
  <input name="<?php echo $name; ?>" type="hidden" value="<?php echo $value; ?>" />
11
- </div>
1
+ <div class="fl-icon-field fl-builder-custom-field<?php if ( empty( $value ) ) { echo ' fl-icon-empty';
2
+ } if ( isset( $field['class'] ) ) { echo ' ' . $field['class'];} ?>">
3
+ <a class="fl-icon-select" href="javascript:void(0);" onclick="return false;"><?php _e( 'Select Icon', 'fl-builder' ); ?></a>
4
  <div class="fl-icon-preview">
5
  <i class="<?php echo $value; ?>" data-icon="<?php echo $value; ?>"></i>
6
+ <a class="fl-icon-replace" href="javascript:void(0);" onclick="return false;"><?php _e( 'Replace', 'fl-builder' ); ?></a>
7
+ <?php if ( isset( $field['show_remove'] ) && $field['show_remove'] ) : ?>
8
+ <a class="fl-icon-remove" href="javascript:void(0);" onclick="return false;"><?php _e( 'Remove', 'fl-builder' ); ?></a>
9
  <?php endif; ?>
10
  </div>
11
  <input name="<?php echo $name; ?>" type="hidden" value="<?php echo $value; ?>" />
12
+ </div>
includes/field-layout.php CHANGED
@@ -1,9 +1,9 @@
1
  <div class="fl-layout-field">
2
- <?php foreach($field['options'] as $key => $img) : ?>
3
- <div class="fl-layout-field-option <?php if($key == $value) echo 'fl-layout-field-option-selected'; ?>" data-value="<?php echo $key; ?>">
4
  <img src="<?php echo $img; ?>" />
5
  </div>
6
  <?php endforeach; ?>
7
  <div class="fl-clear"></div>
8
  <input name="<?php echo $name; ?>" type="hidden" value='<?php echo $value; ?>' />
9
- </div>
1
  <div class="fl-layout-field">
2
+ <?php foreach ( $field['options'] as $key => $img ) : ?>
3
+ <div class="fl-layout-field-option <?php if ( $key == $value ) { echo 'fl-layout-field-option-selected';} ?>" data-value="<?php echo $key; ?>">
4
  <img src="<?php echo $img; ?>" />
5
  </div>
6
  <?php endforeach; ?>
7
  <div class="fl-clear"></div>
8
  <input name="<?php echo $name; ?>" type="hidden" value='<?php echo $value; ?>' />
9
+ </div>
includes/field-link.php CHANGED
@@ -1,9 +1,9 @@
1
  <div class="fl-link-field">
2
  <input type="text" name="<?php echo $name; ?>" value="<?php echo $value; ?>" class="text fl-link-field-input" placeholder="<?php _ex( 'http://www.example.com', 'Link placeholder', 'fl-builder' ); ?>" />
3
- <span class="fl-link-field-select fl-builder-button fl-builder-button-small" href="javascript:void(0);" onclick="return false;"><?php _e('Select', 'fl-builder'); ?></span>
4
  <div class="fl-link-field-search">
5
- <span class="fl-link-field-search-title"><?php _e('Enter a post title to search.', 'fl-builder'); ?></span>
6
  <input type="text" name="<?php echo $name; ?>-search" class="text text-full fl-link-field-search-input" placeholder="<?php esc_attr_e( 'Start typing...', 'fl-builder' ); ?>" />
7
- <span class="fl-link-field-search-cancel fl-builder-button fl-builder-button-small" href="javascript:void(0);" onclick="return false;"><?php _e('Cancel', 'fl-builder'); ?></span>
8
  </div>
9
- </div>
1
  <div class="fl-link-field">
2
  <input type="text" name="<?php echo $name; ?>" value="<?php echo $value; ?>" class="text fl-link-field-input" placeholder="<?php _ex( 'http://www.example.com', 'Link placeholder', 'fl-builder' ); ?>" />
3
+ <span class="fl-link-field-select fl-builder-button fl-builder-button-small" href="javascript:void(0);" onclick="return false;"><?php _e( 'Select', 'fl-builder' ); ?></span>
4
  <div class="fl-link-field-search">
5
+ <span class="fl-link-field-search-title"><?php _e( 'Enter a post title to search.', 'fl-builder' ); ?></span>
6
  <input type="text" name="<?php echo $name; ?>-search" class="text text-full fl-link-field-search-input" placeholder="<?php esc_attr_e( 'Start typing...', 'fl-builder' ); ?>" />
7
+ <span class="fl-link-field-search-cancel fl-builder-button fl-builder-button-small" href="javascript:void(0);" onclick="return false;"><?php _e( 'Cancel', 'fl-builder' ); ?></span>
8
  </div>
9
+ </div>
includes/field-multiple-audios.php CHANGED
@@ -1,8 +1,8 @@
1
  <?php
2
 
3
- // Normalize the value so we have an array.
4
  if ( ! empty( $value ) && is_string( $value ) ) {
5
-
6
  $value = json_decode( $value );
7
  if ( is_string( $value ) ) {
8
  $value = json_decode( $value );
@@ -10,18 +10,18 @@ if ( ! empty( $value ) && is_string( $value ) ) {
10
  if ( is_int( $value ) ) {
11
  $value = (array) $value;
12
  }
13
- }
14
- else if ( empty( $value ) ) {
15
  $value = array();
16
  }
17
 
18
  ?>
19
- <div class="fl-multiple-audios-field fl-builder-custom-field<?php if(empty($value)) echo ' fl-multiple-audios-empty'; if(isset($field['class'])) echo ' ' . $field['class']; ?>" <?php if(isset($field['toggle'])) echo "data-toggle='". json_encode($field['toggle']) ."'";?>>
 
20
  <div class="fl-multiple-audios-count">
21
  <?php printf( _n( '%d Audio File Selected', '%d Audio Files Selected', count( $value ), 'fl-builder' ), count( $value ) ); ?>
22
  </div>
23
- <a class="fl-multiple-audios-select" href="javascript:void(0);" onclick="return false;"><?php _e('Select Audio', 'fl-builder'); ?></a>
24
- <a class="fl-multiple-audios-edit" href="javascript:void(0);" onclick="return false;"><?php _e('Edit Playlist', 'fl-builder'); ?></a>
25
- <a class="fl-multiple-audios-add" href="javascript:void(0);" onclick="return false;"><?php _e('Add Audio Files', 'fl-builder'); ?></a>
26
- <input name="<?php echo $name; ?>" type="hidden" value='<?php if ( ! empty( $value ) ) echo json_encode( $value ); ?>' />
27
- </div>
1
  <?php
2
 
3
+ // Normalize the value so we have an array.
4
  if ( ! empty( $value ) && is_string( $value ) ) {
5
+
6
  $value = json_decode( $value );
7
  if ( is_string( $value ) ) {
8
  $value = json_decode( $value );
10
  if ( is_int( $value ) ) {
11
  $value = (array) $value;
12
  }
13
+ } elseif ( empty( $value ) ) {
 
14
  $value = array();
15
  }
16
 
17
  ?>
18
+ <div class="fl-multiple-audios-field fl-builder-custom-field<?php if ( empty( $value ) ) { echo ' fl-multiple-audios-empty';
19
+ } if ( isset( $field['class'] ) ) { echo ' ' . $field['class'];} ?>" <?php if ( isset( $field['toggle'] ) ) { echo "data-toggle='" . json_encode( $field['toggle'] ) . "'";}?>>
20
  <div class="fl-multiple-audios-count">
21
  <?php printf( _n( '%d Audio File Selected', '%d Audio Files Selected', count( $value ), 'fl-builder' ), count( $value ) ); ?>
22
  </div>
23
+ <a class="fl-multiple-audios-select" href="javascript:void(0);" onclick="return false;"><?php _e( 'Select Audio', 'fl-builder' ); ?></a>
24
+ <a class="fl-multiple-audios-edit" href="javascript:void(0);" onclick="return false;"><?php _e( 'Edit Playlist', 'fl-builder' ); ?></a>
25
+ <a class="fl-multiple-audios-add" href="javascript:void(0);" onclick="return false;"><?php _e( 'Add Audio Files', 'fl-builder' ); ?></a>
26
+ <input name="<?php echo $name; ?>" type="hidden" value='<?php if ( ! empty( $value ) ) { echo json_encode( $value );} ?>' />
27
+ </div>
includes/field-multiple-photos.php CHANGED
@@ -1,26 +1,26 @@
1
  <?php
2
 
3
- // Normalize the value so we have an array.
4
  if ( ! empty( $value ) && is_string( $value ) ) {
5
-
6
  $value = json_decode( $value );
7
-
8
  // Older versions might be double encoded.
9
  if ( is_string( $value ) ) {
10
  $value = json_decode( $value );
11
  }
12
- }
13
- else if ( empty( $value ) ) {
14
  $value = array();
15
  }
16
 
17
  ?>
18
- <div class="fl-multiple-photos-field fl-builder-custom-field<?php if ( empty( $value ) ) echo ' fl-multiple-photos-empty'; if ( isset( $field['class'] ) ) echo ' ' . $field['class']; ?>">
 
19
  <div class="fl-multiple-photos-count">
20
  <?php printf( _n( '%d Photo Selected', '%d Photos Selected', count( $value ), 'fl-builder' ), count( $value ) ); ?>
21
  </div>
22
- <a class="fl-multiple-photos-select" href="javascript:void(0);" onclick="return false;"><?php _e('Create Gallery', 'fl-builder'); ?></a>
23
- <a class="fl-multiple-photos-edit" href="javascript:void(0);" onclick="return false;"><?php _e('Edit Gallery', 'fl-builder'); ?></a>
24
- <a class="fl-multiple-photos-add" href="javascript:void(0);" onclick="return false;"><?php _e('Add Photos', 'fl-builder'); ?></a>
25
- <input name="<?php echo $name; ?>" type="hidden" value='<?php if ( ! empty( $value ) ) echo json_encode( $value ); ?>' />
26
- </div>
1
  <?php
2
 
3
+ // Normalize the value so we have an array.
4
  if ( ! empty( $value ) && is_string( $value ) ) {
5
+
6
  $value = json_decode( $value );
7
+
8
  // Older versions might be double encoded.
9
  if ( is_string( $value ) ) {
10
  $value = json_decode( $value );
11
  }
12
+ } elseif ( empty( $value ) ) {
 
13
  $value = array();
14
  }
15
 
16
  ?>
17
+ <div class="fl-multiple-photos-field fl-builder-custom-field<?php if ( empty( $value ) ) { echo ' fl-multiple-photos-empty';
18
+ } if ( isset( $field['class'] ) ) { echo ' ' . $field['class'];} ?>">
19
  <div class="fl-multiple-photos-count">
20
  <?php printf( _n( '%d Photo Selected', '%d Photos Selected', count( $value ), 'fl-builder' ), count( $value ) ); ?>
21
  </div>
22
+ <a class="fl-multiple-photos-select" href="javascript:void(0);" onclick="return false;"><?php _e( 'Create Gallery', 'fl-builder' ); ?></a>
23
+ <a class="fl-multiple-photos-edit" href="javascript:void(0);" onclick="return false;"><?php _e( 'Edit Gallery', 'fl-builder' ); ?></a>
24
+ <a class="fl-multiple-photos-add" href="javascript:void(0);" onclick="return false;"><?php _e( 'Add Photos', 'fl-builder' ); ?></a>
25
+ <input name="<?php echo $name; ?>" type="hidden" value='<?php if ( ! empty( $value ) ) { echo json_encode( $value );} ?>' />
26
+ </div>
includes/field-ordering.php CHANGED
@@ -12,15 +12,15 @@ if ( empty( $value ) ) {
12
 
13
  // Make sure any new options are added to the value.
14
  foreach ( $field['options'] as $key => $label ) {
15
- if ( ! in_array( $key, $value) ) {
16
  $value[] = $key;
17
  }
18
  }
19
-
20
  ?>
21
- <div class="fl-ordering-field-options<?php if ( isset( $field['class'] ) ) echo ' '. $field['class']; ?>">
22
  <?php foreach ( $value as $key ) : ?>
23
  <div class="fl-ordering-field-option" data-key="<?php echo $key; ?>"><?php echo $field['options'][ $key ]; ?><i class="fa fa-arrows"></i> </div>
24
  <?php endforeach; ?>
25
  </div>
26
- <input type="hidden" name="<?php echo $name; ?>" value='<?php echo json_encode( $value ); ?>' />
12
 
13
  // Make sure any new options are added to the value.
14
  foreach ( $field['options'] as $key => $label ) {
15
+ if ( ! in_array( $key, $value ) ) {
16
  $value[] = $key;
17
  }
18
  }
19
+
20
  ?>
21
+ <div class="fl-ordering-field-options<?php if ( isset( $field['class'] ) ) { echo ' ' . $field['class'];} ?>">
22
  <?php foreach ( $value as $key ) : ?>
23
  <div class="fl-ordering-field-option" data-key="<?php echo $key; ?>"><?php echo $field['options'][ $key ]; ?><i class="fa fa-arrows"></i> </div>
24
  <?php endforeach; ?>
25
  </div>
26
+ <input type="hidden" name="<?php echo $name; ?>" value='<?php echo json_encode( $value ); ?>' />
includes/field-photo-sizes.php CHANGED
@@ -1,12 +1,12 @@
1
  <select name="<?php echo $name; ?>">
2
- <?php
3
-
4
- foreach(FLBuilderPhoto::sizes() as $size => $atts) :
5
-
6
- $label = ucwords(str_replace(array('_', '-'), ' ', $size)) . ' (' . implode('x', $atts) . ')';
7
-
8
  ?>
9
- <option value="<?php echo $size; ?>" <?php selected($value, $size); ?>><?php echo $label; ?></option>
10
  <?php endforeach; ?>
11
  <option value="full" <?php selected( $value, 'full' ); ?>><?php _e( 'Full Size', 'fl-builder' ); ?></option>
12
- </select>
1
  <select name="<?php echo $name; ?>">
2
+ <?php
3
+
4
+ foreach ( FLBuilderPhoto::sizes() as $size => $atts ) :
5
+
6
+ $label = ucwords( str_replace( array( '_', '-' ), ' ', $size ) ) . ' (' . implode( 'x', $atts ) . ')';
7
+
8
  ?>
9
+ <option value="<?php echo $size; ?>" <?php selected( $value, $size ); ?>><?php echo $label; ?></option>
10
  <?php endforeach; ?>
11
  <option value="full" <?php selected( $value, 'full' ); ?>><?php _e( 'Full Size', 'fl-builder' ); ?></option>
12
+ </select>
includes/field-photo.php CHANGED
@@ -1,21 +1,22 @@
1
- <?php $photo = FLBuilderPhoto::get_attachment_data($value); ?>
2
- <div class="fl-photo-field fl-builder-custom-field<?php if(empty($value) || !$photo) echo ' fl-photo-empty'; if(isset($field['class'])) echo ' ' . $field['class']; ?>">
3
- <a class="fl-photo-select" href="javascript:void(0);" onclick="return false;"><?php _e('Select Photo', 'fl-builder'); ?></a>
 
4
  <div class="fl-photo-preview">
5
  <div class="fl-photo-preview-img">
6
- <img src="<?php if($photo) echo FLBuilderPhoto::get_thumb($photo); ?>" />
7
  </div>
8
  <select name="<?php echo $name; ?>_src">
9
- <?php if($photo && isset($settings->{$name . '_src'})) echo FLBuilderPhoto::get_src_options($settings->{$name . '_src'}, $photo); ?>
10
  </select>
11
  <br />
12
- <a class="fl-photo-edit" href="javascript:void(0);" onclick="return false;"><?php _e('Edit', 'fl-builder'); ?></a>
13
- <?php if(isset($field['show_remove']) && $field['show_remove']) : ?>
14
- <a class="fl-photo-remove" href="javascript:void(0);" onclick="return false;"><?php _e('Remove', 'fl-builder'); ?></a>
15
  <?php else : ?>
16
- <a class="fl-photo-replace" href="javascript:void(0);" onclick="return false;"><?php _e('Replace', 'fl-builder'); ?></a>
17
  <?php endif; ?>
18
  <div class="fl-clear"></div>
19
  </div>
20
  <input name="<?php echo $name; ?>" type="hidden" value='<?php echo $value; ?>' />
21
- </div>
1
+ <?php $photo = FLBuilderPhoto::get_attachment_data( $value ); ?>
2
+ <div class="fl-photo-field fl-builder-custom-field<?php if ( empty( $value ) || ! $photo ) { echo ' fl-photo-empty';
3
+ } if ( isset( $field['class'] ) ) { echo ' ' . $field['class'];} ?>">
4
+ <a class="fl-photo-select" href="javascript:void(0);" onclick="return false;"><?php _e( 'Select Photo', 'fl-builder' ); ?></a>
5
  <div class="fl-photo-preview">
6
  <div class="fl-photo-preview-img">
7
+ <img src="<?php if ( $photo ) { echo FLBuilderPhoto::get_thumb( $photo );} ?>" />
8
  </div>
9
  <select name="<?php echo $name; ?>_src">
10
+ <?php if ( $photo && isset( $settings->{$name . '_src'} ) ) { echo FLBuilderPhoto::get_src_options( $settings->{$name . '_src'}, $photo );} ?>
11
  </select>
12
  <br />
13
+ <a class="fl-photo-edit" href="javascript:void(0);" onclick="return false;"><?php _e( 'Edit', 'fl-builder' ); ?></a>
14
+ <?php if ( isset( $field['show_remove'] ) && $field['show_remove'] ) : ?>
15
+ <a class="fl-photo-remove" href="javascript:void(0);" onclick="return false;"><?php _e( 'Remove', 'fl-builder' ); ?></a>
16
  <?php else : ?>
17
+ <a class="fl-photo-replace" href="javascript:void(0);" onclick="return false;"><?php _e( 'Replace', 'fl-builder' ); ?></a>
18
  <?php endif; ?>
19
  <div class="fl-clear"></div>
20
  </div>
21
  <input name="<?php echo $name; ?>" type="hidden" value='<?php echo $value; ?>' />
22
+ </div>
includes/field-post-type.php CHANGED
@@ -1,5 +1,5 @@
1
- <select name="<?php echo $name; ?>"<?php if(isset($field['class'])) echo ' class="'. $field['class'] .'"'; ?>>
2
- <?php foreach(FLBuilderLoop::post_types() as $slug => $type) : ?>
3
- <option value="<?php echo $slug; ?>" <?php selected($value, $slug); ?>><?php echo $type->labels->name; ?></option>
4
  <?php endforeach; ?>
5
- </select>
1
+ <select name="<?php echo $name; ?>"<?php if ( isset( $field['class'] ) ) { echo ' class="' . $field['class'] . '"';} ?>>
2
+ <?php foreach ( FLBuilderLoop::post_types() as $slug => $type ) : ?>
3
+ <option value="<?php echo $slug; ?>" <?php selected( $value, $slug ); ?>><?php echo $type->labels->name; ?></option>
4
  <?php endforeach; ?>
5
+ </select>
includes/field-select.php CHANGED
@@ -77,8 +77,8 @@ if ( isset( $field['trigger'] ) ) {
77
  <select name="<?php echo esc_attr( $name ); ?>"<?php echo $atts; ?>>
78
 
79
  <?php
80
-
81
- // Get the options from a function?
82
  if ( is_string( $field['options'] ) ) {
83
  $field['options'] = call_user_func( $field['options'] );
84
  }
@@ -87,7 +87,7 @@ if ( isset( $field['trigger'] ) ) {
87
  foreach ( (array) $field['options'] as $option_key => $option_val ) {
88
 
89
  // Don't display premium options if using lite plugin version
90
- if ( is_array( $option_val ) && isset( $option_val['premium' ] ) && $option_val['premium'] && true === FL_BUILDER_LITE ) {
91
  continue;
92
  }
93
 
@@ -95,32 +95,32 @@ if ( isset( $field['trigger'] ) ) {
95
 
96
  echo '<optgroup label="' . esc_attr( $option_val['label'] ) . '">';
97
 
98
- foreach( (array) $option_val['options'] as $optgroup_option_key => $optgroup_option_val ) {
99
 
100
- // Don't display premium optgroup options if using lite plugin version
101
- if ( is_array( $optgroup_option_val ) && isset( $optgroup_option_val['premium' ] ) && $optgroup_option_val['premium'] && true === FL_BUILDER_LITE ) {
102
- continue;
103
- }
104
 
105
- // Is selected?
106
 
107
- $selected = '';
108
 
109
- if ( is_array( $value ) && in_array( $optgroup_option_key, $value ) ) {
110
- // Multi select
111
- $selected = ' selected="selected"';
112
- } elseif ( ! is_array( $value ) && selected( $value, $optgroup_option_key, false ) ) {
113
- // Single select
114
- $selected = ' selected="selected"';
115
- }
116
 
117
- // Option label
118
- $label = ( is_array( $optgroup_option_val ) ) ? ( $optgroup_option_val['label'] ) : ( $optgroup_option_val );
119
 
120
- // Output option
121
- echo '<option value="' . esc_attr( $optgroup_option_key ) . '"' . $selected . '>' . esc_html( $label ) . '</option>';
122
 
123
- } // /foreach
124
 
125
  echo '</optgroup>';
126
 
@@ -130,13 +130,13 @@ if ( isset( $field['trigger'] ) ) {
130
 
131
  $selected = '';
132
 
133
- if ( is_array( $value ) && in_array( $option_key, $value ) ) {
134
- // Multi select
135
- $selected = ' selected="selected"';
136
- } elseif ( ! is_array( $value ) && selected( $value, $option_key, false ) ) {
137
- // Single select
138
- $selected = ' selected="selected"';
139
- }
140
 
141
  // Option label
142
  $label = ( is_array( $option_val ) ) ? ( $option_val['label'] ) : ( $option_val );
@@ -144,9 +144,8 @@ if ( isset( $field['trigger'] ) ) {
144
  // Output option
145
  echo '<option value="' . esc_attr( $option_key ) . '"' . $selected . '>' . esc_html( $label ) . '</option>';
146
 
147
- }
148
-
149
- } // /foreach
150
 
151
  ?>
152
 
77
  <select name="<?php echo esc_attr( $name ); ?>"<?php echo $atts; ?>>
78
 
79
  <?php
80
+
81
+ // Get the options from a function?
82
  if ( is_string( $field['options'] ) ) {
83
  $field['options'] = call_user_func( $field['options'] );
84
  }
87
  foreach ( (array) $field['options'] as $option_key => $option_val ) {
88
 
89
  // Don't display premium options if using lite plugin version
90
+ if ( is_array( $option_val ) && isset( $option_val['premium'] ) && $option_val['premium'] && true === FL_BUILDER_LITE ) {
91
  continue;
92
  }
93
 
95
 
96
  echo '<optgroup label="' . esc_attr( $option_val['label'] ) . '">';
97
 
98
+ foreach ( (array) $option_val['options'] as $optgroup_option_key => $optgroup_option_val ) {
99
 
100
+ // Don't display premium optgroup options if using lite plugin version
101
+ if ( is_array( $optgroup_option_val ) && isset( $optgroup_option_val['premium'] ) && $optgroup_option_val['premium'] && true === FL_BUILDER_LITE ) {
102
+ continue;
103
+ }
104
 
105
+ // Is selected?
106
 
107
+ $selected = '';
108
 
109
+ if ( is_array( $value ) && in_array( $optgroup_option_key, $value ) ) {
110
+ // Multi select
111
+ $selected = ' selected="selected"';
112
+ } elseif ( ! is_array( $value ) && selected( $value, $optgroup_option_key, false ) ) {
113
+ // Single select
114
+ $selected = ' selected="selected"';
115
+ }
116
 
117
+ // Option label
118
+ $label = ( is_array( $optgroup_option_val ) ) ? ( $optgroup_option_val['label'] ) : ( $optgroup_option_val );
119
 
120
+ // Output option
121
+ echo '<option value="' . esc_attr( $optgroup_option_key ) . '"' . $selected . '>' . esc_html( $label ) . '</option>';
122
 
123
+ } // End foreach().
124
 
125
  echo '</optgroup>';
126
 
130
 
131
  $selected = '';
132
 
133
+ if ( is_array( $value ) && in_array( $option_key, $value ) ) {
134
+ // Multi select
135
+ $selected = ' selected="selected"';
136
+ } elseif ( ! is_array( $value ) && selected( $value, $option_key, false ) ) {
137
+ // Single select
138
+ $selected = ' selected="selected"';
139
+ }
140
 
141
  // Option label
142
  $label = ( is_array( $option_val ) ) ? ( $option_val['label'] ) : ( $option_val );
144
  // Output option
145
  echo '<option value="' . esc_attr( $option_key ) . '"' . $selected . '>' . esc_html( $label ) . '</option>';
146
 
147
+ }// End if().
148
+ } // End foreach().
 
149
 
150
  ?>
151
 
includes/field-suggest.php CHANGED
@@ -9,4 +9,4 @@ $args = isset( $field['args'] ) && is_array( $field['args'] ) ? $field['args'
9
  $value = FLBuilderAutoSuggest::get_value( $action, $value, $data );
10
 
11
  ?>
12
- <input type="text" class="text text-full fl-suggest-field<?php echo $class; ?>" name="<?php echo $name; ?>" data-value='<?php echo $value; ?>' data-action="<?php echo $action; ?>" data-action-data="<?php echo $data; ?>" data-limit="<?php echo $limit; ?>" data-args='<?php echo json_encode( $args ); ?>' placeholder="<?php echo $placeholder; ?>" />
9
  $value = FLBuilderAutoSuggest::get_value( $action, $value, $data );
10
 
11
  ?>
12
+ <input type="text" class="text text-full fl-suggest-field<?php echo $class; ?>" name="<?php echo $name; ?>" data-value='<?php echo $value; ?>' data-action="<?php echo $action; ?>" data-action-data="<?php echo $data; ?>" data-limit="<?php echo $limit; ?>" data-args='<?php echo json_encode( $args ); ?>' placeholder="<?php echo $placeholder; ?>" />
includes/field-text.php CHANGED
@@ -1,4 +1,7 @@
1
- <input type="text" name="<?php echo $name; ?>" value="<?php echo esc_attr($value); ?>" class="text<?php if(isset($field['class'])) echo ' '. $field['class']; if(!isset($field['size'])) echo ' text-full'; ?>" <?php if(isset($field['placeholder'])) echo ' placeholder="'. $field['placeholder'] .'"'; if(isset($field['maxlength'])) echo ' maxlength="'. $field['maxlength'] .'"'; if(isset($field['size'])) echo ' size="'. $field['size'] .'"'; ?> />
 
 
 
2
 
3
  <?php
4
 
@@ -14,9 +17,9 @@ if (
14
 
15
  // Adding empty value if missing
16
 
17
- if ( ! isset( $field['options'][''] ) ) {
18
- $field['options'][''] = esc_html_x( '- Add predefined -', 'Add predefined value.', 'fl-builder' );
19
- }
20
 
21
  // Moving the empty value to top
22
 
@@ -24,7 +27,9 @@ if (
24
 
25
  unset( $field['options'][''] );
26
 
27
- $field['options'] = array( '' => $selector_value_empty ) + $field['options'];
 
 
28
 
29
  // Outputting select field
30
 
@@ -33,7 +38,7 @@ if (
33
  <select class="fl-select-add-value" data-target="<?php echo esc_attr( $name ); ?>">
34
  <?php
35
 
36
- foreach( $field['options'] as $option_value => $option ) {
37
 
38
  if (
39
  is_array( $option )
@@ -45,9 +50,9 @@ if (
45
 
46
  echo '<optgroup label="' . esc_attr( $option['label'] ) . '">';
47
 
48
- foreach( (array) $option['options'] as $optgroup_option_value => $optgroup_option ) {
49
- echo '<option value="' . esc_attr( $optgroup_option_value ) . '">' . esc_html( $optgroup_option ) . '</option>';
50
- }
51
 
52
  echo '</optgroup>';
53
 
@@ -59,8 +64,7 @@ if (
59
  echo '<option value="' . esc_attr( $option_value ) . '">' . esc_html( $option ) . '</option>';
60
 
61
  }
62
-
63
- } // /foreach
64
 
65
  ?>
66
  </select>
1
+ <input type="text" name="<?php echo $name; ?>" value="<?php echo esc_attr( $value ); ?>" class="text<?php if ( isset( $field['class'] ) ) { echo ' ' . $field['class'];
2
+ } if ( ! isset( $field['size'] ) ) { echo ' text-full';} ?>" <?php if ( isset( $field['placeholder'] ) ) { echo ' placeholder="' . $field['placeholder'] . '"';
3
+ } if ( isset( $field['maxlength'] ) ) { echo ' maxlength="' . $field['maxlength'] . '"';
4
+ } if ( isset( $field['size'] ) ) { echo ' size="' . $field['size'] . '"';} ?> />
5
 
6
  <?php
7
 
17
 
18
  // Adding empty value if missing
19
 
20
+ if ( ! isset( $field['options'][''] ) ) {
21
+ $field['options'][''] = esc_html_x( '- Add predefined -', 'Add predefined value.', 'fl-builder' );
22
+ }
23
 
24
  // Moving the empty value to top
25
 
27
 
28
  unset( $field['options'][''] );
29
 
30
+ $field['options'] = array(
31
+ '' => $selector_value_empty,
32
+ ) + $field['options'];
33
 
34
  // Outputting select field
35
 
38
  <select class="fl-select-add-value" data-target="<?php echo esc_attr( $name ); ?>">
39
  <?php
40
 
41
+ foreach ( $field['options'] as $option_value => $option ) {
42
 
43
  if (
44
  is_array( $option )
50
 
51
  echo '<optgroup label="' . esc_attr( $option['label'] ) . '">';
52
 
53
+ foreach ( (array) $option['options'] as $optgroup_option_value => $optgroup_option ) {
54
+ echo '<option value="' . esc_attr( $optgroup_option_value ) . '">' . esc_html( $optgroup_option ) . '</option>';
55
+ }
56
 
57
  echo '</optgroup>';
58
 
64
  echo '<option value="' . esc_attr( $option_value ) . '">' . esc_html( $option ) . '</option>';
65
 
66
  }
67
+ } // End foreach().
 
68
 
69
  ?>
70
  </select>
includes/field-textarea.php CHANGED
@@ -1 +1,3 @@
1
- <textarea name="<?php echo $name; ?>"<?php if(isset($field['class'])) echo ' class="'. $field['class'] .'"'; if(isset($field['placeholder'])) echo ' placeholder="'. $field['placeholder'] .'"'; if(isset($field['rows'])) echo ' rows="'. $field['rows'] .'"'; ?>><?php echo $value; ?></textarea>
 
 
1
+ <textarea name="<?php echo $name; ?>"<?php if ( isset( $field['class'] ) ) { echo ' class="' . $field['class'] . '"';
2
+ } if ( isset( $field['placeholder'] ) ) { echo ' placeholder="' . $field['placeholder'] . '"';
3
+ } if ( isset( $field['rows'] ) ) { echo ' rows="' . $field['rows'] . '"';} ?>><?php echo $value; ?></textarea>
includes/field-time.php CHANGED
@@ -1,28 +1,28 @@
1
- <?php
2
- $prepend = array('01','02','03','04','05','06','07','08','09');
3
- $hours = array_merge( $prepend, range( 10, 12 ) );
4
- $minutes = array_merge( array('00'), $prepend, range( 10, 59 ) );
5
- $day_period = array( 'am', 'pm' );
6
 
7
- if ( is_object( $value ) ) {
8
- $value = (array) $value;
9
- }
10
  ?>
11
  <select name="<?php echo $name . '[][hours]'; ?>" class="fl-time-field-hours">
12
- <?php foreach( $hours as $hour ) : ?>
13
  <?php $selected = isset( $value['hours'] ) && $value['hours'] == $hour ? ' selected="selected"' : ''; ?>
14
  <option value="<?php echo $hour ?>"<?php echo $selected ?>><?php echo $hour ?></option>
15
  <?php endforeach; ?>
16
  </select>
17
  <select name="<?php echo $name . '[][minutes]'; ?>" class="fl-time-field-minutes">
18
- <?php foreach( $minutes as $minute ) : ?>
19
  <?php $selected = isset( $value['minutes'] ) && $value['minutes'] == $minute ? ' selected="selected"' : ''; ?>
20
  <option value="<?php echo $minute ?>"<?php echo $selected ?>><?php echo $minute ?></option>
21
  <?php endforeach; ?>
22
  </select>
23
  <select name="<?php echo $name . '[][day_period]'; ?>" class="fl-time-field-day_period">
24
- <?php foreach( $day_period as $period ) : ?>
25
  <?php $selected = isset( $value['day_period'] ) && $value['day_period'] == $period ? ' selected="selected"' : ''; ?>
26
  <option value="<?php echo $period ?>"<?php echo $selected ?>><?php echo $period ?></option>
27
  <?php endforeach; ?>
28
- </select>
1
+ <?php
2
+ $prepend = array( '01','02','03','04','05','06','07','08','09' );
3
+ $hours = array_merge( $prepend, range( 10, 12 ) );
4
+ $minutes = array_merge( array( '00' ), $prepend, range( 10, 59 ) );
5
+ $day_period = array( 'am', 'pm' );
6
 
7
+ if ( is_object( $value ) ) {
8
+ $value = (array) $value;
9
+ }
10
  ?>
11
  <select name="<?php echo $name . '[][hours]'; ?>" class="fl-time-field-hours">
12
+ <?php foreach ( $hours as $hour ) : ?>
13
  <?php $selected = isset( $value['hours'] ) && $value['hours'] == $hour ? ' selected="selected"' : ''; ?>
14
  <option value="<?php echo $hour ?>"<?php echo $selected ?>><?php echo $hour ?></option>
15
  <?php endforeach; ?>
16
  </select>
17
  <select name="<?php echo $name . '[][minutes]'; ?>" class="fl-time-field-minutes">
18
+ <?php foreach ( $minutes as $minute ) : ?>
19
  <?php $selected = isset( $value['minutes'] ) && $value['minutes'] == $minute ? ' selected="selected"' : ''; ?>
20
  <option value="<?php echo $minute ?>"<?php echo $selected ?>><?php echo $minute ?></option>
21
  <?php endforeach; ?>
22
  </select>
23
  <select name="<?php echo $name . '[][day_period]'; ?>" class="fl-time-field-day_period">
24
+ <?php foreach ( $day_period as $period ) : ?>
25
  <?php $selected = isset( $value['day_period'] ) && $value['day_period'] == $period ? ' selected="selected"' : ''; ?>
26
  <option value="<?php echo $period ?>"<?php echo $selected ?>><?php echo $period ?></option>
27
  <?php endforeach; ?>
28
+ </select>
includes/field-timezone.php CHANGED
@@ -1,3 +1,6 @@
1
- <select name="<?php echo $name; ?>"<?php if(isset($field['class'])) echo ' class="'. $field['class'] .'"'; if(isset($field['toggle'])) echo "data-toggle='". json_encode($field['toggle']) ."'"; if(isset($field['hide'])) echo "data-hide='". json_encode($field['hide']) ."'"; if(isset($field['trigger'])) echo "data-trigger='". json_encode($field['trigger']) ."'"; ?>>
 
 
 
2
  <?php echo FLBuilderTimezones::build_timezones( $settings->time_zone ); ?>
3
- </select>
1
+ <select name="<?php echo $name; ?>"<?php if ( isset( $field['class'] ) ) { echo ' class="' . $field['class'] . '"';
2
+ } if ( isset( $field['toggle'] ) ) { echo "data-toggle='" . json_encode( $field['toggle'] ) . "'";
3
+ } if ( isset( $field['hide'] ) ) { echo "data-hide='" . json_encode( $field['hide'] ) . "'";
4
+ } if ( isset( $field['trigger'] ) ) { echo "data-trigger='" . json_encode( $field['trigger'] ) . "'";} ?>>
5
  <?php echo FLBuilderTimezones::build_timezones( $settings->time_zone ); ?>
6
+ </select>
includes/field-unit.php CHANGED
@@ -2,5 +2,5 @@
2
  type="number"
3
  name="<?php echo esc_attr( $name ); ?>"
4
  value="<?php echo esc_attr( $value ); ?>"
5
- placeholder="<?php if ( isset( $field['placeholder'] ) ) echo esc_attr( $field['placeholder'] ); ?>"
6
  />
2
  type="number"
3
  name="<?php echo esc_attr( $name ); ?>"
4
  value="<?php echo esc_attr( $value ); ?>"
5
+ placeholder="<?php if ( isset( $field['placeholder'] ) ) { echo esc_attr( $field['placeholder'] );} ?>"
6
  />
includes/field-video.php CHANGED
@@ -1,8 +1,9 @@
1
- <?php $video = FLBuilderPhoto::get_attachment_data($value); ?>
2
- <div class="fl-video-field fl-builder-custom-field<?php if(empty($value) || !$video) echo ' fl-video-empty'; if(isset($field['class'])) echo ' ' . $field['class']; ?>">
3
- <a class="fl-video-select" href="javascript:void(0);" onclick="return false;"><?php _e('Select Video', 'fl-builder'); ?></a>
 
4
  <div class="fl-video-preview">
5
- <?php if(!empty($value) && $video) : ?>
6
  <div class="fl-video-preview-img">
7
  <img src="<?php echo $video->icon; ?>" />
8
  </div>
@@ -14,8 +15,8 @@
14
  <span class="fl-video-preview-filename"></span>
15
  <?php endif; ?>
16
  <br />
17
- <a class="fl-video-replace" href="javascript:void(0);" onclick="return false;"><?php _e('Replace Video', 'fl-builder'); ?></a>
18
  <div class="fl-clear"></div>
19
  </div>
20
  <input name="<?php echo $name; ?>" type="hidden" value='<?php echo $value; ?>' />
21
- </div>
1
+ <?php $video = FLBuilderPhoto::get_attachment_data( $value ); ?>
2
+ <div class="fl-video-field fl-builder-custom-field<?php if ( empty( $value ) || ! $video ) { echo ' fl-video-empty';
3
+ } if ( isset( $field['class'] ) ) { echo ' ' . $field['class'];} ?>">
4
+ <a class="fl-video-select" href="javascript:void(0);" onclick="return false;"><?php _e( 'Select Video', 'fl-builder' ); ?></a>
5
  <div class="fl-video-preview">
6
+ <?php if ( ! empty( $value ) && $video ) : ?>
7
  <div class="fl-video-preview-img">
8
  <img src="<?php echo $video->icon; ?>" />
9
  </div>
15
  <span class="fl-video-preview-filename"></span>
16
  <?php endif; ?>
17
  <br />
18
+ <a class="fl-video-replace" href="javascript:void(0);" onclick="return false;"><?php _e( 'Replace Video', 'fl-builder' ); ?></a>
19
  <div class="fl-clear"></div>
20
  </div>
21
  <input name="<?php echo $name; ?>" type="hidden" value='<?php echo $value; ?>' />
22
+ </div>
includes/field.php CHANGED
@@ -1,24 +1,23 @@
1
- <?php if(empty($field['label'])) : ?>
2
  <td class="fl-field-control" colspan="2">
3
  <?php else : ?>
4
  <th class="fl-field-label">
5
  <label for="<?php echo $name; ?>">
6
- <?php
7
-
8
  if ( 'button' == $field['type'] ) {
9
  echo '&nbsp;';
10
- }
11
- else {
 
12
 
13
- echo $field['label'];
14
-
15
  if ( isset( $i ) ) {
16
  echo ' <span class="fl-builder-field-index">' . ( $i + 1 ) . '</span>';
17
- }
18
  }
19
-
20
  ?>
21
- <?php if(isset($field['help'])) : ?>
22
  <span class="fl-help-tooltip">
23
  <i class="fl-help-tooltip-icon fa fa-question-circle"></i>
24
  <span class="fl-help-tooltip-text"><?php echo $field['help']; ?></span>
@@ -33,21 +32,21 @@
33
  <i class="fl-field-responsive-toggle dashicons dashicons-desktop" data-mode="default"></i>
34
  <?php endif; ?>
35
  <?php
36
-
37
  foreach ( array( 'default', 'medium', 'responsive' ) as $device ) {
38
-
39
  if ( 'default' != $device && ! $responsive ) {
40
  continue;
41
  }
42
-
43
  if ( $responsive ) {
44
-
45
  $name = 'default' == $device ? $root_name : $root_name . '_' . $device;
46
  $value = isset( $settings->$name ) ? $settings->$name : '';
47
-
48
  echo '<div class="fl-field-responsive-setting fl-field-responsive-setting-' . $device . '" data-device="' . $device . '">';
49
-
50
- if ( is_array( $responsive ) ) {
51
  foreach ( $responsive as $responsive_key => $responsive_var ) {
52
  if ( is_array( $responsive_var ) && isset( $responsive_var[ $device ] ) ) {
53
  $field[ $responsive_key ] = $responsive_var[ $device ];
@@ -55,30 +54,29 @@
55
  }
56
  }
57
  }
58
-
59
- do_action('fl_builder_before_control', $name, $value, $field, $settings);
60
- do_action('fl_builder_before_control_' . $field['type'], $name, $value, $field, $settings);
61
-
62
  $field_file = FL_BUILDER_DIR . 'includes/field-' . $field['type'] . '.php';
63
-
64
- if(file_exists($field_file)) {
65
- include $field_file;
66
- }
67
- else {
68
- do_action('fl_builder_control_' . $field['type'], $name, $value, $field, $settings);
69
  }
70
-
71
- do_action('fl_builder_after_control_' . $field['type'], $name, $value, $field, $settings);
72
- do_action('fl_builder_after_control', $name, $value, $field, $settings);
73
 
74
  if ( $responsive ) {
75
  echo '</div>';
76
  }
77
- }
78
-
79
  ?>
80
- <?php if(isset($field['description'])) : ?>
81
  <span class="fl-field-description"><?php echo $field['description']; ?></span>
82
  <?php endif; ?>
83
  </div>
84
- </td>
1
+ <?php if ( empty( $field['label'] ) ) : ?>
2
  <td class="fl-field-control" colspan="2">
3
  <?php else : ?>
4
  <th class="fl-field-label">
5
  <label for="<?php echo $name; ?>">
6
+ <?php
7
+
8
  if ( 'button' == $field['type'] ) {
9
  echo '&nbsp;';
10
+ } else {
11
+
12
+ echo $field['label'];
13
 
 
 
14
  if ( isset( $i ) ) {
15
  echo ' <span class="fl-builder-field-index">' . ( $i + 1 ) . '</span>';
16
+ }
17
  }
18
+
19
  ?>
20
+ <?php if ( isset( $field['help'] ) ) : ?>
21
  <span class="fl-help-tooltip">
22
  <i class="fl-help-tooltip-icon fa fa-question-circle"></i>
23
  <span class="fl-help-tooltip-text"><?php echo $field['help']; ?></span>
32
  <i class="fl-field-responsive-toggle dashicons dashicons-desktop" data-mode="default"></i>
33
  <?php endif; ?>
34
  <?php
35
+
36
  foreach ( array( 'default', 'medium', 'responsive' ) as $device ) {
37
+
38
  if ( 'default' != $device && ! $responsive ) {
39
  continue;
40
  }
41
+
42
  if ( $responsive ) {
43
+
44
  $name = 'default' == $device ? $root_name : $root_name . '_' . $device;
45
  $value = isset( $settings->$name ) ? $settings->$name : '';
46
+
47
  echo '<div class="fl-field-responsive-setting fl-field-responsive-setting-' . $device . '" data-device="' . $device . '">';
48
+
49
+ if ( is_array( $responsive ) ) {
50
  foreach ( $responsive as $responsive_key => $responsive_var ) {
51
  if ( is_array( $responsive_var ) && isset( $responsive_var[ $device ] ) ) {
52
  $field[ $responsive_key ] = $responsive_var[ $device ];
54
  }
55
  }
56
  }
57
+
58
+ do_action( 'fl_builder_before_control', $name, $value, $field, $settings );
59
+ do_action( 'fl_builder_before_control_' . $field['type'], $name, $value, $field, $settings );
60
+
61
  $field_file = FL_BUILDER_DIR . 'includes/field-' . $field['type'] . '.php';
62
+
63
+ if ( file_exists( $field_file ) ) {
64
+ include $field_file;
65
+ } else {
66
+ do_action( 'fl_builder_control_' . $field['type'], $name, $value, $field, $settings );
 
67
  }
68
+
69
+ do_action( 'fl_builder_after_control_' . $field['type'], $name, $value, $field, $settings );
70
+ do_action( 'fl_builder_after_control', $name, $value, $field, $settings );
71
 
72
  if ( $responsive ) {
73
  echo '</div>';
74
  }
75
+ }// End foreach().
76
+
77
  ?>
78
+ <?php if ( isset( $field['description'] ) ) : ?>
79
  <span class="fl-field-description"><?php echo $field['description']; ?></span>
80
  <?php endif; ?>
81
  </div>
82
+ </td>
includes/global-settings.php CHANGED
@@ -4,62 +4,62 @@ FLBuilder::register_settings_form('global', array(
4
  'title' => __( 'Global Settings', 'fl-builder' ),
5
  'tabs' => array(
6
  'general' => array(
7
- 'title' => __('General', 'fl-builder'),
8
- 'description' => __('<strong>Note</strong>: These settings apply to all posts and pages.', 'fl-builder'),
9
  'sections' => array(
10
  'page_heading' => array(
11
- 'title' => __('Default Page Heading', 'fl-builder'),
12
  'fields' => array(
13
  'show_default_heading' => array(
14
  'type' => 'select',
15
  'label' => _x( 'Show', 'General settings form field label. Intended meaning: "Show page heading?"', 'fl-builder' ),
16
  'default' => '0',
17
  'options' => array(
18
- '0' => __('No', 'fl-builder'),
19
- '1' => __('Yes', 'fl-builder')
20
  ),
21
  'toggle' => array(
22
  '0' => array(
23
- 'fields' => array('default_heading_selector')
24
- )
25
  ),
26
- 'help' => __('Choosing no will hide the default theme heading for the "Page" post type. You will also be required to enter some basic CSS for this to work if you choose no.', 'fl-builder'),
27
  ),
28
  'default_heading_selector' => array(
29
  'type' => 'text',
30
- 'label' => __('CSS Selector', 'fl-builder'),
31
  'default' => '.fl-post-header',
32
- 'help' => __('Enter a CSS selector for the default page heading to hide it.', 'fl-builder')
33
- )
34
- )
35
  ),
36
  'rows' => array(
37
- 'title' => __('Rows', 'fl-builder'),
38
  'fields' => array(
39
  'row_margins' => array(
40
  'type' => 'unit',
41
- 'label' => __('Margins', 'fl-builder'),
42
  'default' => '0',
43
  'placeholder' => '0',
44
  'responsive' => true,
45
- 'description' => 'px'
46
  ),
47
  'row_padding' => array(
48
  'type' => 'unit',
49
- 'label' => __('Padding', 'fl-builder'),
50
  'default' => '20',
51
  'placeholder' => '0',
52
  'responsive' => true,
53
- 'description' => 'px'
54
  ),
55
  'row_width' => array(
56
  'type' => 'text',
57
- 'label' => __('Max Width', 'fl-builder'),
58
  'default' => '1100',
59
  'maxlength' => '4',
60
  'size' => '5',
61
  'description' => 'px',
62
- 'help' => __('All rows will default to this width. You can override this and make a row full width in the settings for each row.', 'fl-builder')
63
  ),
64
  'row_width_default' => array(
65
  'type' => 'select',
@@ -67,12 +67,12 @@ FLBuilder::register_settings_form('global', array(
67
  'default' => 'fixed',
68
  'options' => array(
69
  'fixed' => __( 'Fixed', 'fl-builder' ),
70
- 'full' => __( 'Full Width', 'fl-builder' )
71
  ),
72
  'toggle' => array(
73
  'full' => array(
74
- 'fields' => array('row_content_width_default')
75
- )
76
  ),
77
  ),
78
  'row_content_width_default' => array(
@@ -81,75 +81,75 @@ FLBuilder::register_settings_form('global', array(
81
  'default' => 'fixed',
82
  'options' => array(
83
  'fixed' => __( 'Fixed', 'fl-builder' ),
84
- 'full' => __( 'Full Width', 'fl-builder' )
85
  ),
86
- )
87
- )
88
  ),
89
  'modules' => array(
90
- 'title' => __('Modules', 'fl-builder'),
91
  'fields' => array(
92
  'module_margins' => array(
93
  'type' => 'unit',
94
- 'label' => __('Margins', 'fl-builder'),
95
  'default' => '20',
96
  'placeholder' => '0',
97
  'responsive' => true,
98
- 'description' => 'px'
99
- )
100
- )
101
  ),
102
  'responsive' => array(
103
- 'title' => __('Responsive Layout', 'fl-builder'),
104
  'fields' => array(
105
  'responsive_enabled' => array(
106
  'type' => 'select',
107
  'label' => _x( 'Enabled', 'General settings form field label. Intended meaning: "Responsive layout enabled?"', 'fl-builder' ),
108
  'default' => '1',
109
  'options' => array(
110
- '0' => __('No', 'fl-builder'),
111
- '1' => __('Yes', 'fl-builder')
112
  ),
113
  'toggle' => array(
114
  '1' => array(
115
- 'fields' => array('auto_spacing', 'responsive_breakpoint', 'medium_breakpoint')
116
- )
117
- )
118
  ),
119
  'auto_spacing' => array(
120
  'type' => 'select',
121
  'label' => _x( 'Enable Auto Spacing', 'General settings form field label. Intended meaning: "Enable auto spacing for responsive layouts?"', 'fl-builder' ),
122
  'default' => '1',
123
  'options' => array(
124
- '0' => __('No', 'fl-builder'),
125
- '1' => __('Yes', 'fl-builder')
126
  ),
127
- 'help' => __('When auto spacing is enabled, the builder will automatically adjust the margins and padding in your layout once the small device breakpoint is reached. Most users will want to leave this enabled.', 'fl-builder')
128
  ),
129
  'medium_breakpoint' => array(
130
  'type' => 'text',
131
- 'label' => __('Medium Device Breakpoint', 'fl-builder'),
132
  'default' => '992',
133
  'maxlength' => '4',
134
  'size' => '5',
135
  'description' => 'px',
136
- 'help' => __('The browser width at which the layout will adjust for medium devices such as tablets.', 'fl-builder')
137
  ),
138
  'responsive_breakpoint' => array(
139
  'type' => 'text',
140
- 'label' => __('Small Device Breakpoint', 'fl-builder'),
141
  'default' => '768',
142
  'maxlength' => '4',
143
  'size' => '5',
144
  'description' => 'px',
145
- 'help' => __('The browser width at which the layout will adjust for small devices such as phones.', 'fl-builder')
146
- )
147
- )
148
- )
149
- )
150
  ),
151
  'css' => array(
152
- 'title' => __('CSS', 'fl-builder'),
153
  'sections' => array(
154
  'css' => array(
155
  'title' => '',
@@ -160,15 +160,15 @@ FLBuilder::register_settings_form('global', array(
160
  'editor' => 'css',
161
  'rows' => '18',
162
  'preview' => array(
163
- 'type' => 'none'
164
- )
165
- )
166
- )
167
- )
168
- )
169
  ),
170
  'js' => array(
171
- 'title' => __('JavaScript', 'fl-builder'),
172
  'sections' => array(
173
  'js' => array(
174
  'title' => '',
@@ -179,12 +179,12 @@ FLBuilder::register_settings_form('global', array(
179
  'editor' => 'javascript',
180
  'rows' => '18',
181
  'preview' => array(
182
- 'type' => 'none'
183
- )
184
- )
185
- )
186
- )
187
- )
188
- )
189
- )
190
- ));
4
  'title' => __( 'Global Settings', 'fl-builder' ),
5
  'tabs' => array(
6
  'general' => array(
7
+ 'title' => __( 'General', 'fl-builder' ),
8
+ 'description' => __( '<strong>Note</strong>: These settings apply to all posts and pages.', 'fl-builder' ),
9
  'sections' => array(
10
  'page_heading' => array(
11
+ 'title' => __( 'Default Page Heading', 'fl-builder' ),
12
  'fields' => array(
13
  'show_default_heading' => array(
14
  'type' => 'select',
15
  'label' => _x( 'Show', 'General settings form field label. Intended meaning: "Show page heading?"', 'fl-builder' ),
16
  'default' => '0',
17
  'options' => array(
18
+ '0' => __( 'No', 'fl-builder' ),
19
+ '1' => __( 'Yes', 'fl-builder' ),
20
  ),
21
  'toggle' => array(
22
  '0' => array(
23
+ 'fields' => array( 'default_heading_selector' ),
24
+ ),
25
  ),
26
+ 'help' => __( 'Choosing no will hide the default theme heading for the "Page" post type. You will also be required to enter some basic CSS for this to work if you choose no.', 'fl-builder' ),
27
  ),
28
  'default_heading_selector' => array(
29
  'type' => 'text',
30
+ 'label' => __( 'CSS Selector', 'fl-builder' ),
31
  'default' => '.fl-post-header',
32
+ 'help' => __( 'Enter a CSS selector for the default page heading to hide it.', 'fl-builder' ),
33
+ ),
34
+ ),
35
  ),
36
  'rows' => array(
37
+ 'title' => __( 'Rows', 'fl-builder' ),
38
  'fields' => array(
39
  'row_margins' => array(
40
  'type' => 'unit',
41
+ 'label' => __( 'Margins', 'fl-builder' ),
42
  'default' => '0',
43
  'placeholder' => '0',
44
  'responsive' => true,
45
+ 'description' => 'px',
46
  ),
47
  'row_padding' => array(
48
  'type' => 'unit',
49
+ 'label' => __( 'Padding', 'fl-builder' ),
50
  'default' => '20',
51
  'placeholder' => '0',
52
  'responsive' => true,
53
+ 'description' => 'px',
54
  ),
55
  'row_width' => array(
56
  'type' => 'text',
57
+ 'label' => __( 'Max Width', 'fl-builder' ),
58
  'default' => '1100',
59
  'maxlength' => '4',
60
  'size' => '5',
61
  'description' => 'px',
62
+ 'help' => __( 'All rows will default to this width. You can override this and make a row full width in the settings for each row.', 'fl-builder' ),
63
  ),
64
  'row_width_default' => array(
65
  'type' => 'select',
67
  'default' => 'fixed',
68
  'options' => array(
69
  'fixed' => __( 'Fixed', 'fl-builder' ),
70
+ 'full' => __( 'Full Width', 'fl-builder' ),
71
  ),
72
  'toggle' => array(
73
  'full' => array(
74
+ 'fields' => array( 'row_content_width_default' ),
75
+ ),
76
  ),
77
  ),
78
  'row_content_width_default' => array(
81
  'default' => 'fixed',
82
  'options' => array(
83
  'fixed' => __( 'Fixed', 'fl-builder' ),
84
+ 'full' => __( 'Full Width', 'fl-builder' ),
85
  ),
86
+ ),
87
+ ),
88
  ),
89
  'modules' => array(
90
+ 'title' => __( 'Modules', 'fl-builder' ),
91
  'fields' => array(
92
  'module_margins' => array(
93
  'type' => 'unit',
94
+ 'label' => __( 'Margins', 'fl-builder' ),
95
  'default' => '20',
96
  'placeholder' => '0',
97
  'responsive' => true,
98
+ 'description' => 'px',
99
+ ),
100
+ ),
101
  ),
102
  'responsive' => array(
103
+ 'title' => __( 'Responsive Layout', 'fl-builder' ),
104
  'fields' => array(
105
  'responsive_enabled' => array(
106
  'type' => 'select',
107
  'label' => _x( 'Enabled', 'General settings form field label. Intended meaning: "Responsive layout enabled?"', 'fl-builder' ),
108
  'default' => '1',
109
  'options' => array(
110
+ '0' => __( 'No', 'fl-builder' ),
111
+ '1' => __( 'Yes', 'fl-builder' ),
112
  ),
113
  'toggle' => array(
114
  '1' => array(
115
+ 'fields' => array( 'auto_spacing', 'responsive_breakpoint', 'medium_breakpoint' ),
116
+ ),
117
+ ),
118
  ),
119
  'auto_spacing' => array(
120
  'type' => 'select',
121
  'label' => _x( 'Enable Auto Spacing', 'General settings form field label. Intended meaning: "Enable auto spacing for responsive layouts?"', 'fl-builder' ),
122
  'default' => '1',
123
  'options' => array(
124
+ '0' => __( 'No', 'fl-builder' ),
125
+ '1' => __( 'Yes', 'fl-builder' ),
126
  ),
127
+ 'help' => __( 'When auto spacing is enabled, the builder will automatically adjust the margins and padding in your layout once the small device breakpoint is reached. Most users will want to leave this enabled.', 'fl-builder' ),
128
  ),
129
  'medium_breakpoint' => array(
130
  'type' => 'text',
131
+ 'label' => __( 'Medium Device Breakpoint', 'fl-builder' ),
132
  'default' => '992',
133
  'maxlength' => '4',
134
  'size' => '5',
135
  'description' => 'px',
136
+ 'help' => __( 'The browser width at which the layout will adjust for medium devices such as tablets.', 'fl-builder' ),
137
  ),
138
  'responsive_breakpoint' => array(
139
  'type' => 'text',
140
+ 'label' => __( 'Small Device Breakpoint', 'fl-builder' ),
141
  'default' => '768',
142
  'maxlength' => '4',
143
  'size' => '5',
144
  'description' => 'px',
145
+ 'help' => __( 'The browser width at which the layout will adjust for small devices such as phones.', 'fl-builder' ),
146
+ ),
147
+ ),
148
+ ),
149
+ ),
150
  ),
151
  'css' => array(
152
+ 'title' => __( 'CSS', 'fl-builder' ),
153
  'sections' => array(
154
  'css' => array(
155
  'title' => '',
160
  'editor' => 'css',
161
  'rows' => '18',
162
  'preview' => array(
163
+ 'type' => 'none',
164
+ ),
165
+ ),
166
+ ),
167
+ ),
168
+ ),
169
  ),
170
  'js' => array(
171
+ 'title' => __( 'JavaScript', 'fl-builder' ),
172
  'sections' => array(
173
  'js' => array(
174
  'title' => '',
179
  'editor' => 'javascript',
180
  'rows' => '18',
181
  'preview' => array(
182
+ 'type' => 'none',
183
+ ),
184
+ ),
185
+ ),
186
+ ),
187
+ ),
188
+ ),
189
+ ),
190
+ ));
includes/icon-selector.php CHANGED
@@ -14,7 +14,7 @@
14
  <?php foreach ( $icon_sets as $set_key => $set_data ) : ?>
15
  <div class="fl-icons-section fl-<?php echo $set_key; ?>">
16
  <h2><?php echo $set_data['name']; ?></h2>
17
- <?php foreach( $set_data['icons'] as $icon ) : ?>
18
  <?php if ( ! empty( $set_data['prefix'] ) ) : ?>
19
  <i class="<?php echo $set_data['prefix'] . ' ' . $icon; ?>"></i>
20
  <?php else : ?>
@@ -25,5 +25,5 @@
25
  <?php endforeach; ?>
26
  </div>
27
  <div class="fl-lightbox-footer fl-icon-selector-footer">
28
- <a class="fl-icon-selector-cancel fl-builder-button fl-builder-button-large" href="javascript:void(0);" onclick="return false;"><?php _e('Cancel', 'fl-builder'); ?></a>
29
- </div>
14
  <?php foreach ( $icon_sets as $set_key => $set_data ) : ?>
15
  <div class="fl-icons-section fl-<?php echo $set_key; ?>">
16
  <h2><?php echo $set_data['name']; ?></h2>
17
+ <?php foreach ( $set_data['icons'] as $icon ) : ?>
18
  <?php if ( ! empty( $set_data['prefix'] ) ) : ?>
19
  <i class="<?php echo $set_data['prefix'] . ' ' . $icon; ?>"></i>
20
  <?php else : ?>
25
  <?php endforeach; ?>
26
  </div>
27
  <div class="fl-lightbox-footer fl-icon-selector-footer">
28
+ <a class="fl-icon-selector-cancel fl-builder-button fl-builder-button-large" href="javascript:void(0);" onclick="return false;"><?php _e( 'Cancel', 'fl-builder' ); ?></a>
29
+ </div>
includes/jquery.php CHANGED
@@ -5,4 +5,4 @@ if(typeof jQuery == 'undefined' || typeof jQuery.fn.on == 'undefined') {
5
  document.write('<script src="<?php echo FL_BUILDER_URL ?>js/jquery.migrate.min.js"><\/script>');
6
  }
7
 
8
- </script>
5
  document.write('<script src="<?php echo FL_BUILDER_URL ?>js/jquery.migrate.min.js"><\/script>');
6
  }
7
 
8
+ </script>
includes/layout-js-config.php CHANGED
@@ -15,4 +15,4 @@ var FLBuilderLayoutConfig = {
15
  waypoint: {
16
  offset: 80
17
  }
18
- };
15
  waypoint: {
16
  offset: 80
17
  }
18
+ };
includes/layout-settings.php CHANGED
@@ -1,10 +1,10 @@
1
  <?php
2
 
3
  FLBuilder::register_settings_form('layout', array(
4
- 'title' => __('Layout CSS / Javascript', 'fl-builder'),
5
  'tabs' => array(
6
  'css' => array(
7
- 'title' => __('CSS', 'fl-builder'),
8
  'sections' => array(
9
  'css' => array(
10
  'title' => '',
@@ -15,15 +15,15 @@ FLBuilder::register_settings_form('layout', array(
15
  'editor' => 'css',
16
  'rows' => '18',
17
  'preview' => array(
18
- 'type' => 'none'
19
- )
20
- )
21
- )
22
- )
23
- )
24
  ),
25
  'js' => array(
26
- 'title' => __('JavaScript', 'fl-builder'),
27
  'sections' => array(
28
  'js' => array(
29
  'title' => '',
@@ -34,12 +34,12 @@ FLBuilder::register_settings_form('layout', array(
34
  'editor' => 'javascript',
35
  'rows' => '18',
36
  'preview' => array(
37
- 'type' => 'none'
38
- )
39
- )
40
- )
41
- )
42
- )
43
- )
44
- )
45
  ));
1
  <?php
2
 
3
  FLBuilder::register_settings_form('layout', array(
4
+ 'title' => __( 'Layout CSS / Javascript', 'fl-builder' ),
5
  'tabs' => array(
6
  'css' => array(
7
+ 'title' => __( 'CSS', 'fl-builder' ),
8
  'sections' => array(
9
  'css' => array(
10
  'title' => '',
15
  'editor' => 'css',
16
  'rows' => '18',
17
  'preview' => array(
18
+ 'type' => 'none',
19
+ ),
20
+ ),
21
+ ),
22
+ ),
23
+ ),
24
  ),
25
  'js' => array(
26
+ 'title' => __( 'JavaScript', 'fl-builder' ),
27
  'sections' => array(
28
  'js' => array(
29
  'title' => '',
34
  'editor' => 'javascript',
35
  'rows' => '18',
36
  'preview' => array(
37
+ 'type' => 'none',
38
+ ),
39
+ ),
40
+ ),
41
+ ),
42
+ ),
43
+ ),
44
+ ),
45
  ));
includes/loop-settings-matching.php CHANGED
@@ -1,4 +1,4 @@
1
  <select name="<?php echo $name ?>_matching">
2
  <option value="1" <?php selected( $settings->{ $name . '_matching' }, '1' ); ?>><?php printf( _x( 'Match these %s', '%s is an object like posts or taxonomies.', 'fl-builder' ), $field['label'] ); ?></option>
3
  <option value="0" <?php selected( $settings->{ $name . '_matching' }, '0' ); ?>><?php printf( _x( 'Do not match these %s', '%s is an object like posts or taxonomies.', 'fl-builder' ), $field['label'] ); ?></option>
4
- </select>
1
  <select name="<?php echo $name ?>_matching">
2
  <option value="1" <?php selected( $settings->{ $name . '_matching' }, '1' ); ?>><?php printf( _x( 'Match these %s', '%s is an object like posts or taxonomies.', 'fl-builder' ), $field['label'] ); ?></option>
3
  <option value="0" <?php selected( $settings->{ $name . '_matching' }, '0' ); ?>><?php printf( _x( 'Do not match these %s', '%s is an object like posts or taxonomies.', 'fl-builder' ), $field['label'] ); ?></option>
4
+ </select>
includes/loop-settings.php CHANGED
@@ -7,11 +7,11 @@ $defaults = array(
7
  'order_by' => 'date',
8
  'order' => 'DESC',
9
  'offset' => 0,
10
- 'users' => ''
11
  );
12
 
13
  $tab_defaults = isset( $tab['defaults'] ) ? $tab['defaults'] : array();
14
- $settings = (object)array_merge( $defaults, $tab_defaults, (array)$settings );
15
  $settings = apply_filters( 'fl_builder_loop_settings', $settings ); //Allow extension of default Values
16
 
17
  do_action( 'fl_builder_loop_settings_before_form', $settings ); // e.g Add custom FLBuilder::render_settings_field()
@@ -20,98 +20,98 @@ do_action( 'fl_builder_loop_settings_before_form', $settings ); // e.g Add custo
20
  <div id="fl-builder-settings-section-source" class="fl-loop-data-source-select fl-builder-settings-section">
21
  <table class="fl-form-table">
22
  <?php
23
-
24
  // Data Source
25
  FLBuilder::render_settings_field('data_source', array(
26
  'type' => 'select',
27
- 'label' => __('Source', 'fl-builder'),
28
  'default' => 'custom_query',
29
  'options' => array(
30
- 'custom_query' => __('Custom Query', 'fl-builder'),
31
- 'main_query' => __('Main Query', 'fl-builder'),
32
  ),
33
  'toggle' => array(
34
  'custom_query' => array(
35
- 'fields' => array( 'posts_per_page' )
36
- )
37
- )
38
  ), $settings);
39
-
40
  ?>
41
  </table>
42
  </div>
43
  <div class="fl-custom-query fl-loop-data-source" data-source="custom_query">
44
  <div id="fl-builder-settings-section-general" class="fl-builder-settings-section">
45
- <h3 class="fl-builder-settings-title"><?php _e('Custom Query', 'fl-builder'); ?></h3>
46
  <table class="fl-form-table">
47
  <?php
48
-
49
  // Post type
50
  FLBuilder::render_settings_field('post_type', array(
51
  'type' => 'post-type',
52
- 'label' => __('Post Type', 'fl-builder'),
53
  ), $settings);
54
-
55
  // Order
56
  FLBuilder::render_settings_field('order', array(
57
  'type' => 'select',
58
- 'label' => __('Order', 'fl-builder'),
59
  'options' => array(
60
- 'DESC' => __('Descending', 'fl-builder'),
61
- 'ASC' => __('Ascending', 'fl-builder'),
62
- )
63
  ), $settings);
64
-
65
  // Order by
66
  FLBuilder::render_settings_field('order_by', array(
67
  'type' => 'select',
68
- 'label' => __('Order By', 'fl-builder'),
69
  'options' => array(
70
- 'author' => __('Author', 'fl-builder'),
71
- 'comment_count' => __('Comment Count', 'fl-builder'),
72
- 'date' => __('Date', 'fl-builder'),
73
- 'modified' => __('Date Last Modified', 'fl-builder'),
74
- 'ID' => __('ID', 'fl-builder'),
75
- 'menu_order' => __('Menu Order', 'fl-builder'),
76
- 'meta_value' => __('Meta Value (Alphabetical)', 'fl-builder'),
77
- 'meta_value_num' => __('Meta Value (Numeric)', 'fl-builder'),
78
- 'rand' => __('Random', 'fl-builder'),
79
- 'title' => __('Title', 'fl-builder'),
80
  ),
81
  'toggle' => array(
82
  'meta_value' => array(
83
- 'fields' => array( 'order_by_meta_key' )
84
  ),
85
  'meta_value_num' => array(
86
- 'fields' => array( 'order_by_meta_key' )
87
- )
88
- )
89
  ), $settings);
90
-
91
  // Meta Key
92
  FLBuilder::render_settings_field('order_by_meta_key', array(
93
  'type' => 'text',
94
- 'label' => __('Meta Key', 'fl-builder'),
95
  ), $settings);
96
-
97
  // Offset
98
  FLBuilder::render_settings_field('offset', array(
99
  'type' => 'text',
100
- 'label' => _x('Offset', 'How many posts to skip.', 'fl-builder'),
101
  'default' => '0',
102
  'size' => '4',
103
- 'help' => __('Skip this many posts that match the specified criteria.', 'fl-builder')
104
  ), $settings);
105
-
106
  ?>
107
  </table>
108
  </div>
109
  <div id="fl-builder-settings-section-filter" class="fl-builder-settings-section">
110
- <h3 class="fl-builder-settings-title"><?php _e('Filter', 'fl-builder'); ?></h3>
111
- <?php foreach(FLBuilderLoop::post_types() as $slug => $type) : ?>
112
- <table class="fl-form-table fl-custom-query-filter fl-custom-query-<?php echo $slug; ?>-filter" <?php if($slug == $settings->post_type) echo 'style="display:table;"'; ?>>
113
  <?php
114
-
115
  // Posts
116
  FLBuilder::render_settings_field( 'posts_' . $slug, array(
117
  'type' => 'suggest',
@@ -119,37 +119,37 @@ do_action( 'fl_builder_loop_settings_before_form', $settings ); // e.g Add custo
119
  'data' => $slug,
120
  'label' => $type->label,
121
  'help' => sprintf( __( 'Enter a list of %1$s.', 'fl-builder' ), $type->label ),
122
- 'matching' => true
123
  ), $settings );
124
-
125
  // Taxonomies
126
- $taxonomies = FLBuilderLoop::taxonomies($slug);
127
-
128
- foreach($taxonomies as $tax_slug => $tax) {
129
-
130
  FLBuilder::render_settings_field( 'tax_' . $slug . '_' . $tax_slug, array(
131
  'type' => 'suggest',
132
  'action' => 'fl_as_terms',
133
  'data' => $tax_slug,
134
  'label' => $tax->label,
135
  'help' => sprintf( __( 'Enter a list of %1$s.', 'fl-builder' ), $tax->label ),
136
- 'matching' => true
137
  ), $settings );
138
  }
139
-
140
  ?>
141
  </table>
142
  <?php endforeach; ?>
143
  <table class="fl-form-table">
144
  <?php
145
-
146
  // Author
147
  FLBuilder::render_settings_field('users', array(
148
  'type' => 'suggest',
149
  'action' => 'fl_as_users',
150
- 'label' => __('Authors', 'fl-builder'),
151
- 'help' => __('Enter a list of authors usernames.', 'fl-builder'),
152
- 'matching' => true
153
  ), $settings);
154
 
155
  ?>
@@ -157,4 +157,4 @@ do_action( 'fl_builder_loop_settings_before_form', $settings ); // e.g Add custo
157
  </div>
158
  </div>
159
  <?php
160
- do_action( 'fl_builder_loop_settings_after_form', $settings ); // e.g Add custom FLBuilder::render_settings_field()
7
  'order_by' => 'date',
8
  'order' => 'DESC',
9
  'offset' => 0,
10
+ 'users' => '',
11
  );
12
 
13
  $tab_defaults = isset( $tab['defaults'] ) ? $tab['defaults'] : array();
14
+ $settings = (object) array_merge( $defaults, $tab_defaults, (array) $settings );
15
  $settings = apply_filters( 'fl_builder_loop_settings', $settings ); //Allow extension of default Values
16
 
17
  do_action( 'fl_builder_loop_settings_before_form', $settings ); // e.g Add custom FLBuilder::render_settings_field()
20
  <div id="fl-builder-settings-section-source" class="fl-loop-data-source-select fl-builder-settings-section">
21
  <table class="fl-form-table">
22
  <?php
23
+
24
  // Data Source
25
  FLBuilder::render_settings_field('data_source', array(
26
  'type' => 'select',
27
+ 'label' => __( 'Source', 'fl-builder' ),
28
  'default' => 'custom_query',
29
  'options' => array(
30
+ 'custom_query' => __( 'Custom Query', 'fl-builder' ),
31
+ 'main_query' => __( 'Main Query', 'fl-builder' ),
32
  ),
33
  'toggle' => array(
34
  'custom_query' => array(
35
+ 'fields' => array( 'posts_per_page' ),
36
+ ),
37
+ ),
38
  ), $settings);
39
+
40
  ?>
41
  </table>
42
  </div>
43
  <div class="fl-custom-query fl-loop-data-source" data-source="custom_query">
44
  <div id="fl-builder-settings-section-general" class="fl-builder-settings-section">
45
+ <h3 class="fl-builder-settings-title"><?php _e( 'Custom Query', 'fl-builder' ); ?></h3>
46
  <table class="fl-form-table">
47
  <?php
48
+
49
  // Post type
50
  FLBuilder::render_settings_field('post_type', array(
51
  'type' => 'post-type',
52
+ 'label' => __( 'Post Type', 'fl-builder' ),
53
  ), $settings);
54
+
55
  // Order
56
  FLBuilder::render_settings_field('order', array(
57
  'type' => 'select',
58
+ 'label' => __( 'Order', 'fl-builder' ),
59
  'options' => array(
60
+ 'DESC' => __( 'Descending', 'fl-builder' ),
61
+ 'ASC' => __( 'Ascending', 'fl-builder' ),
62
+ ),
63
  ), $settings);
64
+
65
  // Order by
66
  FLBuilder::render_settings_field('order_by', array(
67
  'type' => 'select',
68
+ 'label' => __( 'Order By', 'fl-builder' ),
69
  'options' => array(
70
+ 'author' => __( 'Author', 'fl-builder' ),
71
+ 'comment_count' => __( 'Comment Count', 'fl-builder' ),
72
+ 'date' => __( 'Date', 'fl-builder' ),
73
+ 'modified' => __( 'Date Last Modified', 'fl-builder' ),
74
+ 'ID' => __( 'ID', 'fl-builder' ),
75
+ 'menu_order' => __( 'Menu Order', 'fl-builder' ),
76
+ 'meta_value' => __( 'Meta Value (Alphabetical)', 'fl-builder' ),
77
+ 'meta_value_num' => __( 'Meta Value (Numeric)', 'fl-builder' ),
78
+ 'rand' => __( 'Random', 'fl-builder' ),
79
+ 'title' => __( 'Title', 'fl-builder' ),
80
  ),
81
  'toggle' => array(
82
  'meta_value' => array(
83
+ 'fields' => array( 'order_by_meta_key' ),
84
  ),
85
  'meta_value_num' => array(
86
+ 'fields' => array( 'order_by_meta_key' ),
87
+ ),
88
+ ),
89
  ), $settings);
90
+
91
  // Meta Key
92
  FLBuilder::render_settings_field('order_by_meta_key', array(
93
  'type' => 'text',
94
+ 'label' => __( 'Meta Key', 'fl-builder' ),
95
  ), $settings);
96
+
97
  // Offset
98
  FLBuilder::render_settings_field('offset', array(
99
  'type' => 'text',
100
+ 'label' => _x( 'Offset', 'How many posts to skip.', 'fl-builder' ),
101
  'default' => '0',
102
  'size' => '4',
103
+ 'help' => __( 'Skip this many posts that match the specified criteria.', 'fl-builder' ),
104
  ), $settings);
105
+
106
  ?>
107
  </table>
108
  </div>
109
  <div id="fl-builder-settings-section-filter" class="fl-builder-settings-section">
110
+ <h3 class="fl-builder-settings-title"><?php _e( 'Filter', 'fl-builder' ); ?></h3>
111
+ <?php foreach ( FLBuilderLoop::post_types() as $slug => $type ) : ?>
112
+ <table class="fl-form-table fl-custom-query-filter fl-custom-query-<?php echo $slug; ?>-filter" <?php if ( $slug == $settings->post_type ) { echo 'style="display:table;"';} ?>>
113
  <?php
114
+
115
  // Posts
116
  FLBuilder::render_settings_field( 'posts_' . $slug, array(
117
  'type' => 'suggest',
119
  'data' => $slug,
120
  'label' => $type->label,
121
  'help' => sprintf( __( 'Enter a list of %1$s.', 'fl-builder' ), $type->label ),
122
+ 'matching' => true,
123
  ), $settings );
124
+
125
  // Taxonomies
126
+ $taxonomies = FLBuilderLoop::taxonomies( $slug );
127
+
128
+ foreach ( $taxonomies as $tax_slug => $tax ) {
129
+
130
  FLBuilder::render_settings_field( 'tax_' . $slug . '_' . $tax_slug, array(
131
  'type' => 'suggest',
132
  'action' => 'fl_as_terms',
133
  'data' => $tax_slug,
134
  'label' => $tax->label,
135
  'help' => sprintf( __( 'Enter a list of %1$s.', 'fl-builder' ), $tax->label ),
136
+ 'matching' => true,
137
  ), $settings );
138
  }
139
+
140
  ?>
141
  </table>
142
  <?php endforeach; ?>
143
  <table class="fl-form-table">
144
  <?php
145
+
146
  // Author
147
  FLBuilder::render_settings_field('users', array(
148
  'type' => 'suggest',
149
  'action' => 'fl_as_users',
150
+ 'label' => __( 'Authors', 'fl-builder' ),
151
+ 'help' => __( 'Enter a list of authors usernames.', 'fl-builder' ),
152
+ 'matching' => true,
153
  ), $settings);
154
 
155
  ?>
157
  </div>
158
  </div>
159
  <?php
160
+ do_action( 'fl_builder_loop_settings_after_form', $settings ); // e.g Add custom FLBuilder::render_settings_field()
includes/module-settings.php CHANGED
@@ -3,10 +3,10 @@
3
  $global_settings = FLBuilderModel::get_global_settings();
4
 
5
  FLBuilder::register_settings_form('module_advanced', array(
6
- 'title' => __('Advanced', 'fl-builder'),
7
  'sections' => array(
8
  'margins' => array(
9
- 'title' => __('Margins', 'fl-builder'),
10
  'fields' => array(
11
  'margin_top' => array(
12
  'type' => 'unit',
@@ -20,8 +20,8 @@ FLBuilder::register_settings_form('module_advanced', array(
20
  'default' => ( isset( $global_settings->module_margins ) ) ? $global_settings->module_margins : '',
21
  'medium' => ( isset( $global_settings->module_margins_medium ) ) ? $global_settings->module_margins_medium : '',
22
  'responsive' => ( isset( $global_settings->module_margins_responsive ) ) ? $global_settings->module_margins_responsive : '',
23
- )
24
- )
25
  ),
26
  'margin_bottom' => array(
27
  'type' => 'unit',
@@ -35,8 +35,8 @@ FLBuilder::register_settings_form('module_advanced', array(
35
  'default' => ( isset( $global_settings->module_margins ) ) ? $global_settings->module_margins : '',
36
  'medium' => ( isset( $global_settings->module_margins_medium ) ) ? $global_settings->module_margins_medium : '',
37
  'responsive' => ( isset( $global_settings->module_margins_responsive ) ) ? $global_settings->module_margins_responsive : '',
38
- )
39
- )
40
  ),
41
  'margin_left' => array(
42
  'type' => 'unit',
@@ -50,8 +50,8 @@ FLBuilder::register_settings_form('module_advanced', array(
50
  'default' => ( isset( $global_settings->module_margins ) ) ? $global_settings->module_margins : '',
51
  'medium' => ( isset( $global_settings->module_margins_medium ) ) ? $global_settings->module_margins_medium : '',
52
  'responsive' => ( isset( $global_settings->module_margins_responsive ) ) ? $global_settings->module_margins_responsive : '',
53
- )
54
- )
55
  ),
56
  'margin_right' => array(
57
  'type' => 'unit',
@@ -65,69 +65,69 @@ FLBuilder::register_settings_form('module_advanced', array(
65
  'default' => ( isset( $global_settings->module_margins ) ) ? $global_settings->module_margins : '',
66
  'medium' => ( isset( $global_settings->module_margins_medium ) ) ? $global_settings->module_margins_medium : '',
67
  'responsive' => ( isset( $global_settings->module_margins_responsive ) ) ? $global_settings->module_margins_responsive : '',
68
- )
69
- )
70
  ),
71
- )
72
  ),
73
  'responsive' => array(
74
- 'title' => __('Responsive Layout', 'fl-builder'),
75
  'fields' => array(
76
  'responsive_display' => array(
77
  'type' => 'select',
78
- 'label' => __('Display', 'fl-builder'),
79
  'options' => array(
80
- '' => __('Always', 'fl-builder'),
81
- 'desktop' => __('Large Devices Only', 'fl-builder'),
82
- 'desktop-medium' => __('Large &amp; Medium Devices Only', 'fl-builder'),
83
- 'medium' => __('Medium Devices Only', 'fl-builder'),
84
- 'medium-mobile' => __('Medium &amp; Small Devices Only', 'fl-builder'),
85
- 'mobile' => __('Small Devices Only', 'fl-builder'),
86
  ),
87
  'help' => __( 'Choose whether to show or hide this module at different device sizes.', 'fl-builder' ),
88
  'preview' => array(
89
- 'type' => 'none'
90
- )
91
  ),
92
- )
93
  ),
94
  'visibility' => array(
95
- 'title' => __('Visibility', 'fl-builder'),
96
  'fields' => array(
97
  'visibility_display' => array(
98
  'type' => 'select',
99
- 'label' => __('Display', 'fl-builder'),
100
  'options' => array(
101
- '' => __('Always', 'fl-builder'),
102
- 'logged_out' => __('Logged Out User', 'fl-builder'),
103
- 'logged_in' => __('Logged In User', 'fl-builder'),
104
- '0' => __('Never', 'fl-builder'),
105
  ),
106
  'toggle' => array(
107
  'logged_in' => array(
108
- 'fields' => array('visibility_user_capability')
109
- )
110
  ),
111
  'preview' => array(
112
- 'type' => 'none'
113
- )
114
  ),
115
  'visibility_user_capability' => array(
116
  'type' => 'text',
117
- 'label' => __('User Capability', 'fl-builder'),
118
  'description' => sprintf( __( 'Optional. Set the <a%s>capability</a> required for users to view this module.', 'fl-builder' ), ' href="http://codex.wordpress.org/Roles_and_Capabilities#Capability_vs._Role_Table" target="_blank"' ),
119
  'preview' => array(
120
- 'type' => 'none'
121
  ),
122
- )
123
- )
124
  ),
125
  'animation' => array(
126
- 'title' => __('Animation', 'fl-builder'),
127
  'fields' => array(
128
  'animation' => array(
129
  'type' => 'select',
130
- 'label' => __('Style', 'fl-builder'),
131
  'options' => array(
132
  '' => _x( 'None', 'Animation style.', 'fl-builder' ),
133
  'fade-in' => _x( 'Fade In', 'Animation style.', 'fl-builder' ),
@@ -137,43 +137,43 @@ FLBuilder::register_settings_form('module_advanced', array(
137
  'slide-down' => _x( 'Slide Down', 'Animation style.', 'fl-builder' ),
138
  ),
139
  'preview' => array(
140
- 'type' => 'none'
141
- )
142
  ),
143
  'animation_delay' => array(
144
  'type' => 'text',
145
- 'label' => __('Delay', 'fl-builder'),
146
  'default' => '0.0',
147
  'maxlength' => '4',
148
  'size' => '5',
149
  'description' => _x( 'seconds', 'Value unit for form field of time in seconds. Such as: "5 seconds"', 'fl-builder' ),
150
- 'help' => __('The amount of time in seconds before this animation starts.', 'fl-builder'),
151
  'preview' => array(
152
- 'type' => 'none'
153
- )
154
- )
155
- )
156
  ),
157
  'css_selectors' => array(
158
- 'title' => __('HTML Element', 'fl-builder'),
159
  'fields' => array(
160
  'id' => array(
161
  'type' => 'text',
162
- 'label' => __('ID', 'fl-builder'),
163
  'help' => __( "A unique ID that will be applied to this module's HTML. Must start with a letter and only contain dashes, underscores, letters or numbers. No spaces.", 'fl-builder' ),
164
  'preview' => array(
165
- 'type' => 'none'
166
- )
167
  ),
168
  'class' => array(
169
  'type' => 'text',
170
- 'label' => __('Class', 'fl-builder'),
171
  'help' => __( "A class that will be applied to this module's HTML. Must start with a letter and only contain dashes, underscores, letters or numbers. Separate multiple classes with spaces.", 'fl-builder' ),
172
  'preview' => array(
173
- 'type' => 'none'
174
- )
175
- )
176
- )
177
- )
178
- )
179
  ));
3
  $global_settings = FLBuilderModel::get_global_settings();
4
 
5
  FLBuilder::register_settings_form('module_advanced', array(
6
+ 'title' => __( 'Advanced', 'fl-builder' ),
7
  'sections' => array(
8
  'margins' => array(
9
+ 'title' => __( 'Margins', 'fl-builder' ),
10
  'fields' => array(
11
  'margin_top' => array(
12
  'type' => 'unit',
20
  'default' => ( isset( $global_settings->module_margins ) ) ? $global_settings->module_margins : '',
21
  'medium' => ( isset( $global_settings->module_margins_medium ) ) ? $global_settings->module_margins_medium : '',
22
  'responsive' => ( isset( $global_settings->module_margins_responsive ) ) ? $global_settings->module_margins_responsive : '',
23
+ ),
24
+ ),
25
  ),
26
  'margin_bottom' => array(
27
  'type' => 'unit',
35
  'default' => ( isset( $global_settings->module_margins ) ) ? $global_settings->module_margins : '',
36
  'medium' => ( isset( $global_settings->module_margins_medium ) ) ? $global_settings->module_margins_medium : '',
37
  'responsive' => ( isset( $global_settings->module_margins_responsive ) ) ? $global_settings->module_margins_responsive : '',
38
+ ),
39
+ ),
40
  ),
41
  'margin_left' => array(
42
  'type' => 'unit',
50
  'default' => ( isset( $global_settings->module_margins ) ) ? $global_settings->module_margins : '',
51
  'medium' => ( isset( $global_settings->module_margins_medium ) ) ? $global_settings->module_margins_medium : '',
52
  'responsive' => ( isset( $global_settings->module_margins_responsive ) ) ? $global_settings->module_margins_responsive : '',
53
+ ),
54
+ ),
55
  ),
56
  'margin_right' => array(
57
  'type' => 'unit',
65
  'default' => ( isset( $global_settings->module_margins ) ) ? $global_settings->module_margins : '',
66
  'medium' => ( isset( $global_settings->module_margins_medium ) ) ? $global_settings->module_margins_medium : '',
67
  'responsive' => ( isset( $global_settings->module_margins_responsive ) ) ? $global_settings->module_margins_responsive : '',
68
+ ),
69
+ ),
70
  ),
71
+ ),
72
  ),
73
  'responsive' => array(
74
+ 'title' => __( 'Responsive Layout', 'fl-builder' ),
75
  'fields' => array(
76
  'responsive_display' => array(
77
  'type' => 'select',
78
+ 'label' => __( 'Display', 'fl-builder' ),
79
  'options' => array(
80
+ '' => __( 'Always', 'fl-builder' ),
81
+ 'desktop' => __( 'Large Devices Only', 'fl-builder' ),
82
+ 'desktop-medium' => __( 'Large &amp; Medium Devices Only', 'fl-builder' ),
83
+ 'medium' => __( 'Medium Devices Only', 'fl-builder' ),
84
+ 'medium-mobile' => __( 'Medium &amp; Small Devices Only', 'fl-builder' ),
85
+ 'mobile' => __( 'Small Devices Only', 'fl-builder' ),
86
  ),
87
  'help' => __( 'Choose whether to show or hide this module at different device sizes.', 'fl-builder' ),
88
  'preview' => array(
89
+ 'type' => 'none',
90
+ ),
91
  ),
92
+ ),
93
  ),
94
  'visibility' => array(
95
+ 'title' => __( 'Visibility', 'fl-builder' ),
96
  'fields' => array(
97
  'visibility_display' => array(
98
  'type' => 'select',
99
+ 'label' => __( 'Display', 'fl-builder' ),
100
  'options' => array(
101
+ '' => __( 'Always', 'fl-builder' ),
102
+ 'logged_out' => __( 'Logged Out User', 'fl-builder' ),
103
+ 'logged_in' => __( 'Logged In User', 'fl-builder' ),
104
+ '0' => __( 'Never', 'fl-builder' ),
105
  ),
106
  'toggle' => array(
107
  'logged_in' => array(
108
+ 'fields' => array( 'visibility_user_capability' ),
109
+ ),
110
  ),
111
  'preview' => array(
112
+ 'type' => 'none',
113
+ ),
114
  ),
115
  'visibility_user_capability' => array(
116
  'type' => 'text',
117
+ 'label' => __( 'User Capability', 'fl-builder' ),
118
  'description' => sprintf( __( 'Optional. Set the <a%s>capability</a> required for users to view this module.', 'fl-builder' ), ' href="http://codex.wordpress.org/Roles_and_Capabilities#Capability_vs._Role_Table" target="_blank"' ),
119
  'preview' => array(
120
+ 'type' => 'none',
121
  ),
122
+ ),
123
+ ),
124
  ),
125
  'animation' => array(
126
+ 'title' => __( 'Animation', 'fl-builder' ),
127
  'fields' => array(
128
  'animation' => array(
129
  'type' => 'select',
130
+ 'label' => __( 'Style', 'fl-builder' ),
131
  'options' => array(
132
  '' => _x( 'None', 'Animation style.', 'fl-builder' ),
133
  'fade-in' => _x( 'Fade In', 'Animation style.', 'fl-builder' ),
137
  'slide-down' => _x( 'Slide Down', 'Animation style.', 'fl-builder' ),
138
  ),
139
  'preview' => array(
140
+ 'type' => 'none',
141
+ ),
142
  ),
143
  'animation_delay' => array(
144
  'type' => 'text',
145
+ 'label' => __( 'Delay', 'fl-builder' ),
146
  'default' => '0.0',
147
  'maxlength' => '4',
148
  'size' => '5',
149
  'description' => _x( 'seconds', 'Value unit for form field of time in seconds. Such as: "5 seconds"', 'fl-builder' ),
150
+ 'help' => __( 'The amount of time in seconds before this animation starts.', 'fl-builder' ),
151
  'preview' => array(
152
+ 'type' => 'none',
153
+ ),
154
+ ),
155
+ ),
156
  ),
157
  'css_selectors' => array(
158
+ 'title' => __( 'HTML Element', 'fl-builder' ),
159
  'fields' => array(
160
  'id' => array(
161
  'type' => 'text',
162
+ 'label' => __( 'ID', 'fl-builder' ),
163
  'help' => __( "A unique ID that will be applied to this module's HTML. Must start with a letter and only contain dashes, underscores, letters or numbers. No spaces.", 'fl-builder' ),
164
  'preview' => array(
165
+ 'type' => 'none',
166
+ ),
167
  ),
168
  'class' => array(
169
  'type' => 'text',
170
+ 'label' => __( 'Class', 'fl-builder' ),
171
  'help' => __( "A class that will be applied to this module's HTML. Must start with a letter and only contain dashes, underscores, letters or numbers. Separate multiple classes with spaces.", 'fl-builder' ),
172
  'preview' => array(
173
+ 'type' => 'none',
174
+ ),
175
+ ),
176
+ ),
177
+ ),
178
+ ),
179
  ));
includes/module.php CHANGED
@@ -1,5 +1,11 @@
1
  <div<?php FLBuilder::render_module_attributes( $module ); ?>>
2
  <div class="fl-module-content fl-node-content">
3
- <?php include $module->dir . 'includes/frontend.php'; ?>
 
 
 
 
 
 
4
  </div>
5
- </div>
1
  <div<?php FLBuilder::render_module_attributes( $module ); ?>>
2
  <div class="fl-module-content fl-node-content">
3
+ <?php ob_start();
4
+ include $module->dir . 'includes/frontend.php';
5
+
6
+ $out = ob_get_clean();
7
+
8
+ echo apply_filters( 'fl_builder_render_module_content', $out, $module );
9
+ ?>
10
  </div>
11
+ </div>
includes/row-css.php CHANGED
@@ -1,4 +1,4 @@
1
- <?php if(!empty($row->settings->text_color)) : // Text Color ?>
2
  .fl-node-<?php echo $row->node; ?> {
3
  color: #<?php echo $row->settings->text_color; ?>;
4
  }
@@ -7,27 +7,27 @@
7
  }
8
  <?php endif; ?>
9
 
10
- <?php if(!empty($row->settings->link_color)) : // Link Color ?>
11
  .fl-builder-content .fl-node-<?php echo $row->node; ?> a {
12
  color: #<?php echo $row->settings->link_color; ?>;
13
  }
14
- <?php elseif(!empty($row->settings->text_color)) : ?>
15
  .fl-builder-content .fl-node-<?php echo $row->node; ?> a {
16
  color: #<?php echo $row->settings->text_color; ?>;
17
  }
18
  <?php endif; ?>
19
 
20
- <?php if(!empty($row->settings->hover_color)) : // Link Hover Color ?>
21
  .fl-builder-content .fl-node-<?php echo $row->node; ?> a:hover {
22
  color: #<?php echo $row->settings->hover_color; ?>;
23
  }
24
- <?php elseif(!empty($row->settings->text_color)) : ?>
25
  .fl-builder-content .fl-node-<?php echo $row->node; ?> a:hover {
26
  color: #<?php echo $row->settings->text_color; ?>;
27
  }
28
  <?php endif; ?>
29
 
30
- <?php if(!empty($row->settings->heading_color)) : // Heading Color ?>
31
  .fl-builder-content .fl-node-<?php echo $row->node; ?> h1,
32
  .fl-builder-content .fl-node-<?php echo $row->node; ?> h2,
33
  .fl-builder-content .fl-node-<?php echo $row->node; ?> h3,
@@ -42,7 +42,7 @@
42
  .fl-builder-content .fl-node-<?php echo $row->node; ?> h6 a {
43
  color: #<?php echo $row->settings->heading_color; ?>;
44
  }
45
- <?php elseif(!empty($row->settings->text_color)) : ?>
46
  .fl-builder-content .fl-node-<?php echo $row->node; ?> h1,
47
  .fl-builder-content .fl-node-<?php echo $row->node; ?> h2,
48
  .fl-builder-content .fl-node-<?php echo $row->node; ?> h3,
@@ -59,14 +59,14 @@
59
  }
60
  <?php endif; ?>
61
 
62
- <?php if(in_array( $row->settings->bg_type, array('color', 'photo', 'parallax', 'slideshow', 'video') ) && !empty($row->settings->bg_color)) : // Background Color ?>
63
  .fl-node-<?php echo $row->node; ?> > .fl-row-content-wrap {
64
  background-color: #<?php echo $row->settings->bg_color; ?>;
65
- background-color: rgba(<?php echo implode(',', FLBuilderColor::hex_to_rgb($row->settings->bg_color)) ?>, <?php echo $row->settings->bg_opacity/100; ?>);
66
  }
67
  <?php endif; ?>
68
 
69
- <?php if($row->settings->bg_type == 'photo' && !empty($row->settings->bg_image)) : // Background Photo ?>
70
  .fl-node-<?php echo $row->node; ?> > .fl-row-content-wrap {
71
  background-image: url(<?php echo $row->settings->bg_image_src; ?>);
72
  background-repeat: <?php echo $row->settings->bg_repeat; ?>;
@@ -76,14 +76,14 @@
76
  }
77
  <?php endif; ?>
78
 
79
- <?php if( in_array( $row->settings->bg_type, array('photo', 'parallax', 'slideshow', 'video') ) && !empty($row->settings->bg_overlay_color)) : // Background Color Overlay ?>
80
  .fl-node-<?php echo $row->node; ?> > .fl-row-content-wrap:after {
81
  background-color: #<?php echo $row->settings->bg_overlay_color; ?>;
82
- background-color: rgba(<?php echo implode(',', FLBuilderColor::hex_to_rgb($row->settings->bg_overlay_color)) ?>, <?php echo $row->settings->bg_overlay_opacity/100; ?>);
83
  }
84
  <?php endif; ?>
85
 
86
- <?php if($row->settings->bg_type == 'parallax' && !empty($row->settings->bg_parallax_image_src)) : // Parallax Background ?>
87
  .fl-node-<?php echo $row->node; ?> > .fl-row-content-wrap {
88
  background-repeat: no-repeat;
89
  background-position: center center;
@@ -97,13 +97,13 @@
97
  }
98
  <?php endif; ?>
99
 
100
- <?php if(!empty($row->settings->border_type)) : // Border ?>
101
  .fl-node-<?php echo $row->node; ?> > .fl-row-content-wrap {
102
  border-style: <?php echo $row->settings->border_type; ?>;
103
  border-width: 0;
104
- <?php if(!empty($row->settings->border_color)) : ?>
105
  border-color: #<?php echo $row->settings->border_color; ?>;
106
- border-color: rgba(<?php echo implode(',', FLBuilderColor::hex_to_rgb($row->settings->border_color)) ?>, <?php echo $row->settings->border_opacity/100; ?>);
107
  <?php endif; ?>
108
  }
109
- <?php endif; ?>
1
+ <?php if ( ! empty( $row->settings->text_color ) ) : // Text Color ?>
2
  .fl-node-<?php echo $row->node; ?> {
3
  color: #<?php echo $row->settings->text_color; ?>;
4
  }
7
  }
8
  <?php endif; ?>
9
 
10
+ <?php if ( ! empty( $row->settings->link_color ) ) : // Link Color ?>
11
  .fl-builder-content .fl-node-<?php echo $row->node; ?> a {
12
  color: #<?php echo $row->settings->link_color; ?>;
13
  }
14
+ <?php elseif ( ! empty( $row->settings->text_color ) ) : ?>
15
  .fl-builder-content .fl-node-<?php echo $row->node; ?> a {
16
  color: #<?php echo $row->settings->text_color; ?>;
17
  }
18
  <?php endif; ?>
19
 
20
+ <?php if ( ! empty( $row->settings->hover_color ) ) : // Link Hover Color ?>
21
  .fl-builder-content .fl-node-<?php echo $row->node; ?> a:hover {
22
  color: #<?php echo $row->settings->hover_color; ?>;
23
  }
24
+ <?php elseif ( ! empty( $row->settings->text_color ) ) : ?>
25
  .fl-builder-content .fl-node-<?php echo $row->node; ?> a:hover {
26
  color: #<?php echo $row->settings->text_color; ?>;
27
  }
28
  <?php endif; ?>
29
 
30
+ <?php if ( ! empty( $row->settings->heading_color ) ) : // Heading Color ?>
31
  .fl-builder-content .fl-node-<?php echo $row->node; ?> h1,
32
  .fl-builder-content .fl-node-<?php echo $row->node; ?> h2,
33
  .fl-builder-content .fl-node-<?php echo $row->node; ?> h3,
42
  .fl-builder-content .fl-node-<?php echo $row->node; ?> h6 a {
43
  color: #<?php echo $row->settings->heading_color; ?>;
44
  }
45
+ <?php elseif ( ! empty( $row->settings->text_color ) ) : ?>
46
  .fl-builder-content .fl-node-<?php echo $row->node; ?> h1,
47
  .fl-builder-content .fl-node-<?php echo $row->node; ?> h2,
48
  .fl-builder-content .fl-node-<?php echo $row->node; ?> h3,
59
  }
60
  <?php endif; ?>
61
 
62
+ <?php if ( in_array( $row->settings->bg_type, array( 'color', 'photo', 'parallax', 'slideshow', 'video' ) ) && ! empty( $row->settings->bg_color ) ) : // Background Color ?>
63
  .fl-node-<?php echo $row->node; ?> > .fl-row-content-wrap {
64
  background-color: #<?php echo $row->settings->bg_color; ?>;
65
+ background-color: rgba(<?php echo implode( ',', FLBuilderColor::hex_to_rgb( $row->settings->bg_color ) ) ?>, <?php echo $row->settings->bg_opacity / 100; ?>);
66
  }
67
  <?php endif; ?>
68
 
69
+ <?php if ( 'photo' == $row->settings->bg_type && ! empty( $row->settings->bg_image ) ) : // Background Photo ?>
70
  .fl-node-<?php echo $row->node; ?> > .fl-row-content-wrap {
71
  background-image: url(<?php echo $row->settings->bg_image_src; ?>);
72
  background-repeat: <?php echo $row->settings->bg_repeat; ?>;
76
  }
77
  <?php endif; ?>
78
 
79
+ <?php if ( in_array( $row->settings->bg_type, array( 'photo', 'parallax', 'slideshow', 'video' ) ) && ! empty( $row->settings->bg_overlay_color ) ) : // Background Color Overlay ?>
80
  .fl-node-<?php echo $row->node; ?> > .fl-row-content-wrap:after {
81
  background-color: #<?php echo $row->settings->bg_overlay_color; ?>;
82
+ background-color: rgba(<?php echo implode( ',', FLBuilderColor::hex_to_rgb( $row->settings->bg_overlay_color ) ) ?>, <?php echo $row->settings->bg_overlay_opacity / 100; ?>);
83
  }
84
  <?php endif; ?>
85
 
86
+ <?php if ( 'parallax' == $row->settings->bg_type && ! empty( $row->settings->bg_parallax_image_src ) ) : // Parallax Background ?>
87
  .fl-node-<?php echo $row->node; ?> > .fl-row-content-wrap {
88
  background-repeat: no-repeat;
89
  background-position: center center;
97
  }
98
  <?php endif; ?>
99
 
100
+ <?php if ( ! empty( $row->settings->border_type ) ) : // Border ?>
101
  .fl-node-<?php echo $row->node; ?> > .fl-row-content-wrap {
102
  border-style: <?php echo $row->settings->border_type; ?>;
103
  border-width: 0;
104
+ <?php if ( ! empty( $row->settings->border_color ) ) : ?>
105
  border-color: #<?php echo $row->settings->border_color; ?>;
106
+ border-color: rgba(<?php echo implode( ',', FLBuilderColor::hex_to_rgb( $row->settings->border_color ) ) ?>, <?php echo $row->settings->border_opacity / 100; ?>);
107
  <?php endif; ?>
108
  }
109
+ <?php endif; ?>
includes/row-js.php CHANGED
@@ -1,14 +1,14 @@
1
- <?php
2
 
3
- if($settings->bg_type == 'slideshow') :
4
 
5
- $source = FLBuilderModel::get_row_slideshow_source($row);
6
-
7
- if(!empty($source)) :
8
 
9
  ?>
10
  YUI({'logExclude': { 'yui': true } }).use('fl-slideshow', function(Y) {
11
-
12
  if( null === Y.one('.fl-node-<?php echo $id; ?> .fl-bg-slideshow') ) {
13
  return;
14
  }
@@ -25,19 +25,19 @@ YUI({'logExclude': { 'yui': true } }).use('fl-slideshow', function(Y) {
25
  stretchy : true,
26
  stretchyType : 'contain',
27
  transition : '<?php echo $settings->ss_transition; ?>',
28
- transitionDuration : <?php echo !empty($settings->ss_transitionDuration) ? $settings->ss_transitionDuration : 1; ?>
29
  });
30
-
31
  if(oldSlideshow) {
32
  oldSlideshow.remove(true);
33
  }
34
 
35
  newSlideshow.render('.fl-node-<?php echo $id; ?> .fl-bg-slideshow');
36
  });
37
- <?php
38
 
39
  endif;
40
 
41
- endif;
42
 
43
- ?>
1
+ <?php
2
 
3
+ if ( 'slideshow' == $settings->bg_type ) :
4
 
5
+ $source = FLBuilderModel::get_row_slideshow_source( $row );
6
+
7
+ if ( ! empty( $source ) ) :
8
 
9
  ?>
10
  YUI({'logExclude': { 'yui': true } }).use('fl-slideshow', function(Y) {
11
+
12
  if( null === Y.one('.fl-node-<?php echo $id; ?> .fl-bg-slideshow') ) {
13
  return;
14
  }
25
  stretchy : true,
26
  stretchyType : 'contain',
27
  transition : '<?php echo $settings->ss_transition; ?>',
28
+ transitionDuration : <?php echo ! empty( $settings->ss_transitionDuration ) ? $settings->ss_transitionDuration : 1; // @codingStandardsIgnoreLine ?>
29
  });
30
+
31
  if(oldSlideshow) {
32
  oldSlideshow.remove(true);
33
  }
34
 
35
  newSlideshow.render('.fl-node-<?php echo $id; ?> .fl-bg-slideshow');
36
  });
37
+ <?php
38
 
39
  endif;
40
 
41
+ endif;
42
 
43
+ ?>
includes/row-settings.php CHANGED
@@ -4,66 +4,66 @@ $global_settings = FLBuilderModel::get_global_settings();
4
  $spacing_placeholders = FLBuilderModel::get_row_spacing_placeholders();
5
 
6
  FLBuilder::register_settings_form('row', array(
7
- 'title' => __('Row Settings', 'fl-builder'),
8
  'tabs' => array(
9
  'style' => array(
10
- 'title' => __('Style', 'fl-builder'),
11
  'sections' => array(
12
  'general' => array(
13
  'title' => '',
14
  'fields' => array(
15
  'width' => array(
16
  'type' => 'select',
17
- 'label' => __('Width', 'fl-builder'),
18
  'default' => $global_settings->row_width_default,
19
  'options' => array(
20
- 'fixed' => __('Fixed', 'fl-builder'),
21
- 'full' => __('Full Width', 'fl-builder')
22
  ),
23
  'toggle' => array(
24
  'full' => array(
25
- 'fields' => array('content_width')
26
- )
27
  ),
28
- 'help' => __('Full width rows span the width of the page from edge to edge. Fixed rows are no wider than the Row Max Width set in the Global Settings.', 'fl-builder'),
29
  'preview' => array(
30
- 'type' => 'none'
31
- )
32
  ),
33
  'content_width' => array(
34
  'type' => 'select',
35
- 'label' => __('Content Width', 'fl-builder'),
36
  'default' => $global_settings->row_content_width_default,
37
  'options' => array(
38
- 'fixed' => __('Fixed', 'fl-builder'),
39
- 'full' => __('Full Width', 'fl-builder')
40
  ),
41
- 'help' => __('Full width content spans the width of the page from edge to edge. Fixed content is no wider than the Row Max Width set in the Global Settings.', 'fl-builder'),
42
  'preview' => array(
43
- 'type' => 'none'
44
- )
45
  ),
46
  'full_height' => array(
47
  'type' => 'select',
48
- 'label' => __('Height', 'fl-builder'),
49
  'default' => 'default',
50
  'options' => array(
51
- 'default' => __('Default', 'fl-builder'),
52
- 'full' => __('Full Height', 'fl-builder')
53
  ),
54
- 'help' => __('Full height rows fill the height of the browser window.', 'fl-builder'),
55
  'toggle' => array(
56
  'full' => array(
57
- 'fields' => array('content_alignment')
58
- )
59
  ),
60
  'preview' => array(
61
- 'type' => 'none'
62
- )
63
  ),
64
  'content_alignment' => array(
65
  'type' => 'select',
66
- 'label' => __('Content Alignment', 'fl-builder'),
67
  'default' => 'center',
68
  'options' => array(
69
  'top' => __( 'Top', 'fl-builder' ),
@@ -71,54 +71,54 @@ FLBuilder::register_settings_form('row', array(
71
  'bottom' => __( 'Bottom', 'fl-builder' ),
72
  ),
73
  'preview' => array(
74
- 'type' => 'none'
75
- )
76
- )
77
- )
78
  ),
79
  'colors' => array(
80
- 'title' => __('Colors', 'fl-builder'),
81
  'fields' => array(
82
  'text_color' => array(
83
  'type' => 'color',
84
- 'label' => __('Text Color', 'fl-builder'),
85
  'show_reset' => true,
86
  'preview' => array(
87
- 'type' => 'none'
88
- )
89
  ),
90
  'link_color' => array(
91
  'type' => 'color',
92
- 'label' => __('Link Color', 'fl-builder'),
93
  'show_reset' => true,
94
  'preview' => array(
95
- 'type' => 'none'
96
- )
97
  ),
98
  'hover_color' => array(
99
  'type' => 'color',
100
- 'label' => __('Link Hover Color', 'fl-builder'),
101
  'show_reset' => true,
102
  'preview' => array(
103
- 'type' => 'none'
104
- )
105
  ),
106
  'heading_color' => array(
107
  'type' => 'color',
108
- 'label' => __('Heading Color', 'fl-builder'),
109
  'show_reset' => true,
110
  'preview' => array(
111
- 'type' => 'none'
112
- )
113
- )
114
- )
115
  ),
116
  'background' => array(
117
- 'title' => __('Background', 'fl-builder'),
118
  'fields' => array(
119
  'bg_type' => array(
120
  'type' => 'select',
121
- 'label' => __('Type', 'fl-builder'),
122
  'default' => 'none',
123
  'options' => array(
124
  'none' => _x( 'None', 'Background type.', 'fl-builder' ),
@@ -127,427 +127,428 @@ FLBuilder::register_settings_form('row', array(
127
  'video' => _x( 'Video', 'Background type.', 'fl-builder' ),
128
  'slideshow' => array(
129
  'label' => _x( 'Slideshow', 'Background type.', 'fl-builder' ),
130
- 'premium' => true
131
  ),
132
  'parallax' => array(
133
  'label' => _x( 'Parallax', 'Background type.', 'fl-builder' ),
134
- 'premium' => true
135
- )
136
  ),
137
  'toggle' => array(
138
  'color' => array(
139
- 'sections' => array('bg_color')
140
  ),
141
  'photo' => array(
142
- 'sections' => array('bg_color', 'bg_photo', 'bg_overlay')
143
  ),
144
  'video' => array(
145
- 'sections' => array('bg_color', 'bg_video', 'bg_overlay')
146
  ),
147
  'slideshow' => array(
148
- 'sections' => array('bg_color', 'bg_slideshow', 'bg_overlay')
149
  ),
150
  'parallax' => array(
151
- 'sections' => array('bg_color','bg_parallax', 'bg_overlay')
152
- )
153
  ),
154
  'preview' => array(
155
- 'type' => 'none'
156
- )
157
- )
158
- )
159
  ),
160
  'bg_photo' => array(
161
- 'title' => __('Background Photo', 'fl-builder'),
162
  'fields' => array(
163
  'bg_image' => array(
164
  'type' => 'photo',
165
- 'label' => __('Photo', 'fl-builder'),
166
  'preview' => array(
167
- 'type' => 'none'
168
  ),
169
- 'connections' => array( 'photo' )
170
  ),
171
  'bg_repeat' => array(
172
  'type' => 'select',
173
- 'label' => __('Repeat', 'fl-builder'),
174
  'default' => 'none',
175
  'options' => array(
176
  'no-repeat' => _x( 'None', 'Background repeat.', 'fl-builder' ),
177
  'repeat' => _x( 'Tile', 'Background repeat.', 'fl-builder' ),
178
  'repeat-x' => _x( 'Horizontal', 'Background repeat.', 'fl-builder' ),
179
- 'repeat-y' => _x( 'Vertical', 'Background repeat.', 'fl-builder' )
180
  ),
181
- 'help' => __('Repeat applies to how the image should display in the background. Choosing none will display the image as uploaded. Tile will repeat the image as many times as needed to fill the background horizontally and vertically. You can also specify the image to only repeat horizontally or vertically.', 'fl-builder'),
182
  'preview' => array(
183
- 'type' => 'none'
184
- )
185
  ),
186
  'bg_position' => array(
187
  'type' => 'select',
188
- 'label' => __('Position', 'fl-builder'),
189
  'default' => 'center center',
190
  'options' => array(
191
- 'left top' => __('Left Top', 'fl-builder'),
192
- 'left center' => __('Left Center', 'fl-builder'),
193
- 'left bottom' => __('Left Bottom', 'fl-builder'),
194
- 'right top' => __('Right Top', 'fl-builder'),
195
- 'right center' => __('Right Center', 'fl-builder'),
196
- 'right bottom' => __('Right Bottom', 'fl-builder'),
197
- 'center top' => __('Center Top', 'fl-builder'),
198
  'center center' => __( 'Center', 'fl-builder' ),
199
- 'center bottom' => __('Center Bottom', 'fl-builder')
200
  ),
201
- 'help' => __('Position will tell the image where it should sit in the background.', 'fl-builder'),
202
  'preview' => array(
203
- 'type' => 'none'
204
- )
205
  ),
206
  'bg_attachment' => array(
207
  'type' => 'select',
208
- 'label' => __('Attachment', 'fl-builder'),
209
  'default' => 'scroll',
210
  'options' => array(
211
  'scroll' => __( 'Scroll', 'fl-builder' ),
212
- 'fixed' => __( 'Fixed', 'fl-builder' )
213
  ),
214
- 'help' => __('Attachment will specify how the image reacts when scrolling a page. When scrolling is selected, the image will scroll with page scrolling. This is the default setting. Fixed will allow the image to scroll within the background if fill is selected in the scale setting.', 'fl-builder'),
215
  'preview' => array(
216
- 'type' => 'none'
217
- )
218
  ),
219
  'bg_size' => array(
220
  'type' => 'select',
221
- 'label' => __('Scale', 'fl-builder'),
222
  'default' => 'cover',
223
  'options' => array(
224
  'auto' => _x( 'None', 'Background scale.', 'fl-builder' ),
225
- 'contain' => __( 'Fit', 'fl-builder'),
226
- 'cover' => __( 'Fill', 'fl-builder')
227
  ),
228
- 'help' => __('Scale applies to how the image should display in the background. You can select either fill or fit to the background.', 'fl-builder'),
229
  'preview' => array(
230
- 'type' => 'none'
231
- )
232
- )
233
- )
234
  ),
235
  'bg_video' => array(
236
- 'title' => __('Background Video', 'fl-builder'),
237
  'fields' => array(
238
  'bg_video_source' => array(
239
  'type' => 'select',
240
- 'label' => __('Source', 'fl-builder'),
241
  'default' => 'wordpress',
242
  'options' => array(
243
- 'wordpress' => __('Media Library', 'fl-builder'),
244
  'video_url' => 'URL',
245
- 'video_service' => __('YouTube or Vimeo', 'fl-builder')
246
  ),
247
  'toggle' => array(
248
  'wordpress' => array(
249
- 'fields' => array('bg_video', 'bg_video_webm')
250
  ),
251
  'video_url' => array(
252
- 'fields' => array('bg_video_url_mp4', 'bg_video_url_webm')
253
  ),
254
  'video_service' => array(
255
- 'fields' => array('bg_video_service_url', 'bg_video_audio')
256
- )
257
  ),
258
  'preview' => array(
259
- 'type' => 'none'
260
- )
261
  ),
262
  'bg_video' => array(
263
  'type' => 'video',
264
- 'label' => __('Video (MP4)', 'fl-builder'),
265
- 'help' => __('A video in the MP4 format to use as the background of this row. Most modern browsers support this format.', 'fl-builder'),
266
  'preview' => array(
267
- 'type' => 'refresh'
268
- )
269
  ),
270
  'bg_video_webm' => array(
271
  'type' => 'video',
272
- 'label' => __('Video (WebM)', 'fl-builder'),
273
- 'help' => __('A video in the WebM format to use as the background of this row. This format is required to support browsers such as FireFox and Opera.', 'fl-builder'),
274
  'preview' => array(
275
- 'type' => 'refresh'
276
- )
277
  ),
278
  'bg_video_url_mp4' => array(
279
  'type' => 'text',
280
- 'label' => __('Video URL (MP4)', 'fl-builder'),
281
- 'help' => __('A video in the MP4 to use as the background of this row. Most modern browsers support this format.', 'fl-builder'),
282
  'preview' => array(
283
- 'type' => 'refresh'
284
  ),
285
- 'connections' => array( 'custom_field' )
286
  ),
287
  'bg_video_url_webm' => array(
288
  'type' => 'text',
289
- 'label' => __('Video URL (WebM)', 'fl-builder'),
290
- 'help' => __('A video in the WebM format to use as the background of this row. This format is required to support browsers such as FireFox and Opera.', 'fl-builder'),
291
  'preview' => array(
292
- 'type' => 'refresh'
293
  ),
294
- 'connections' => array( 'custom_field' )
295
  ),
296
  'bg_video_service_url' => array(
297
  'type' => 'text',
298
- 'label' => __('Youtube Or Vimeo URL', 'fl-builder'),
299
- 'help' => __('A video from Youtube or Vimeo to use as the background of this row. Most modern browsers support this format.', 'fl-builder'),
300
  'preview' => array(
301
- 'type' => 'refresh'
302
  ),
303
- 'connections' => array( 'custom_field' )
304
  ),
305
  'bg_video_audio' => array(
306
  'type' => 'select',
307
- 'label' => __('Enable Audio', 'fl-builder'),
308
  'default' => 'no',
309
  'options' => array(
310
- 'no' => __('No', 'fl-builder'),
311
- 'yes' => __('Yes', 'fl-builder')
312
  ),
313
  'preview' => array(
314
- 'type' => 'refresh'
315
- )
316
  ),
317
  'bg_video_fallback' => array(
318
  'type' => 'photo',
319
- 'label' => __('Fallback Photo', 'fl-builder'),
320
- 'help' => __('A photo that will be displayed if the video fails to load.', 'fl-builder'),
321
  'preview' => array(
322
- 'type' => 'refresh'
323
  ),
324
- 'connections' => array( 'custom_field' )
325
- )
326
- )
327
  ),
328
  'bg_slideshow' => array(
329
- 'title' => __('Background Slideshow', 'fl-builder'),
330
  'fields' => array(
331
  'ss_source' => array(
332
  'type' => 'select',
333
- 'label' => __('Source', 'fl-builder'),
334
  'default' => 'wordpress',
335
  'options' => array(
336
- 'wordpress' => __('Media Library', 'fl-builder'),
337
- 'smugmug' => 'SmugMug'
338
  ),
339
- 'help' => __('Pull images from the WordPress media library or a gallery on your SmugMug site by inserting the RSS feed URL from SmugMug. The RSS feed URL can be accessed by using the get a link function in your SmugMug gallery.', 'fl-builder'),
340
  'toggle' => array(
341
  'wordpress' => array(
342
- 'fields' => array('ss_photos')
343
  ),
344
  'smugmug' => array(
345
- 'fields' => array('ss_feed_url')
346
- )
347
  ),
348
  'preview' => array(
349
- 'type' => 'none'
350
- )
351
  ),
352
  'ss_photos' => array(
353
  'type' => 'multiple-photos',
354
- 'label' => __('Photos', 'fl-builder'),
355
  'preview' => array(
356
- 'type' => 'none'
357
  ),
358
- 'connections' => array( 'multiple-photos' )
359
  ),
360
  'ss_feed_url' => array(
361
  'type' => 'text',
362
- 'label' => __('Feed URL', 'fl-builder'),
363
  'preview' => array(
364
- 'type' => 'none'
365
- )
 
366
  ),
367
  'ss_speed' => array(
368
  'type' => 'text',
369
- 'label' => __('Speed', 'fl-builder'),
370
  'default' => '3',
371
  'size' => '5',
372
  'description' => _x( 'seconds', 'Value unit for form field of time in seconds. Such as: "5 seconds"', 'fl-builder' ),
373
  'preview' => array(
374
- 'type' => 'none'
375
- )
376
  ),
377
  'ss_transition' => array(
378
  'type' => 'select',
379
- 'label' => __('Transition', 'fl-builder'),
380
  'default' => 'fade',
381
  'options' => array(
382
  'none' => _x( 'None', 'Slideshow transition type.', 'fl-builder' ),
383
- 'fade' => __('Fade', 'fl-builder'),
384
- 'kenBurns' => __('Ken Burns', 'fl-builder'),
385
- 'slideHorizontal' => __('Slide Horizontal', 'fl-builder'),
386
- 'slideVertical' => __('Slide Vertical', 'fl-builder'),
387
- 'blinds' => __('Blinds', 'fl-builder'),
388
- 'bars' => __('Bars', 'fl-builder'),
389
- 'barsRandom' => __('Random Bars', 'fl-builder'),
390
- 'boxes' => __('Boxes', 'fl-builder'),
391
- 'boxesRandom' => __('Random Boxes', 'fl-builder'),
392
- 'boxesGrow' => __('Boxes Grow', 'fl-builder')
393
  ),
394
  'preview' => array(
395
- 'type' => 'none'
396
- )
397
  ),
398
  'ss_transitionDuration' => array(
399
  'type' => 'text',
400
- 'label' => __('Transition Speed', 'fl-builder'),
401
  'default' => '1',
402
  'size' => '5',
403
  'description' => _x( 'seconds', 'Value unit for form field of time in seconds. Such as: "5 seconds"', 'fl-builder' ),
404
  'preview' => array(
405
- 'type' => 'none'
406
- )
407
  ),
408
  'ss_randomize' => array(
409
  'type' => 'select',
410
- 'label' => __('Randomize Photos', 'fl-builder'),
411
  'default' => 'false',
412
  'options' => array(
413
- 'false' => __('No', 'fl-builder'),
414
- 'true' => __('Yes', 'fl-builder')
415
  ),
416
  'preview' => array(
417
- 'type' => 'none'
418
- )
419
- )
420
- )
421
  ),
422
  'bg_parallax' => array(
423
- 'title' => __('Background Parallax', 'fl-builder'),
424
  'fields' => array(
425
  'bg_parallax_image' => array(
426
  'type' => 'photo',
427
- 'label' => __('Photo', 'fl-builder'),
428
  'preview' => array(
429
- 'type' => 'none'
430
  ),
431
- 'connections' => array( 'photo' )
432
  ),
433
  'bg_parallax_speed' => array(
434
  'type' => 'select',
435
- 'label' => __('Speed', 'fl-builder'),
436
  'default' => 'fast',
437
  'options' => array(
438
- '2' => __('Fast', 'fl-builder'),
439
  '5' => _x( 'Medium', 'Speed.', 'fl-builder' ),
440
- '8' => __('Slow', 'fl-builder')
441
  ),
442
  'preview' => array(
443
- 'type' => 'none'
444
- )
445
- )
446
- )
447
  ),
448
  'bg_color' => array(
449
- 'title' => __('Background Color', 'fl-builder'),
450
  'fields' => array(
451
  'bg_color' => array(
452
  'type' => 'color',
453
- 'label' => __('Color', 'fl-builder'),
454
  'show_reset' => true,
455
  'preview' => array(
456
- 'type' => 'none'
457
  ),
458
- 'connections' => array( 'color' )
459
  ),
460
  'bg_opacity' => array(
461
  'type' => 'text',
462
- 'label' => __('Opacity', 'fl-builder'),
463
  'default' => '100',
464
  'description' => '%',
465
  'maxlength' => '3',
466
  'size' => '5',
467
  'preview' => array(
468
- 'type' => 'none'
469
- )
470
- )
471
- )
472
  ),
473
  'bg_overlay' => array(
474
- 'title' => __('Background Overlay', 'fl-builder'),
475
  'fields' => array(
476
  'bg_overlay_color' => array(
477
  'type' => 'color',
478
- 'label' => __('Overlay Color', 'fl-builder'),
479
  'show_reset' => true,
480
  'preview' => array(
481
- 'type' => 'none'
482
- )
483
  ),
484
  'bg_overlay_opacity' => array(
485
  'type' => 'text',
486
- 'label' => __('Overlay Opacity', 'fl-builder'),
487
  'default' => '50',
488
  'description' => '%',
489
  'maxlength' => '3',
490
  'size' => '5',
491
  'preview' => array(
492
- 'type' => 'none'
493
- )
494
- )
495
- )
496
  ),
497
  'border' => array(
498
- 'title' => __('Border', 'fl-builder'),
499
  'fields' => array(
500
  'border_type' => array(
501
  'type' => 'select',
502
- 'label' => __('Type', 'fl-builder'),
503
  'default' => '',
504
- 'help' => __('The type of border to use. Double borders must have a width of at least 3px to render properly.', 'fl-builder'),
505
  'options' => array(
506
  '' => _x( 'None', 'Border type.', 'fl-builder' ),
507
  'solid' => _x( 'Solid', 'Border type.', 'fl-builder' ),
508
  'dashed' => _x( 'Dashed', 'Border type.', 'fl-builder' ),
509
  'dotted' => _x( 'Dotted', 'Border type.', 'fl-builder' ),
510
- 'double' => _x( 'Double', 'Border type.', 'fl-builder' )
511
  ),
512
  'toggle' => array(
513
  '' => array(
514
- 'fields' => array()
515
  ),
516
  'solid' => array(
517
- 'fields' => array('border_color', 'border_opacity', 'border_top', 'border_bottom', 'border_left', 'border_right')
518
  ),
519
  'dashed' => array(
520
- 'fields' => array('border_color', 'border_opacity', 'border_top', 'border_bottom', 'border_left', 'border_right')
521
  ),
522
  'dotted' => array(
523
- 'fields' => array('border_color', 'border_opacity', 'border_top', 'border_bottom', 'border_left', 'border_right')
524
  ),
525
  'double' => array(
526
- 'fields' => array('border_color', 'border_opacity', 'border_top', 'border_bottom', 'border_left', 'border_right')
527
- )
528
  ),
529
  'preview' => array(
530
- 'type' => 'none'
531
- )
532
  ),
533
  'border_color' => array(
534
  'type' => 'color',
535
- 'label' => __('Color', 'fl-builder'),
536
  'show_reset' => true,
537
  'preview' => array(
538
- 'type' => 'none'
539
- )
540
  ),
541
  'border_opacity' => array(
542
  'type' => 'text',
543
- 'label' => __('Opacity', 'fl-builder'),
544
  'default' => '100',
545
  'description' => '%',
546
  'maxlength' => '3',
547
  'size' => '5',
548
  'preview' => array(
549
- 'type' => 'none'
550
- )
551
  ),
552
  'border_top' => array(
553
  'type' => 'unit',
@@ -562,8 +563,8 @@ FLBuilder::register_settings_form('row', array(
562
  'default' => '1',
563
  'medium' => '',
564
  'responsive' => '',
565
- )
566
- )
567
  ),
568
  'border_bottom' => array(
569
  'type' => 'unit',
@@ -578,8 +579,8 @@ FLBuilder::register_settings_form('row', array(
578
  'default' => '1',
579
  'medium' => '',
580
  'responsive' => '',
581
- )
582
- )
583
  ),
584
  'border_left' => array(
585
  'type' => 'unit',
@@ -594,8 +595,8 @@ FLBuilder::register_settings_form('row', array(
594
  'default' => '0',
595
  'medium' => '',
596
  'responsive' => '',
597
- )
598
- )
599
  ),
600
  'border_right' => array(
601
  'type' => 'unit',
@@ -610,18 +611,18 @@ FLBuilder::register_settings_form('row', array(
610
  'default' => '0',
611
  'medium' => '',
612
  'responsive' => '',
613
- )
614
- )
615
  ),
616
  ),
617
  ),
618
- )
619
  ),
620
  'advanced' => array(
621
- 'title' => __('Advanced', 'fl-builder'),
622
  'sections' => array(
623
  'margins' => array(
624
- 'title' => __('Margins', 'fl-builder'),
625
  'fields' => array(
626
  'margin_top' => array(
627
  'type' => 'unit',
@@ -635,8 +636,8 @@ FLBuilder::register_settings_form('row', array(
635
  'default' => $spacing_placeholders['row_margins'],
636
  'medium' => $spacing_placeholders['row_margins_medium'],
637
  'responsive' => $spacing_placeholders['row_margins_responsive'],
638
- )
639
- )
640
  ),
641
  'margin_bottom' => array(
642
  'type' => 'unit',
@@ -650,8 +651,8 @@ FLBuilder::register_settings_form('row', array(
650
  'default' => $spacing_placeholders['row_margins'],
651
  'medium' => $spacing_placeholders['row_margins_medium'],
652
  'responsive' => $spacing_placeholders['row_margins_responsive'],
653
- )
654
- )
655
  ),
656
  'margin_left' => array(
657
  'type' => 'unit',
@@ -665,8 +666,8 @@ FLBuilder::register_settings_form('row', array(
665
  'default' => $spacing_placeholders['row_margins'],
666
  'medium' => $spacing_placeholders['row_margins_medium'],
667
  'responsive' => $spacing_placeholders['row_margins_responsive'],
668
- )
669
- )
670
  ),
671
  'margin_right' => array(
672
  'type' => 'unit',
@@ -680,13 +681,13 @@ FLBuilder::register_settings_form('row', array(
680
  'default' => $spacing_placeholders['row_margins'],
681
  'medium' => $spacing_placeholders['row_margins_medium'],
682
  'responsive' => $spacing_placeholders['row_margins_responsive'],
683
- )
684
- )
685
  ),
686
  ),
687
  ),
688
  'padding' => array(
689
- 'title' => __('Padding', 'fl-builder'),
690
  'fields' => array(
691
  'padding_top' => array(
692
  'type' => 'unit',
@@ -700,8 +701,8 @@ FLBuilder::register_settings_form('row', array(
700
  'default' => $spacing_placeholders['row_padding'],
701
  'medium' => $spacing_placeholders['row_padding_medium'],
702
  'responsive' => $spacing_placeholders['row_padding_tb_responsive'],
703
- )
704
- )
705
  ),
706
  'padding_bottom' => array(
707
  'type' => 'unit',
@@ -715,8 +716,8 @@ FLBuilder::register_settings_form('row', array(
715
  'default' => $spacing_placeholders['row_padding'],
716
  'medium' => $spacing_placeholders['row_padding_medium'],
717
  'responsive' => $spacing_placeholders['row_padding_tb_responsive'],
718
- )
719
- )
720
  ),
721
  'padding_left' => array(
722
  'type' => 'unit',
@@ -730,8 +731,8 @@ FLBuilder::register_settings_form('row', array(
730
  'default' => $spacing_placeholders['row_padding'],
731
  'medium' => $spacing_placeholders['row_padding_medium'],
732
  'responsive' => $spacing_placeholders['row_padding_lr_responsive'],
733
- )
734
- )
735
  ),
736
  'padding_right' => array(
737
  'type' => 'unit',
@@ -745,85 +746,85 @@ FLBuilder::register_settings_form('row', array(
745
  'default' => $spacing_placeholders['row_padding'],
746
  'medium' => $spacing_placeholders['row_padding_medium'],
747
  'responsive' => $spacing_placeholders['row_padding_lr_responsive'],
748
- )
749
- )
750
  ),
751
  ),
752
  ),
753
  'responsive' => array(
754
- 'title' => __('Responsive Layout', 'fl-builder'),
755
  'fields' => array(
756
  'responsive_display' => array(
757
  'type' => 'select',
758
- 'label' => __('Display', 'fl-builder'),
759
  'options' => array(
760
- '' => __('Always', 'fl-builder'),
761
- 'desktop' => __('Large Devices Only', 'fl-builder'),
762
- 'desktop-medium' => __('Large &amp; Medium Devices Only', 'fl-builder'),
763
- 'medium' => __('Medium Devices Only', 'fl-builder'),
764
- 'medium-mobile' => __('Medium &amp; Small Devices Only', 'fl-builder'),
765
- 'mobile' => __('Small Devices Only', 'fl-builder'),
766
  ),
767
  'help' => __( 'Choose whether to show or hide this row at different device sizes.', 'fl-builder' ),
768
  'preview' => array(
769
- 'type' => 'none'
770
- )
771
- )
772
- )
773
  ),
774
  'visibility' => array(
775
- 'title' => __('Visibility', 'fl-builder'),
776
  'fields' => array(
777
  'visibility_display' => array(
778
  'type' => 'select',
779
- 'label' => __('Display', 'fl-builder'),
780
  'options' => array(
781
- '' => __('Always', 'fl-builder'),
782
- 'logged_out' => __('Logged Out User', 'fl-builder'),
783
- 'logged_in' => __('Logged In User', 'fl-builder'),
784
- '0' => __('Never', 'fl-builder'),
785
  ),
786
  'toggle' => array(
787
  'logged_in' => array(
788
- 'fields' => array('visibility_user_capability')
789
- )
790
  ),
791
  'preview' => array(
792
- 'type' => 'none'
793
- )
794
  ),
795
  'visibility_user_capability' => array(
796
  'type' => 'text',
797
- 'label' => __('User Capability', 'fl-builder'),
798
  'description' => sprintf( __( 'Optional. Set the <a%s>capability</a> required for users to view this row.', 'fl-builder' ), ' href="http://codex.wordpress.org/Roles_and_Capabilities#Capability_vs._Role_Table" target="_blank"' ),
799
  'preview' => array(
800
- 'type' => 'none'
801
  ),
802
- )
803
- )
804
  ),
805
  'css_selectors' => array(
806
- 'title' => __('HTML Element', 'fl-builder'),
807
  'fields' => array(
808
  'id' => array(
809
  'type' => 'text',
810
- 'label' => __('ID', 'fl-builder'),
811
  'help' => __( "A unique ID that will be applied to this row's HTML. Must start with a letter and only contain dashes, underscores, letters or numbers. No spaces.", 'fl-builder' ),
812
  'preview' => array(
813
- 'type' => 'none'
814
- )
815
  ),
816
  'class' => array(
817
  'type' => 'text',
818
- 'label' => __('Class', 'fl-builder'),
819
  'help' => __( "A class that will be applied to this row's HTML. Must start with a letter and only contain dashes, underscores, letters or numbers. Separate multiple classes with spaces.", 'fl-builder' ),
820
  'preview' => array(
821
- 'type' => 'none'
822
- )
823
- )
824
- )
825
- )
826
- )
827
- )
828
- )
829
  ));
4
  $spacing_placeholders = FLBuilderModel::get_row_spacing_placeholders();
5
 
6
  FLBuilder::register_settings_form('row', array(
7
+ 'title' => __( 'Row Settings', 'fl-builder' ),
8
  'tabs' => array(
9
  'style' => array(
10
+ 'title' => __( 'Style', 'fl-builder' ),
11
  'sections' => array(
12
  'general' => array(
13
  'title' => '',
14
  'fields' => array(
15
  'width' => array(
16
  'type' => 'select',
17
+ 'label' => __( 'Width', 'fl-builder' ),
18
  'default' => $global_settings->row_width_default,
19
  'options' => array(
20
+ 'fixed' => __( 'Fixed', 'fl-builder' ),
21
+ 'full' => __( 'Full Width', 'fl-builder' ),
22
  ),
23
  'toggle' => array(
24
  'full' => array(
25
+ 'fields' => array( 'content_width' ),
26
+ ),
27
  ),
28
+ 'help' => __( 'Full width rows span the width of the page from edge to edge. Fixed rows are no wider than the Row Max Width set in the Global Settings.', 'fl-builder' ),
29
  'preview' => array(
30
+ 'type' => 'none',
31
+ ),
32
  ),
33
  'content_width' => array(
34
  'type' => 'select',
35
+ 'label' => __( 'Content Width', 'fl-builder' ),
36
  'default' => $global_settings->row_content_width_default,
37
  'options' => array(
38
+ 'fixed' => __( 'Fixed', 'fl-builder' ),
39
+ 'full' => __( 'Full Width', 'fl-builder' ),
40
  ),
41
+ 'help' => __( 'Full width content spans the width of the page from edge to edge. Fixed content is no wider than the Row Max Width set in the Global Settings.', 'fl-builder' ),
42
  'preview' => array(
43
+ 'type' => 'none',
44
+ ),
45
  ),
46
  'full_height' => array(
47
  'type' => 'select',
48
+ 'label' => __( 'Height', 'fl-builder' ),
49
  'default' => 'default',
50
  'options' => array(
51
+ 'default' => __( 'Default', 'fl-builder' ),
52
+ 'full' => __( 'Full Height', 'fl-builder' ),
53
  ),
54
+ 'help' => __( 'Full height rows fill the height of the browser window.', 'fl-builder' ),
55
  'toggle' => array(
56
  'full' => array(
57
+ 'fields' => array( 'content_alignment' ),
58
+ ),
59
  ),
60
  'preview' => array(
61
+ 'type' => 'none',
62
+ ),
63
  ),
64
  'content_alignment' => array(
65
  'type' => 'select',
66
+ 'label' => __( 'Content Alignment', 'fl-builder' ),
67
  'default' => 'center',
68
  'options' => array(
69
  'top' => __( 'Top', 'fl-builder' ),
71
  'bottom' => __( 'Bottom', 'fl-builder' ),
72
  ),
73
  'preview' => array(
74
+ 'type' => 'none',
75
+ ),
76
+ ),
77
+ ),
78
  ),
79
  'colors' => array(
80
+ 'title' => __( 'Colors', 'fl-builder' ),
81
  'fields' => array(
82
  'text_color' => array(
83
  'type' => 'color',
84
+ 'label' => __( 'Text Color', 'fl-builder' ),
85
  'show_reset' => true,
86
  'preview' => array(
87
+ 'type' => 'none',
88
+ ),
89
  ),
90
  'link_color' => array(
91
  'type' => 'color',
92
+ 'label' => __( 'Link Color', 'fl-builder' ),
93
  'show_reset' => true,
94
  'preview' => array(
95
+ 'type' => 'none',
96
+ ),
97
  ),
98
  'hover_color' => array(
99
  'type' => 'color',
100
+ 'label' => __( 'Link Hover Color', 'fl-builder' ),
101
  'show_reset' => true,
102
  'preview' => array(
103
+ 'type' => 'none',
104
+ ),
105
  ),
106
  'heading_color' => array(
107
  'type' => 'color',
108
+ 'label' => __( 'Heading Color', 'fl-builder' ),
109
  'show_reset' => true,
110
  'preview' => array(
111
+ 'type' => 'none',
112
+ ),
113
+ ),
114
+ ),
115
  ),
116
  'background' => array(
117
+ 'title' => __( 'Background', 'fl-builder' ),
118
  'fields' => array(
119
  'bg_type' => array(
120
  'type' => 'select',
121
+ 'label' => __( 'Type', 'fl-builder' ),
122
  'default' => 'none',
123
  'options' => array(
124
  'none' => _x( 'None', 'Background type.', 'fl-builder' ),
127
  'video' => _x( 'Video', 'Background type.', 'fl-builder' ),
128
  'slideshow' => array(
129
  'label' => _x( 'Slideshow', 'Background type.', 'fl-builder' ),
130
+ 'premium' => true,
131
  ),
132
  'parallax' => array(
133
  'label' => _x( 'Parallax', 'Background type.', 'fl-builder' ),
134
+ 'premium' => true,
135
+ ),
136
  ),
137
  'toggle' => array(
138
  'color' => array(
139
+ 'sections' => array( 'bg_color' ),
140
  ),
141
  'photo' => array(
142
+ 'sections' => array( 'bg_color', 'bg_photo', 'bg_overlay' ),
143
  ),
144
  'video' => array(
145
+ 'sections' => array( 'bg_color', 'bg_video', 'bg_overlay' ),
146
  ),
147
  'slideshow' => array(
148
+ 'sections' => array( 'bg_color', 'bg_slideshow', 'bg_overlay' ),
149
  ),
150
  'parallax' => array(
151
+ 'sections' => array( 'bg_color','bg_parallax', 'bg_overlay' ),
152
+ ),
153
  ),
154
  'preview' => array(
155
+ 'type' => 'none',
156
+ ),
157
+ ),
158
+ ),
159
  ),
160
  'bg_photo' => array(
161
+ 'title' => __( 'Background Photo', 'fl-builder' ),
162
  'fields' => array(
163
  'bg_image' => array(
164
  'type' => 'photo',
165
+ 'label' => __( 'Photo', 'fl-builder' ),
166
  'preview' => array(
167
+ 'type' => 'none',
168
  ),
169
+ 'connections' => array( 'photo' ),
170
  ),
171
  'bg_repeat' => array(
172
  'type' => 'select',
173
+ 'label' => __( 'Repeat', 'fl-builder' ),
174
  'default' => 'none',
175
  'options' => array(
176
  'no-repeat' => _x( 'None', 'Background repeat.', 'fl-builder' ),
177
  'repeat' => _x( 'Tile', 'Background repeat.', 'fl-builder' ),
178
  'repeat-x' => _x( 'Horizontal', 'Background repeat.', 'fl-builder' ),
179
+ 'repeat-y' => _x( 'Vertical', 'Background repeat.', 'fl-builder' ),
180
  ),
181
+ 'help' => __( 'Repeat applies to how the image should display in the background. Choosing none will display the image as uploaded. Tile will repeat the image as many times as needed to fill the background horizontally and vertically. You can also specify the image to only repeat horizontally or vertically.', 'fl-builder' ),
182
  'preview' => array(
183
+ 'type' => 'none',
184
+ ),
185
  ),
186
  'bg_position' => array(
187
  'type' => 'select',
188
+ 'label' => __( 'Position', 'fl-builder' ),
189
  'default' => 'center center',
190
  'options' => array(
191
+ 'left top' => __( 'Left Top', 'fl-builder' ),
192
+ 'left center' => __( 'Left Center', 'fl-builder' ),
193
+ 'left bottom' => __( 'Left Bottom', 'fl-builder' ),
194
+ 'right top' => __( 'Right Top', 'fl-builder' ),
195
+ 'right center' => __( 'Right Center', 'fl-builder' ),
196
+ 'right bottom' => __( 'Right Bottom', 'fl-builder' ),
197
+ 'center top' => __( 'Center Top', 'fl-builder' ),
198
  'center center' => __( 'Center', 'fl-builder' ),
199
+ 'center bottom' => __( 'Center Bottom', 'fl-builder' ),
200
  ),
201
+ 'help' => __( 'Position will tell the image where it should sit in the background.', 'fl-builder' ),
202
  'preview' => array(
203
+ 'type' => 'none',
204
+ ),
205
  ),
206
  'bg_attachment' => array(
207
  'type' => 'select',
208
+ 'label' => __( 'Attachment', 'fl-builder' ),
209
  'default' => 'scroll',
210
  'options' => array(
211
  'scroll' => __( 'Scroll', 'fl-builder' ),
212
+ 'fixed' => __( 'Fixed', 'fl-builder' ),
213
  ),
214
+ 'help' => __( 'Attachment will specify how the image reacts when scrolling a page. When scrolling is selected, the image will scroll with page scrolling. This is the default setting. Fixed will allow the image to scroll within the background if fill is selected in the scale setting.', 'fl-builder' ),
215
  'preview' => array(
216
+ 'type' => 'none',
217
+ ),
218
  ),
219
  'bg_size' => array(
220
  'type' => 'select',
221
+ 'label' => __( 'Scale', 'fl-builder' ),
222
  'default' => 'cover',
223
  'options' => array(
224
  'auto' => _x( 'None', 'Background scale.', 'fl-builder' ),
225
+ 'contain' => __( 'Fit', 'fl-builder' ),
226
+ 'cover' => __( 'Fill', 'fl-builder' ),
227
  ),
228
+ 'help' => __( 'Scale applies to how the image should display in the background. You can select either fill or fit to the background.', 'fl-builder' ),
229
  'preview' => array(
230
+ 'type' => 'none',
231
+ ),
232
+ ),
233
+ ),
234
  ),
235
  'bg_video' => array(
236
+ 'title' => __( 'Background Video', 'fl-builder' ),
237
  'fields' => array(
238
  'bg_video_source' => array(
239
  'type' => 'select',
240
+ 'label' => __( 'Source', 'fl-builder' ),
241
  'default' => 'wordpress',
242
  'options' => array(
243
+ 'wordpress' => __( 'Media Library', 'fl-builder' ),
244
  'video_url' => 'URL',
245
+ 'video_service' => __( 'YouTube or Vimeo', 'fl-builder' ),
246
  ),
247
  'toggle' => array(
248
  'wordpress' => array(
249
+ 'fields' => array( 'bg_video', 'bg_video_webm' ),
250
  ),
251
  'video_url' => array(
252
+ 'fields' => array( 'bg_video_url_mp4', 'bg_video_url_webm' ),
253
  ),
254
  'video_service' => array(
255
+ 'fields' => array( 'bg_video_service_url', 'bg_video_audio' ),
256
+ ),
257
  ),
258
  'preview' => array(
259
+ 'type' => 'none',
260
+ ),
261
  ),
262
  'bg_video' => array(
263
  'type' => 'video',
264
+ 'label' => __( 'Video (MP4)', 'fl-builder' ),
265
+ 'help' => __( 'A video in the MP4 format to use as the background of this row. Most modern browsers support this format.', 'fl-builder' ),
266
  'preview' => array(
267
+ 'type' => 'refresh',
268
+ ),
269
  ),
270
  'bg_video_webm' => array(
271
  'type' => 'video',
272
+ 'label' => __( 'Video (WebM)', 'fl-builder' ),
273
+ 'help' => __( 'A video in the WebM format to use as the background of this row. This format is required to support browsers such as FireFox and Opera.', 'fl-builder' ),
274
  'preview' => array(
275
+ 'type' => 'refresh',
276
+ ),
277
  ),
278
  'bg_video_url_mp4' => array(
279
  'type' => 'text',
280
+ 'label' => __( 'Video URL (MP4)', 'fl-builder' ),
281
+ 'help' => __( 'A video in the MP4 to use as the background of this row. Most modern browsers support this format.', 'fl-builder' ),
282
  'preview' => array(
283
+ 'type' => 'refresh',
284
  ),
285
+ 'connections' => array( 'custom_field' ),
286
  ),
287
  'bg_video_url_webm' => array(
288
  'type' => 'text',
289
+ 'label' => __( 'Video URL (WebM)', 'fl-builder' ),
290
+ 'help' => __( 'A video in the WebM format to use as the background of this row. This format is required to support browsers such as FireFox and Opera.', 'fl-builder' ),
291
  'preview' => array(
292
+ 'type' => 'refresh',
293
  ),
294
+ 'connections' => array( 'custom_field' ),
295
  ),
296
  'bg_video_service_url' => array(
297
  'type' => 'text',
298
+ 'label' => __( 'Youtube Or Vimeo URL', 'fl-builder' ),
299
+ 'help' => __( 'A video from Youtube or Vimeo to use as the background of this row. Most modern browsers support this format.', 'fl-builder' ),
300
  'preview' => array(
301
+ 'type' => 'refresh',
302
  ),
303
+ 'connections' => array( 'custom_field' ),
304
  ),
305
  'bg_video_audio' => array(
306
  'type' => 'select',
307
+ 'label' => __( 'Enable Audio', 'fl-builder' ),
308
  'default' => 'no',
309
  'options' => array(
310
+ 'no' => __( 'No', 'fl-builder' ),
311
+ 'yes' => __( 'Yes', 'fl-builder' ),
312
  ),
313
  'preview' => array(
314
+ 'type' => 'refresh',
315
+ ),
316
  ),
317
  'bg_video_fallback' => array(
318
  'type' => 'photo',
319
+ 'label' => __( 'Fallback Photo', 'fl-builder' ),
320
+ 'help' => __( 'A photo that will be displayed if the video fails to load.', 'fl-builder' ),
321
  'preview' => array(
322
+ 'type' => 'refresh',
323
  ),
324
+ 'connections' => array( 'custom_field' ),
325
+ ),
326
+ ),
327
  ),
328
  'bg_slideshow' => array(
329
+ 'title' => __( 'Background Slideshow', 'fl-builder' ),
330
  'fields' => array(
331
  'ss_source' => array(
332
  'type' => 'select',
333
+ 'label' => __( 'Source', 'fl-builder' ),
334
  'default' => 'wordpress',
335
  'options' => array(
336
+ 'wordpress' => __( 'Media Library', 'fl-builder' ),
337
+ 'smugmug' => 'SmugMug',
338
  ),
339
+ 'help' => __( 'Pull images from the WordPress media library or a gallery on your SmugMug site by inserting the RSS feed URL from SmugMug. The RSS feed URL can be accessed by using the get a link function in your SmugMug gallery.', 'fl-builder' ),
340
  'toggle' => array(
341
  'wordpress' => array(
342
+ 'fields' => array( 'ss_photos' ),
343
  ),
344
  'smugmug' => array(
345
+ 'fields' => array( 'ss_feed_url' ),
346
+ ),
347
  ),
348
  'preview' => array(
349
+ 'type' => 'none',
350
+ ),
351
  ),
352
  'ss_photos' => array(
353
  'type' => 'multiple-photos',
354
+ 'label' => __( 'Photos', 'fl-builder' ),
355
  'preview' => array(
356
+ 'type' => 'none',
357
  ),
358
+ 'connections' => array( 'multiple-photos' ),
359
  ),
360
  'ss_feed_url' => array(
361
  'type' => 'text',
362
+ 'label' => __( 'Feed URL', 'fl-builder' ),
363
  'preview' => array(
364
+ 'type' => 'none',
365
+ ),
366
+ 'connections' => array( 'custom_field' ),
367
  ),
368
  'ss_speed' => array(
369
  'type' => 'text',
370
+ 'label' => __( 'Speed', 'fl-builder' ),
371
  'default' => '3',
372
  'size' => '5',
373
  'description' => _x( 'seconds', 'Value unit for form field of time in seconds. Such as: "5 seconds"', 'fl-builder' ),
374
  'preview' => array(
375
+ 'type' => 'none',
376
+ ),
377
  ),
378
  'ss_transition' => array(
379
  'type' => 'select',
380
+ 'label' => __( 'Transition', 'fl-builder' ),
381
  'default' => 'fade',
382
  'options' => array(
383
  'none' => _x( 'None', 'Slideshow transition type.', 'fl-builder' ),
384
+ 'fade' => __( 'Fade', 'fl-builder' ),
385
+ 'kenBurns' => __( 'Ken Burns', 'fl-builder' ),
386
+ 'slideHorizontal' => __( 'Slide Horizontal', 'fl-builder' ),
387
+ 'slideVertical' => __( 'Slide Vertical', 'fl-builder' ),
388
+ 'blinds' => __( 'Blinds', 'fl-builder' ),
389
+ 'bars' => __( 'Bars', 'fl-builder' ),
390
+ 'barsRandom' => __( 'Random Bars', 'fl-builder' ),
391
+ 'boxes' => __( 'Boxes', 'fl-builder' ),
392
+ 'boxesRandom' => __( 'Random Boxes', 'fl-builder' ),
393
+ 'boxesGrow' => __( 'Boxes Grow', 'fl-builder' ),
394
  ),
395
  'preview' => array(
396
+ 'type' => 'none',
397
+ ),
398
  ),
399
  'ss_transitionDuration' => array(
400
  'type' => 'text',
401
+ 'label' => __( 'Transition Speed', 'fl-builder' ),
402
  'default' => '1',
403
  'size' => '5',
404
  'description' => _x( 'seconds', 'Value unit for form field of time in seconds. Such as: "5 seconds"', 'fl-builder' ),
405
  'preview' => array(
406
+ 'type' => 'none',
407
+ ),
408
  ),
409
  'ss_randomize' => array(
410
  'type' => 'select',
411
+ 'label' => __( 'Randomize Photos', 'fl-builder' ),
412
  'default' => 'false',
413
  'options' => array(
414
+ 'false' => __( 'No', 'fl-builder' ),
415
+ 'true' => __( 'Yes', 'fl-builder' ),
416
  ),
417
  'preview' => array(
418
+ 'type' => 'none',
419
+ ),
420
+ ),
421
+ ),
422
  ),
423
  'bg_parallax' => array(
424
+ 'title' => __( 'Background Parallax', 'fl-builder' ),
425
  'fields' => array(
426
  'bg_parallax_image' => array(
427
  'type' => 'photo',
428
+ 'label' => __( 'Photo', 'fl-builder' ),
429
  'preview' => array(
430
+ 'type' => 'none',
431
  ),
432
+ 'connections' => array( 'photo' ),
433
  ),
434
  'bg_parallax_speed' => array(
435
  'type' => 'select',
436
+ 'label' => __( 'Speed', 'fl-builder' ),
437
  'default' => 'fast',
438
  'options' => array(
439
+ '2' => __( 'Fast', 'fl-builder' ),
440
  '5' => _x( 'Medium', 'Speed.', 'fl-builder' ),
441
+ '8' => __( 'Slow', 'fl-builder' ),
442
  ),
443
  'preview' => array(
444
+ 'type' => 'none',
445
+ ),
446
+ ),
447
+ ),
448
  ),
449
  'bg_color' => array(
450
+ 'title' => __( 'Background Color', 'fl-builder' ),
451
  'fields' => array(
452
  'bg_color' => array(
453
  'type' => 'color',
454
+ 'label' => __( 'Color', 'fl-builder' ),
455
  'show_reset' => true,
456
  'preview' => array(
457
+ 'type' => 'none',
458
  ),
459
+ 'connections' => array( 'color' ),
460
  ),
461
  'bg_opacity' => array(
462
  'type' => 'text',
463
+ 'label' => __( 'Opacity', 'fl-builder' ),
464
  'default' => '100',
465
  'description' => '%',
466
  'maxlength' => '3',
467
  'size' => '5',
468
  'preview' => array(
469
+ 'type' => 'none',
470
+ ),
471
+ ),
472
+ ),
473
  ),
474
  'bg_overlay' => array(
475
+ 'title' => __( 'Background Overlay', 'fl-builder' ),
476
  'fields' => array(
477
  'bg_overlay_color' => array(
478
  'type' => 'color',
479
+ 'label' => __( 'Overlay Color', 'fl-builder' ),
480
  'show_reset' => true,
481
  'preview' => array(
482
+ 'type' => 'none',
483
+ ),
484
  ),
485
  'bg_overlay_opacity' => array(
486
  'type' => 'text',
487
+ 'label' => __( 'Overlay Opacity', 'fl-builder' ),
488
  'default' => '50',
489
  'description' => '%',
490
  'maxlength' => '3',
491
  'size' => '5',
492
  'preview' => array(
493
+ 'type' => 'none',
494
+ ),
495
+ ),
496
+ ),
497
  ),
498
  'border' => array(
499
+ 'title' => __( 'Border', 'fl-builder' ),
500
  'fields' => array(
501
  'border_type' => array(
502
  'type' => 'select',
503
+ 'label' => __( 'Type', 'fl-builder' ),
504
  'default' => '',
505
+ 'help' => __( 'The type of border to use. Double borders must have a width of at least 3px to render properly.', 'fl-builder' ),
506
  'options' => array(
507
  '' => _x( 'None', 'Border type.', 'fl-builder' ),
508
  'solid' => _x( 'Solid', 'Border type.', 'fl-builder' ),
509
  'dashed' => _x( 'Dashed', 'Border type.', 'fl-builder' ),
510
  'dotted' => _x( 'Dotted', 'Border type.', 'fl-builder' ),
511
+ 'double' => _x( 'Double', 'Border type.', 'fl-builder' ),
512
  ),
513
  'toggle' => array(
514
  '' => array(
515
+ 'fields' => array(),
516
  ),
517
  'solid' => array(
518
+ 'fields' => array( 'border_color', 'border_opacity', 'border_top', 'border_bottom', 'border_left', 'border_right' ),
519
  ),
520
  'dashed' => array(
521
+ 'fields' => array( 'border_color', 'border_opacity', 'border_top', 'border_bottom', 'border_left', 'border_right' ),
522
  ),
523
  'dotted' => array(
524
+ 'fields' => array( 'border_color', 'border_opacity', 'border_top', 'border_bottom', 'border_left', 'border_right' ),
525
  ),
526
  'double' => array(
527
+ 'fields' => array( 'border_color', 'border_opacity', 'border_top', 'border_bottom', 'border_left', 'border_right' ),
528
+ ),
529
  ),
530
  'preview' => array(
531
+ 'type' => 'none',
532
+ ),
533
  ),
534
  'border_color' => array(
535
  'type' => 'color',
536
+ 'label' => __( 'Color', 'fl-builder' ),
537
  'show_reset' => true,
538
  'preview' => array(
539
+ 'type' => 'none',
540
+ ),
541
  ),
542
  'border_opacity' => array(
543
  'type' => 'text',
544
+ 'label' => __( 'Opacity', 'fl-builder' ),
545
  'default' => '100',
546
  'description' => '%',
547
  'maxlength' => '3',
548
  'size' => '5',
549
  'preview' => array(
550
+ 'type' => 'none',
551
+ ),
552
  ),
553
  'border_top' => array(
554
  'type' => 'unit',
563
  'default' => '1',
564
  'medium' => '',
565
  'responsive' => '',
566
+ ),
567
+ ),
568
  ),
569
  'border_bottom' => array(
570
  'type' => 'unit',
579
  'default' => '1',
580
  'medium' => '',
581
  'responsive' => '',
582
+ ),
583
+ ),
584
  ),
585
  'border_left' => array(
586
  'type' => 'unit',
595
  'default' => '0',
596
  'medium' => '',
597
  'responsive' => '',
598
+ ),
599
+ ),
600
  ),
601
  'border_right' => array(
602
  'type' => 'unit',
611
  'default' => '0',
612
  'medium' => '',
613
  'responsive' => '',
614
+ ),
615
+ ),
616
  ),
617
  ),
618
  ),
619
+ ),
620
  ),
621
  'advanced' => array(
622
+ 'title' => __( 'Advanced', 'fl-builder' ),
623
  'sections' => array(
624
  'margins' => array(
625
+ 'title' => __( 'Margins', 'fl-builder' ),
626
  'fields' => array(
627
  'margin_top' => array(
628
  'type' => 'unit',
636
  'default' => $spacing_placeholders['row_margins'],
637
  'medium' => $spacing_placeholders['row_margins_medium'],
638
  'responsive' => $spacing_placeholders['row_margins_responsive'],
639
+ ),
640
+ ),
641
  ),
642
  'margin_bottom' => array(
643
  'type' => 'unit',
651
  'default' => $spacing_placeholders['row_margins'],
652
  'medium' => $spacing_placeholders['row_margins_medium'],
653
  'responsive' => $spacing_placeholders['row_margins_responsive'],
654
+ ),
655
+ ),
656
  ),
657
  'margin_left' => array(
658
  'type' => 'unit',
666
  'default' => $spacing_placeholders['row_margins'],
667
  'medium' => $spacing_placeholders['row_margins_medium'],
668
  'responsive' => $spacing_placeholders['row_margins_responsive'],
669
+ ),
670
+ ),
671
  ),
672
  'margin_right' => array(
673
  'type' => 'unit',
681
  'default' => $spacing_placeholders['row_margins'],
682
  'medium' => $spacing_placeholders['row_margins_medium'],
683
  'responsive' => $spacing_placeholders['row_margins_responsive'],
684
+ ),
685
+ ),
686
  ),
687
  ),
688
  ),
689
  'padding' => array(
690
+ 'title' => __( 'Padding', 'fl-builder' ),
691
  'fields' => array(
692
  'padding_top' => array(
693
  'type' => 'unit',
701
  'default' => $spacing_placeholders['row_padding'],
702
  'medium' => $spacing_placeholders['row_padding_medium'],
703
  'responsive' => $spacing_placeholders['row_padding_tb_responsive'],
704
+ ),
705
+ ),
706
  ),
707
  'padding_bottom' => array(
708
  'type' => 'unit',
716
  'default' => $spacing_placeholders['row_padding'],
717
  'medium' => $spacing_placeholders['row_padding_medium'],
718
  'responsive' => $spacing_placeholders['row_padding_tb_responsive'],
719
+ ),
720
+ ),
721
  ),
722
  'padding_left' => array(
723
  'type' => 'unit',
731
  'default' => $spacing_placeholders['row_padding'],
732
  'medium' => $spacing_placeholders['row_padding_medium'],
733
  'responsive' => $spacing_placeholders['row_padding_lr_responsive'],
734
+ ),
735
+ ),
736
  ),
737
  'padding_right' => array(
738
  'type' => 'unit',
746
  'default' => $spacing_placeholders['row_padding'],
747
  'medium' => $spacing_placeholders['row_padding_medium'],
748
  'responsive' => $spacing_placeholders['row_padding_lr_responsive'],
749
+ ),
750
+ ),
751
  ),
752
  ),
753
  ),
754
  'responsive' => array(
755
+ 'title' => __( 'Responsive Layout', 'fl-builder' ),
756
  'fields' => array(
757
  'responsive_display' => array(
758
  'type' => 'select',
759
+ 'label' => __( 'Display', 'fl-builder' ),
760
  'options' => array(
761
+ '' => __( 'Always', 'fl-builder' ),
762
+ 'desktop' => __( 'Large Devices Only', 'fl-builder' ),
763
+ 'desktop-medium' => __( 'Large &amp; Medium Devices Only', 'fl-builder' ),
764
+ 'medium' => __( 'Medium Devices Only', 'fl-builder' ),
765
+ 'medium-mobile' => __( 'Medium &amp; Small Devices Only', 'fl-builder' ),
766
+ 'mobile' => __( 'Small Devices Only', 'fl-builder' ),
767
  ),
768
  'help' => __( 'Choose whether to show or hide this row at different device sizes.', 'fl-builder' ),
769
  'preview' => array(
770
+ 'type' => 'none',
771
+ ),
772
+ ),
773
+ ),
774
  ),
775
  'visibility' => array(
776
+ 'title' => __( 'Visibility', 'fl-builder' ),
777
  'fields' => array(
778
  'visibility_display' => array(
779
  'type' => 'select',
780
+ 'label' => __( 'Display', 'fl-builder' ),
781
  'options' => array(
782
+ '' => __( 'Always', 'fl-builder' ),
783
+ 'logged_out' => __( 'Logged Out User', 'fl-builder' ),
784
+ 'logged_in' => __( 'Logged In User', 'fl-builder' ),
785
+ '0' => __( 'Never', 'fl-builder' ),
786
  ),
787
  'toggle' => array(
788
  'logged_in' => array(
789
+ 'fields' => array( 'visibility_user_capability' ),
790
+ ),
791
  ),
792
  'preview' => array(
793
+ 'type' => 'none',
794
+ ),
795
  ),
796
  'visibility_user_capability' => array(
797
  'type' => 'text',
798
+ 'label' => __( 'User Capability', 'fl-builder' ),
799
  'description' => sprintf( __( 'Optional. Set the <a%s>capability</a> required for users to view this row.', 'fl-builder' ), ' href="http://codex.wordpress.org/Roles_and_Capabilities#Capability_vs._Role_Table" target="_blank"' ),
800
  'preview' => array(
801
+ 'type' => 'none',
802
  ),
803
+ ),
804
+ ),
805
  ),
806
  'css_selectors' => array(
807
+ 'title' => __( 'HTML Element', 'fl-builder' ),
808
  'fields' => array(
809
  'id' => array(
810
  'type' => 'text',
811
+ 'label' => __( 'ID', 'fl-builder' ),
812
  'help' => __( "A unique ID that will be applied to this row's HTML. Must start with a letter and only contain dashes, underscores, letters or numbers. No spaces.", 'fl-builder' ),
813
  'preview' => array(
814
+ 'type' => 'none',
815
+ ),
816
  ),
817
  'class' => array(
818
  'type' => 'text',
819
+ 'label' => __( 'Class', 'fl-builder' ),
820
  'help' => __( "A class that will be applied to this row's HTML. Must start with a letter and only contain dashes, underscores, letters or numbers. Separate multiple classes with spaces.", 'fl-builder' ),
821
  'preview' => array(
822
+ 'type' => 'none',
823
+ ),
824
+ ),
825
+ ),
826
+ ),
827
+ ),
828
+ ),
829
+ ),
830
  ));
includes/row-video.php CHANGED
@@ -1,8 +1,14 @@
1
- <?php if($row->settings->bg_video_source == 'wordpress') { ?>
2
  <div class="fl-bg-video"
3
- data-width="<?php if ( isset( $vid_data['mp4'] ) ) echo $vid_data['mp4']->width; else echo $vid_data['webm']->width; ?>"
4
- data-height="<?php if ( isset( $vid_data['mp4'] ) ) echo $vid_data['mp4']->height; else echo $vid_data['webm']->height; ?>"
5
- data-fallback="<?php if ( isset( $vid_data['mp4'] ) ) echo $vid_data['mp4']->fallback; else echo $vid_data['webm']->fallback; ?>"
 
 
 
 
 
 
6
  <?php if ( isset( $vid_data['mp4'] ) ) : ?>
7
  data-mp4="<?php echo $vid_data['mp4']->url; ?>"
8
  data-mp4-type="video/<?php echo $vid_data['mp4']->extension; ?>"
@@ -13,9 +19,9 @@ data-webm-type="video/<?php echo $vid_data['webm']->extension; ?>"
13
  <?php endif; ?>></div>
14
  <?php } ?>
15
 
16
- <?php if($row->settings->bg_video_source == 'video_url') { ?>
17
  <div class="fl-bg-video"
18
- data-fallback="<?php if ( isset( $row->settings->bg_video_fallback_src ) ) echo $row->settings->bg_video_fallback_src; ?>"
19
  <?php if ( isset( $row->settings->bg_video_url_mp4 ) ) : ?>
20
  data-mp4="<?php echo $row->settings->bg_video_url_mp4; ?>"
21
  data-mp4-type="video/mp4"
@@ -26,12 +32,12 @@ data-webm-type="video/webm"
26
  <?php endif; ?>></div>
27
  <?php } ?>
28
 
29
- <?php if($row->settings->bg_video_source == 'video_service') {
30
- $video_data = FLBuilderUtils::get_video_data($row->settings->bg_video_service_url); ?>
31
- <div class="fl-bg-video"
32
- data-fallback="<?php if ( isset( $row->settings->bg_video_fallback_src ) ) echo $row->settings->bg_video_fallback_src; ?>"
33
  <?php if ( isset( $row->settings->bg_video_service_url ) ) : ?>
34
- data-<?php echo $video_data['type']; ?>="<?php echo $row->settings->bg_video_service_url; ?>"
35
  data-video-id="<?php echo $video_data['video_id']; ?>"
36
  data-enable-audio="<?php echo $row->settings->bg_video_audio; ?>"
37
  <?php endif; ?>>
1
+ <?php if ( 'wordpress' == $row->settings->bg_video_source ) { ?>
2
  <div class="fl-bg-video"
3
+ data-width="<?php if ( isset( $vid_data['mp4'] ) ) { echo $vid_data['mp4']->width;
4
+ } else { echo $vid_data['webm']->width;
5
+ } ?>"
6
+ data-height="<?php if ( isset( $vid_data['mp4'] ) ) { echo $vid_data['mp4']->height;
7
+ } else { echo $vid_data['webm']->height;
8
+ } ?>"
9
+ data-fallback="<?php if ( isset( $vid_data['mp4'] ) ) { echo $vid_data['mp4']->fallback;
10
+ } else { echo $vid_data['webm']->fallback;
11
+ } ?>"
12
  <?php if ( isset( $vid_data['mp4'] ) ) : ?>
13
  data-mp4="<?php echo $vid_data['mp4']->url; ?>"
14
  data-mp4-type="video/<?php echo $vid_data['mp4']->extension; ?>"
19
  <?php endif; ?>></div>
20
  <?php } ?>
21
 
22
+ <?php if ( 'video_url' == $row->settings->bg_video_source ) { ?>
23
  <div class="fl-bg-video"
24
+ data-fallback="<?php if ( isset( $row->settings->bg_video_fallback_src ) ) { echo $row->settings->bg_video_fallback_src;} ?>"
25
  <?php if ( isset( $row->settings->bg_video_url_mp4 ) ) : ?>
26
  data-mp4="<?php echo $row->settings->bg_video_url_mp4; ?>"
27
  data-mp4-type="video/mp4"
32
  <?php endif; ?>></div>
33
  <?php } ?>
34
 
35
+ <?php if ( 'video_service' == $row->settings->bg_video_source ) {
36
+ $video_data = FLBuilderUtils::get_video_data( $row->settings->bg_video_service_url ); ?>
37
+ <div class="fl-bg-video"
38
+ data-fallback="<?php if ( isset( $row->settings->bg_video_fallback_src ) ) { echo $row->settings->bg_video_fallback_src;} ?>"
39
  <?php if ( isset( $row->settings->bg_video_service_url ) ) : ?>
40
+ data-<?php echo $video_data['type']; ?>="<?php echo $row->settings->bg_video_service_url; ?>"
41
  data-video-id="<?php echo $video_data['video_id']; ?>"
42
  data-enable-audio="<?php echo $row->settings->bg_video_audio; ?>"
43
  <?php endif; ?>>
includes/row.php CHANGED
@@ -7,8 +7,8 @@
7
  foreach ( $groups as $group ) {
8
  FLBuilder::render_column_group( $group );
9
  }
10
-
11
  ?>
12
  </div>
13
  </div>
14
- </div>
7
  foreach ( $groups as $group ) {
8
  FLBuilder::render_column_group( $group );
9
  }
10
+
11
  ?>
12
  </div>
13
  </div>
14
+ </div>
includes/service-settings.php CHANGED
@@ -1,32 +1,34 @@
1
  <div class="fl-builder-service-settings">
2
  <table class="fl-form-table">
3
- <?php
4
-
5
  // Get the service type.
6
  $service_type = null;
7
-
8
- if ( isset( $section['services'] ) && $section['services'] != 'all' ) {
9
  $service_type = $section['services'];
10
  }
11
-
12
  // Get the service data.
13
  $services = FLBuilderServices::get_services_data( $service_type );
14
-
15
  // Remove services that don't meet the requirements.
16
- if ( isset( $services['mailpoet'] )
17
- && ! class_exists( 'WYSIJA' )
18
  && ( ! defined( 'MAILPOET_INITIALIZED' ) || ( defined( 'MAILPOET_INITIALIZED' ) && false === MAILPOET_INITIALIZED ) )
19
  ) {
20
  unset( $services['mailpoet'] );
21
  }
22
-
23
  // Build the select options.
24
- $options = array( '' => __( 'Choose...', 'fl-builder' ) );
25
-
 
 
26
  foreach ( $services as $key => $service ) {
27
  $options[ $key ] = $service['name'];
28
  }
29
-
30
  // Render the service select.
31
  FLBuilder::render_settings_field( 'service', array(
32
  'row_class' => 'fl-builder-service-select-row',
@@ -35,10 +37,10 @@
35
  'label' => __( 'Service', 'fl-builder' ),
36
  'options' => $options,
37
  'preview' => array(
38
- 'type' => 'none'
39
- )
40
- ), $settings );
41
-
42
  ?>
43
  </table>
44
- </div>
1
  <div class="fl-builder-service-settings">
2
  <table class="fl-form-table">
3
+ <?php
4
+
5
  // Get the service type.
6
  $service_type = null;
7
+
8
+ if ( isset( $section['services'] ) && 'all' != $section['services'] ) {
9
  $service_type = $section['services'];
10
  }
11
+
12
  // Get the service data.
13
  $services = FLBuilderServices::get_services_data( $service_type );
14
+
15
  // Remove services that don't meet the requirements.
16
+ if ( isset( $services['mailpoet'] )
17
+ && ! class_exists( 'WYSIJA' )
18
  && ( ! defined( 'MAILPOET_INITIALIZED' ) || ( defined( 'MAILPOET_INITIALIZED' ) && false === MAILPOET_INITIALIZED ) )
19
  ) {
20
  unset( $services['mailpoet'] );
21
  }
22
+
23
  // Build the select options.
24
+ $options = array(
25
+ '' => __( 'Choose...', 'fl-builder' ),
26
+ );
27
+
28
  foreach ( $services as $key => $service ) {
29
  $options[ $key ] = $service['name'];
30
  }
31
+
32
  // Render the service select.
33
  FLBuilder::render_settings_field( 'service', array(
34
  'row_class' => 'fl-builder-service-select-row',
37
  'label' => __( 'Service', 'fl-builder' ),
38
  'options' => $options,
39
  'preview' => array(
40
+ 'type' => 'none',
41
+ ),
42
+ ), $settings );
43
+
44
  ?>
45
  </table>
46
+ </div>
includes/settings.php CHANGED
@@ -6,42 +6,43 @@
6
  <span class="fl-builder-badge fl-builder-badge-<?php echo $form_badge_slug; ?>"><?php echo $form_badge_title; ?></span>
7
  <?php endforeach; ?>
8
  </h1>
9
- <?php if (isset($form['resizable']) && $form['resizable'] === true) : ?>
10
  <div class="fl-lightbox-controls"><i class="fa fa-expand"></i></div>
11
  <?php endif; ?>
12
  </div>
13
- <?php if(count($form['tabs']) > 1) : ?>
14
  <div class="fl-builder-settings-tabs">
15
- <?php $i = 0; foreach($form['tabs'] as $id => $tab) : ?>
16
- <a href="#fl-builder-settings-tab-<?php echo $id; ?>"<?php if($i == 0) echo ' class="fl-active"'; ?>><?php echo $tab['title']; ?></a>
17
- <?php $i++; endforeach; ?>
 
18
  </div>
19
  <?php endif; ?>
20
  <div class="fl-builder-settings-fields fl-nanoscroller">
21
  <div class="fl-nanoscroller-content">
22
- <?php $i = 0; foreach($form['tabs'] as $id => $tab) : // Tabs ?>
23
- <div id="fl-builder-settings-tab-<?php echo $id; ?>" class="fl-builder-settings-tab <?php if($i == 0) echo 'fl-active'; ?>">
24
 
25
- <?php if(isset($tab['file']) && file_exists($tab['file'])) : // Tab File ?>
26
 
27
  <?php include $tab['file']; ?>
28
 
29
  <?php else : ?>
30
 
31
- <?php if(!empty($tab['description'])) : // Tab Description ?>
32
  <p class="fl-builder-settings-tab-description"><?php echo $tab['description']; ?></p>
33
  <?php endif; ?>
34
 
35
- <?php foreach($tab['sections'] as $id => $section) : // Tab Sections ?>
36
  <div id="fl-builder-settings-section-<?php echo $id; ?>" class="fl-builder-settings-section">
37
 
38
- <?php if(isset($section['file']) && file_exists($section['file'])) : // Section File ?>
39
 
40
  <?php include $section['file']; ?>
41
 
42
  <?php else : ?>
43
 
44
- <?php if(!empty($section['title'])) : // Section Title ?>
45
  <h3 class="fl-builder-settings-title"><?php echo $section['title']; ?></h3>
46
  <?php endif; ?>
47
 
@@ -52,8 +53,8 @@
52
  <table class="fl-form-table">
53
  <?php
54
 
55
- foreach($section['fields'] as $name => $field) { // Fields
56
- FLBuilder::render_settings_field($name, $field, $settings);
57
  }
58
 
59
  ?>
@@ -67,14 +68,15 @@
67
  <?php endif; ?>
68
 
69
  </div>
70
- <?php $i++; endforeach; ?>
 
71
  </div>
72
  </div>
73
  <div class="fl-lightbox-footer">
74
- <span class="fl-builder-settings-save fl-builder-button fl-builder-button-large fl-builder-button-primary" href="javascript:void(0);" onclick="return false;"><?php _e('Save', 'fl-builder'); ?></span>
75
  <?php if ( in_array( 'save-as', $form['buttons'] ) ) : ?>
76
- <span class="fl-builder-settings-save-as fl-builder-button fl-builder-button-large" href="javascript:void(0);" onclick="return false;"><?php _e('Save As...', 'fl-builder'); ?></span>
77
  <?php endif; ?>
78
- <span class="fl-builder-settings-cancel fl-builder-button fl-builder-button-large" href="javascript:void(0);" onclick="return false;"><?php _e('Cancel', 'fl-builder'); ?></span>
79
  </div>
80
  </form>
6
  <span class="fl-builder-badge fl-builder-badge-<?php echo $form_badge_slug; ?>"><?php echo $form_badge_title; ?></span>
7
  <?php endforeach; ?>
8
  </h1>
9
+ <?php if ( isset( $form['resizable'] ) && true === $form['resizable'] ) : ?>
10
  <div class="fl-lightbox-controls"><i class="fa fa-expand"></i></div>
11
  <?php endif; ?>
12
  </div>
13
+ <?php if ( count( $form['tabs'] ) > 1 ) : ?>
14
  <div class="fl-builder-settings-tabs">
15
+ <?php $i = 0; foreach ( $form['tabs'] as $id => $tab ) : ?>
16
+ <a href="#fl-builder-settings-tab-<?php echo $id; ?>"<?php if ( 0 == $i ) { echo ' class="fl-active"';} ?>><?php echo $tab['title']; ?></a>
17
+ <?php $i++;
18
+ endforeach; ?>
19
  </div>
20
  <?php endif; ?>
21
  <div class="fl-builder-settings-fields fl-nanoscroller">
22
  <div class="fl-nanoscroller-content">
23
+ <?php $i = 0; foreach ( $form['tabs'] as $id => $tab ) : // Tabs ?>
24
+ <div id="fl-builder-settings-tab-<?php echo $id; ?>" class="fl-builder-settings-tab <?php if ( 0 == $i ) { echo 'fl-active';} ?>">
25
 
26
+ <?php if ( isset( $tab['file'] ) && file_exists( $tab['file'] ) ) : // Tab File ?>
27
 
28
  <?php include $tab['file']; ?>
29
 
30
  <?php else : ?>
31
 
32
+ <?php if ( ! empty( $tab['description'] ) ) : // Tab Description ?>
33
  <p class="fl-builder-settings-tab-description"><?php echo $tab['description']; ?></p>
34
  <?php endif; ?>
35
 
36
+ <?php foreach ( $tab['sections'] as $id => $section ) : // Tab Sections ?>
37
  <div id="fl-builder-settings-section-<?php echo $id; ?>" class="fl-builder-settings-section">
38
 
39
+ <?php if ( isset( $section['file'] ) && file_exists( $section['file'] ) ) : // Section File ?>
40
 
41
  <?php include $section['file']; ?>
42
 
43
  <?php else : ?>
44
 
45
+ <?php if ( ! empty( $section['title'] ) ) : // Section Title ?>
46
  <h3 class="fl-builder-settings-title"><?php echo $section['title']; ?></h3>
47
  <?php endif; ?>
48
 
53
  <table class="fl-form-table">
54
  <?php
55
 
56
+ foreach ( $section['fields'] as $name => $field ) { // Fields
57
+ FLBuilder::render_settings_field( $name, $field, $settings );
58
  }
59
 
60
  ?>
68
  <?php endif; ?>
69
 
70
  </div>
71
+ <?php $i++;
72
+ endforeach; ?>
73
  </div>
74
  </div>
75
  <div class="fl-lightbox-footer">
76
+ <span class="fl-builder-settings-save fl-builder-button fl-builder-button-large fl-builder-button-primary" href="javascript:void(0);" onclick="return false;"><?php _e( 'Save', 'fl-builder' ); ?></span>
77
  <?php if ( in_array( 'save-as', $form['buttons'] ) ) : ?>
78
+ <span class="fl-builder-settings-save-as fl-builder-button fl-builder-button-large" href="javascript:void(0);" onclick="return false;"><?php _e( 'Save As...', 'fl-builder' ); ?></span>
79
  <?php endif; ?>
80
+ <span class="fl-builder-settings-cancel fl-builder-button fl-builder-button-large" href="javascript:void(0);" onclick="return false;"><?php _e( 'Cancel', 'fl-builder' ); ?></span>
81
  </div>
82
  </form>
includes/template-selector.php CHANGED
@@ -1,7 +1,7 @@
1
  <form class="fl-builder-settings fl-template-selector">
2
  <div class="fl-lightbox-header">
3
 
4
- <h1><?php _e('Layout Templates', 'fl-builder'); ?></h1>
5
 
6
  <?php if ( count( $filter_data ) > 1 ) : ?>
7
  <div class="fl-template-category-filter fl-builder-settings-fields">
@@ -21,37 +21,47 @@
21
  <?php if ( FLBuilderModel::has_templates() ) : ?>
22
  <div class="fl-builder-settings-message fl-builder-templates-cta">
23
  <p><?php _e( 'Save and reuse your layouts or kick-start your creativity with even more professionally designed templates.', 'fl-builder' ); ?></p>
24
- <a class="fl-builder-upgrade-button fl-builder-button" href="<?php echo FLBuilderModel::get_store_url( '', array( 'utm_medium' => 'bb-lite', 'utm_source' => 'builder-ui', 'utm_campaign' => 'templates-cta' ) ); ?>" target="_blank"><?php _e( 'Learn More', 'fl-builder' ); ?> <i class="fa fa-external-link-square"></i></a>
 
 
 
 
25
  </div>
26
  <?php else : ?>
27
  <div class="fl-builder-settings-message fl-builder-templates-cta">
28
  <p><?php _e( 'Save and reuse your layouts or kick-start your creativity with dozens of professionally designed templates.', 'fl-builder' ); ?></p>
29
- <a class="fl-builder-upgrade-button fl-builder-button" href="<?php echo FLBuilderModel::get_store_url( '', array( 'utm_medium' => 'bb-lite', 'utm_source' => 'builder-ui', 'utm_campaign' => 'templates-cta' ) ); ?>" target="_blank"><?php _e( 'Learn More', 'fl-builder' ); ?> <i class="fa fa-external-link-square"></i></a>
 
 
 
 
30
  </div>
31
  <img class="fl-builder-templates-cta-img" src="<?php echo FL_BUILDER_URL; ?>img/templates-preview.jpg" />
32
  <?php endif; ?>
33
  <?php endif; ?>
34
 
35
  <?php $i = 0; foreach ( $templates['categorized'] as $slug => $category ) : ?>
36
- <div id="fl-builder-settings-tab-<?php echo $slug; ?>" class="fl-builder-settings-tab<?php if ( 0 === $i ) echo ' fl-active'; ?>">
37
  <div class="fl-builder-settings-section">
38
  <?php $k = 0; foreach ( $category['templates'] as $template ) : ?>
39
- <div class="fl-template-preview<?php if(($k + 1) % 3 === 0) echo ' fl-last'; ?>" data-id="<?php echo $template['id']; ?>">
40
  <div class="fl-template-image">
41
  <img src="<?php echo $template['image']; ?>" />
42
  </div>
43
  <span><?php echo $template['name']; ?></span>
44
  </div>
45
- <?php $k++; endforeach; ?>
 
46
  </div>
47
  </div>
48
- <?php $i++; endforeach; ?>
 
49
 
50
  <?php do_action( 'fl_builder_template_selector_content' ); ?>
51
 
52
  </div>
53
  </div>
54
  <div class="fl-lightbox-footer">
55
- <span class="fl-builder-settings-cancel fl-builder-button fl-builder-button-large" href="javascript:void(0);" onclick="return false;"><?php _e('Cancel', 'fl-builder'); ?></span>
56
  </div>
57
  </form>
1
  <form class="fl-builder-settings fl-template-selector">
2
  <div class="fl-lightbox-header">
3
 
4
+ <h1><?php _e( 'Layout Templates', 'fl-builder' ); ?></h1>
5
 
6
  <?php if ( count( $filter_data ) > 1 ) : ?>
7
  <div class="fl-template-category-filter fl-builder-settings-fields">
21
  <?php if ( FLBuilderModel::has_templates() ) : ?>
22
  <div class="fl-builder-settings-message fl-builder-templates-cta">
23
  <p><?php _e( 'Save and reuse your layouts or kick-start your creativity with even more professionally designed templates.', 'fl-builder' ); ?></p>
24
+ <a class="fl-builder-upgrade-button fl-builder-button" href="<?php echo FLBuilderModel::get_store_url( '', array(
25
+ 'utm_medium' => 'bb-lite',
26
+ 'utm_source' => 'builder-ui',
27
+ 'utm_campaign' => 'templates-cta',
28
+ ) ); ?>" target="_blank"><?php _e( 'Learn More', 'fl-builder' ); ?> <i class="fa fa-external-link-square"></i></a>
29
  </div>
30
  <?php else : ?>
31
  <div class="fl-builder-settings-message fl-builder-templates-cta">
32
  <p><?php _e( 'Save and reuse your layouts or kick-start your creativity with dozens of professionally designed templates.', 'fl-builder' ); ?></p>
33
+ <a class="fl-builder-upgrade-button fl-builder-button" href="<?php echo FLBuilderModel::get_store_url( '', array(
34
+ 'utm_medium' => 'bb-lite',
35
+ 'utm_source' => 'builder-ui',
36
+ 'utm_campaign' => 'templates-cta',
37
+ ) ); ?>" target="_blank"><?php _e( 'Learn More', 'fl-builder' ); ?> <i class="fa fa-external-link-square"></i></a>
38
  </div>
39
  <img class="fl-builder-templates-cta-img" src="<?php echo FL_BUILDER_URL; ?>img/templates-preview.jpg" />
40
  <?php endif; ?>
41
  <?php endif; ?>
42
 
43
  <?php $i = 0; foreach ( $templates['categorized'] as $slug => $category ) : ?>
44
+ <div id="fl-builder-settings-tab-<?php echo $slug; ?>" class="fl-builder-settings-tab<?php if ( 0 === $i ) { echo ' fl-active';} ?>">
45
  <div class="fl-builder-settings-section">
46
  <?php $k = 0; foreach ( $category['templates'] as $template ) : ?>
47
+ <div class="fl-template-preview<?php if ( ($k + 1) % 3 === 0 ) { echo ' fl-last';} ?>" data-id="<?php echo $template['id']; ?>">
48
  <div class="fl-template-image">
49
  <img src="<?php echo $template['image']; ?>" />
50
  </div>
51
  <span><?php echo $template['name']; ?></span>
52
  </div>
53
+ <?php $k++;
54
+ endforeach; ?>
55
  </div>
56
  </div>
57
+ <?php $i++;
58
+ endforeach; ?>
59
 
60
  <?php do_action( 'fl_builder_template_selector_content' ); ?>
61
 
62
  </div>
63
  </div>
64
  <div class="fl-lightbox-footer">
65
+ <span class="fl-builder-settings-cancel fl-builder-button fl-builder-button-large" href="javascript:void(0);" onclick="return false;"><?php _e( 'Cancel', 'fl-builder' ); ?></span>
66
  </div>
67
  </form>
includes/ui-bar.php CHANGED
@@ -4,4 +4,4 @@
4
  <?php FLBuilder::render_ui_bar_buttons(); ?>
5
  <div class="fl-clear"></div>
6
  </div>
7
- </div>
4
  <?php FLBuilder::render_ui_bar_buttons(); ?>
5
  <div class="fl-clear"></div>
6
  </div>
7
+ </div>
includes/ui-fields.php CHANGED
@@ -2,5 +2,7 @@
2
  <div class="fl-sortable-proxy fl-row-sortable-proxy"><div class="fl-row-sortable-proxy-item"></div></div>
3
  <div class="fl-sortable-proxy fl-col-sortable-proxy"><div class="fl-col-sortable-proxy-item"></div></div>
4
  <div class="fl-builder-hidden-editor">
5
- <?php wp_editor(' ', 'flhiddeneditor', array('wpautop' => true)); ?>
6
- </div>
 
 
2
  <div class="fl-sortable-proxy fl-row-sortable-proxy"><div class="fl-row-sortable-proxy-item"></div></div>
3
  <div class="fl-sortable-proxy fl-col-sortable-proxy"><div class="fl-col-sortable-proxy-item"></div></div>
4
  <div class="fl-builder-hidden-editor">
5
+ <?php wp_editor( ' ', 'flhiddeneditor', array(
6
+ 'wpautop' => true,
7
+ ) ); ?>
8
+ </div>
includes/ui-js-config.php CHANGED
@@ -1,6 +1,6 @@
1
  <script>
2
  <?php
3
-
4
  echo 'FLBuilderConfig = ' . json_encode( apply_filters('fl_builder_ui_js_config', array(
5
  'adminUrl' => admin_url(),
6
  'ajaxNonce' => wp_create_nonce( 'fl_ajax_update' ),
@@ -23,121 +23,125 @@ echo 'FLBuilderConfig = ' . json_encode( apply_filters('fl_builder_ui_js_config'
23
  'postStatus' => get_post_status(),
24
  'postType' => get_post_type(),
25
  'simpleUi' => $simple_ui ? true : false,
26
- 'upgradeUrl' => FLBuilderModel::get_store_url( '', array( 'utm_medium' => ( true === FL_BUILDER_LITE ? 'bb-lite' : 'bb-demo' ), 'utm_source' => 'builder-ui', 'utm_campaign' => ( true === FL_BUILDER_LITE ? 'top-panel-cta' : 'demo-cta' ) ) ),
 
 
 
 
27
  'userCanEditGlobalTemplates' => FLBuilderUserAccess::current_user_can( 'global_node_editing' ),
28
- 'userCanPublish' => current_user_can('publish_posts'),
29
  'userTemplateType' => FLBuilderModel::get_user_template_type(),
30
- 'googleFontsUrl' => apply_filters( 'fl_builder_google_fonts_domain', '//fonts.googleapis.com/' ) . 'css?family='
31
  ) ) ) . ';';
32
 
33
  echo 'FLBuilderStrings = ' . json_encode( apply_filters('fl_builder_ui_js_strings', array(
34
- 'actionsLightboxTitle' => esc_attr__('What would you like to do?', 'fl-builder'),
35
  'alreadySaved' => esc_attr_x( '%s is already a saved preset.', '%s is the preset hex color code.', 'fl-builder' ),
36
- 'audioSelected' => esc_attr__('Audio File Selected', 'fl-builder'),
37
- 'audiosSelected' => esc_attr__('Audio Files Selected', 'fl-builder'),
38
- 'cancel' => esc_attr__('Cancel', 'fl-builder'),
39
- 'changeTemplate' => esc_attr__('Change Template', 'fl-builder'),
40
- 'changeTemplateMessage' => esc_attr__('Warning! Changing the template will replace your existing layout. Do you really want to do this?', 'fl-builder'),
41
  'colorPresets' => esc_attr__( 'Color Presets', 'fl-builder' ),
42
  'colorPicker' => esc_attr__( 'Color Picker', 'fl-builder' ),
43
- 'column' => esc_attr__('Column', 'fl-builder'),
44
- 'contentSliderSelectLayout' => esc_attr__('Please select either a background layout or content layout before submitting.', 'fl-builder'),
45
  'countdownDateisInThePast' => esc_attr__( 'Error! Please enter a date that is in the future.', 'fl-builder' ),
46
- 'deleteAccount' => esc_attr__('Remove Account', 'fl-builder'),
47
- 'deleteAccountWarning' => esc_attr__('Are you sure you want to remove this account? Other modules that are connected to it will be affected.', 'fl-builder'),
48
- 'deleteColumnMessage' => esc_attr__('Do you really want to delete this column?', 'fl-builder'),
49
- 'deleteFieldMessage' => esc_attr__('Do you really want to delete this item?', 'fl-builder'),
50
- 'deleteModuleMessage' => esc_attr__('Do you really want to delete this module?', 'fl-builder'),
51
- 'deleteRowMessage' => esc_attr__('Do you really want to delete this row?', 'fl-builder'),
52
- 'deleteTemplate' => esc_attr__('Do you really want to delete this template?', 'fl-builder'),
53
- 'deleteGlobalTemplate' => esc_attr__('WARNING! You are about to delete a global template that may be linked to other pages. Do you really want to delete this template and unlink it?', 'fl-builder'),
54
- 'discard' => esc_attr__('Discard Changes and Exit', 'fl-builder'),
55
- 'discardMessage' => esc_attr__('Do you really want to discard these changes? All of your changes that are not published will be lost.', 'fl-builder'),
56
- 'done' => esc_attr__('Done', 'fl-builder'),
57
- 'draft' => esc_attr__('Save Changes and Exit', 'fl-builder'),
58
  'duplicate' => esc_attr__( 'Duplicate', 'fl-builder' ),
59
- 'duplicateLayout' => esc_attr_x('Duplicate Layout', 'Duplicate page/post action label.', 'fl-builder'),
60
- 'editGlobalSettings' => esc_attr__('Global Settings', 'fl-builder'),
61
- 'editLayoutSettings' => esc_attr__('Layout CSS / Javascript', 'fl-builder'),
62
- 'emptyMessage' => esc_attr__('Drop a row layout or module to get started!', 'fl-builder'),
63
  'enterValidDay' => esc_attr__( 'Error! Please enter a valid day.', 'fl-builder' ),
64
  'enterValidMonth' => esc_attr__( 'Error! Please enter a valid month.', 'fl-builder' ),
65
  'enterValidYear' => esc_attr__( 'Error! Please enter a valid year.', 'fl-builder' ),
66
- 'errorMessage' => esc_attr__('Beaver Builder caught the following JavaScript error. If Beaver Builder is not functioning as expected the cause is most likely this error. Please help us by disabling all plugins and testing Beaver Builder while reactivating each to determine if the issue is related to a third party plugin.', 'fl-builder'),
67
- 'fullSize' => esc_attr__('Full Size', 'fl-builder'),
68
- 'getHelp' => esc_attr__('Get Help', 'fl-builder'),
69
- 'globalErrorMessage' => __('"{message}" on line {line} of {file}.', 'fl-builder'),
70
- 'insert' => esc_attr__('Insert', 'fl-builder'),
71
- 'large' => esc_attr__('Large', 'fl-builder'),
72
- 'manageTemplates' => esc_attr__('Manage Templates', 'fl-builder'),
73
- 'medium' => esc_attr__('Medium', 'fl-builder'),
74
- 'module' => esc_attr__('Module', 'fl-builder'),
75
- 'moduleTemplateSaved' => esc_attr__('Module Saved!', 'fl-builder'),
76
- 'move' => esc_attr__('Move', 'fl-builder'),
77
- 'newColumn' => esc_attr__('New Column', 'fl-builder'),
78
- 'newRow' => esc_attr__('New Row', 'fl-builder'),
79
  'noneColorSelected' => esc_attr__( 'Please enter a color first.', 'fl-builder' ),
80
  'noPresets' => esc_attr__( 'Add a color preset first.', 'fl-builder' ),
81
- 'noResultsFound' => esc_attr__('No results found.', 'fl-builder'),
82
- 'noSavedRows' => esc_attr__('No saved rows found.', 'fl-builder'),
83
- 'noSavedModules' => esc_attr__('No saved modules found.', 'fl-builder'),
84
  'ok' => esc_attr__( 'OK', 'fl-builder' ),
85
- 'photoPage' => esc_attr__('Photo Page', 'fl-builder'),
86
- 'photoSelected' => esc_attr__('Photo Selected', 'fl-builder'),
87
- 'photosSelected' => esc_attr__('Photos Selected', 'fl-builder'),
88
  'placeholder' => esc_attr__( 'Paste color here...', 'fl-builder' ),
89
- 'pleaseWait' => esc_attr__('Please Wait...', 'fl-builder'),
90
  'presetAdded' => esc_attr_x( '%s added to presets!', '%s is the preset hex color code.', 'fl-builder' ),
91
- 'publish' => esc_attr__('Publish Changes', 'fl-builder'),
92
- 'remove' => esc_attr__('Remove', 'fl-builder'),
93
  'removePresetConfirm' => esc_attr__( 'Are you sure?', 'fl-builder' ),
94
- 'row' => esc_attr__('Row', 'fl-builder'),
95
- 'rowSettings' => esc_attr__('Row Settings', 'fl-builder'),
96
- 'rowTemplateSaved' => esc_attr__('Row Saved!', 'fl-builder'),
97
- 'saveCoreTemplate' => esc_attr__('Save Core Template', 'fl-builder'),
98
- 'saveTemplate' => esc_attr__('Save Template', 'fl-builder'),
99
- 'selectAudio' => esc_attr__('Select Audio', 'fl-builder'),
100
- 'selectPhoto' => esc_attr__('Select Photo', 'fl-builder'),
101
- 'selectPhotos' => esc_attr__('Select Photos', 'fl-builder'),
102
- 'selectVideo' => esc_attr__('Select Video', 'fl-builder'),
103
- 'submitForReview' => esc_attr__('Submit for Review', 'fl-builder'),
104
- 'subscriptionModuleAccountError' => esc_attr__('Please select an account before saving.', 'fl-builder'),
105
- 'subscriptionModuleConnectError' => esc_attr__('Please connect an account before saving.', 'fl-builder'),
106
- 'subscriptionModuleListError' => esc_attr__('Please select a list before saving.', 'fl-builder'),
107
- 'subscriptionModuleTagsError' => esc_attr__('Please enter at least one tag before saving.', 'fl-builder'),
108
- 'takeHelpTour' => esc_attr__('Take a Tour', 'fl-builder'),
109
- 'templateAppend' => esc_attr__('Append New Layout', 'fl-builder'),
110
- 'templateReplace' => esc_attr__('Replace Existing Layout', 'fl-builder'),
111
- 'templateSaved' => esc_attr__('Template Saved!', 'fl-builder'),
112
- 'thumbnail' => esc_attr__('Thumbnail', 'fl-builder'),
113
- 'tourNext' => esc_attr__('Next', 'fl-builder'),
114
- 'tourEnd' => esc_attr__('Get Started', 'fl-builder'),
115
- 'tourTemplatesTitle' => esc_attr__('Choose a Template', 'fl-builder'),
116
- 'tourTemplates' => esc_attr__('Get started by choosing a layout template to customize, or build a page from scratch by selecting the blank layout template.', 'fl-builder'),
117
- 'tourAddRowsTitle' => esc_attr__('Add Rows', 'fl-builder'),
118
- 'tourAddRows' => esc_attr__('Add multi-column rows, adjust spacing, add backgrounds and more by dragging and dropping row layouts onto the page.', 'fl-builder'),
119
- 'tourAddContentTitle' => esc_attr__('Add Content', 'fl-builder'),
120
- 'tourAddContent' => esc_attr__('Add new content by dragging and dropping modules or widgets into your row layouts or to create a new row layout.', 'fl-builder'),
121
- 'tourEditContentTitle' => esc_attr__('Edit Content', 'fl-builder'),
122
- 'tourEditContent' => esc_attr__('Move your mouse over rows, columns or modules to edit and interact with them.', 'fl-builder'),
123
- 'tourEditContent2' => esc_attr__('Use the action buttons to perform actions such as moving, editing, duplicating or deleting rows, columns and modules.', 'fl-builder'),
124
- 'tourAddContentButtonTitle' => esc_attr__('Add More Content', 'fl-builder'),
125
- 'tourAddContentButton' => esc_attr__('Use the Add Content button to open the content panel and add new row layouts, modules or widgets.', 'fl-builder'),
126
- 'tourTemplatesButtonTitle' => esc_attr__('Change Templates', 'fl-builder'),
127
- 'tourTemplatesButton' => esc_attr__('Use the Templates button to pick a new template or append one to your layout. Appending will insert a new template at the end of your existing page content.', 'fl-builder'),
128
- 'tourToolsButtonTitle' => esc_attr__('Helpful Tools', 'fl-builder'),
129
- 'tourToolsButton' => esc_attr__('The Tools button lets you save a template, duplicate a layout, edit the settings for a layout or edit the global settings.', 'fl-builder'),
130
- 'tourDoneButtonTitle' => esc_attr__('Publish Your Changes', 'fl-builder'),
131
- 'tourDoneButton' => esc_attr__("Once you're finished, click the Done button to publish your changes, save a draft or revert back to the last published state.", 'fl-builder'),
132
- 'tourFinishedTitle' => esc_attr__("Let's Get Building!", 'fl-builder'),
133
- 'tourFinished' => esc_attr__("Now that you know the basics, you're ready to start building! If at any time you need help, click the help icon in the upper right corner to access the help menu. Happy building!", 'fl-builder'),
134
- 'unloadWarning' => esc_attr__('The settings you are currently editing will not be saved if you navigate away from this page.', 'fl-builder'),
135
- 'viewKnowledgeBase' => esc_attr__('View the Knowledge Base', 'fl-builder'),
136
- 'validateRequiredMessage' => esc_attr__('This field is required.', 'fl-builder'),
137
- 'visitForums' => esc_attr__('Contact Support', 'fl-builder'),
138
- 'watchHelpVideo' => esc_attr__('Watch the Video', 'fl-builder'),
139
- 'welcomeMessage' => esc_attr__('Welcome! It looks like this might be your first time using the builder. Would you like to take a tour?', 'fl-builder'),
140
- 'yesPlease' => esc_attr__('Yes Please!', 'fl-builder')
141
  ) ) ) . ';';
142
 
143
  FLBuilderFonts::js();
1
  <script>
2
  <?php
3
+
4
  echo 'FLBuilderConfig = ' . json_encode( apply_filters('fl_builder_ui_js_config', array(
5
  'adminUrl' => admin_url(),
6
  'ajaxNonce' => wp_create_nonce( 'fl_ajax_update' ),
23
  'postStatus' => get_post_status(),
24
  'postType' => get_post_type(),
25
  'simpleUi' => $simple_ui ? true : false,
26
+ 'upgradeUrl' => FLBuilderModel::get_store_url( '', array(
27
+ 'utm_medium' => ( true === FL_BUILDER_LITE ? 'bb-lite' : 'bb-demo' ),
28
+ 'utm_source' => 'builder-ui',
29
+ 'utm_campaign' => ( true === FL_BUILDER_LITE ? 'top-panel-cta' : 'demo-cta' ),
30
+ ) ),
31
  'userCanEditGlobalTemplates' => FLBuilderUserAccess::current_user_can( 'global_node_editing' ),
32
+ 'userCanPublish' => current_user_can( 'publish_posts' ),
33
  'userTemplateType' => FLBuilderModel::get_user_template_type(),
34
+ 'googleFontsUrl' => apply_filters( 'fl_builder_google_fonts_domain', '//fonts.googleapis.com/' ) . 'css?family=',
35
  ) ) ) . ';';
36
 
37
  echo 'FLBuilderStrings = ' . json_encode( apply_filters('fl_builder_ui_js_strings', array(
38
+ 'actionsLightboxTitle' => esc_attr__( 'What would you like to do?', 'fl-builder' ),
39
  'alreadySaved' => esc_attr_x( '%s is already a saved preset.', '%s is the preset hex color code.', 'fl-builder' ),
40
+ 'audioSelected' => esc_attr__( 'Audio File Selected', 'fl-builder' ),
41
+ 'audiosSelected' => esc_attr__( 'Audio Files Selected', 'fl-builder' ),
42
+ 'cancel' => esc_attr__( 'Cancel', 'fl-builder' ),
43
+ 'changeTemplate' => esc_attr__( 'Change Template', 'fl-builder' ),
44
+ 'changeTemplateMessage' => esc_attr__( 'Warning! Changing the template will replace your existing layout. Do you really want to do this?', 'fl-builder' ),
45
  'colorPresets' => esc_attr__( 'Color Presets', 'fl-builder' ),
46
  'colorPicker' => esc_attr__( 'Color Picker', 'fl-builder' ),
47
+ 'column' => esc_attr__( 'Column', 'fl-builder' ),
48
+ 'contentSliderSelectLayout' => esc_attr__( 'Please select either a background layout or content layout before submitting.', 'fl-builder' ),
49
  'countdownDateisInThePast' => esc_attr__( 'Error! Please enter a date that is in the future.', 'fl-builder' ),
50
+ 'deleteAccount' => esc_attr__( 'Remove Account', 'fl-builder' ),
51
+ 'deleteAccountWarning' => esc_attr__( 'Are you sure you want to remove this account? Other modules that are connected to it will be affected.', 'fl-builder' ),
52
+ 'deleteColumnMessage' => esc_attr__( 'Do you really want to delete this column?', 'fl-builder' ),
53
+ 'deleteFieldMessage' => esc_attr__( 'Do you really want to delete this item?', 'fl-builder' ),
54
+ 'deleteModuleMessage' => esc_attr__( 'Do you really want to delete this module?', 'fl-builder' ),
55
+ 'deleteRowMessage' => esc_attr__( 'Do you really want to delete this row?', 'fl-builder' ),
56
+ 'deleteTemplate' => esc_attr__( 'Do you really want to delete this template?', 'fl-builder' ),
57
+ 'deleteGlobalTemplate' => esc_attr__( 'WARNING! You are about to delete a global template that may be linked to other pages. Do you really want to delete this template and unlink it?', 'fl-builder' ),
58
+ 'discard' => esc_attr__( 'Discard Changes and Exit', 'fl-builder' ),
59
+ 'discardMessage' => esc_attr__( 'Do you really want to discard these changes? All of your changes that are not published will be lost.', 'fl-builder' ),
60
+ 'done' => esc_attr__( 'Done', 'fl-builder' ),
61
+ 'draft' => esc_attr__( 'Save Changes and Exit', 'fl-builder' ),
62
  'duplicate' => esc_attr__( 'Duplicate', 'fl-builder' ),
63
+ 'duplicateLayout' => esc_attr_x( 'Duplicate Layout', 'Duplicate page/post action label.', 'fl-builder' ),
64
+ 'editGlobalSettings' => esc_attr__( 'Global Settings', 'fl-builder' ),
65
+ 'editLayoutSettings' => esc_attr__( 'Layout CSS / Javascript', 'fl-builder' ),
66
+ 'emptyMessage' => esc_attr__( 'Drop a row layout or module to get started!', 'fl-builder' ),
67
  'enterValidDay' => esc_attr__( 'Error! Please enter a valid day.', 'fl-builder' ),
68
  'enterValidMonth' => esc_attr__( 'Error! Please enter a valid month.', 'fl-builder' ),
69
  'enterValidYear' => esc_attr__( 'Error! Please enter a valid year.', 'fl-builder' ),
70
+ 'errorMessage' => esc_attr__( 'Beaver Builder caught the following JavaScript error. If Beaver Builder is not functioning as expected the cause is most likely this error. Please help us by disabling all plugins and testing Beaver Builder while reactivating each to determine if the issue is related to a third party plugin.', 'fl-builder' ),
71
+ 'fullSize' => esc_attr__( 'Full Size', 'fl-builder' ),
72
+ 'getHelp' => esc_attr__( 'Get Help', 'fl-builder' ),
73
+ 'globalErrorMessage' => __( '"{message}" on line {line} of {file}.', 'fl-builder' ),
74
+ 'insert' => esc_attr__( 'Insert', 'fl-builder' ),
75
+ 'large' => esc_attr__( 'Large', 'fl-builder' ),
76
+ 'manageTemplates' => esc_attr__( 'Manage Templates', 'fl-builder' ),
77
+ 'medium' => esc_attr__( 'Medium', 'fl-builder' ),
78
+ 'module' => esc_attr__( 'Module', 'fl-builder' ),
79
+ 'moduleTemplateSaved' => esc_attr__( 'Module Saved!', 'fl-builder' ),
80
+ 'move' => esc_attr__( 'Move', 'fl-builder' ),
81
+ 'newColumn' => esc_attr__( 'New Column', 'fl-builder' ),
82
+ 'newRow' => esc_attr__( 'New Row', 'fl-builder' ),
83
  'noneColorSelected' => esc_attr__( 'Please enter a color first.', 'fl-builder' ),
84
  'noPresets' => esc_attr__( 'Add a color preset first.', 'fl-builder' ),
85
+ 'noResultsFound' => esc_attr__( 'No results found.', 'fl-builder' ),
86
+ 'noSavedRows' => esc_attr__( 'No saved rows found.', 'fl-builder' ),
87
+ 'noSavedModules' => esc_attr__( 'No saved modules found.', 'fl-builder' ),
88
  'ok' => esc_attr__( 'OK', 'fl-builder' ),
89
+ 'photoPage' => esc_attr__( 'Photo Page', 'fl-builder' ),
90
+ 'photoSelected' => esc_attr__( 'Photo Selected', 'fl-builder' ),
91
+ 'photosSelected' => esc_attr__( 'Photos Selected', 'fl-builder' ),
92
  'placeholder' => esc_attr__( 'Paste color here...', 'fl-builder' ),
93
+ 'pleaseWait' => esc_attr__( 'Please Wait...', 'fl-builder' ),
94
  'presetAdded' => esc_attr_x( '%s added to presets!', '%s is the preset hex color code.', 'fl-builder' ),
95
+ 'publish' => esc_attr__( 'Publish Changes', 'fl-builder' ),
96
+ 'remove' => esc_attr__( 'Remove', 'fl-builder' ),
97
  'removePresetConfirm' => esc_attr__( 'Are you sure?', 'fl-builder' ),
98
+ 'row' => esc_attr__( 'Row', 'fl-builder' ),
99
+ 'rowSettings' => esc_attr__( 'Row Settings', 'fl-builder' ),
100
+ 'rowTemplateSaved' => esc_attr__( 'Row Saved!', 'fl-builder' ),
101
+ 'saveCoreTemplate' => esc_attr__( 'Save Core Template', 'fl-builder' ),
102
+ 'saveTemplate' => esc_attr__( 'Save Template', 'fl-builder' ),
103
+ 'selectAudio' => esc_attr__( 'Select Audio', 'fl-builder' ),
104
+ 'selectPhoto' => esc_attr__( 'Select Photo', 'fl-builder' ),
105
+ 'selectPhotos' => esc_attr__( 'Select Photos', 'fl-builder' ),
106
+ 'selectVideo' => esc_attr__( 'Select Video', 'fl-builder' ),
107
+ 'submitForReview' => esc_attr__( 'Submit for Review', 'fl-builder' ),
108
+ 'subscriptionModuleAccountError' => esc_attr__( 'Please select an account before saving.', 'fl-builder' ),
109
+ 'subscriptionModuleConnectError' => esc_attr__( 'Please connect an account before saving.', 'fl-builder' ),
110
+ 'subscriptionModuleListError' => esc_attr__( 'Please select a list before saving.', 'fl-builder' ),
111
+ 'subscriptionModuleTagsError' => esc_attr__( 'Please enter at least one tag before saving.', 'fl-builder' ),
112
+ 'takeHelpTour' => esc_attr__( 'Take a Tour', 'fl-builder' ),
113
+ 'templateAppend' => esc_attr__( 'Append New Layout', 'fl-builder' ),
114
+ 'templateReplace' => esc_attr__( 'Replace Existing Layout', 'fl-builder' ),
115
+ 'templateSaved' => esc_attr__( 'Template Saved!', 'fl-builder' ),
116
+ 'thumbnail' => esc_attr__( 'Thumbnail', 'fl-builder' ),
117
+ 'tourNext' => esc_attr__( 'Next', 'fl-builder' ),
118
+ 'tourEnd' => esc_attr__( 'Get Started', 'fl-builder' ),
119
+ 'tourTemplatesTitle' => esc_attr__( 'Choose a Template', 'fl-builder' ),
120
+ 'tourTemplates' => esc_attr__( 'Get started by choosing a layout template to customize, or build a page from scratch by selecting the blank layout template.', 'fl-builder' ),
121
+ 'tourAddRowsTitle' => esc_attr__( 'Add Rows', 'fl-builder' ),
122
+ 'tourAddRows' => esc_attr__( 'Add multi-column rows, adjust spacing, add backgrounds and more by dragging and dropping row layouts onto the page.', 'fl-builder' ),
123
+ 'tourAddContentTitle' => esc_attr__( 'Add Content', 'fl-builder' ),
124
+ 'tourAddContent' => esc_attr__( 'Add new content by dragging and dropping modules or widgets into your row layouts or to create a new row layout.', 'fl-builder' ),
125
+ 'tourEditContentTitle' => esc_attr__( 'Edit Content', 'fl-builder' ),
126
+ 'tourEditContent' => esc_attr__( 'Move your mouse over rows, columns or modules to edit and interact with them.', 'fl-builder' ),
127
+ 'tourEditContent2' => esc_attr__( 'Use the action buttons to perform actions such as moving, editing, duplicating or deleting rows, columns and modules.', 'fl-builder' ),
128
+ 'tourAddContentButtonTitle' => esc_attr__( 'Add More Content', 'fl-builder' ),
129
+ 'tourAddContentButton' => esc_attr__( 'Use the Add Content button to open the content panel and add new row layouts, modules or widgets.', 'fl-builder' ),
130
+ 'tourTemplatesButtonTitle' => esc_attr__( 'Change Templates', 'fl-builder' ),
131
+ 'tourTemplatesButton' => esc_attr__( 'Use the Templates button to pick a new template or append one to your layout. Appending will insert a new template at the end of your existing page content.', 'fl-builder' ),
132
+ 'tourToolsButtonTitle' => esc_attr__( 'Helpful Tools', 'fl-builder' ),
133
+ 'tourToolsButton' => esc_attr__( 'The Tools button lets you save a template, duplicate a layout, edit the settings for a layout or edit the global settings.', 'fl-builder' ),
134
+ 'tourDoneButtonTitle' => esc_attr__( 'Publish Your Changes', 'fl-builder' ),
135
+ 'tourDoneButton' => esc_attr__( "Once you're finished, click the Done button to publish your changes, save a draft or revert back to the last published state.", 'fl-builder' ),
136
+ 'tourFinishedTitle' => esc_attr__( "Let's Get Building!", 'fl-builder' ),
137
+ 'tourFinished' => esc_attr__( "Now that you know the basics, you're ready to start building! If at any time you need help, click the help icon in the upper right corner to access the help menu. Happy building!", 'fl-builder' ),
138
+ 'unloadWarning' => esc_attr__( 'The settings you are currently editing will not be saved if you navigate away from this page.', 'fl-builder' ),
139
+ 'viewKnowledgeBase' => esc_attr__( 'View the Knowledge Base', 'fl-builder' ),
140
+ 'validateRequiredMessage' => esc_attr__( 'This field is required.', 'fl-builder' ),
141
+ 'visitForums' => esc_attr__( 'Contact Support', 'fl-builder' ),
142
+ 'watchHelpVideo' => esc_attr__( 'Watch the Video', 'fl-builder' ),
143
+ 'welcomeMessage' => esc_attr__( 'Welcome! It looks like this might be your first time using the builder. Would you like to take a tour?', 'fl-builder' ),
144
+ 'yesPlease' => esc_attr__( 'Yes Please!', 'fl-builder' ),
145
  ) ) ) . ';';
146
 
147
  FLBuilderFonts::js();
includes/ui-js-templates.php CHANGED
@@ -2,14 +2,14 @@
2
  <div class="fl-row-overlay fl-block-overlay<# if ( data.global ) { #> fl-block-overlay-global<# } #>">
3
  <div class="fl-block-overlay-header">
4
  <div class="fl-block-overlay-actions">
5
- <div class="fl-block-overlay-title"><?php _e('Row', 'fl-builder'); ?></div>
6
  <# if ( data.global && ! FLBuilderConfig.userCanEditGlobalTemplates ) { #>
7
- <i class="fa fa-lock fl-tip" title="<?php _e('Locked', 'fl-builder'); ?>"></i>
8
  <# } else { #>
9
  <?php if ( ! FLBuilderModel::is_post_user_template( 'row' ) && ! $simple_ui ) : ?>
10
- <i class="fl-block-move fa fa-arrows fl-tip" title="<?php _e('Move', 'fl-builder'); ?>"></i>
11
  <?php endif; ?>
12
- <i class="fl-block-settings fa fa-wrench fl-tip" title="<?php _e('Row Settings', 'fl-builder'); ?>"></i>
13
  <?php if ( ! FLBuilderModel::is_post_user_template( 'row' ) && ! $simple_ui ) : ?>
14
  <i class="fl-block-copy fa fa-copy fl-tip" title="<?php _e( 'Duplicate', 'fl-builder' ); ?>"></i>
15
  <i class="fl-block-remove fa fa-times fl-tip" title="<?php _e( 'Remove', 'fl-builder' ); ?>"></i>
@@ -27,7 +27,7 @@
27
  <div class="fl-block-overlay-header">
28
  <div class="fl-block-overlay-actions">
29
  <?php if ( ! $simple_ui ) : ?>
30
- <i class="fl-block-move fa fa-arrows fl-tip" title="<?php _e('Move', 'fl-builder'); ?>"></i>
31
  <span class="fl-builder-has-submenu">
32
  <i class="fl-block-settings fa fa-columns fl-tip" title="<?php _e( 'Edit Column', 'fl-builder' ); ?>"></i>
33
  <ul class="fl-builder-submenu fl-block-col-submenu">
@@ -78,10 +78,10 @@
78
  <div class="fl-block-overlay-header">
79
  <div class="fl-block-overlay-actions">
80
  <# if ( data.global && ! FLBuilderConfig.userCanEditGlobalTemplates ) { #>
81
- <i class="fa fa-lock fl-tip" title="<?php _e('Locked', 'fl-builder'); ?>"></i>
82
  <# } else { #>
83
  <?php if ( ! FLBuilderModel::is_post_user_template( 'module' ) && ! $simple_ui ) : ?>
84
- <i class="fl-block-move fa fa-arrows fl-tip" title="<?php _e('Move', 'fl-builder'); ?>"></i>
85
  <?php endif; ?>
86
  <i class="fl-block-settings fa fa-wrench fl-tip" title="<?php printf( __( '%s Settings', 'fl-builder' ), '{{data.moduleName}}' ); ?>"></i>
87
  <?php if ( ! FLBuilderModel::is_post_user_template( 'module' ) && ! $simple_ui ) : ?>
@@ -158,7 +158,7 @@
158
  <# for( var i in data.buttons ) { #>
159
  <span class="fl-builder-{{data.buttons[ i ].key}}-button fl-builder-button fl-builder-button-large">{{data.buttons[ i ].label}}</span>
160
  <# } #>
161
- <span class="fl-builder-cancel-button fl-builder-button fl-builder-button-primary fl-builder-button-large"><?php _e('Cancel', 'fl-builder'); ?></span>
162
  </div>
163
  </script>
164
  <!-- #tmpl-fl-actions-lightbox -->
@@ -166,7 +166,7 @@
166
  <script type="text/html" id="tmpl-fl-alert-lightbox">
167
  <div class="fl-lightbox-message">{{{data.message}}}</div>
168
  <div class="fl-lightbox-footer">
169
- <span class="fl-builder-alert-close fl-builder-button fl-builder-button-large fl-builder-button-primary" href="javascript:void(0);"><?php _e('OK', 'fl-builder'); ?></span>
170
  </div>
171
  </script>
172
  <!-- #tmpl-fl-alert-lightbox -->
@@ -182,20 +182,20 @@
182
 
183
  <script type="text/html" id="tmpl-fl-tour-lightbox">
184
  <div class="fl-builder-actions fl-builder-tour-actions">
185
- <span class="fl-builder-actions-title"><?php _e('Welcome! It looks like this might be your first time using the builder. Would you like to take a tour?', 'fl-builder'); ?></span>
186
- <span class="fl-builder-no-tour-button fl-builder-button fl-builder-button-large"><?php _e('No Thanks', 'fl-builder'); ?></span>
187
- <span class="fl-builder-yes-tour-button fl-builder-button fl-builder-button-primary fl-builder-button-large"><?php _e('Yes Please!', 'fl-builder'); ?></span>
188
  </div>
189
  </script>
190
  <!-- #tmpl-fl-tour-lightbox -->
191
 
192
  <script type="text/html" id="tmpl-fl-video-lightbox">
193
  <div class="fl-lightbox-header">
194
- <h1><?php _e('Getting Started Video', 'fl-builder'); ?></h1>
195
  </div>
196
  <div class="fl-builder-getting-started-video">{{{data.video}}}</div>
197
  <div class="fl-lightbox-footer">
198
- <span class="fl-builder-settings-cancel fl-builder-button fl-builder-button-large fl-builder-button-primary" href="javascript:void(0);"><?php _e('Done', 'fl-builder'); ?></span>
199
  </div>
200
  </script>
201
  <!-- #tmpl-fl-video-lightbox -->
@@ -210,4 +210,4 @@
210
  </div>
211
  </div>
212
  </script>
213
- <!-- #tmpl-fl-responsive-preview -->
2
  <div class="fl-row-overlay fl-block-overlay<# if ( data.global ) { #> fl-block-overlay-global<# } #>">
3
  <div class="fl-block-overlay-header">
4
  <div class="fl-block-overlay-actions">
5
+ <div class="fl-block-overlay-title"><?php _e( 'Row', 'fl-builder' ); ?></div>
6
  <# if ( data.global && ! FLBuilderConfig.userCanEditGlobalTemplates ) { #>
7
+ <i class="fa fa-lock fl-tip" title="<?php _e( 'Locked', 'fl-builder' ); ?>"></i>
8
  <# } else { #>
9
  <?php if ( ! FLBuilderModel::is_post_user_template( 'row' ) && ! $simple_ui ) : ?>
10
+ <i class="fl-block-move fa fa-arrows fl-tip" title="<?php _e( 'Move', 'fl-builder' ); ?>"></i>
11
  <?php endif; ?>
12
+ <i class="fl-block-settings fa fa-wrench fl-tip" title="<?php _e( 'Row Settings', 'fl-builder' ); ?>"></i>
13
  <?php if ( ! FLBuilderModel::is_post_user_template( 'row' ) && ! $simple_ui ) : ?>
14
  <i class="fl-block-copy fa fa-copy fl-tip" title="<?php _e( 'Duplicate', 'fl-builder' ); ?>"></i>
15
  <i class="fl-block-remove fa fa-times fl-tip" title="<?php _e( 'Remove', 'fl-builder' ); ?>"></i>
27
  <div class="fl-block-overlay-header">
28
  <div class="fl-block-overlay-actions">
29
  <?php if ( ! $simple_ui ) : ?>
30
+ <i class="fl-block-move fa fa-arrows fl-tip" title="<?php _e( 'Move', 'fl-builder' ); ?>"></i>
31
  <span class="fl-builder-has-submenu">
32
  <i class="fl-block-settings fa fa-columns fl-tip" title="<?php _e( 'Edit Column', 'fl-builder' ); ?>"></i>
33
  <ul class="fl-builder-submenu fl-block-col-submenu">
78
  <div class="fl-block-overlay-header">
79
  <div class="fl-block-overlay-actions">
80
  <# if ( data.global && ! FLBuilderConfig.userCanEditGlobalTemplates ) { #>
81
+ <i class="fa fa-lock fl-tip" title="<?php _e( 'Locked', 'fl-builder' ); ?>"></i>
82
  <# } else { #>
83
  <?php if ( ! FLBuilderModel::is_post_user_template( 'module' ) && ! $simple_ui ) : ?>
84
+ <i class="fl-block-move fa fa-arrows fl-tip" title="<?php _e( 'Move', 'fl-builder' ); ?>"></i>
85
  <?php endif; ?>
86
  <i class="fl-block-settings fa fa-wrench fl-tip" title="<?php printf( __( '%s Settings', 'fl-builder' ), '{{data.moduleName}}' ); ?>"></i>
87
  <?php if ( ! FLBuilderModel::is_post_user_template( 'module' ) && ! $simple_ui ) : ?>
158
  <# for( var i in data.buttons ) { #>
159
  <span class="fl-builder-{{data.buttons[ i ].key}}-button fl-builder-button fl-builder-button-large">{{data.buttons[ i ].label}}</span>
160
  <# } #>
161
+ <span class="fl-builder-cancel-button fl-builder-button fl-builder-button-primary fl-builder-button-large"><?php _e( 'Cancel', 'fl-builder' ); ?></span>
162
  </div>
163
  </script>
164
  <!-- #tmpl-fl-actions-lightbox -->
166
  <script type="text/html" id="tmpl-fl-alert-lightbox">
167
  <div class="fl-lightbox-message">{{{data.message}}}</div>
168
  <div class="fl-lightbox-footer">
169
+ <span class="fl-builder-alert-close fl-builder-button fl-builder-button-large fl-builder-button-primary" href="javascript:void(0);"><?php _e( 'OK', 'fl-builder' ); ?></span>
170
  </div>
171
  </script>
172
  <!-- #tmpl-fl-alert-lightbox -->
182
 
183
  <script type="text/html" id="tmpl-fl-tour-lightbox">
184
  <div class="fl-builder-actions fl-builder-tour-actions">
185
+ <span class="fl-builder-actions-title"><?php _e( 'Welcome! It looks like this might be your first time using the builder. Would you like to take a tour?', 'fl-builder' ); ?></span>
186
+ <span class="fl-builder-no-tour-button fl-builder-button fl-builder-button-large"><?php _e( 'No Thanks', 'fl-builder' ); ?></span>
187
+ <span class="fl-builder-yes-tour-button fl-builder-button fl-builder-button-primary fl-builder-button-large"><?php _e( 'Yes Please!', 'fl-builder' ); ?></span>
188
  </div>
189
  </script>
190
  <!-- #tmpl-fl-tour-lightbox -->
191
 
192
  <script type="text/html" id="tmpl-fl-video-lightbox">
193
  <div class="fl-lightbox-header">
194
+ <h1><?php _e( 'Getting Started Video', 'fl-builder' ); ?></h1>
195
  </div>
196
  <div class="fl-builder-getting-started-video">{{{data.video}}}</div>
197
  <div class="fl-lightbox-footer">
198
+ <span class="fl-builder-settings-cancel fl-builder-button fl-builder-button-large fl-builder-button-primary" href="javascript:void(0);"><?php _e( 'Done', 'fl-builder' ); ?></span>
199
  </div>
200
  </script>
201
  <!-- #tmpl-fl-video-lightbox -->
210
  </div>
211
  </div>
212
  </script>
213
+ <!-- #tmpl-fl-responsive-preview -->
includes/ui-panel-module-templates.php CHANGED
@@ -17,4 +17,4 @@
17
  </div>
18
  </div>
19
  <?php endforeach; ?>
20
- <?php endif; ?>
17
  </div>
18
  </div>
19
  <?php endforeach; ?>
20
+ <?php endif; ?>
includes/ui-panel-row-templates.php CHANGED
@@ -17,4 +17,4 @@
17
  </div>
18
  </div>
19
  <?php endforeach; ?>
20
- <?php endif; ?>
17
  </div>
18
  </div>
19
  <?php endforeach; ?>
20
+ <?php endif; ?>
includes/ui-panel.php CHANGED
@@ -10,19 +10,19 @@
10
 
11
  <div id="fl-builder-blocks-rows" class="fl-builder-blocks-section">
12
  <span class="fl-builder-blocks-section-title">
13
- <?php _e('Row Layouts', 'fl-builder'); ?>
14
  <i class="fa fa-chevron-down"></i>
15
  </span>
16
  <div class="fl-builder-blocks-section-content fl-builder-rows">
17
- <span class="fl-builder-block fl-builder-block-row" data-cols="1-col"><span class="fl-builder-block-title"><?php _e('1 Column', 'fl-builder'); ?></span></span>
18
- <span class="fl-builder-block fl-builder-block-row" data-cols="2-cols"><span class="fl-builder-block-title"><?php _e('2 Columns', 'fl-builder'); ?></span></span>
19
- <span class="fl-builder-block fl-builder-block-row" data-cols="3-cols"><span class="fl-builder-block-title"><?php _e('3 Columns', 'fl-builder'); ?></span></span>
20
- <span class="fl-builder-block fl-builder-block-row" data-cols="4-cols"><span class="fl-builder-block-title"><?php _e('4 Columns', 'fl-builder'); ?></span></span>
21
- <span class="fl-builder-block fl-builder-block-row" data-cols="5-cols"><span class="fl-builder-block-title"><?php _e('5 Columns', 'fl-builder'); ?></span></span>
22
- <span class="fl-builder-block fl-builder-block-row" data-cols="6-cols"><span class="fl-builder-block-title"><?php _e('6 Columns', 'fl-builder'); ?></span></span>
23
- <span class="fl-builder-block fl-builder-block-row" data-cols="left-sidebar"><span class="fl-builder-block-title"><?php _e('Left Sidebar', 'fl-builder'); ?></span></span>
24
- <span class="fl-builder-block fl-builder-block-row" data-cols="right-sidebar"><span class="fl-builder-block-title"><?php _e('Right Sidebar', 'fl-builder'); ?></span></span>
25
- <span class="fl-builder-block fl-builder-block-row" data-cols="left-right-sidebar"><span class="fl-builder-block-title"><?php _e('Left &amp; Right Sidebar', 'fl-builder'); ?></span></span>
26
  </div>
27
  </div>
28
 
@@ -32,22 +32,22 @@
32
 
33
  <?php do_action( 'fl_builder_ui_panel_before_modules' ); ?>
34
 
35
- <?php foreach($categories as $title => $modules) : ?>
36
  <div id="fl-builder-blocks-<?php echo FLBuilderModel::get_module_category_slug( $title ); ?>" class="fl-builder-blocks-section">
37
  <span class="fl-builder-blocks-section-title">
38
  <?php echo $title; ?>
39
  <i class="fa fa-chevron-down"></i>
40
  </span>
41
- <?php if($title == __('WordPress Widgets', 'fl-builder')) : ?>
42
  <div class="fl-builder-blocks-section-content fl-builder-widgets">
43
- <?php foreach($modules as $module) : ?>
44
  <span class="fl-builder-block fl-builder-block-module" data-type="widget" data-widget="<?php echo $module->class; ?>"><span class="fl-builder-block-title" title="<?php echo esc_attr( $module->name ); ?>"><?php echo $module->name; ?></span></span>
45
  <?php endforeach; ?>
46
  </div>
47
  <?php else : ?>
48
  <div class="fl-builder-blocks-section-content fl-builder-modules">
49
- <?php foreach($modules as $module) : ?>
50
- <span class="fl-builder-block fl-builder-block-module" data-type="<?php echo $module->slug; ?>"<?php if ( isset( $module->alias ) ) echo ' data-alias="' . $module->alias . '"'; ?>><span class="fl-builder-block-title" title="<?php echo esc_attr( $module->name ); ?>"><?php echo $module->name; ?></span></span>
51
  <?php endforeach; ?>
52
  </div>
53
  <?php endif; ?>
@@ -58,7 +58,11 @@
58
 
59
  <?php if ( true === FL_BUILDER_LITE ) : ?>
60
  <div class="fl-builder-modules-cta">
61
- <a href="#" onclick="window.open('<?php echo FLBuilderModel::get_store_url( '', array( 'utm_medium' => 'bb-lite', 'utm_source' => 'builder-ui', 'utm_campaign' => 'modules-panel-cta' ) ); ?>');" target="_blank"><i class="fa fa-external-link-square"></i> <?php _e( 'Get more time-saving features, modules, and expert support.', 'fl-builder' ); ?></a>
 
 
 
 
62
  </div>
63
  <?php endif; ?>
64
 
10
 
11
  <div id="fl-builder-blocks-rows" class="fl-builder-blocks-section">
12
  <span class="fl-builder-blocks-section-title">
13
+ <?php _e( 'Row Layouts', 'fl-builder' ); ?>
14
  <i class="fa fa-chevron-down"></i>
15
  </span>
16
  <div class="fl-builder-blocks-section-content fl-builder-rows">
17
+ <span class="fl-builder-block fl-builder-block-row" data-cols="1-col"><span class="fl-builder-block-title"><?php _e( '1 Column', 'fl-builder' ); ?></span></span>
18
+ <span class="fl-builder-block fl-builder-block-row" data-cols="2-cols"><span class="fl-builder-block-title"><?php _e( '2 Columns', 'fl-builder' ); ?></span></span>
19
+ <span class="fl-builder-block fl-builder-block-row" data-cols="3-cols"><span class="fl-builder-block-title"><?php _e( '3 Columns', 'fl-builder' ); ?></span></span>
20
+ <span class="fl-builder-block fl-builder-block-row" data-cols="4-cols"><span class="fl-builder-block-title"><?php _e( '4 Columns', 'fl-builder' ); ?></span></span>
21
+ <span class="fl-builder-block fl-builder-block-row" data-cols="5-cols"><span class="fl-builder-block-title"><?php _e( '5 Columns', 'fl-builder' ); ?></span></span>
22
+ <span class="fl-builder-block fl-builder-block-row" data-cols="6-cols"><span class="fl-builder-block-title"><?php _e( '6 Columns', 'fl-builder' ); ?></span></span>
23
+ <span class="fl-builder-block fl-builder-block-row" data-cols="left-sidebar"><span class="fl-builder-block-title"><?php _e( 'Left Sidebar', 'fl-builder' ); ?></span></span>
24
+ <span class="fl-builder-block fl-builder-block-row" data-cols="right-sidebar"><span class="fl-builder-block-title"><?php _e( 'Right Sidebar', 'fl-builder' ); ?></span></span>
25
+ <span class="fl-builder-block fl-builder-block-row" data-cols="left-right-sidebar"><span class="fl-builder-block-title"><?php _e( 'Left &amp; Right Sidebar', 'fl-builder' ); ?></span></span>
26
  </div>
27
  </div>
28
 
32
 
33
  <?php do_action( 'fl_builder_ui_panel_before_modules' ); ?>
34
 
35
+ <?php foreach ( $categories as $title => $modules ) : ?>
36
  <div id="fl-builder-blocks-<?php echo FLBuilderModel::get_module_category_slug( $title ); ?>" class="fl-builder-blocks-section">
37
  <span class="fl-builder-blocks-section-title">
38
  <?php echo $title; ?>
39
  <i class="fa fa-chevron-down"></i>
40
  </span>
41
+ <?php if ( __( 'WordPress Widgets', 'fl-builder' ) == $title ) : ?>
42
  <div class="fl-builder-blocks-section-content fl-builder-widgets">
43
+ <?php foreach ( $modules as $module ) : ?>
44
  <span class="fl-builder-block fl-builder-block-module" data-type="widget" data-widget="<?php echo $module->class; ?>"><span class="fl-builder-block-title" title="<?php echo esc_attr( $module->name ); ?>"><?php echo $module->name; ?></span></span>
45
  <?php endforeach; ?>
46
  </div>
47
  <?php else : ?>
48
  <div class="fl-builder-blocks-section-content fl-builder-modules">
49
+ <?php foreach ( $modules as $module ) : ?>
50
+ <span class="fl-builder-block fl-builder-block-module" data-type="<?php echo $module->slug; ?>"<?php if ( isset( $module->alias ) ) { echo ' data-alias="' . $module->alias . '"';} ?>><span class="fl-builder-block-title" title="<?php echo esc_attr( $module->name ); ?>"><?php echo $module->name; ?></span></span>
51
  <?php endforeach; ?>
52
  </div>
53
  <?php endif; ?>
58
 
59
  <?php if ( true === FL_BUILDER_LITE ) : ?>
60
  <div class="fl-builder-modules-cta">
61
+ <a href="#" onclick="window.open('<?php echo FLBuilderModel::get_store_url( '', array(
62
+ 'utm_medium' => 'bb-lite',
63
+ 'utm_source' => 'builder-ui',
64
+ 'utm_campaign' => 'modules-panel-cta',
65
+ ) ); ?>');" target="_blank"><i class="fa fa-external-link-square"></i> <?php _e( 'Get more time-saving features, modules, and expert support.', 'fl-builder' ); ?></a>
66
  </div>
67
  <?php endif; ?>
68
 
includes/updater-config.php CHANGED
@@ -1,10 +1,10 @@
1
  <?php
2
 
3
- if(class_exists('FLUpdater')) {
4
  FLUpdater::add_product(array(
5
- 'name' => 'Beaver Builder Plugin (Lite Version)',
6
- 'version' => '1.10.6.5',
7
  'slug' => 'bb-plugin',
8
- 'type' => 'plugin'
9
- ));
10
- }
1
  <?php
2
 
3
+ if ( class_exists( 'FLUpdater' ) ) {
4
  FLUpdater::add_product(array(
5
+ 'name' => 'Beaver Builder Plugin (Lite Version)',
6
+ 'version' => '1.10.7',
7
  'slug' => 'bb-plugin',
8
+ 'type' => 'plugin',
9
+ ));
10
+ }
includes/updater/classes/class-fl-updater.php CHANGED
@@ -51,16 +51,14 @@ final class FLUpdater {
51
  * @param array $settings An array of settings for this instance.
52
  * @return void
53
  */
54
- public function __construct( $settings = array() )
55
- {
56
  $this->settings = $settings;
57
 
58
  if ( 'plugin' == $settings['type'] ) {
59
  add_filter( 'pre_set_site_transient_update_plugins', array( $this, 'update_check' ) );
60
  add_filter( 'plugins_api', array( $this, 'plugin_info' ), 10, 3 );
61
  add_action( 'in_plugin_update_message-' . self::get_plugin_file( $settings['slug'] ), array( $this, 'update_message' ), 1, 2 );
62
- }
63
- else if ( $settings['type'] == 'theme' ) {
64
  add_filter( 'pre_set_site_transient_update_themes', array( $this, 'update_check' ) );
65
  }
66
  }
@@ -71,8 +69,7 @@ final class FLUpdater {
71
  * @since 1.7.7
72
  * @return object
73
  */
74
- public function get_response()
75
- {
76
  $slug = $this->settings['slug'];
77
 
78
  if ( isset( FLUpdater::$_responses[ $slug ] ) ) {
@@ -86,7 +83,7 @@ final class FLUpdater {
86
  'product' => $this->settings['name'],
87
  'slug' => $this->settings['slug'],
88
  'version' => $this->settings['version'],
89
- 'php' => phpversion()
90
  ) );
91
 
92
  return FLUpdater::$_responses[ $slug ];
@@ -99,11 +96,10 @@ final class FLUpdater {
99
  * @param object $transient A WordPress transient object with update data.
100
  * @return object
101
  */
102
- public function update_check( $transient )
103
- {
104
  global $pagenow;
105
 
106
- if( 'plugins.php' == $pagenow && is_multisite() ) {
107
  return $transient;
108
  }
109
  if ( ! is_object( $transient ) ) {
@@ -115,14 +111,14 @@ final class FLUpdater {
115
 
116
  $response = $this->get_response();
117
 
118
- if( ! isset( $response->error ) ) {
119
 
120
  $transient->last_checked = time();
121
  $transient->checked[ $this->settings['slug'] ] = $this->settings['version'];
122
 
123
- if($this->settings['type'] == 'plugin') {
124
 
125
- $plugin = self::get_plugin_file($this->settings['slug']);
126
 
127
  if ( version_compare( $response->new_version, $this->settings['version'], '>' ) ) {
128
 
@@ -137,12 +133,11 @@ final class FLUpdater {
137
  $transient->response[ $plugin ]->upgrade_notice = FLUpdater::get_update_error_message();
138
  }
139
  }
140
- }
141
- else if($this->settings['type'] == 'theme') {
142
 
143
- if(version_compare($response->new_version, $this->settings['version'], '>')) {
144
 
145
- $transient->response[$this->settings['slug']] = array(
146
  'new_version' => $response->new_version,
147
  'url' => $response->homepage,
148
  'package' => $response->package,
@@ -150,7 +145,7 @@ final class FLUpdater {
150
  );
151
  }
152
  }
153
- }
154
 
155
  return $transient;
156
  }
@@ -164,18 +159,17 @@ final class FLUpdater {
164
  * @param object $args
165
  * @return object|bool
166
  */
167
- public function plugin_info($false, $action, $args)
168
- {
169
  if ( 'plugin_information' != $action ) {
170
  return $false;
171
  }
172
- if(!isset($args->slug) || $args->slug != $this->settings['slug']) {
173
  return $false;
174
  }
175
 
176
  $response = $this->get_response();
177
 
178
- if( ! isset( $response->error ) ) {
179
 
180
  $info = new stdClass();
181
  $info->name = $this->settings['name'];
@@ -188,7 +182,7 @@ final class FLUpdater {
188
  $info->tested = $response->tested;
189
  $info->last_updated = $response->last_updated;
190
  $info->download_link = $response->package;
191
- $info->sections = (array)$response->sections;
192
 
193
  return $info;
194
  }
@@ -205,8 +199,7 @@ final class FLUpdater {
205
  * @param object $response An object with update data for this plugin.
206
  * @return void
207
  */
208
- public function update_message( $plugin_data, $response )
209
- {
210
  if ( empty( $response->package ) ) {
211
  echo FLUpdater::get_update_error_message( $plugin_data );
212
  }
@@ -219,12 +212,11 @@ final class FLUpdater {
219
  * @since 1.0
220
  * @return void
221
  */
222
- static public function init()
223
- {
224
  include FL_UPDATER_DIR . 'includes/config.php';
225
 
226
- foreach($config as $path) {
227
- if(file_exists($path)) {
228
  require_once $path;
229
  }
230
  }
@@ -238,20 +230,19 @@ final class FLUpdater {
238
  * @param array $args An array of settings for the product.
239
  * @return void
240
  */
241
- static public function add_product($args = array())
242
- {
243
- if(is_array($args) && isset($args['slug'])) {
244
-
245
- if($args['type'] == 'plugin') {
246
- if(file_exists(WP_CONTENT_DIR . '/plugins/' . $args['slug'])) {
247
- self::$_products[$args['name']] = $args;
248
- new FLUpdater(self::$_products[$args['name']]);
249
  }
250
  }
251
- if($args['type'] == 'theme') {
252
- if(file_exists(WP_CONTENT_DIR . '/themes/' . $args['slug'])) {
253
- self::$_products[$args['name']] = $args;
254
- new FLUpdater(self::$_products[$args['name']]);
255
  }
256
  }
257
  }
@@ -263,12 +254,11 @@ final class FLUpdater {
263
  * @since 1.0
264
  * @return void
265
  */
266
- static public function render_form()
267
- {
268
  // Activate a subscription?
269
- if(isset($_POST['fl-updater-nonce'])) {
270
- if(wp_verify_nonce($_POST['fl-updater-nonce'], 'updater-nonce')) {
271
- self::save_subscription_license($_POST['license']);
272
  }
273
  }
274
 
@@ -286,8 +276,7 @@ final class FLUpdater {
286
  * @param object $subscription
287
  * @return void
288
  */
289
- static public function render_subscriptions( $subscription )
290
- {
291
  if ( isset( $subscription->error ) || ! $subscription->active || ! $subscription->domain->active || ! isset( $subscription->downloads ) ) {
292
  return;
293
  }
@@ -306,9 +295,8 @@ final class FLUpdater {
306
  * @since 1.0
307
  * @return string
308
  */
309
- static public function get_subscription_license()
310
- {
311
- $value = get_site_option('fl_themes_subscription_email');
312
 
313
  return $value ? $value : '';
314
  }
@@ -320,16 +308,15 @@ final class FLUpdater {
320
  * @param string $license The new license key.
321
  * @return void
322
  */
323
- static public function save_subscription_license($license)
324
- {
325
  FLUpdater::api_request(self::$_updates_api_url, array(
326
  'fl-api-method' => 'activate_domain',
327
  'license' => $license,
328
  'domain' => network_home_url(),
329
- 'products' => json_encode( self::$_products )
330
  ));
331
 
332
- update_site_option('fl_themes_subscription_email', $license);
333
  }
334
 
335
  /**
@@ -338,12 +325,11 @@ final class FLUpdater {
338
  * @since 1.0
339
  * @return bool
340
  */
341
- static public function get_subscription_info()
342
- {
343
  return self::api_request(self::$_updates_api_url, array(
344
  'fl-api-method' => 'subscription_info',
345
  'domain' => network_home_url(),
346
- 'license' => FLUpdater::get_subscription_license()
347
  ));
348
  }
349
 
@@ -355,17 +341,16 @@ final class FLUpdater {
355
  * @param array $plugin_data An array of data for this plugin.
356
  * @return string
357
  */
358
- static private function get_update_error_message( $plugin_data = null )
359
- {
360
  $message = '';
361
  $message .= '<p style="padding:10px 20px; margin-top: 10px; background: #d54e21; color: #fff;">';
362
  $message .= __( '<strong>UPDATE UNAVAILABLE!</strong>', 'fl-builder' );
363
  $message .= '&nbsp;&nbsp;&nbsp;';
364
- $message .= __('Please subscribe to enable automatic updates for this plugin.', 'fl-builder');
365
 
366
  if ( $plugin_data && isset( $plugin_data['PluginURI'] ) ) {
367
  $message .= ' <a href="' . $plugin_data['PluginURI'] . '" target="_blank" style="color: #fff; text-decoration: underline;">';
368
- $message .= __('Subscribe Now', 'fl-builder');
369
  $message .= ' &raquo;</a>';
370
  }
371
 
@@ -383,12 +368,10 @@ final class FLUpdater {
383
  * @param string $slug The product slug.
384
  * @return string
385
  */
386
- static private function get_plugin_file( $slug )
387
- {
388
  if ( 'bb-plugin' == $slug ) {
389
  $file = $slug . '/fl-builder.php';
390
- }
391
- else {
392
  $file = $slug . '/' . $slug . '.php';
393
  }
394
 
@@ -405,17 +388,16 @@ final class FLUpdater {
405
  * @param array $args An array of args to send along with the request.
406
  * @return mixed The response or false if there is an error.
407
  */
408
- static private function api_request($api_url = false, $args = array())
409
- {
410
- if($api_url) {
411
 
412
  $params = array();
413
 
414
- foreach($args as $key => $val) {
415
- $params[] = $key . '=' . urlencode($val);
416
  }
417
 
418
- return self::remote_get($api_url . '?' . implode('&', $params));
419
  }
420
 
421
  return false;
@@ -429,28 +411,27 @@ final class FLUpdater {
429
  * @param string $url The URL to get.
430
  * @return mixed The response or false if there is an error.
431
  */
432
- static private function remote_get($url)
433
- {
434
- $request = wp_remote_get($url);
435
  $error = new stdClass();
436
  $error->error = 'connection';
437
 
438
- if(is_wp_error($request)) {
439
  return $error;
440
  }
441
- if(wp_remote_retrieve_response_code($request) != 200) {
442
  return $error;
443
  }
444
 
445
- $body = wp_remote_retrieve_body($request);
446
 
447
- if(is_wp_error($body)) {
448
  return $error;
449
  }
450
 
451
- $body_decoded = json_decode($body);
452
 
453
- if(!is_object($body_decoded)) {
454
  return $error;
455
  }
456
 
51
  * @param array $settings An array of settings for this instance.
52
  * @return void
53
  */
54
+ public function __construct( $settings = array() ) {
 
55
  $this->settings = $settings;
56
 
57
  if ( 'plugin' == $settings['type'] ) {
58
  add_filter( 'pre_set_site_transient_update_plugins', array( $this, 'update_check' ) );
59
  add_filter( 'plugins_api', array( $this, 'plugin_info' ), 10, 3 );
60
  add_action( 'in_plugin_update_message-' . self::get_plugin_file( $settings['slug'] ), array( $this, 'update_message' ), 1, 2 );
61
+ } elseif ( 'theme' == $settings['type'] ) {
 
62
  add_filter( 'pre_set_site_transient_update_themes', array( $this, 'update_check' ) );
63
  }
64
  }
69
  * @since 1.7.7
70
  * @return object
71
  */
72
+ public function get_response() {
 
73
  $slug = $this->settings['slug'];
74
 
75
  if ( isset( FLUpdater::$_responses[ $slug ] ) ) {
83
  'product' => $this->settings['name'],
84
  'slug' => $this->settings['slug'],
85
  'version' => $this->settings['version'],
86
+ 'php' => phpversion(),
87
  ) );
88
 
89
  return FLUpdater::$_responses[ $slug ];
96
  * @param object $transient A WordPress transient object with update data.
97
  * @return object
98
  */
99
+ public function update_check( $transient ) {
 
100
  global $pagenow;
101
 
102
+ if ( 'plugins.php' == $pagenow && is_multisite() ) {
103
  return $transient;
104
  }
105
  if ( ! is_object( $transient ) ) {
111
 
112
  $response = $this->get_response();
113
 
114
+ if ( ! isset( $response->error ) ) {
115
 
116
  $transient->last_checked = time();
117
  $transient->checked[ $this->settings['slug'] ] = $this->settings['version'];
118
 
119
+ if ( 'plugin' == $this->settings['type'] ) {
120
 
121
+ $plugin = self::get_plugin_file( $this->settings['slug'] );
122
 
123
  if ( version_compare( $response->new_version, $this->settings['version'], '>' ) ) {
124
 
133
  $transient->response[ $plugin ]->upgrade_notice = FLUpdater::get_update_error_message();
134
  }
135
  }
136
+ } elseif ( 'theme' == $this->settings['type'] ) {
 
137
 
138
+ if ( version_compare( $response->new_version, $this->settings['version'], '>' ) ) {
139
 
140
+ $transient->response[ $this->settings['slug'] ] = array(
141
  'new_version' => $response->new_version,
142
  'url' => $response->homepage,
143
  'package' => $response->package,
145
  );
146
  }
147
  }
148
+ }// End if().
149
 
150
  return $transient;
151
  }
159
  * @param object $args
160
  * @return object|bool
161
  */
162
+ public function plugin_info( $false, $action, $args ) {
 
163
  if ( 'plugin_information' != $action ) {
164
  return $false;
165
  }
166
+ if ( ! isset( $args->slug ) || $args->slug != $this->settings['slug'] ) {
167
  return $false;
168
  }
169
 
170
  $response = $this->get_response();
171
 
172
+ if ( ! isset( $response->error ) ) {
173
 
174
  $info = new stdClass();
175
  $info->name = $this->settings['name'];
182
  $info->tested = $response->tested;
183
  $info->last_updated = $response->last_updated;
184
  $info->download_link = $response->package;
185
+ $info->sections = (array) $response->sections;
186
 
187
  return $info;
188
  }
199
  * @param object $response An object with update data for this plugin.
200
  * @return void
201
  */
202
+ public function update_message( $plugin_data, $response ) {
 
203
  if ( empty( $response->package ) ) {
204
  echo FLUpdater::get_update_error_message( $plugin_data );
205
  }
212
  * @since 1.0
213
  * @return void
214
  */
215
+ static public function init() {
 
216
  include FL_UPDATER_DIR . 'includes/config.php';
217
 
218
+ foreach ( $config as $path ) {
219
+ if ( file_exists( $path ) ) {
220
  require_once $path;
221
  }
222
  }
230
  * @param array $args An array of settings for the product.
231
  * @return void
232
  */
233
+ static public function add_product( $args = array() ) {
234
+ if ( is_array( $args ) && isset( $args['slug'] ) ) {
235
+
236
+ if ( 'plugin' == $args['type'] ) {
237
+ if ( file_exists( WP_CONTENT_DIR . '/plugins/' . $args['slug'] ) ) {
238
+ self::$_products[ $args['name'] ] = $args;
239
+ new FLUpdater( self::$_products[ $args['name'] ] );
 
240
  }
241
  }
242
+ if ( 'theme' == $args['type'] ) {
243
+ if ( file_exists( WP_CONTENT_DIR . '/themes/' . $args['slug'] ) ) {
244
+ self::$_products[ $args['name'] ] = $args;
245
+ new FLUpdater( self::$_products[ $args['name'] ] );
246
  }
247
  }
248
  }
254
  * @since 1.0
255
  * @return void
256
  */
257
+ static public function render_form() {
 
258
  // Activate a subscription?
259
+ if ( isset( $_POST['fl-updater-nonce'] ) ) {
260
+ if ( wp_verify_nonce( $_POST['fl-updater-nonce'], 'updater-nonce' ) ) {
261
+ self::save_subscription_license( $_POST['license'] );
262
  }
263
  }
264
 
276
  * @param object $subscription
277
  * @return void
278
  */
279
+ static public function render_subscriptions( $subscription ) {
 
280
  if ( isset( $subscription->error ) || ! $subscription->active || ! $subscription->domain->active || ! isset( $subscription->downloads ) ) {
281
  return;
282
  }
295
  * @since 1.0
296
  * @return string
297
  */
298
+ static public function get_subscription_license() {
299
+ $value = get_site_option( 'fl_themes_subscription_email' );
 
300
 
301
  return $value ? $value : '';
302
  }
308
  * @param string $license The new license key.
309
  * @return void
310
  */
311
+ static public function save_subscription_license( $license ) {
 
312
  FLUpdater::api_request(self::$_updates_api_url, array(
313
  'fl-api-method' => 'activate_domain',
314
  'license' => $license,
315
  'domain' => network_home_url(),
316
+ 'products' => json_encode( self::$_products ),
317
  ));
318
 
319
+ update_site_option( 'fl_themes_subscription_email', $license );
320
  }
321
 
322
  /**
325
  * @since 1.0
326
  * @return bool
327
  */
328
+ static public function get_subscription_info() {
 
329
  return self::api_request(self::$_updates_api_url, array(
330
  'fl-api-method' => 'subscription_info',
331
  'domain' => network_home_url(),
332
+ 'license' => FLUpdater::get_subscription_license(),
333
  ));
334
  }
335
 
341
  * @param array $plugin_data An array of data for this plugin.
342
  * @return string
343
  */
344
+ static private function get_update_error_message( $plugin_data = null ) {
 
345
  $message = '';
346
  $message .= '<p style="padding:10px 20px; margin-top: 10px; background: #d54e21; color: #fff;">';
347
  $message .= __( '<strong>UPDATE UNAVAILABLE!</strong>', 'fl-builder' );
348
  $message .= '&nbsp;&nbsp;&nbsp;';
349
+ $message .= __( 'Please subscribe to enable automatic updates for this plugin.', 'fl-builder' );
350
 
351
  if ( $plugin_data && isset( $plugin_data['PluginURI'] ) ) {
352
  $message .= ' <a href="' . $plugin_data['PluginURI'] . '" target="_blank" style="color: #fff; text-decoration: underline;">';
353
+ $message .= __( 'Subscribe Now', 'fl-builder' );
354
  $message .= ' &raquo;</a>';
355
  }
356
 
368
  * @param string $slug The product slug.
369
  * @return string
370
  */
371
+ static private function get_plugin_file( $slug ) {
 
372
  if ( 'bb-plugin' == $slug ) {
373
  $file = $slug . '/fl-builder.php';
374
+ } else {
 
375
  $file = $slug . '/' . $slug . '.php';
376
  }
377
 
388
  * @param array $args An array of args to send along with the request.
389
  * @return mixed The response or false if there is an error.
390
  */
391
+ static private function api_request( $api_url = false, $args = array() ) {
392
+ if ( $api_url ) {
 
393
 
394
  $params = array();
395
 
396
+ foreach ( $args as $key => $val ) {
397
+ $params[] = $key . '=' . urlencode( $val );
398
  }
399
 
400
+ return self::remote_get( $api_url . '?' . implode( '&', $params ) );
401
  }
402
 
403
  return false;
411
  * @param string $url The URL to get.
412
  * @return mixed The response or false if there is an error.
413
  */
414
+ static private function remote_get( $url ) {
415
+ $request = wp_remote_get( $url );
 
416
  $error = new stdClass();
417
  $error->error = 'connection';
418
 
419
+ if ( is_wp_error( $request ) ) {
420
  return $error;
421
  }
422
+ if ( wp_remote_retrieve_response_code( $request ) != 200 ) {
423
  return $error;
424
  }
425
 
426
+ $body = wp_remote_retrieve_body( $request );
427
 
428
+ if ( is_wp_error( $body ) ) {
429
  return $error;
430
  }
431
 
432
+ $body_decoded = json_decode( $body );
433
 
434
+ if ( ! is_object( $body_decoded ) ) {
435
  return $error;
436
  }
437
 
includes/updater/includes/config.php CHANGED
@@ -4,5 +4,5 @@ $config = array(
4
  'fl-automator' => WP_CONTENT_DIR . '/themes/fl-automator/includes/updater-config.php',
5
  'fl-builder' => WP_PLUGIN_DIR . '/fl-builder/includes/updater-config.php',
6
  'bb-theme' => WP_CONTENT_DIR . '/themes/bb-theme/includes/updater-config.php',
7
- 'bb-plugin' => WP_PLUGIN_DIR . '/bb-plugin/includes/updater-config.php'
8
- );
4
  'fl-automator' => WP_CONTENT_DIR . '/themes/fl-automator/includes/updater-config.php',
5
  'fl-builder' => WP_PLUGIN_DIR . '/fl-builder/includes/updater-config.php',
6
  'bb-theme' => WP_CONTENT_DIR . '/themes/bb-theme/includes/updater-config.php',
7
+ 'bb-plugin' => WP_PLUGIN_DIR . '/bb-plugin/includes/updater-config.php',
8
+ );
includes/updater/includes/form.php CHANGED
@@ -1,60 +1,72 @@
1
  <div class="wrap">
2
 
3
- <?php if(isset($subscription->error) && 'connection' == $subscription->error) : ?>
4
  <p class="fl-license-error" style="padding:10px 20px; background: #d54e21; color: #fff;">
5
- <?php _e('ERROR! We were unable to connect to the update server. If the issue persists, please contact your host and let them know your website cannot connect to updates.wpbeaverbuilder.com.', 'fl-builder'); ?>
6
  </p>
7
- <?php elseif(isset($subscription->error) || !$subscription->active) : ?>
8
  <p class="fl-license-error" style="padding:10px 20px; background: #d54e21; color: #fff;">
9
- <?php _e('UPDATES UNAVAILABLE! Please subscribe or enter your license key below to enable automatic updates.', 'fl-builder'); ?>
10
- &nbsp;<a style="color: #fff;" href="<?php echo FLBuilderModel::get_store_url( '', array( 'utm_medium' => 'bb-pro', 'utm_source' => 'license-settings-page', 'utm_campaign' => 'license-expired' ) ); ?>" target="_blank"><?php _e('Subscribe Now', 'fl-builder'); ?> &raquo;</a>
 
 
 
 
11
  </p>
12
- <?php elseif(!$subscription->domain->active) : ?>
13
  <p class="fl-license-error" style="padding:10px 20px; background: #d54e21; color: #fff;">
14
- <?php _e('UPDATES UNAVAILABLE! Your subscription is active but this domain has been deactivated. Please reactivate this domain in your account to enable automatic updates.', 'fl-builder'); ?>
15
- &nbsp;<a style="color: #fff;" href="<?php echo FLBuilderModel::get_store_url( 'my-account', array( 'utm_medium' => 'bb-pro', 'utm_source' => 'license-settings-page', 'utm_campaign' => 'license-deactivated' ) ); ?>" target="_blank"><?php _e('Visit Account', 'fl-builder'); ?> &raquo;</a>
 
 
 
 
16
  </p>
17
  <?php endif; ?>
18
 
19
  <h3 class="fl-settings-form-header">
20
- <?php _e('Updates &amp; Support Subscription', 'fl-builder'); ?>
21
  <span> &mdash; </span>
22
- <?php if(isset($subscription->error) || !$subscription->active) : ?>
23
- <i style="color:#ae5842;"><?php _e('Not Active!', 'fl-builder'); ?></i>
24
- <?php elseif(!$subscription->domain->active) : ?>
25
- <i style="color:#ae5842;"><?php _e('Deactivated!', 'fl-builder'); ?></i>
26
  <?php else : ?>
27
- <i style="color:#3cb341;"><?php _e('Active!', 'fl-builder'); ?></i>
28
  <?php endif; ?>
29
  </h3>
30
 
31
- <?php if(isset($_POST['fl-updater-nonce'])) : ?>
32
  <div class="updated">
33
- <p><?php _e('License key saved!', 'fl-builder'); ?></p>
34
  </div>
35
  <?php endif; ?>
36
 
37
  <p>
38
- <?php echo sprintf( __( 'Enter your <a%s>license key</a> to enable remote updates and support.', 'fl-builder' ), ' href="' . FLBuilderModel::get_store_url( 'my-account', array( 'utm_medium' => 'bb-pro', 'utm_source' => 'license-settings-page', 'utm_campaign' => 'license-key-link' ) ) . '" target="_blank"' ) ?>
 
 
 
 
39
  </p>
40
 
41
- <?php if(is_multisite()) : ?>
42
  <p>
43
- <strong><?php _e( 'NOTE:', 'fl-builder' ); ?></strong> <?php _e('This applies to all sites on the network.', 'fl-builder'); ?>
44
  </p>
45
  <?php endif; ?>
46
 
47
- <form class="fl-license-form" action="" method="post" <?php if ( ! empty( $license ) ) echo 'style="display:none;"'; ?>>
48
 
49
  <input type="password" name="license" value="" class="regular-text" />
50
 
51
  <p class="submit">
52
  <input type="submit" name="submit" class="button button-primary" value="<?php esc_attr_e( 'Save License Key', 'fl-builder' ); ?>">
53
- <?php wp_nonce_field('updater-nonce', 'fl-updater-nonce'); ?>
54
  </p>
55
  </form>
56
 
57
- <div class="fl-new-license-form" <?php if ( empty( $license ) ) echo 'style="display:none;"'; ?>>
58
  <p class="submit">
59
  <input type="button" class="button button-primary" value="<?php esc_attr_e( 'Enter License Key', 'fl-builder' ); ?>">
60
  </p>
1
  <div class="wrap">
2
 
3
+ <?php if ( isset( $subscription->error ) && 'connection' == $subscription->error ) : ?>
4
  <p class="fl-license-error" style="padding:10px 20px; background: #d54e21; color: #fff;">
5
+ <?php _e( 'ERROR! We were unable to connect to the update server. If the issue persists, please contact your host and let them know your website cannot connect to updates.wpbeaverbuilder.com.', 'fl-builder' ); ?>
6
  </p>
7
+ <?php elseif ( isset( $subscription->error ) || ! $subscription->active ) : ?>
8
  <p class="fl-license-error" style="padding:10px 20px; background: #d54e21; color: #fff;">
9
+ <?php _e( 'UPDATES UNAVAILABLE! Please subscribe or enter your license key below to enable automatic updates.', 'fl-builder' ); ?>
10
+ &nbsp;<a style="color: #fff;" href="<?php echo FLBuilderModel::get_store_url( '', array(
11
+ 'utm_medium' => 'bb-pro',
12
+ 'utm_source' => 'license-settings-page',
13
+ 'utm_campaign' => 'license-expired',
14
+ ) ); ?>" target="_blank"><?php _e( 'Subscribe Now', 'fl-builder' ); ?> &raquo;</a>
15
  </p>
16
+ <?php elseif ( ! $subscription->domain->active ) : ?>
17
  <p class="fl-license-error" style="padding:10px 20px; background: #d54e21; color: #fff;">
18
+ <?php _e( 'UPDATES UNAVAILABLE! Your subscription is active but this domain has been deactivated. Please reactivate this domain in your account to enable automatic updates.', 'fl-builder' ); ?>
19
+ &nbsp;<a style="color: #fff;" href="<?php echo FLBuilderModel::get_store_url( 'my-account', array(
20
+ 'utm_medium' => 'bb-pro',
21
+ 'utm_source' => 'license-settings-page',
22
+ 'utm_campaign' => 'license-deactivated',
23
+ ) ); ?>" target="_blank"><?php _e( 'Visit Account', 'fl-builder' ); ?> &raquo;</a>
24
  </p>
25
  <?php endif; ?>
26
 
27
  <h3 class="fl-settings-form-header">
28
+ <?php _e( 'Updates &amp; Support Subscription', 'fl-builder' ); ?>
29
  <span> &mdash; </span>
30
+ <?php if ( isset( $subscription->error ) || ! $subscription->active ) : ?>
31
+ <i style="color:#ae5842;"><?php _e( 'Not Active!', 'fl-builder' ); ?></i>
32
+ <?php elseif ( ! $subscription->domain->active ) : ?>
33
+ <i style="color:#ae5842;"><?php _e( 'Deactivated!', 'fl-builder' ); ?></i>
34
  <?php else : ?>
35
+ <i style="color:#3cb341;"><?php _e( 'Active!', 'fl-builder' ); ?></i>
36
  <?php endif; ?>
37
  </h3>
38
 
39
+ <?php if ( isset( $_POST['fl-updater-nonce'] ) ) : ?>
40
  <div class="updated">
41
+ <p><?php _e( 'License key saved!', 'fl-builder' ); ?></p>
42
  </div>
43
  <?php endif; ?>
44
 
45
  <p>
46
+ <?php echo sprintf( __( 'Enter your <a%s>license key</a> to enable remote updates and support.', 'fl-builder' ), ' href="' . FLBuilderModel::get_store_url( 'my-account', array(
47
+ 'utm_medium' => 'bb-pro',
48
+ 'utm_source' => 'license-settings-page',
49
+ 'utm_campaign' => 'license-key-link',
50
+ ) ) . '" target="_blank"' ) ?>
51
  </p>
52
 
53
+ <?php if ( is_multisite() ) : ?>
54
  <p>
55
+ <strong><?php _e( 'NOTE:', 'fl-builder' ); ?></strong> <?php _e( 'This applies to all sites on the network.', 'fl-builder' ); ?>
56
  </p>
57
  <?php endif; ?>
58
 
59
+ <form class="fl-license-form" action="" method="post" <?php if ( ! empty( $license ) ) { echo 'style="display:none;"';} ?>>
60
 
61
  <input type="password" name="license" value="" class="regular-text" />
62
 
63
  <p class="submit">
64
  <input type="submit" name="submit" class="button button-primary" value="<?php esc_attr_e( 'Save License Key', 'fl-builder' ); ?>">
65
+ <?php wp_nonce_field( 'updater-nonce', 'fl-updater-nonce' ); ?>
66
  </p>
67
  </form>
68
 
69
+ <div class="fl-new-license-form" <?php if ( empty( $license ) ) { echo 'style="display:none;"';} ?>>
70
  <p class="submit">
71
  <input type="button" class="button button-primary" value="<?php esc_attr_e( 'Enter License Key', 'fl-builder' ); ?>">
72
  </p>
includes/updater/includes/subscriptions.php CHANGED
@@ -2,16 +2,16 @@
2
  <h3><?php _e( 'Available Downloads', 'fl-builder' ); ?></h3>
3
  <p><?php _e( 'The following downloads are currently available for remote update with the subscription(s) associated with this license.', 'fl-builder' ); ?></p>
4
  <ul>
5
- <?php
6
-
7
  foreach ( $subscription->downloads as $download ) {
8
-
9
  if ( stristr( $download, 'child theme' ) ) {
10
  continue;
11
  }
12
-
13
  echo '<li>' . $download . '</li>';
14
  }
15
-
16
  ?>
17
- </ul>
2
  <h3><?php _e( 'Available Downloads', 'fl-builder' ); ?></h3>
3
  <p><?php _e( 'The following downloads are currently available for remote update with the subscription(s) associated with this license.', 'fl-builder' ); ?></p>
4
  <ul>
5
+ <?php
6
+
7
  foreach ( $subscription->downloads as $download ) {
8
+
9
  if ( stristr( $download, 'child theme' ) ) {
10
  continue;
11
  }
12
+
13
  echo '<li>' . $download . '</li>';
14
  }
15
+
16
  ?>
17
+ </ul>
includes/updater/updater.php CHANGED
@@ -1,17 +1,17 @@
1
  <?php
2
 
3
  /* Only run if not already setup and not using a repo version. */
4
- if(!class_exists('FLUpdater') && FL_BUILDER_LITE !== true) {
5
-
6
  /* Defines */
7
- define('FL_UPDATER_DIR', trailingslashit(dirname(__FILE__)));
8
-
9
  /* Classes */
10
  require_once FL_UPDATER_DIR . 'classes/class-fl-updater.php';
11
-
12
  /* Actions */
13
- add_action('fl_themes_license_form', 'FLUpdater::render_form');
14
-
15
  /* Initialize the updater. */
16
  FLUpdater::init();
17
- }
1
  <?php
2
 
3
  /* Only run if not already setup and not using a repo version. */
4
+ if ( ! class_exists( 'FLUpdater' ) && FL_BUILDER_LITE !== true ) {
5
+
6
  /* Defines */
7
+ define( 'FL_UPDATER_DIR', trailingslashit( dirname( __FILE__ ) ) );
8
+
9
  /* Classes */
10
  require_once FL_UPDATER_DIR . 'classes/class-fl-updater.php';
11
+
12
  /* Actions */
13
+ add_action( 'fl_themes_license_form', 'FLUpdater::render_form' );
14
+
15
  /* Initialize the updater. */
16
  FLUpdater::init();
17
+ }
includes/vendor/godaddy-email-marketing/class-godaddy-em.php CHANGED
@@ -2,8 +2,8 @@
2
 
3
  /**
4
  * GoDaddy Email Marketing Dispatcher.
5
- *
6
- * A modified version from GoDaddy Email Marketing plugin
7
  * (https://wordpress.org/plugins/godaddy-email-marketing-sign-up-forms/)
8
  *
9
  * @since 1.0
@@ -31,7 +31,7 @@ class GoDaddyEM {
31
 
32
  /**
33
  * Constructor
34
- *
35
  * @param string $email The username.
36
  * @param string $api_key The API key.
37
  */
@@ -85,13 +85,13 @@ class GoDaddyEM {
85
  * @return array|false The form fields array or false.
86
  */
87
  public static function get_forms() {
88
-
89
  if ( ! self::$api_username ) {
90
  return false;
91
  }
92
 
93
  $data = self::fetch_forms();
94
-
95
  return $data;
96
  }
97
 
@@ -102,7 +102,7 @@ class GoDaddyEM {
102
  * @return false|object The form fields JSON object or false.
103
  */
104
  public static function get_fields( $form_id ) {
105
-
106
  // Fields are not cached. fetch and cache.
107
  $response = wp_remote_get( self::get_method_url( 'fields', array(
108
  'id' => $form_id,
@@ -113,7 +113,7 @@ class GoDaddyEM {
113
  return false;
114
  }
115
 
116
- $data = json_decode( wp_remote_retrieve_body( $response ) );
117
 
118
  return $data;
119
  }
@@ -203,7 +203,7 @@ class GoDaddyEM {
203
  if ( ! self::$api_username || ! self::$api_key ) {
204
  return false;
205
  }
206
-
207
  if ( isset( $data[ 'form_id' ] ) && isset( $data[ 'email' ] ) ) {
208
  $form = self::get_fields( $data[ 'form_id' ] );
209
 
@@ -214,11 +214,11 @@ class GoDaddyEM {
214
  'signup[email]' => $data['email']
215
  );
216
 
217
- if ( $data[ 'first_name' ] ) {
218
  $submit_data[ 'signup[first_name]' ] = $data['first_name'];
219
  }
220
 
221
- if ( $data[ 'last_name' ] ) {
222
  $submit_data[ 'signup[last_name]' ] = $data['last_name'];
223
  }
224
 
@@ -235,6 +235,6 @@ class GoDaddyEM {
235
  }
236
  }
237
 
238
- return false;
239
  }
240
  }
2
 
3
  /**
4
  * GoDaddy Email Marketing Dispatcher.
5
+ *
6
+ * A modified version from GoDaddy Email Marketing plugin
7
  * (https://wordpress.org/plugins/godaddy-email-marketing-sign-up-forms/)
8
  *
9
  * @since 1.0
31
 
32
  /**
33
  * Constructor
34
+ *
35
  * @param string $email The username.
36
  * @param string $api_key The API key.
37
  */
85
  * @return array|false The form fields array or false.
86
  */
87
  public static function get_forms() {
88
+
89
  if ( ! self::$api_username ) {
90
  return false;
91
  }
92
 
93
  $data = self::fetch_forms();
94
+
95
  return $data;
96
  }
97
 
102
  * @return false|object The form fields JSON object or false.
103
  */
104
  public static function get_fields( $form_id ) {
105
+
106
  // Fields are not cached. fetch and cache.
107
  $response = wp_remote_get( self::get_method_url( 'fields', array(
108
  'id' => $form_id,
113
  return false;
114
  }
115
 
116
+ $data = json_decode( wp_remote_retrieve_body( $response ) );
117
 
118
  return $data;
119
  }
203
  if ( ! self::$api_username || ! self::$api_key ) {
204
  return false;
205
  }
206
+
207
  if ( isset( $data[ 'form_id' ] ) && isset( $data[ 'email' ] ) ) {
208
  $form = self::get_fields( $data[ 'form_id' ] );
209
 
214
  'signup[email]' => $data['email']
215
  );
216
 
217
+ if ( isset( $data[ 'first_name' ] ) ) {
218
  $submit_data[ 'signup[first_name]' ] = $data['first_name'];
219
  }
220
 
221
+ if ( isset( $data[ 'last_name' ] ) ) {
222
  $submit_data[ 'signup[last_name]' ] = $data['last_name'];
223
  }
224
 
235
  }
236
  }
237
 
238
+ return false;
239
  }
240
  }
js/fl-builder-layout.js CHANGED
@@ -518,7 +518,8 @@
518
  },
519
  playerVars: {
520
  controls: 0,
521
- showinfo: 0
 
522
  }
523
  } );
524
  }, 1 );
518
  },
519
  playerVars: {
520
  controls: 0,
521
+ showinfo: 0,
522
+ rel : 0
523
  }
524
  } );
525
  }, 1 );
js/fl-builder.js CHANGED
@@ -1637,16 +1637,10 @@
1637
  {
1638
  var form = $(this).closest('.fl-builder-settings'),
1639
  valid = form.validate().form(),
1640
- data = form.serializeArray(),
1641
- settings = {},
1642
- i = 0;
1643
 
1644
  if(valid) {
1645
 
1646
- for( ; i < data.length; i++) {
1647
- settings[data[i].name] = data[i].value;
1648
- }
1649
-
1650
  FLBuilder.showAjaxLoader();
1651
  FLBuilder._layoutSettingsCSSCache = null;
1652
 
@@ -7436,14 +7430,14 @@
7436
  if ( FLBuilderConfig.modSecFix && 'undefined' != typeof btoa ) {
7437
 
7438
  if ( 'string' == typeof settings ) {
7439
- settings = btoa( settings );
7440
  }
7441
  else {
7442
 
7443
  for ( prop in settings ) {
7444
 
7445
  if ( 'string' == typeof settings[ prop ] ) {
7446
- settings[ prop ] = btoa( settings[ prop ] );
7447
  }
7448
  else if( 'object' == typeof settings[ prop ] ) {
7449
  settings[ prop ] = FLBuilder._ajaxModSecFix( settings[ prop ] );
@@ -7455,6 +7449,21 @@
7455
  return settings;
7456
  },
7457
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7458
  /* Lightboxes
7459
  ----------------------------------------------------------*/
7460
 
1637
  {
1638
  var form = $(this).closest('.fl-builder-settings'),
1639
  valid = form.validate().form(),
1640
+ settings = FLBuilder._getSettings( form );
 
 
1641
 
1642
  if(valid) {
1643
 
 
 
 
 
1644
  FLBuilder.showAjaxLoader();
1645
  FLBuilder._layoutSettingsCSSCache = null;
1646
 
7430
  if ( FLBuilderConfig.modSecFix && 'undefined' != typeof btoa ) {
7431
 
7432
  if ( 'string' == typeof settings ) {
7433
+ settings = FLBuilder._btoa( settings );
7434
  }
7435
  else {
7436
 
7437
  for ( prop in settings ) {
7438
 
7439
  if ( 'string' == typeof settings[ prop ] ) {
7440
+ settings[ prop ] = FLBuilder._btoa( settings[ prop ] );
7441
  }
7442
  else if( 'object' == typeof settings[ prop ] ) {
7443
  settings[ prop ] = FLBuilder._ajaxModSecFix( settings[ prop ] );
7449
  return settings;
7450
  },
7451
 
7452
+ /**
7453
+ * Helper function for _ajaxModSecFix
7454
+ * btoa() does not handle utf8/16 characters
7455
+ * See: https://stackoverflow.com/questions/30106476/using-javascripts-atob-to-decode-base64-doesnt-properly-decode-utf-8-strings
7456
+ *
7457
+ * @since 1.10.7
7458
+ * @access private
7459
+ * @method _btoa
7460
+ */
7461
+ _btoa: function(str) {
7462
+ return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, function(match, p1) {
7463
+ return String.fromCharCode('0x' + p1);
7464
+ }));
7465
+ },
7466
+
7467
  /* Lightboxes
7468
  ----------------------------------------------------------*/
7469
 
js/fl-builder.min.js CHANGED
@@ -1,6 +1,6 @@
1
- !function(e){FLLightbox=function(e){this._init(e),this._render(),this._bind()},FLLightbox.closeParent=function(t){var l=e(t).closest(".fl-lightbox-wrap").attr("data-instance-id");FLLightbox._instances[l].close()},FLLightbox._instances={},FLLightbox.prototype={_id:null,_node:null,_visible:!1,_resizeTimer:null,_draggable:!1,_defaults:{className:"",destroyOnClose:!1},open:function(e){this._node.find(".fl-lightbox").attr("style",""),this._node.show(),this._visible=!0,"undefined"!=typeof e?this.setContent(e):this._resize(),this.trigger("open")},close:function(){this._node.hide(),this._visible=!1,this.trigger("close"),this._defaults.destroyOnClose&&this.destroy()},setContent:function(e){this._node.find(".fl-lightbox-content").html(e),this._resize()},empty:function(){this._node.find(".fl-lightbox-content").empty(),this._node.find(".fl-lightbox").removeClass("fl-lightbox-expanded")},on:function(e,t){this._node.on(e,t)},off:function(e){this._node.off(e)},trigger:function(e,t){this._node.trigger(e,t)},draggable:function(e){var t=this._node.find(".fl-lightbox-mask"),l=this._node.find(".fl-lightbox");e="undefined"!=typeof e&&e,this._draggable&&l.draggable("destroy"),e?(this._unbind(),this._draggable=!0,t.hide(),l.draggable({cursor:"move",handle:e.handle||""})):(t.show(),this._bind(),this._draggable=!1),this._resize()},destroy:function(){e(window).off("resize.fl-lightbox-"+this._id),this._node.empty(),this._node.remove(),FLLightbox._instances[this._id]="undefined";try{delete FLLightbox._instances[this._id]}catch(t){}},renderResize:function(t){if("undefined"!=typeof t){var l=this._getActiveNode();if(lightbox=l.find(".fl-lightbox"),boxFields=lightbox.find(".fl-builder-settings-fields"),win=e(window),winHeight=win.height(),winWidth=win.width(),boxHeaderHeight=lightbox.find(".fl-lightbox-header").height(),boxTabsHeight=lightbox.find(".fl-builder-settings-tabs").height(),boxFooterHeight=lightbox.find(".fl-lightbox-footer").height(),boxFieldHeight=winHeight-(boxHeaderHeight+boxTabsHeight+boxFooterHeight+103),editor="undefined"!=typeof tinymce&&tinymce.EditorManager.activeEditor?tinymce:null,editorId=editor?editor.EditorManager.activeEditor.id:"flhiddeneditor",editorIframeEl=lightbox.find("#"+editorId+"_ifr"),editorTextarea=lightbox.find("#"+editorId),codeField=lightbox.find(".fl-code-field .ace_editor"),"expand"==t||"window_resize"==t){if("window_resize"==t&&!lightbox.hasClass("fl-lightbox-expanded"))return!1;boxFields.css("height",boxFieldHeight+"px"),"expand"==t&&(lightbox.addClass("fl-lightbox-expanded"),lightbox.draggable("disable")),editorIframeEl.length>0&&editorIframeEl.css("height",boxFieldHeight-145+"px"),editorTextarea.length>0&&editorTextarea.css("height",boxFieldHeight-145+"px"),codeField.length>0&&codeField.css("height",boxFieldHeight-60+"px")}else setTimeout(e.proxy(this._resize,this),250),lightbox.removeClass("fl-lightbox-expanded"),boxFields.removeAttr("style"),null!==editorId&&(editorIframeEl.css("height","232px"),editorTextarea.css("height","232px")),codeField.length>0&&codeField.css("height","360px"),lightbox.draggable("enable")}},_init:function(t){var l=0,i=null;for(i in FLLightbox._instances)l++;this._defaults=e.extend({},this._defaults,t),this._id=(new Date).getTime()+l,FLLightbox._instances[this._id]=this},_render:function(){this._node=e('<div class="fl-lightbox-wrap" data-instance-id="'+this._id+'"><div class="fl-lightbox-mask"></div><div class="fl-lightbox"><div class="fl-lightbox-content-wrap"><div class="fl-lightbox-content"></div></div></div></div>'),this._node.addClass(this._defaults.className),e("body").append(this._node)},_bind:function(){e(window).on("resize.fl-lightbox-"+this._id,e.proxy(this._delayedResize,this))},_unbind:function(){e(window).off("resize.fl-lightbox-"+this._id)},_delayedResize:function(){clearTimeout(this._resizeTimer),this._resizeTimer=setTimeout(e.proxy(this._resize,this),250),this.renderResize("window_resize")},_resize:function(){if(this._visible){var t=this._node.find(".fl-lightbox"),l=t.height(),i=t.width(),o=e(window),s=o.height(),r=o.width(),n="0px",a=(r-i)/2-30+"px";t.css({margin:"0px",top:"auto",left:"auto"}),s-80>l&&(n=(s-l)/2-40+"px"),this._draggable?(t.css("top",n),t.css("left",FLBuilderConfig.isRtl?"-"+a:a)):(t.css("margin-top",n),t.css("margin-left","auto"),t.css("margin-right","auto"))}},_onKeypress:function(e){27==e.which&&this._visible&&this.close()},_getActiveNode:function(){var t=this._node;return e.each(FLLightbox._instances,function(l,i){e(i._node).is(":visible")&&(t=e(i._node))}),t}}}(jQuery),function(e){FLBuilder={preview:null,_actionsLightbox:null,_addModuleAfterNodeRender:null,_colResizeData:null,_colResizing:!1,_contentClass:!1,_dragEnabled:!1,_dragging:!1,_dragInitialScrollTop:0,_exitUrl:null,_layout:null,_layoutSettingsCSSCache:null,_layoutSettingsCSSTimeout:null,_lightbox:null,_lightboxScrollbarTimeout:null,_loadedModuleAssets:[],_moduleHelpers:{},_multiplePhotoSelector:null,_newColGroupParent:null,_newColGroupPosition:0,_newModuleParent:null,_newModulePosition:0,_newRowPosition:0,_selectedTemplateId:null,_selectedTemplateType:null,_singlePhotoSelector:null,_singleVideoSelector:null,_multipleAudiosSelector:null,_init:function(){FLBuilder._initJQueryReadyFix(),FLBuilder._initGlobalErrorHandling(),FLBuilder._initPostLock(),FLBuilder._initClassNames(),FLBuilder._initMediaUploader(),FLBuilder._initOverflowFix(),FLBuilder._initScrollbars(),FLBuilder._initLightboxes(),FLBuilder._initDropTargets(),FLBuilder._initSortables(),FLBuilder._initStrings(),FLBuilder._initTipTips(),FLBuilder._bindEvents(),FLBuilder._bindOverlayEvents(),FLBuilder._setupEmptyLayout(),FLBuilder._highlightEmptyCols(),FLBuilder._showTourOrTemplates()},_initJQueryReadyFix:function(){FLBuilderConfig.debug||(jQuery.fn.oldReady=jQuery.fn.ready,jQuery.fn.ready=function(e){return jQuery.fn.oldReady(function(){try{"function"==typeof e&&e()}catch(t){FLBuilder.logError(t)}})})},_initGlobalErrorHandling:function(){FLBuilderConfig.debug||(window.onerror=function(e,t,l,i,o){return FLBuilder.logGlobalError(e,t,l,i,o),!0})},_initPostLock:function(){"undefined"!=typeof wp.heartbeat&&(wp.heartbeat.interval(30),wp.heartbeat.enqueue("fl_builder_post_lock",{post_id:FLBuilderConfig.postId}))},_initClassNames:function(){e("html").addClass("fl-builder-edit"),e("body").addClass("fl-builder"),FLBuilderConfig.simpleUi&&e("body").addClass("fl-builder-simple"),FLBuilder._contentClass=".fl-builder-content-"+FLBuilderConfig.postId,e(FLBuilder._contentClass).addClass("fl-builder-content-editing")},_initMediaUploader:function(){wp.media.model.settings.post.id=FLBuilderConfig.postId},_initOverflowFix:function(){e(FLBuilder._contentClass).parents().css("overflow","visible")},_initScrollbars:function(){e(".fl-nanoscroller").nanoScroller({alwaysVisible:!0,preventPageScrolling:!0,paneClass:"fl-nanoscroller-pane",sliderClass:"fl-nanoscroller-slider",contentClass:"fl-nanoscroller-content"})},_initLightboxes:function(){FLBuilder._lightbox=new FLLightbox({className:"fl-builder-lightbox fl-builder-settings-lightbox"}),FLBuilder._lightbox.on("close",FLBuilder._lightboxClosed),FLBuilder._actionsLightbox=new FLLightbox({className:"fl-builder-actions-lightbox"})},_initSortables:function(){var t={appendTo:"body",cursor:"move",cursorAt:{left:60,top:20},distance:1,helper:FLBuilder._blockDragHelper,start:FLBuilder._blockDragStart,sort:FLBuilder._blockDragSort,change:FLBuilder._blockDragChange,stop:FLBuilder._blockDragStop,placeholder:"fl-builder-drop-zone",tolerance:"intersect"},l="",i="";i="row"==FLBuilderConfig.userTemplateType?FLBuilder._contentClass+" .fl-col-group-drop-target, "+FLBuilder._contentClass+" .fl-col-drop-target, "+FLBuilder._contentClass+" .fl-col-content":FLBuilder._contentClass+" .fl-row-drop-target, "+FLBuilder._contentClass+" .fl-col-group-drop-target, "+FLBuilder._contentClass+" .fl-col-drop-target, "+FLBuilder._contentClass+" .fl-row:not(.fl-node-global) .fl-col-content",l=FLBuilderConfig.nestedColumns?i:"row"==FLBuilderConfig.userTemplateType?FLBuilder._contentClass+" .fl-col-group-drop-target, "+FLBuilder._contentClass+" .fl-col-drop-target":FLBuilder._contentClass+" .fl-row-drop-target, "+FLBuilder._contentClass+" .fl-col-group-drop-target, "+FLBuilder._contentClass+" .fl-col-drop-target",e(".fl-builder-rows").sortable(e.extend({},t,{connectWith:l,items:".fl-builder-block-row",stop:FLBuilder._rowDragStop})),e(".fl-builder-row-templates").sortable(e.extend({},t,{connectWith:FLBuilder._contentClass+" .fl-row-drop-target",items:".fl-builder-block-row-template",stop:FLBuilder._nodeTemplateDragStop})),e(".fl-builder-saved-rows").sortable(e.extend({},t,{cancel:".fl-builder-node-template-actions, .fl-builder-node-template-edit, .fl-builder-node-template-delete",connectWith:FLBuilder._contentClass+" .fl-row-drop-target",items:".fl-builder-block-saved-row",stop:FLBuilder._nodeTemplateDragStop})),e(".fl-builder-modules, .fl-builder-widgets").sortable(e.extend({},t,{connectWith:i,items:".fl-builder-block-module",stop:FLBuilder._moduleDragStop})),e(".fl-builder-module-templates").sortable(e.extend({},t,{connectWith:i,items:".fl-builder-block-module-template",stop:FLBuilder._nodeTemplateDragStop})),e(".fl-builder-saved-modules").sortable(e.extend({},t,{cancel:".fl-builder-node-template-actions, .fl-builder-node-template-edit, .fl-builder-node-template-delete",connectWith:i,items:".fl-builder-block-saved-module",stop:FLBuilder._nodeTemplateDragStop})),e(".fl-row-sortable-proxy").sortable(e.extend({},t,{connectWith:FLBuilder._contentClass+" .fl-row-drop-target",helper:FLBuilder._rowDragHelper,start:FLBuilder._rowDragStart,stop:FLBuilder._rowDragStop})),e(".fl-col-sortable-proxy").sortable(e.extend({},t,{connectWith:i,helper:FLBuilder._colDragHelper,start:FLBuilder._colDragStart,stop:FLBuilder._colDragStop})),e(FLBuilder._contentClass+" .fl-col-content").sortable(e.extend({},t,{connectWith:i,handle:".fl-module-overlay .fl-block-overlay-actions .fl-block-move",helper:FLBuilder._moduleDragHelper,items:".fl-module, .fl-col-group",start:FLBuilder._moduleDragStart,stop:FLBuilder._moduleDragStop})),e(FLBuilder._contentClass+" .fl-row-drop-target").sortable(t),e(FLBuilder._contentClass+" .fl-col-group-drop-target").sortable(t),e(FLBuilder._contentClass+" .fl-col-drop-target").sortable(t)},_initStrings:function(){e.validator.messages.required=FLBuilderStrings.validateRequiredMessage},_bindEvents:function(){e("a").on("click",FLBuilder._preventDefault),e(".fl-page-nav .nav a").on("click",FLBuilder._headerLinkClicked),e(document).on("heartbeat-tick",FLBuilder._initPostLock),e(window).on("beforeunload",FLBuilder._warnBeforeUnload),e("body").delegate(".fl-builder-has-submenu","click",FLBuilder._submenuParentClicked),e("body").delegate(".fl-builder-has-submenu a","click",FLBuilder._submenuChildClicked),e("body").delegate(".fl-builder-submenu","mouseenter",FLBuilder._submenuMouseenter),e("body").delegate(".fl-builder-submenu","mouseleave",FLBuilder._submenuMouseleave),e("body").delegate(".fl-builder-submenu .fl-builder-has-submenu","mouseenter",FLBuilder._submenuNestedParentMouseenter),e(".fl-builder-tools-button").on("click",FLBuilder._toolsClicked),e(".fl-builder-done-button").on("click",FLBuilder._doneClicked),e(".fl-builder-add-content-button").on("click",FLBuilder._showPanel),e(".fl-builder-templates-button").on("click",FLBuilder._changeTemplateClicked),e(".fl-builder-buy-button").on("click",FLBuilder._upgradeClicked),e(".fl-builder-upgrade-button").on("click",FLBuilder._upgradeClicked),e(".fl-builder-help-button").on("click",FLBuilder._helpButtonClicked),e(".fl-builder-panel-actions .fl-builder-panel-close").on("click",FLBuilder._closePanel),e(".fl-builder-blocks-section-title").on("click",FLBuilder._blockSectionTitleClicked),e("body").delegate(".fl-builder-node-template-actions","mousedown",FLBuilder._stopPropagation),e("body").delegate(".fl-builder-node-template-edit","mousedown",FLBuilder._stopPropagation),e("body").delegate(".fl-builder-node-template-delete","mousedown",FLBuilder._stopPropagation),e("body").delegate(".fl-builder-node-template-edit","click",FLBuilder._editNodeTemplateClicked),e("body").delegate(".fl-builder-node-template-delete","click",FLBuilder._deleteNodeTemplateClicked),e("body").delegate(".fl-builder-block","mousedown",FLBuilder._blockDragInit),e("body").on("mouseup",FLBuilder._blockDragCancel),e("body").delegate(".fl-builder-actions .fl-builder-cancel-button","click",FLBuilder._cancelButtonClicked),e("body").delegate(".fl-lightbox-controls .fa","click",FLBuilder._resizeLightbox),e("body").delegate(".fl-builder-save-actions .fl-builder-publish-button","click",FLBuilder._publishButtonClicked),e("body").delegate(".fl-builder-save-actions .fl-builder-draft-button","click",FLBuilder._draftButtonClicked),e("body").delegate(".fl-builder-save-actions .fl-builder-discard-button","click",FLBuilder._discardButtonClicked),e("body").delegate(".fl-builder-save-user-template-button","click",FLBuilder._saveUserTemplateClicked),e("body").delegate(".fl-builder-duplicate-layout-button","click",FLBuilder._duplicateLayoutClicked),e("body").delegate(".fl-builder-layout-settings-button","click",FLBuilder._layoutSettingsClicked),e("body").delegate(".fl-builder-layout-settings .fl-builder-settings-save","click",FLBuilder._saveLayoutSettingsClicked),e("body").delegate(".fl-builder-layout-settings .fl-builder-settings-cancel","click",FLBuilder._cancelLayoutSettingsClicked),e("body").delegate(".fl-builder-global-settings-button","click",FLBuilder._globalSettingsClicked),e("body").delegate(".fl-builder-global-settings .fl-builder-settings-save","click",FLBuilder._saveGlobalSettingsClicked),e("body").delegate(".fl-builder-global-settings .fl-builder-settings-cancel","click",FLBuilder._cancelLayoutSettingsClicked),e("body").delegate(".fl-template-category-select","change",FLBuilder._templateCategoryChanged),e("body").delegate(".fl-template-preview","click",FLBuilder._templateClicked),e("body").delegate(".fl-user-template","click",FLBuilder._userTemplateClicked),e("body").delegate(".fl-user-template-edit","click",FLBuilder._editUserTemplateClicked),e("body").delegate(".fl-user-template-delete","click",FLBuilder._deleteUserTemplateClicked),e("body").delegate(".fl-builder-template-replace-button","click",FLBuilder._templateReplaceClicked),e("body").delegate(".fl-builder-template-append-button","click",FLBuilder._templateAppendClicked),e("body").delegate(".fl-builder-template-actions .fl-builder-cancel-button","click",FLBuilder._templateCancelClicked),e("body").delegate(".fl-builder-user-template-settings .fl-builder-settings-save","click",FLBuilder._saveUserTemplateSettings),e("body").delegate(".fl-builder-help-tour-button","click",FLBuilder._startHelpTour),e("body").delegate(".fl-builder-help-video-button","click",FLBuilder._watchVideoClicked),e("body").delegate(".fl-builder-knowledge-base-button","click",FLBuilder._viewKnowledgeBaseClicked),e("body").delegate(".fl-builder-forums-button","click",FLBuilder._visitForumsClicked),e("body").delegate(".fl-builder-no-tour-button","click",FLBuilder._noTourButtonClicked),e("body").delegate(".fl-builder-yes-tour-button","click",FLBuilder._yesTourButtonClicked),e("body").delegate(".fl-builder-alert-close","click",FLBuilder._alertClose),e("body").delegate(".fl-row-overlay .fl-block-remove","click",FLBuilder._deleteRowClicked),e("body").delegate(".fl-row-overlay .fl-block-copy","click",FLBuilder._rowCopyClicked),e("body").delegate(".fl-row-overlay .fl-block-move","mousedown",FLBuilder._rowDragInit),e("body").delegate(".fl-row-overlay .fl-block-settings","click",FLBuilder._rowSettingsClicked),e("body").delegate(".fl-row-overlay","click",FLBuilder._rowSettingsClicked),e("body").delegate(".fl-builder-row-settings .fl-builder-settings-save","click",FLBuilder._saveSettings),e("body").delegate(".fl-col-overlay .fl-block-move","mousedown",FLBuilder._colDragInit),e("body").delegate(".fl-col-overlay .fl-block-remove","click",FLBuilder._deleteColClicked),e("body").delegate(".fl-col-overlay","click",FLBuilder._colSettingsClicked),e("body").delegate(".fl-builder-col-settings .fl-builder-settings-save","click",FLBuilder._saveSettings),e("body").delegate(".fl-block-col-submenu .fl-block-col-move","mousedown",FLBuilder._colDragInit),e("body").delegate(".fl-block-col-submenu .fl-block-col-edit","click",FLBuilder._colSettingsClicked),e("body").delegate(".fl-block-col-submenu .fl-block-col-delete","click",FLBuilder._deleteColClicked),e("body").delegate(".fl-block-col-submenu .fl-block-col-reset","click",FLBuilder._resetColumnWidthsClicked),e("body").delegate(".fl-block-col-submenu li","mouseenter",FLBuilder._showColHighlightGuide),e("body").delegate(".fl-block-col-submenu li","mouseleave",FLBuilder._removeColHighlightGuides),e("body").delegate(".fl-block-col-submenu .fl-block-col-move-parent","mousedown",FLBuilder._colDragInit),e("body").delegate(".fl-block-col-submenu .fl-block-col-edit-parent","click",FLBuilder._colSettingsClicked),e("body").delegate(".fl-module-overlay .fl-block-remove","click",FLBuilder._deleteModuleClicked),e("body").delegate(".fl-module-overlay .fl-block-copy","click",FLBuilder._moduleCopyClicked),e("body").delegate(".fl-module-overlay .fl-block-move","mousedown",FLBuilder._blockDragInit),e("body").delegate(".fl-module-overlay .fl-block-settings","click",FLBuilder._moduleSettingsClicked),e("body").delegate(".fl-module-overlay","click",FLBuilder._moduleSettingsClicked),e("body").delegate(".fl-builder-module-settings .fl-builder-settings-save","click",FLBuilder._saveModuleClicked),e("body").delegate(".fl-builder-settings-save-as","click",FLBuilder._showNodeTemplateSettings),e("body").delegate(".fl-builder-node-template-settings .fl-builder-settings-save","click",FLBuilder._saveNodeTemplate),e("body").delegate(".fl-builder-settings-tabs a","click",FLBuilder._settingsTabClicked),e("body").delegate(".fl-builder-settings-cancel","click",FLBuilder._settingsCancelClicked),e("body").delegate(".fl-help-tooltip-icon","mouseover",FLBuilder._showHelpTooltip),e("body").delegate(".fl-help-tooltip-icon","mouseout",FLBuilder._hideHelpTooltip),e("body").delegate(".fl-builder-field-add","click",FLBuilder._addFieldClicked),e("body").delegate(".fl-builder-field-copy","click",FLBuilder._copyFieldClicked),e("body").delegate(".fl-builder-field-delete","click",FLBuilder._deleteFieldClicked),e("body").delegate(".fl-builder-settings-fields select","change",FLBuilder._settingsSelectChanged),e("body").delegate(".fl-photo-field .fl-photo-select","click",FLBuilder._selectSinglePhoto),e("body").delegate(".fl-photo-field .fl-photo-edit","click",FLBuilder._selectSinglePhoto),e("body").delegate(".fl-photo-field .fl-photo-replace","click",FLBuilder._selectSinglePhoto),e("body").delegate(".fl-photo-field .fl-photo-remove","click",FLBuilder._singlePhotoRemoved),e("body").delegate(".fl-multiple-photos-field .fl-multiple-photos-select","click",FLBuilder._selectMultiplePhotos),e("body").delegate(".fl-multiple-photos-field .fl-multiple-photos-edit","click",FLBuilder._selectMultiplePhotos),e("body").delegate(".fl-multiple-photos-field .fl-multiple-photos-add","click",FLBuilder._selectMultiplePhotos),e("body").delegate(".fl-video-field .fl-video-select","click",FLBuilder._selectSingleVideo),e("body").delegate(".fl-video-field .fl-video-replace","click",FLBuilder._selectSingleVideo),e("body").delegate(".fl-multiple-audios-field .fl-multiple-audios-select","click",FLBuilder._selectMultipleAudios),e("body").delegate(".fl-multiple-audios-field .fl-multiple-audios-edit","click",FLBuilder._selectMultipleAudios),e("body").delegate(".fl-multiple-audios-field .fl-multiple-audios-add","click",FLBuilder._selectMultipleAudios),e("body").delegate(".fl-icon-field .fl-icon-select","click",FLBuilder._selectIcon),e("body").delegate(".fl-icon-field .fl-icon-replace","click",FLBuilder._selectIcon),e("body").delegate(".fl-icon-field .fl-icon-remove","click",FLBuilder._removeIcon),e("body").delegate(".fl-form-field .fl-form-field-edit","click",FLBuilder._formFieldClicked),e("body").delegate(".fl-form-field-settings .fl-builder-settings-save","click",FLBuilder._saveFormFieldClicked),e("body").delegate(".fl-layout-field-option","click",FLBuilder._layoutFieldClicked),e("body").delegate(".fl-link-field-select","click",FLBuilder._linkFieldSelectClicked),e("body").delegate(".fl-link-field-search-cancel","click",FLBuilder._linkFieldSelectCancelClicked),e("body").delegate(".fl-loop-data-source-select select[name=data_source]","change",FLBuilder._loopDataSourceChange),e("body").delegate(".fl-custom-query select[name=post_type]","change",FLBuilder._customQueryPostTypeChange),e("body").delegate(".fl-select-add-value","change",FLBuilder._textFieldAddValueSelectChange)},_bindOverlayEvents:function(){var t=e(FLBuilder._contentClass);t.delegate(".fl-row","mouseenter",FLBuilder._rowMouseenter),t.delegate(".fl-row","mouseleave",FLBuilder._rowMouseleave),t.delegate(".fl-row-overlay","mouseleave",FLBuilder._rowMouseleave),t.delegate(".fl-col","mouseenter",FLBuilder._colMouseenter),t.delegate(".fl-col","mouseleave",FLBuilder._colMouseleave),t.delegate(".fl-module","mouseenter",FLBuilder._moduleMouseenter),t.delegate(".fl-module","mouseleave",FLBuilder._moduleMouseleave)},_destroyOverlayEvents:function(){var t=e(FLBuilder._contentClass);t.undelegate(".fl-row","mouseenter",FLBuilder._rowMouseenter),t.undelegate(".fl-row","mouseleave",FLBuilder._rowMouseleave),t.undelegate(".fl-row-overlay","mouseleave",FLBuilder._rowMouseleave),t.undelegate(".fl-col","mouseenter",FLBuilder._colMouseenter),t.undelegate(".fl-col","mouseleave",FLBuilder._colMouseleave),t.undelegate(".fl-module","mouseenter",FLBuilder._moduleMouseenter),t.undelegate(".fl-module","mouseleave",FLBuilder._moduleMouseleave)},_preventDefault:function(e){e.preventDefault()},_stopPropagation:function(e){e.stopPropagation()},_headerLinkClicked:function(t){var l=e(this),i=l.attr("href");this.hash||(t.preventDefault(),FLBuilderConfig.isUserTemplate||(FLBuilder._exitUrl=i.indexOf("?")>-1?i:i+"?fl_builder",FLBuilder._doneClicked()))},_warnBeforeUnload:function(){var t=e(".fl-builder-row-settings").length>0,l=e(".fl-builder-col-settings").length>0,i=e(".fl-builder-module-settings").length>0;if(t||l||i)return FLBuilderStrings.unloadWarning},_initTipTips:function(){e(".fl-tip:not(.fl-has-tip)").each(function(){var t=e(this);t.addClass("fl-has-tip"),void 0==t.attr("data-title")&&t.attr("data-title",t.attr("title"))}).tipTip({defaultPosition:"top",delay:1500})},_hideTipTips:function(){e("#tiptip_holder").stop().remove()},_submenuParentClicked:function(t){var l=e(this),i=l.find(".fl-builder-submenu");l.hasClass("fl-builder-submenu-open")?(l.removeClass("fl-builder-submenu-open"),l.removeClass("fl-builder-submenu-right")):(l.offset().left+i.width()>e(window).width()&&l.addClass("fl-builder-submenu-right"),l.addClass("fl-builder-submenu-open")),FLBuilder._hideTipTips(),t.preventDefault(),t.stopPropagation()},_submenuChildClicked:function(t){var l=e(this).parents(".fl-builder-has-submenu");l.parents(".fl-builder-has-submenu").length||l.removeClass("fl-builder-submenu-open")},_submenuMouseenter:function(t){var l=e(this),i=l.data("timeout");"undefined"!=typeof i&&clearTimeout(i)},_submenuMouseleave:function(t){var l=e(this),i=setTimeout(function(){l.closest(".fl-builder-has-submenu").removeClass("fl-builder-submenu-open")},500);l.data("timeout",i)},_submenuNestedParentMouseenter:function(t){var l=e(this),i=l.find(".fl-builder-submenu");l.width()+l.offset().left+i.width()>e(window).width()&&l.addClass("fl-builder-submenu-right")},_closeAllSubmenus:function(){e(".fl-builder-submenu-open").removeClass("fl-builder-submenu-open")},_toolsClicked:function(){var e=[],t=FLBuilderConfig.lite,l=FLBuilderConfig.enabledTemplates,i="row"==FLBuilderConfig.userTemplateType,o="module"==FLBuilderConfig.userTemplateType;t||i||o||"enabled"!=l&&"user"!=l||(e[10]={key:"save-user-template",label:FLBuilderStrings.saveTemplate}),FLBuilderConfig.isUserTemplate?"undefined"!=typeof window.opener&&window.opener||(e[20]={key:"duplicate-layout",label:FLBuilderStrings.duplicateLayout}):e[20]={key:"duplicate-layout",label:FLBuilderStrings.duplicateLayout},e[30]={key:"layout-settings",label:FLBuilderStrings.editLayoutSettings},e[40]={key:"global-settings",label:FLBuilderStrings.editGlobalSettings},FLBuilder._showActionsLightbox({className:"fl-builder-tools-actions",title:FLBuilderStrings.actionsLightboxTitle,buttons:e})},_doneClicked:function(){var e=[],t=FLBuilderStrings.publish;"publish"==FLBuilderConfig.postStatus||FLBuilderConfig.userCanPublish||(t=FLBuilderStrings.submitForReview),e[10]={key:"publish",label:t},e[20]={key:"draft",label:FLBuilderStrings.draft},e[30]={key:"discard",label:FLBuilderStrings.discard},FLBuilder._showActionsLightbox({className:"fl-builder-save-actions",title:FLBuilderStrings.actionsLightboxTitle,buttons:e})},_upgradeClicked:function(){window.open(FLBuilderConfig.upgradeUrl)},_helpButtonClicked:function(){var e={};FLBuilderConfig.help.tour&&(e[10]={key:"help-tour",label:FLBuilderStrings.takeHelpTour}),FLBuilderConfig.help.video&&(e[20]={key:"help-video",label:FLBuilderStrings.watchHelpVideo}),FLBuilderConfig.help.knowledge_base&&(e[30]={key:"knowledge-base",label:FLBuilderStrings.viewKnowledgeBase}),FLBuilderConfig.help.forums&&(e[40]={key:"forums",label:FLBuilderStrings.visitForums}),FLBuilder._showActionsLightbox({className:"fl-builder-help-actions",title:FLBuilderStrings.actionsLightboxTitle,buttons:e})},_closePanel:function(){e(".fl-builder-panel").stop(!0,!0).animate({right:"-350px"},500,function(){e(this).hide()}),e(".fl-builder-bar .fl-builder-add-content-button").stop(!0,!0).fadeIn(),FLBuilder.triggerHook("hideContentPanel")},_showPanel:function(){e(".fl-builder-bar .fl-builder-add-content-button").stop(!0,!0).fadeOut(),e(".fl-builder-panel").stop(!0,!0).show().animate({right:"0"},500),FLBuilder.triggerHook("showContentPanel")},_blockSectionTitleClicked:function(){var t=e(this),l=t.parent();l.hasClass("fl-active")?l.removeClass("fl-active"):(e(".fl-builder-blocks-section").removeClass("fl-active"),l.addClass("fl-active")),FLBuilder._initScrollbars()},_publishButtonClicked:function(){FLBuilder.showAjaxLoader(),FLBuilder.ajax({action:"save_layout"},FLBuilder._exit),FLBuilder._actionsLightbox.close()},_draftButtonClicked:function(){FLBuilder.showAjaxLoader(),FLBuilder.ajax({action:"save_draft"},FLBuilder._exit),FLBuilder._actionsLightbox.close()},_discardButtonClicked:function(){var e=confirm(FLBuilderStrings.discardMessage);e&&(FLBuilder.showAjaxLoader(),FLBuilder.ajax({action:"clear_draft_layout"},FLBuilder._exit),FLBuilder._actionsLightbox.close())},_cancelButtonClicked:function(){FLBuilder._exitUrl=null,FLBuilder._actionsLightbox.close()},_exit:function(){var e=window.location.href;FLBuilderConfig.isUserTemplate&&"undefined"!=typeof window.opener&&window.opener?("undefined"!=typeof window.opener.FLBuilder&&window.opener.FLBuilder._updateLayout(),window.close()):(FLBuilder._exitUrl?e=FLBuilder._exitUrl:(e=e.replace("?fl_builder&","?"),e=e.replace("?fl_builder",""),e=e.replace("&fl_builder","")),window.location.href=e)},_duplicateLayoutClicked:function(){FLBuilder._actionsLightbox.close(),FLBuilder.showAjaxLoader(),FLBuilder.ajax({action:"duplicate_post"},FLBuilder._duplicateLayoutComplete)},_duplicateLayoutComplete:function(e){var t=FLBuilderConfig.adminUrl;window.location.href=t+"post.php?post="+e+"&action=edit"},_layoutSettingsClicked:function(){FLBuilder._actionsLightbox.close(),FLBuilder._showLightbox(),FLBuilder._closePanel(),FLBuilder.ajax({action:"render_layout_settings"},FLBuilder._layoutSettingsLoaded)},_layoutSettingsLoaded:function(e){var t=JSON.parse(e);FLBuilder._setSettingsFormContent(t.html),FLBuilder._layoutSettingsInitCSS()},_layoutSettingsInitCSS:function(){var t=e(".fl-builder-settings #fl-field-css textarea:not(.ace_text-input)");t.on("change",FLBuilder._layoutSettingsCSSChanged),FLBuilder._layoutSettingsCSSCache=t.val()},_layoutSettingsCSSChanged:function(){FLBuilder._layoutSettingsCSSTimeout&&clearTimeout(FLBuilder._layoutSettingsCSSTimeout),FLBuilder._layoutSettingsCSSTimeout=setTimeout(e.proxy(FLBuilder._layoutSettingsCSSDoChange,this),600)},_layoutSettingsCSSDoChange:function(){var t=e(".fl-builder-settings"),l=e(this),i=l.parents("#fl-field-css");i.find(".ace_error").length>0||(t.hasClass("fl-builder-layout-settings")?e("#fl-builder-layout-css").html(l.val()):e("#fl-builder-global-css").html(l.val()),FLBuilder._layoutSettingsCSSTimeout=null)},_saveLayoutSettingsClicked:function(){for(var t=e(this).closest(".fl-builder-settings"),l=t.serializeArray(),i={},o=0;o<l.length;o++)i[l[o].name]=l[o].value;FLBuilder.showAjaxLoader(),FLBuilder._lightbox.close(),FLBuilder._layoutSettingsCSSCache=null,FLBuilder.ajax({action:"save_layout_settings",settings:i},FLBuilder._updateLayout)},_cancelLayoutSettingsClicked:function(){var t=e(".fl-builder-settings");t.hasClass("fl-builder-layout-settings")?e("#fl-builder-layout-css").html(FLBuilder._layoutSettingsCSSCache):e("#fl-builder-global-css").html(FLBuilder._layoutSettingsCSSCache),FLBuilder._layoutSettingsCSSCache=null},_globalSettingsClicked:function(){FLBuilder._actionsLightbox.close(),FLBuilder._showLightbox(),FLBuilder.ajax({action:"render_global_settings"},FLBuilder._globalSettingsLoaded)},_globalSettingsLoaded:function(e){var t=JSON.parse(e);FLBuilder._setSettingsFormContent(t.html),FLBuilder._layoutSettingsInitCSS(),FLBuilder._initSettingsValidation({row_width:{required:!0,number:!0},responsive_breakpoint:{required:!0,number:!0},medium_breakpoint:{required:!0,number:!0}})},_saveGlobalSettingsClicked:function(){var t=e(this).closest(".fl-builder-settings"),l=t.validate().form(),i=t.serializeArray(),o={},s=0;if(l){for(;s<i.length;s++)o[i[s].name]=i[s].value;FLBuilder.showAjaxLoader(),FLBuilder._layoutSettingsCSSCache=null,FLBuilder.ajax({action:"save_global_settings",settings:o},FLBuilder._saveGlobalSettingsComplete),FLBuilder._lightbox.close()}},_saveGlobalSettingsComplete:function(e){FLBuilderConfig.global=JSON.parse(e),FLBuilder._updateLayout()},_initTemplateSelector:function(){var t=e(FLBuilder._contentClass).find(".fl-row");0===t.length&&FLBuilder._showTemplateSelector()},_changeTemplateClicked:function(){FLBuilder._actionsLightbox.close(),FLBuilder._showTemplateSelector()},_showTemplateSelector:function(){FLBuilderConfig.simpleUi||"row"!=FLBuilderConfig.userTemplateType&&"module"!=FLBuilderConfig.userTemplateType&&"disabled"!=FLBuilderConfig.enabledTemplates&&0!==e(".fl-builder-templates-button").length&&(FLBuilder._showLightbox(!1),FLBuilder.ajax({action:"render_template_selector"},FLBuilder._templateSelectorLoaded))},_templateSelectorLoaded:function(t){var l=JSON.parse(t),i=null,o=null;FLBuilder._setLightboxContent(l.html),i=e(".fl-template-category-select"),tabs=e(".fl-builder-settings-tab"),userTemplatesTab=e("#fl-builder-settings-tab-yours"),o=e(".fl-user-template"),("user"==FLBuilderConfig.enabledTemplates||o.length>0||userTemplatesTab.length>0&&1==tabs.length)&&(i.val("fl-builder-settings-tab-yours"),e(".fl-builder-settings-tab").removeClass("fl-active"),e("#fl-builder-settings-tab-yours").addClass("fl-active")),0===o.length&&e(".fl-user-templates-message").show(),e("body").trigger("fl-builder.template-selector-loaded")},_templateCategoryChanged:function(){e(".fl-template-selector .fl-builder-settings-tab").hide(),e("#"+e(this).val()).show()},_templateClicked:function(){var t=e(this),l=t.closest(".fl-template-preview").attr("data-id");e(FLBuilder._contentClass).children(".fl-row").length>0?0==l?confirm(FLBuilderStrings.changeTemplateMessage)&&(FLBuilder._lightbox._node.hide(),FLBuilder._applyTemplate(0,!1,"core")):(FLBuilder._selectedTemplateId=l,FLBuilder._selectedTemplateType="core",FLBuilder._showTemplateActions(),FLBuilder._lightbox._node.hide()):FLBuilder._applyTemplate(l,!1,"core")},_showTemplateActions:function(){var e=[];e[10]={key:"template-replace",label:FLBuilderStrings.templateReplace},e[20]={key:"template-append",label:FLBuilderStrings.templateAppend
2
- },FLBuilder._showActionsLightbox({className:"fl-builder-template-actions",title:FLBuilderStrings.actionsLightboxTitle,buttons:e})},_templateReplaceClicked:function(){confirm(FLBuilderStrings.changeTemplateMessage)&&(FLBuilder._actionsLightbox.close(),FLBuilder._applyTemplate(FLBuilder._selectedTemplateId,!1,FLBuilder._selectedTemplateType))},_templateAppendClicked:function(){FLBuilder._actionsLightbox.close(),FLBuilder._applyTemplate(FLBuilder._selectedTemplateId,!0,FLBuilder._selectedTemplateType)},_templateCancelClicked:function(){FLBuilder._lightbox._node.show()},_applyTemplate:function(e,t,l){t="undefined"!=typeof t&&t?"1":"0",l="undefined"==typeof l?"core":l,FLBuilder._lightbox.close(),FLBuilder.showAjaxLoader(),"core"==l?FLBuilder.ajax({action:"apply_template",template_id:e,append:t},FLBuilder._updateLayout):FLBuilder.ajax({action:"apply_user_template",template_id:e,append:t},FLBuilder._updateTemplateLayout)},_updateTemplateLayout:function(t){var l=JSON.parse(t);null!==l&&e("#fl-builder-layout-css").html(l.layout_css),FLBuilder._updateLayout()},_saveUserTemplateClicked:function(){FLBuilder._actionsLightbox.close(),FLBuilder._showLightbox(!1),FLBuilder.ajax({action:"render_user_template_settings"},FLBuilder._userTemplateSettingsLoaded)},_userTemplateSettingsLoaded:function(e){var t=JSON.parse(e);FLBuilder._setSettingsFormContent(t.html),FLBuilder._initSettingsValidation({name:{required:!0}})},_saveUserTemplateSettings:function(){var t=e(this).closest(".fl-builder-settings"),l=t.validate().form(),i=FLBuilder._getSettings(t);l&&(FLBuilder.showAjaxLoader(),FLBuilder.ajax({action:"save_user_template",settings:i},FLBuilder._saveUserTemplateSettingsComplete),FLBuilder._lightbox.close())},_saveUserTemplateSettingsComplete:function(){FLBuilder.alert(FLBuilderStrings.templateSaved)},_userTemplateClicked:function(){var t=e(this).attr("data-id");e(FLBuilder._contentClass).children(".fl-row").length>0?"blank"==t?confirm(FLBuilderStrings.changeTemplateMessage)&&(FLBuilder._lightbox._node.hide(),FLBuilder._applyTemplate("blank",!1,"user")):(FLBuilder._selectedTemplateId=t,FLBuilder._selectedTemplateType="user",FLBuilder._showTemplateActions(),FLBuilder._lightbox._node.hide()):FLBuilder._applyTemplate(t,!1,"user")},_editUserTemplateClicked:function(t){t.preventDefault(),t.stopPropagation(),window.open(e(this).attr("href"))},_deleteUserTemplateClicked:function(t){var l=e(this).closest(".fl-user-template"),i=l.attr("data-id"),o=e(".fl-user-template[data-id="+i+"]"),s=null;confirm(FLBuilderStrings.deleteTemplate)&&(FLBuilder.ajax({action:"delete_user_template",template_id:i}),o.fadeOut(function(){l=e(this),s=l.closest(".fl-user-template-category"),l.remove(),0===s.find(".fl-user-template").length&&s.remove(),1===e(".fl-user-template").length&&(e(".fl-user-templates").hide(),e(".fl-user-templates-message").show())})),t.stopPropagation()},_watchVideoClicked:function(){var e=wp.template("fl-video-lightbox");FLBuilder._actionsLightbox.close(),FLBuilder._lightbox.open(e({video:FLBuilderConfig.help.video_embed}))},_viewKnowledgeBaseClicked:function(){FLBuilder._actionsLightbox.close(),window.open(FLBuilderConfig.help.knowledge_base_url)},_visitForumsClicked:function(){FLBuilder._actionsLightbox.close(),window.open(FLBuilderConfig.help.forums_url)},_showTourOrTemplates:function(){FLBuilderConfig.simpleUi||FLBuilderConfig.isUserTemplate||(FLBuilderConfig.help.tour&&FLBuilderConfig.newUser?FLBuilder._showTourLightbox():FLBuilder._initTemplateSelector())},_showTourLightbox:function(){var e=wp.template("fl-tour-lightbox");FLBuilder._actionsLightbox.open(e())},_noTourButtonClicked:function(){FLBuilder._actionsLightbox.close(),FLBuilder._initTemplateSelector()},_yesTourButtonClicked:function(){FLBuilder._actionsLightbox.close(),FLBuilderTour.start()},_startHelpTour:function(){FLBuilder._actionsLightbox.close(),FLBuilderTour.start()},_setupEmptyLayout:function(){var t=e(FLBuilder._contentClass);FLBuilderConfig.isUserTemplate&&"module"==FLBuilderConfig.userTemplateType||(t.removeClass("fl-builder-empty"),t.find(".fl-builder-empty-message").remove(),0===t.children(".fl-row").length&&(t.addClass("fl-builder-empty"),t.append('<span class="fl-builder-empty-message">'+FLBuilderStrings.emptyMessage+"</span>"),FLBuilder._initSortables()))},_updateLayout:function(){FLBuilder.showAjaxLoader(),FLBuilder.ajax({action:"render_layout"},FLBuilder._renderLayout)},_renderLayout:function(e,t){FLBuilder._layout=new FLBuilderAJAXLayout(e,t)},_renderLayoutComplete:function(){FLBuilder._layout&&(FLBuilder._layout._complete(),FLBuilder._layout=null)},_resizeLayout:function(){e(window).trigger("resize"),"undefined"!=typeof YUI&&YUI().use("node-event-simulate",function(e){e.one(window).simulate("resize")})},_initMediaElements:function(){var t={};"undefined"!=typeof e.fn.mediaelementplayer&&("undefined"!=typeof _wpmejsSettings&&(t.pluginPath=_wpmejsSettings.pluginPath),e(".wp-audio-shortcode, .wp-video-shortcode").not(".mejs-container").mediaelementplayer(t))},_initDropTargets:function(){var t="row"==FLBuilderConfig.userTemplateType?"":":not(.fl-node-global)",l=e(FLBuilder._contentClass+" .fl-row"),i=null,o=e(FLBuilder._contentClass+" .fl-row"+t).find(".fl-col-group"),s=null,r=null,n=0;for(e(".fl-col-drop-target").remove(),e(".fl-col-group-drop-target").remove(),e(".fl-row-drop-target").remove(),e(FLBuilder._contentClass).append('<div class="fl-drop-target fl-row-drop-target"></div>'),l.prepend('<div class="fl-drop-target fl-row-drop-target"></div>'),l.append('<div class="fl-drop-target fl-drop-target-last fl-row-drop-target fl-row-drop-target-last"></div>');n<l.length;n++)i=l.eq(n),0===i.find(".fl-col-group").length&&i.find(".fl-row-content").prepend('<div class="fl-drop-target fl-col-group-drop-target"></div>');for(n=0;n<o.length;n++)s=o.eq(n),r=s.find("> .fl-col"),s.hasClass("fl-col-group-nested")||(s.append('<div class="fl-drop-target fl-col-group-drop-target"></div>'),s.append('<div class="fl-drop-target fl-drop-target-last fl-col-group-drop-target fl-col-group-drop-target-last"></div>')),r.append('<div class="fl-drop-target fl-col-drop-target"></div>'),r.append('<div class="fl-drop-target fl-drop-target-last fl-col-drop-target fl-col-drop-target-last"></div>')},_blockDragHelper:function(e,t){var l=t.clone();return t.clone().insertAfter(t),l.addClass("fl-builder-block-drag-helper"),l},_blockDragInit:function(t){var l=e(t.currentTarget),i=null,o=e(window).scrollTop(),s=0;FLBuilder._dragEnabled=!0,FLBuilder._dragInitialScrollTop=o,l.closest("[data-node]").length>0?(i=l.closest("[data-node]"),i.addClass("fl-node-drag-init")):l.hasClass("fl-builder-block")&&e(".fl-row").each(function(){null===i&&e(this).offset().top-o>0&&(i=e(this))}),null!==i&&(s=i.offset().top-o),FLBuilder._highlightRowsAndColsForDrag(l),FLBuilder._adjustColHeightsForDrag(),FLBuilder._disableGlobalRows(),FLBuilder._closePanel(),FLBuilder._destroyOverlayEvents(),FLBuilder._removeAllOverlays(),FLBuilder._initSortables(),e("body").addClass("fl-builder-dragging"),e(".fl-builder-empty-message").hide(),e(".fl-sortable-disabled").removeClass("fl-sortable-disabled"),s>0&&scrollTo(0,i.offset().top-s)},_blockDragStart:function(t,l){FLBuilder._dragging=!0,e(".fl-node-drag-init").removeClass("fl-node-drag-init")},_blockDragSort:function(t,l){var i=l.placeholder.parent(),o=FLBuilderStrings.insert;FLBuilder._blockPreventSort(l.item,i)||(i.hasClass("fl-col-content")?o=l.item.hasClass("fl-builder-block-row")?l.item.find(".fl-builder-block-title").text():l.item.hasClass("fl-col-sortable-proxy-item")?FLBuilderStrings.column:l.item.hasClass("fl-builder-block-module")?l.item.find(".fl-builder-block-title").text():l.item.hasClass("fl-builder-block-saved-module")||l.item.hasClass("fl-builder-block-module-template")?l.item.find(".fl-builder-block-title").text():l.item.attr("data-name"):i.hasClass("fl-col-drop-target")?o="":i.hasClass("fl-col-group-drop-target")?o="":i.hasClass("fl-row-drop-target")&&(o=l.item.hasClass("fl-builder-block-row")?l.item.find(".fl-builder-block-title").text():l.item.hasClass("fl-builder-block-saved-row")?l.item.find(".fl-builder-block-title").text():l.item.hasClass("fl-row-sortable-proxy-item")?FLBuilderStrings.row:FLBuilderStrings.newRow),l.placeholder.html(o),l.item.hasClass("fl-node-global")||l.item.hasClass("fl-builder-block-global")||e(".fl-node-dragging").hasClass("fl-node-global")?l.placeholder.addClass("fl-builder-drop-zone-global"):l.placeholder.removeClass("fl-builder-drop-zone-global"))},_blockDragChange:function(e,t){t.placeholder.hide(),t.placeholder.fadeIn(100)},_blockPreventSort:function(t,l){var i=!1,o=t.hasClass("fl-builder-block-row"),s=t.hasClass("fl-col-sortable-proxy-item"),r=l.hasClass("fl-col-content"),n=l.hasClass("fl-col-drop-target"),a=l.parents(".fl-col-group:not(.fl-col-group-nested)"),d=l.parents(".fl-col-group-nested");return(o||s)&&r&&d.length>0&&(i=!0),r&&!l.find(".fl-module, .fl-col").length&&(o&&"1-col"==t.data("cols")?i=!0:s&&(i=!0)),o&&r&&e.inArray(t.data("cols"),["5-cols","6-cols"])>-1&&(i=!0),s&&e(".fl-node-dragging").find(".fl-col-group-nested").length>0&&(r||n&&d.length>0)&&(i=!0),n&&a.length>0&&0===d.length&&a.find("> .fl-col:visible").length>11&&(i=!0),n&&d.length>0&&d.find(".fl-col:visible").length>3&&(i=!0),i&&l.addClass("fl-sortable-disabled"),i},_blockDragStop:function(t,l){var i=e(window).scrollTop(),o=l.item.parent(),s=null;o.hasClass("fl-drop-target")&&o.closest("[data-node]").length?(o=o.closest("[data-node]"),s=o.offset().top-i):s=o.offset().top-i,o.hasClass("fl-builder-blocks-section-content")&&FLBuilder._showPanel(),FLBuilder._dragEnabled=!1,FLBuilder._dragging=!1,FLBuilder._bindOverlayEvents(),FLBuilder._highlightEmptyCols(),FLBuilder._enableGlobalRows(),FLBuilder._setupEmptyLayout(),e("body").removeClass("fl-builder-dragging"),scrollTo(0,o.offset().top-s)},_blockDragCancel:function(){FLBuilder._dragEnabled&&!FLBuilder._dragging&&(FLBuilder._dragEnabled=!1,FLBuilder._dragging=!1,FLBuilder._bindOverlayEvents(),FLBuilder._highlightEmptyCols(),FLBuilder._enableGlobalRows(),FLBuilder._setupEmptyLayout(),e("body").removeClass("fl-builder-dragging"),e(".fl-node-drag-init").removeClass("fl-node-drag-init"),e(".fl-node-dragging").removeClass("fl-node-dragging"),scrollTo(0,FLBuilder._dragInitialScrollTop))},_reorderNode:function(e,t){FLBuilder.ajax({action:"reorder_node",node_id:e,position:t})},_moveNode:function(e,t,l){FLBuilder.ajax({action:"move_node",new_parent:e,node_id:t,position:l})},_removeAllOverlays:function(){FLBuilder._removeRowOverlays(),FLBuilder._removeColOverlays(),FLBuilder._removeColHighlightGuides(),FLBuilder._removeModuleOverlays(),FLBuilder._hideTipTips()},_appendOverlay:function(e,t){var l=0,i=null,o=e.hasClass("fl-row"),s=o?e.find("> .fl-row-content-wrap"):e.find("> .fl-node-content"),r={top:parseInt(s.css("margin-top"),10),bottom:parseInt(s.css("margin-bottom"),10)};return e.append(t),e.addClass("fl-block-overlay-active"),FLBuilder._initTipTips(),i=e.find("> .fl-block-overlay"),r.top<0&&(l=parseInt(i.css("top"),10),l=isNaN(l)?0:l,i.css("top",r.top+l+"px")),r.bottom<0&&(l=parseInt(i.css("bottom"),10),l=isNaN(l)?0:l,i.css("bottom",r.bottom+l+"px")),i},_buildOverlayOverflowMenu:function(e){var t=e.find(".fl-block-overlay-actions"),l=t.data("original"),i=0,o=null,s=0,r=null,n=0,a=[],d=[],u=[],c=wp.template("fl-overlay-overflow-menu");for(void 0!=l&&(t.after(l),t.remove(),t=l),t.data("original",t.clone()),i=t[0].getBoundingClientRect().width,o=t.find(" > i, > span.fl-builder-has-submenu");n<o.length;n++)r=o.eq(n),s+=r.outerWidth(),s>i?(d.push(r),r.remove()):a.push(r);if(d.length>0){for(d.unshift(a.pop().remove()),n=0;n<d.length;n++)d[n].is(".fl-builder-has-submenu")?u.push({type:"submenu",label:d[n].find(".fa").data("title"),submenu:d[n].find(".fl-builder-submenu")[0].outerHTML}):u.push({type:"action",label:d[n].data("title"),className:d[n].removeClass(function(e,t){return t.replace(/fl-block-([^\s]+)/,"")}).attr("class")});t.append(c(u)),FLBuilder._initTipTips()}},_removeRowOverlays:function(){e(".fl-row").removeClass("fl-block-overlay-active"),e(".fl-row-overlay").remove(),e(".fl-module").removeClass("fl-module-adjust-height")},_disableGlobalRows:function(){"row"!=FLBuilderConfig.userTemplateType&&e(".fl-row.fl-node-global").addClass("fl-node-disabled")},_enableGlobalRows:function(){"row"!=FLBuilderConfig.userTemplateType&&e(".fl-node-disabled").removeClass("fl-node-disabled")},_rowMouseenter:function(){var t=e(this),l=t.offset().top,i=null,o=null,s=wp.template("fl-row-overlay");t.closest(".fl-builder-node-loading").length||t.hasClass("fl-block-overlay-active")||(o=FLBuilder._appendOverlay(t,s({global:t.hasClass("fl-node-global"),node:t.attr("data-node")})),t.find(".fl-node-content:visible").each(function(){var t=e(this).offset().top;i=null===i||i>t?t:i}),null!==i&&i<l&&o.css("top",i-l-30+"px"),o.offset().top<43&&o.addClass("fl-row-overlay-header-bottom"),t.find(".fl-module").each(function(){var t=e(this);t.outerHeight(!0)<20&&t.addClass("fl-module-adjust-height")}))},_rowMouseleave:function(t){var l=e(t.toElement)||e(t.relatedTarget),i=l.hasClass("fl-row-overlay"),o=l.closest(".fl-row-overlay").length>0,s=l.is("#tiptip_holder"),r=l.closest("#tiptip_holder").length>0;i||o||s||r||FLBuilder._removeRowOverlays()},_rowDragHelper:function(){return e('<div class="fl-builder-block-drag-helper">'+FLBuilderStrings.row+"</div>")},_rowDragInit:function(t){var l=e(t.target),i=e(".fl-row-sortable-proxy-item"),o=l.closest(".fl-row");o.addClass("fl-node-dragging"),FLBuilder._blockDragInit(t),t.target=i[0],i.trigger(t)},_rowDragStart:function(t,l){var i=e(FLBuilder._contentClass+" .fl-row"),o=e(".fl-node-dragging");1===i.length&&e(FLBuilder._contentClass).addClass("fl-builder-empty"),o.hide(),FLBuilder._blockDragStart(t,l)},_rowDragStop:function(t,l){var i=l.item,o=i.parent(),s=null,r=null,n=0;if(FLBuilder._blockDragStop(t,l),o.hasClass("fl-builder-rows"))return void i.remove();if(o.hasClass("fl-row-sortable-proxy"))return void e(".fl-node-dragging").removeClass("fl-node-dragging").show();if(i.hasClass("fl-builder-block")){if(o.hasClass("fl-sortable-disabled"))return i.remove(),void FLBuilder._showPanel();o.hasClass("fl-col-content")?FLBuilder._addColGroup(i.closest(".fl-col").attr("data-node"),i.attr("data-cols"),o.find("> .fl-module, .fl-col-group, .fl-builder-block").index(i)):o.hasClass("fl-col-drop-target")?FLBuilder._addCols(o.closest(".fl-col"),o.hasClass("fl-col-drop-target-last")?"after":"before",i.attr("data-cols"),o.closest(".fl-col-group-nested").length>0):o.hasClass("fl-col-group-drop-target")?(r=i.closest(".fl-col-group"),n=i.closest(".fl-row").find(".fl-row-content > .fl-col-group").index(r),FLBuilder._addColGroup(i.closest(".fl-row").attr("data-node"),i.attr("data-cols"),o.hasClass("fl-drop-target-last")?n+1:n)):(s=i.closest(".fl-row"),n=s.length?e(FLBuilder._contentClass+" .fl-row").index(s):0,FLBuilder._addRow(i.attr("data-cols"),o.hasClass("fl-drop-target-last")?n+1:n)),i.remove(),FLBuilder._showPanel(),e(".fl-builder-modules").siblings(".fl-builder-blocks-section-title").eq(0).trigger("click")}else s=e(".fl-node-dragging").removeClass("fl-node-dragging").show(),o.parent().hasClass("fl-builder-content")||(o.hasClass("fl-drop-target-last")?o.parent().after(s):o.parent().before(s),FLBuilder._reorderNode(s.attr("data-node"),s.index())),e(".fl-row-sortable-proxy").append(l.item)},_addRow:function(t,l){FLBuilder._showNodeLoadingPlaceholder(e(FLBuilder._contentClass),l),FLBuilder._newRowPosition=l,FLBuilder.ajax({action:"render_new_row",cols:t,position:l},FLBuilder._addRowComplete)},_addRowComplete:function(t){var l=JSON.parse(t),i=e(FLBuilder._contentClass),o=e(l.html).data("node"),s=FLBuilder._addModuleAfterNodeRender;l.nodeParent=i,l.nodePosition=FLBuilder._newRowPosition,FLBuilder._renderLayout(l,function(){null!==s&&(e(".fl-node-"+o+" .fl-col-content").append(s),FLBuilder._reorderModule(s),FLBuilder._addModuleAfterNodeRender=null),FLBuilder._removeNodeLoadingPlaceholder(e(".fl-node-"+o))})},_deleteRowClicked:function(t){var l=e(this).closest(".fl-row"),i=null;l.find(".fl-module").length?(i=confirm(FLBuilderStrings.deleteRowMessage),i&&FLBuilder._deleteRow(l)):FLBuilder._deleteRow(l),FLBuilder._removeAllOverlays(),t.stopPropagation()},_deleteRow:function(e){FLBuilder.ajax({action:"delete_node",node_id:e.attr("data-node")}),e.empty(),e.remove(),FLBuilder._setupEmptyLayout(),FLBuilder._removeRowOverlays()},_rowCopyClicked:function(t){var l=e(this).closest(".fl-row"),i=l.attr("data-node"),o=e(FLBuilder._contentClass+" .fl-row").index(l)+1,s=l.clone();s.addClass("fl-builder-node-clone"),s.attr("data-node",i+"-clone"),s.find(".fl-block-overlay").remove(),l.after(s),FLBuilder._showNodeLoading(i+"-clone"),FLBuilder._newRowPosition=o,FLBuilder.ajax({action:"copy_row",node_id:i},FLBuilder._rowCopyComplete),t.stopPropagation()},_rowCopyComplete:function(t){var l=JSON.parse(t);l.nodeParent=e(FLBuilder._contentClass),l.nodePosition=FLBuilder._newRowPosition,FLBuilder._renderLayout(l,function(){l.nodeParent.find(".fl-builder-node-loading").eq(0).remove()})},_rowSettingsClicked:function(t){var l=e(this),i=l.closest(".fl-row").attr("data-node"),o=l.closest(".fl-block-overlay-global").length>0;o&&"row"!=FLBuilderConfig.userTemplateType?FLBuilderConfig.userCanEditGlobalTemplates&&window.open(e('.fl-row[data-node="'+i+'"]').attr("data-template-url")):l.hasClass("fl-block-settings")&&(FLBuilder._closePanel(),FLBuilder._showLightbox(),FLBuilder.ajax({action:"render_row_settings",node_id:i},FLBuilder._rowSettingsLoaded)),t.stopPropagation()},_rowSettingsLoaded:function(e){var t=JSON.parse(e);FLBuilder._setSettingsFormContent(t.settings),FLBuilder.preview=new FLBuilderPreview({type:"row",state:t.state})},_highlightEmptyCols:function(){var t="row"==FLBuilderConfig.userTemplateType?"":":not(.fl-node-global)",l=(e(FLBuilder._contentClass+" .fl-row"+t),e(FLBuilder._contentClass+" .fl-col"+t));e(".fl-row-highlight").removeClass("fl-row-highlight"),l.removeClass("fl-col-highlight").find(".fl-col-content").css("height",""),l.each(function(){var t=e(this);0===t.find(".fl-module, .fl-col").length&&t.addClass("fl-col-highlight")})},_highlightRowsAndColsForDrag:function(t){var l="row"==FLBuilderConfig.userTemplateType?"":":not(.fl-node-global)";e(FLBuilder._contentClass+" .fl-row").addClass("fl-row-highlight"),t.closest(".fl-row-overlay").length||e(FLBuilder._contentClass+" .fl-col"+l).addClass("fl-col-highlight")},_adjustColHeightsForDrag:function(){var t="row"==FLBuilderConfig.userTemplateType?"":".fl-row:not(.fl-node-global) ",l=e(FLBuilder._contentClass),i=l.find(t+".fl-col-group:not(.fl-col-group-nested) > .fl-col > .fl-col-content"),o=l.find(t+".fl-col-group-nested .fl-col-content"),s=0;for(e(".fl-node-drag-init").hide();s<o.length;s++)FLBuilder._adjustColHeightForDrag(o.eq(s));for(s=0;s<i.length;s++)FLBuilder._adjustColHeightForDrag(i.eq(s));e(".fl-node-drag-init").show()},_adjustColHeightForDrag:function(e){e.find(".fl-module:visible, .fl-col:visible").length&&e.height(e.height()+45)},_showColHighlightGuide:function(){var t=e(this),l=t.find("a"),i=t.closest(".fl-col"),o=i.parents(".fl-col"),s=e('<div class="fl-col-highlight-guide"></div>'),r=null,n=t.closest(".fl-block-overlay").offset().top;(l.hasClass("fl-block-col-move-parent")||l.hasClass("fl-block-col-edit-parent"))&&(i=o),i.hasClass("fl-col-highlight")||(i.find("> .fl-col-content").append(s),i.addClass("fl-col-has-highlight-guide"),r=s.offset().top,r>n&&s.css("top",n-r+4+"px"))},_removeColHighlightGuides:function(){e(".fl-col-has-highlight-guide").removeClass("fl-col-has-highlight-guide"),e(".fl-col-highlight-guide").remove()},_colMouseenter:function(){var t=e(this),l=t.closest(".fl-col-group"),i=l.hasClass("fl-col-group-has-child-loading"),o=t.hasClass("fl-node-global"),s=t.parents(".fl-node-global").length>0,r=t.closest(".fl-col-group").find("> .fl-col").length,n=l.find("> .fl-col").index(t),a=0===n,d=r===n+1,u=t.find(".fl-col").length>0,c=t.parents(".fl-col"),f=c.closest(".fl-col-group"),h=c.length>0,p=h?f.find("> .fl-col").length:0,g=f.find("> .fl-col").index(c),_=!!h&&0===g,m=!!h&&p===g+1,b=t.find("> .fl-col-content").width(),v=wp.template("fl-col-overlay"),L=null;FLBuilderConfig.simpleUi||o&&s&&"row"!=FLBuilderConfig.userTemplateType||t.find(".fl-module, .fl-builder-node-loading-placeholder").length>0||t.find(".fl-col").length>0||t.closest(".fl-builder-node-loading").length||(t.hasClass("fl-block-overlay-active")||(FLBuilder._removeColOverlays(),FLBuilder._removeModuleOverlays(),L=FLBuilder._appendOverlay(t,v({global:o,groupLoading:i,numCols:r,first:a,last:d,hasChildCols:u,hasParentCol:h,parentFirst:_,parentLast:m,numParentCols:p,contentWidth:b})),FLBuilder._buildOverlayOverflowMenu(L),FLBuilder._initColDragResizing()),e("body").addClass("fl-block-overlay-muted"))},_colMouseleave:function(t){var l=e(this),i=e(t.toElement)||e(t.relatedTarget),o=l.find(".fl-module").length>0,s=i.is("#tiptip_holder"),r=i.closest("#tiptip_holder").length>0;s||r||o||(FLBuilder._removeColOverlays(),FLBuilder._removeColHighlightGuides())},_removeColOverlays:function(){var t=e(".fl-col");t.removeClass("fl-block-overlay-active"),t.find(".fl-col-overlay").remove(),e("body").removeClass("fl-block-overlay-muted")},_colDragHelper:function(){return e('<div class="fl-builder-block-drag-helper">'+FLBuilderStrings.column+"</div>")},_colDragInit:function(t){var l=e(t.target),i=e(".fl-col-sortable-proxy-item"),o=l.closest(".fl-col");l.hasClass("fl-block-col-move-parent")&&(o=o.parents(".fl-col")),o.addClass("fl-node-dragging"),FLBuilder._blockDragInit(t),FLBuilder._removeColHighlightGuides(),t.target=i[0],i.trigger(t)},_colDragStart:function(t,l){var i=e(".fl-node-dragging");i.hide(),FLBuilder._resetColumnWidths(i.parent()),FLBuilder._blockDragStart(t,l)},_colDragStop:function(t,l){FLBuilder._blockDragStop(t,l);var i=e(".fl-node-dragging").removeClass("fl-node-dragging").show(),o=i.attr("data-node"),s=l.item.parent(),r=i.parent(),n=r.attr("data-node");newGroup=s.closest(".fl-col-group"),newGroupId=newGroup.attr("data-node"),newRow=s.closest(".fl-row"),position=0,s.hasClass("fl-sortable-disabled")?FLBuilder._resetColumnWidths(r):s.hasClass("fl-col-sortable-proxy")?FLBuilder._resetColumnWidths(r):s.hasClass("fl-col-content")?(i.remove(),0===r.find(".fl-col").length&&r.remove(),position=s.find("> .fl-module, .fl-col-group, .fl-col-sortable-proxy-item").index(l.item),FLBuilder._addColGroup(s.closest(".fl-col").attr("data-node"),o,position)):s.hasClass("fl-col-drop-target")?(s.hasClass("fl-col-drop-target-last")?s.parent().after(i):s.parent().before(i),FLBuilder._resetColumnWidths(newGroup),n==newGroupId?FLBuilder.ajax({action:"reorder_col",node_id:o,position:i.index()}):FLBuilder.ajax({action:"move_col",node_id:o,new_parent:newGroupId,position:i.index(),resize:[n,newGroupId]}),FLBuilder._resizeLayout()):s.hasClass("fl-col-group-drop-target")?(i.remove(),0===r.find(".fl-col").length&&r.remove(),position=newRow.find(".fl-row-content > .fl-col-group").index(newGroup),position=s.hasClass("fl-drop-target-last")?position+1:position,FLBuilder._addColGroup(newRow.attr("data-node"),o,position)):s.hasClass("fl-row-drop-target")&&(i.remove(),position=s.closest(".fl-builder-content").find(".fl-row").index(newRow),position=s.hasClass("fl-drop-target-last")?position+1:position,FLBuilder._addRow(o,position)),0===r.find(".fl-col").length&&r.remove(),e(".fl-col-sortable-proxy").append(l.item),FLBuilder._highlightEmptyCols(),FLBuilder._initDropTargets(),FLBuilder._initSortables()},_colSettingsClicked:function(t){var l=e(this),i=l.closest(".fl-col"),o=null;FLBuilder._colResizing||(o=l.hasClass("fl-block-col-edit-parent")?i.parents(".fl-col").data("node"):i.attr("data-node"),FLBuilder._closePanel(),FLBuilder._showLightbox(),FLBuilder.ajax({action:"render_column_settings",node_id:o},FLBuilder._colSettingsLoaded),t.stopPropagation())},_colSettingsLoaded:function(t){var l=JSON.parse(t),i=null,o=null,s=null,r=null;FLBuilder._setSettingsFormContent(l.settings),i=e(".fl-builder-col-settings"),o=i.data("node"),s=e('.fl-col[data-node="'+o+'"]'),r=s.find("> .fl-col-content"),0===s.siblings(".fl-col").length?e(i).find("#fl-builder-settings-section-general").css("display","none"):r.width()<=40&&e("#fl-field-size").hide(),FLBuilder.preview=new FLBuilderPreview({type:"col",state:l.state})},_deleteColClicked:function(t){var l=e(this),i=l.closest(".fl-col"),o=i.closest(".fl-col-group"),s=i.parents(".fl-col"),r=s.length>0,n=s.find("> .fl-col-content > .fl-module, > .fl-col-content > .fl-col-group"),a=i.siblings(".fl-col"),d=!0;i.find(".fl-module").length>0&&(d=confirm(FLBuilderStrings.deleteColumnMessage)),r&&1===n.length&&(0===a.length?i=s:1!==a.length||a.find(".fl-module").length||(i=o)),d&&(FLBuilder._deleteCol(i),FLBuilder._removeAllOverlays(),FLBuilder._highlightEmptyCols()),t.stopPropagation()},_deleteCol:function(e){var t=e.closest(".fl-row"),l=e.closest(".fl-col-group"),i=0;e.remove(),rowCols=t.find(".fl-row-content > .fl-col-group > .fl-col"),groupCols=l.find(" > .fl-col"),0===rowCols.length&&"row"!=FLBuilderConfig.userTemplateType?FLBuilder._deleteRow(t):(0===groupCols.length?l.remove():(i=6===groupCols.length?16.65:7===groupCols.length?14.28:Math.round(100/groupCols.length*100)/100,groupCols.css("width",i+"%")),FLBuilder.ajax({action:"delete_col",node_id:e.attr("data-node"),new_width:i}),FLBuilder._initDropTargets(),FLBuilder._initSortables())},_addCols:function(e,t,l,i){var o=e.closest(".fl-col-group"),s=o.find(".fl-col").index(e);l="undefined"==typeof l?"1-col":l,i="undefined"!=typeof i&&i,"after"==t&&s++,FLBuilder._showNodeLoadingPlaceholder(o,s),FLBuilder._removeAllOverlays(),FLBuilder.ajax({action:"render_new_columns",node_id:e.attr("data-node"),insert:t,type:l,nested:i?1:0},FLBuilder._addColsComplete)},_addColsComplete:function(t){var l=JSON.parse(t),i=null,o=FLBuilder._addModuleAfterNodeRender;FLBuilder._renderLayout(l,function(){null!==o&&(e('[data-node="'+o.module.data("node")+'"]').remove(),i=e('[data-node="'+o.colId+'"]'),"after"==o.position?i.next().find(".fl-col-content").append(o.module):i.prev().find(".fl-col-content").append(o.module),FLBuilder._reorderModule(o.module),FLBuilder._addModuleAfterNodeRender=null)})},_addColGroup:function(t,l,i){var o=e(".fl-node-"+t);FLBuilder._newColGroupPosition=i,o.hasClass("fl-col")?FLBuilder._newColGroupParent=o.find(" > .fl-col-content"):FLBuilder._newColGroupParent=o.find(".fl-row-content"),FLBuilder._showNodeLoadingPlaceholder(FLBuilder._newColGroupParent,i),FLBuilder.ajax({action:"render_new_column_group",cols:l,node_id:t,position:i},FLBuilder._addColGroupComplete)},_addColGroupComplete:function(t){var l=JSON.parse(t),i=e(l.html),o=i.data("node"),s=i.find(".fl-col").data("node"),r=FLBuilder._addModuleAfterNodeRender;l.nodeParent=FLBuilder._newColGroupParent,l.nodePosition=FLBuilder._newColGroupPosition,FLBuilder._renderLayout(l,function(){l.nodeParent.hasClass("fl-col-content")&&l.nodeParent.parents(".fl-col").addClass("fl-col-has-cols"),null!==r&&(e(".fl-node-"+s+" .fl-col-content").append(r),FLBuilder._reorderModule(r),FLBuilder._addModuleAfterNodeRender=null),FLBuilder._removeNodeLoadingPlaceholder(e(".fl-node-"+o))})},_initColDragResizing:function(){e(".fl-block-col-resize").draggable({axis:"x",start:FLBuilder._colDragResizeStart,drag:FLBuilder._colDragResize,stop:FLBuilder._colDragResizeStop})},_colDragResizeStart:function(t,l){var i=e(l.helper),o="",s=i.hasClass("fl-block-col-resize-parent"),r=s?i.closest(".fl-col").parents(".fl-col"):null,n=s?r.parents(".fl-col-group"):i.closest(".fl-col-group"),a=n.find("> .fl-col"),d=s?r:i.closest(".fl-col"),u=null,c=100,f=0;for(i.hasClass("fl-block-col-resize-e")?(o="e",u=d.nextAll(".fl-col").first()):(o="w",u=d.prevAll(".fl-col").first());f<a.length;f++)a.eq(f).data("node")!=d.data("node")&&a.eq(f).data("node")!=u.data("node")&&(c-=parseFloat(a.eq(f)[0].style.width));FLBuilder._colResizeData={handle:i,feedbackLeft:i.find(".fl-block-col-resize-feedback-left"),feedbackRight:i.find(".fl-block-col-resize-feedback-right"),direction:o,groupWidth:n.outerWidth(),col:d,colWidth:parseFloat(d[0].style.width)/100,sibling:u,offset:l.position.left,availWidth:c},FLBuilder._colResizing=!0,e("body").addClass("fl-builder-col-resizing"),FLBuilder._closePanel(),FLBuilder._destroyOverlayEvents(),FLBuilder.triggerHook("col-resize-start")},_colDragResize:function(e,t){var l=FLBuilder._colResizeData,i=(l.offset-t.position.left)/l.groupWidth,o="e"==l.direction?100*(l.colWidth-i):100*(l.colWidth+i),s=Math.round(100*o)/100,r=l.availWidth-o,n=Math.round(100*r)/100,a=8,d=Math.round(100*(l.availWidth-a))/100;s<a?(s=a,n=d):n<a&&(s=d,n=a),"e"==l.direction?(l.feedbackLeft.html(s.toFixed(1)+"%").show(),l.feedbackRight.html(n.toFixed(1)+"%").show()):(l.feedbackLeft.html(n.toFixed(1)+"%").show(),l.feedbackRight.html(s.toFixed(1)+"%").show()),l.col.css("width",s+"%"),l.sibling.css("width",n+"%"),FLBuilder.triggerHook("col-resize-drag")},_colDragResizeStop:function(t,l){var i=FLBuilder._colResizeData,o=FLBuilder._colResizeData.handle.closest(".fl-block-overlay");FLBuilder._colResizeData.feedbackLeft.hide(),FLBuilder._colResizeData.feedbackRight.hide(),FLBuilder.ajax({action:"resize_cols",col_id:i.col.data("node"),col_width:parseFloat(i.col[0].style.width),sibling_id:i.sibling.data("node"),sibling_width:parseFloat(i.sibling[0].style.width)}),FLBuilder._buildOverlayOverflowMenu(o),FLBuilder._colResizeData=null,e("body").removeClass("fl-builder-col-resizing"),FLBuilder._bindOverlayEvents(),setTimeout(function(){FLBuilder._colResizing=!1},50),FLBuilder.triggerHook("col-resize-stop")},_resetColumnWidthsClicked:function(t){var l=e(this).parents(".fl-col-group").last(),i=[l.data("node")],o=l.find(".fl-col-group"),s=0;for(FLBuilder._resetColumnWidths(l);s<o.length;s++)FLBuilder._resetColumnWidths(o.eq(s)),i.push(o.eq(s).data("node"));FLBuilder.ajax({action:"reset_col_widths",group_id:i}),FLBuilder.triggerHook("col-reset-widths"),FLBuilder._closeAllSubmenus(),t.stopPropagation()},_resetColumnWidths:function(e){var t=e.find(" > .fl-col:visible"),l=0;l=6===t.length?16.65:7===t.length?14.28:Math.round(100/t.length*100)/100,t.css("width",l+"%")},_moduleMouseenter:function(){var t=e(this),l=t.attr("data-name"),i=t.hasClass("fl-node-global"),o=t.parents(".fl-node-global").length>0,s=t.parents(".fl-col-group").last(),r=s.hasClass("fl-col-group-has-child-loading"),n=t.closest(".fl-col-group").find("> .fl-col").length,a=t.closest(".fl-col"),d=0===a.index(),u=n===a.index()+1,c=a.parents(".fl-col"),f=c.length>0,h=f?c.closest(".fl-col-group").find("> .fl-col").length:0,p=!!f&&0===c.index(),g=!!f&&h===c.index()+1,_=a.find("> .fl-col-content").width(),m=wp.template("fl-module-overlay"),b=null;FLBuilder._removeColOverlays(),FLBuilder._removeModuleOverlays(),i&&o&&"row"!=FLBuilderConfig.userTemplateType||t.closest(".fl-builder-node-loading").length||(t.hasClass("fl-block-overlay-active")||(b=FLBuilder._appendOverlay(t,m({global:i,moduleName:l,groupLoading:r,numCols:n,colFirst:d,colLast:u,hasParentCol:f,numParentCols:h,parentFirst:p,parentLast:g,contentWidth:_})),FLBuilder._buildOverlayOverflowMenu(b),FLBuilder._initColDragResizing()),e("body").addClass("fl-block-overlay-muted"))},_moduleMouseleave:function(t){var l=(e(this),e(t.toElement)||e(t.relatedTarget)),i=l.is("#tiptip_holder"),o=l.closest("#tiptip_holder").length>0;i||o||(FLBuilder._removeModuleOverlays(),FLBuilder._removeColHighlightGuides())},_removeModuleOverlays:function(){var t=e(".fl-module");t.removeClass("fl-block-overlay-active"),t.find(".fl-module-overlay").remove(),e("body").removeClass("fl-block-overlay-muted")},_moduleDragHelper:function(t,l){return e('<div class="fl-builder-block-drag-helper">'+l.attr("data-name")+"</div>")},_moduleDragStart:function(t,l){e(l.item).data("original-position",l.item.index()),FLBuilder._blockDragStart(t,l)},_moduleDragStop:function(t,l){FLBuilder._blockDragStop(t,l);var i=l.item,o=i.parent(),s=null,r=0,n=0;if(o.hasClass("fl-builder-modules")||o.hasClass("fl-builder-widgets"))return void i.remove();
3
- if(i.hasClass("fl-builder-block")){if(o.hasClass("fl-sortable-disabled"))return i.remove(),void FLBuilder._showPanel();o.hasClass("fl-row-drop-target")?(o=i.closest(".fl-builder-content"),n=0,s=i.closest(".fl-row"),r=o.find(".fl-row").index(s)):o.hasClass("fl-col-group-drop-target")?(o=i.closest(".fl-row-content"),n=o.closest(".fl-row").attr("data-node"),s=i.closest(".fl-col-group"),r=o.find(" > .fl-col-group").index(s)):o.hasClass("fl-col-drop-target")?(o=i.closest(".fl-col-group"),n=o.attr("data-node"),s=i.closest(".fl-col"),r=o.find(" > .fl-col").index(s)):(r=o.find("> .fl-module, .fl-col-group, .fl-builder-block").index(i),n=i.closest(".fl-col").attr("data-node")),i.closest(".fl-drop-target-last").length&&(r+=1),FLBuilder._addModule(o,n,i.attr("data-type"),r,i.attr("data-widget"),i.attr("data-alias")),i.remove()}else{if(o.hasClass("fl-sortable-disabled"))return e(t.target).append(l.item),e(t.target).children().eq(l.item.data("original-position")).before(l.item),void FLBuilder._highlightEmptyCols();o.hasClass("fl-row-drop-target")?(s=i.closest(".fl-row"),r=i.closest(".fl-builder-content").children(".fl-row").index(s),r=i.closest(".fl-drop-target-last").length?r+1:r,FLBuilder._addModuleAfterNodeRender=i,FLBuilder._addRow("1-col",r),i.remove()):o.hasClass("fl-col-group-drop-target")?(s=i.closest(".fl-col-group"),r=i.closest(".fl-row-content ").find(" > .fl-col-group").index(s),r=i.closest(".fl-drop-target-last").length?r+1:r,FLBuilder._addModuleAfterNodeRender=i,FLBuilder._addColGroup(i.closest(".fl-row").attr("data-node"),"1-col",r),i.remove()):o.hasClass("fl-col-drop-target")?(s=i.closest(".fl-col"),r=i.closest(".fl-col-drop-target-last").length?"after":"before",FLBuilder._addModuleAfterNodeRender={module:i,colId:s.data("node"),position:r},FLBuilder._addCols(s,r,"1-col",i.closest(".fl-col-group-nested").length>0),i.remove()):FLBuilder._reorderModule(i)}FLBuilder._resizeLayout()},_reorderModule:function(e){var t=e.closest(".fl-col").attr("data-node"),l=e.attr("data-parent"),i=e.attr("data-node"),o=e.index();t==l?FLBuilder._reorderNode(i,o):(e.attr("data-parent",t),FLBuilder._moveNode(t,i,o))},_deleteModuleClicked:function(t){var l=e(this).closest(".fl-module"),i=confirm(FLBuilderStrings.deleteModuleMessage);i&&(FLBuilder._deleteModule(l),FLBuilder._removeAllOverlays()),t.stopPropagation()},_deleteModule:function(e){var t=e.closest(".fl-row");FLBuilder.ajax({action:"delete_node",node_id:e.attr("data-node")}),e.empty(),e.remove(),t.removeClass("fl-block-overlay-muted"),FLBuilder._highlightEmptyCols(),FLBuilder._removeAllOverlays()},_moduleCopyClicked:function(t){var l=e(this).closest(".fl-module");nodeId=l.attr("data-node"),position=l.index()+1,clone=l.clone(),clone.addClass("fl-builder-node-clone"),clone.attr("data-node",nodeId+"-clone"),clone.find(".fl-block-overlay").remove(),l.after(clone),FLBuilder._showNodeLoading(nodeId+"-clone"),FLBuilder._newModuleParent=l.parent(),FLBuilder._newModulePosition=position,FLBuilder.ajax({action:"copy_module",node_id:nodeId},FLBuilder._moduleCopyComplete),t.stopPropagation()},_moduleCopyComplete:function(e){var t=JSON.parse(e);t.nodeParent=FLBuilder._newModuleParent,t.nodePosition=FLBuilder._newModulePosition,FLBuilder._renderLayout(t,function(){t.nodeParent.find(".fl-builder-node-loading").eq(0).remove()})},_moduleSettingsClicked:function(t){var l=e(this),i=l.closest(".fl-module").attr("data-node"),o=l.closest(".fl-col").attr("data-node"),s=l.closest(".fl-module").attr("data-type"),r=l.closest(".fl-block-overlay-global").length>0;t.stopPropagation(),FLBuilder._colResizing||r&&!FLBuilderConfig.userCanEditGlobalTemplates||FLBuilder._showModuleSettings(i,o,s)},_showModuleSettings:function(e,t,l){FLBuilder._closePanel(),FLBuilder._showLightbox(),FLBuilder.ajax({action:"render_module_settings",node_id:e,type:l,parent_id:t},FLBuilder._moduleSettingsLoaded)},_moduleSettingsLoaded:function(t){var l=JSON.parse(t),i=e("<div>"+l.settings+"</div>"),o=i.find("link.fl-builder-settings-css"),s=i.find("script.fl-builder-settings-js"),r=i.find(".fl-builder-settings"),n=r.attr("data-type"),a=null,d=null,u=null;e.inArray(n,FLBuilder._loadedModuleAssets)>-1?(o.remove(),s.remove()):(e("head").append(o),e("head").append(s),FLBuilder._loadedModuleAssets.push(n)),FLBuilder._setSettingsFormContent(i),"undefined"!=typeof l.layout&&(a=l.layout,a.nodeParent=FLBuilder._newModuleParent,a.nodePosition=FLBuilder._newModulePosition),"undefined"!=typeof l.state&&(d=l.state),FLBuilder.preview=new FLBuilderPreview({type:"module",layout:a,state:d}),u=FLBuilder._moduleHelpers[n],"undefined"!=typeof u&&(FLBuilder._initSettingsValidation(u.rules),u.init())},_saveModuleClicked:function(){var t=e(this).closest(".fl-builder-settings"),l=t.attr("data-type"),i=(t.attr("data-node"),FLBuilder._moduleHelpers[l]),o=!0;"undefined"!=typeof i&&(t.find("label.error").remove(),t.validate().hideErrors(),o=t.validate().form(),o&&(o=i.submit())),o?(FLBuilder._saveSettings(),FLBuilder._lightbox.close()):FLBuilder._toggleSettingsTabErrors()},_addModule:function(e,t,l,i,o,s){FLBuilder._showNodeLoadingPlaceholder(e,i),e.hasClass("fl-col-group")?(FLBuilder._newModuleParent=null,FLBuilder._newModulePosition=0):(FLBuilder._newModuleParent=e,FLBuilder._newModulePosition=i),FLBuilder.ajax({action:"render_new_module",parent_id:t,type:l,position:i,node_preview:1,widget:"undefined"==typeof o?"":o,alias:"undefined"==typeof s?"":s},FLBuilder._addModuleComplete)},_addModuleComplete:function(t){FLBuilder._showLightbox(),FLBuilder._moduleSettingsLoaded(t),e(".fl-builder-module-settings").data("new-module","1")},registerModuleHelper:function(t,l){var i={rules:{},init:function(){},submit:function(){return!0},preview:function(){}};FLBuilder._moduleHelpers[t]=e.extend({},i,l)},_registerModuleHelper:function(e,t){FLBuilder.registerModuleHelper(e,t)},_showNodeTemplateSettings:function(t){var l=e(".fl-builder-settings-lightbox .fl-builder-settings");FLBuilder._saveSettings(),FLBuilder._showLightbox(),FLBuilder.ajax({action:"render_node_template_settings",node_id:l.attr("data-node")},FLBuilder._nodeTemplateSettingsLoaded)},_nodeTemplateSettingsLoaded:function(t){var l=JSON.parse(t);FLBuilder._showLightbox(!1),FLBuilder._setSettingsFormContent(l.html),FLBuilder._initSettingsValidation({name:{required:!0}}),FLBuilderConfig.userCanEditGlobalTemplates||e("#fl-field-global").hide()},_saveNodeTemplate:function(){var t=e(".fl-builder-settings-lightbox .fl-builder-settings"),l=t.validate().form();l&&(FLBuilder.showAjaxLoader(),FLBuilder.ajax({action:"save_node_template",node_id:t.attr("data-node"),settings:FLBuilder._getSettings(t)},FLBuilder._saveNodeTemplateComplete),FLBuilder._lightbox.close())},_saveNodeTemplateComplete:function(t){var l=JSON.parse(t),i=e(".fl-builder-saved-"+l.type+"s"),o=i.find(".fl-builder-block"),s=null,r="",n=l.name.toLowerCase(),a=0,d=wp.template("fl-node-template-block");if("row"==l.type?FLBuilder.alert(FLBuilderStrings.rowTemplateSaved):"module"==l.type&&FLBuilder.alert(FLBuilderStrings.moduleTemplateSaved),l.layout&&FLBuilder._renderLayout(l.layout),0===o.length)i.append(d(l));else for(;a<o.length;a++){if(s=o.eq(a),r=s.text().toLowerCase().trim(),0===a&&n<r){i.prepend(d(l));break}if(n<r){s.before(d(l));break}if(o.length-1===a){i.append(d(l));break}}i.find(".fl-builder-block-no-node-templates").remove()},_nodeTemplateDragStop:function(t,l){FLBuilder._blockDragStop(t,l);var i=l.item,o=i.parent(),s=null,r=0,n=null,a="",d=null;if(i.hasClass("fl-builder-block-saved-row")||i.hasClass("fl-builder-block-row-template"))n=i.closest(".fl-row"),r=n.length?e(FLBuilder._contentClass+" .fl-row").index(n):0,r=o.hasClass("fl-drop-target-last")?r+1:r,s=null,a="render_new_row",d=FLBuilder._addRowComplete,FLBuilder._newRowPosition=r,FLBuilder._showNodeLoadingPlaceholder(e(FLBuilder._contentClass),r);else if(i.hasClass("fl-builder-block-saved-module")||i.hasClass("fl-builder-block-module-template")){if(a="render_new_module",d=FLBuilder._addModuleComplete,o.hasClass("fl-sortable-disabled"))return i.remove(),void FLBuilder._showPanel();o.hasClass("fl-row-drop-target")?(o=i.closest(".fl-builder-content"),s=0,r=o.find(".fl-row").index(i.closest(".fl-row"))):o.hasClass("fl-col-group-drop-target")?(o=i.closest(".fl-row-content"),s=o.closest(".fl-row").attr("data-node"),r=o.find(" > .fl-col-group").index(i.closest(".fl-col-group"))):o.hasClass("fl-col-drop-target")?(o=i.closest(".fl-col-group"),r=o.children(".fl-col").index(i.closest(".fl-col")),s=o.attr("data-node")):(r=o.children(".fl-module, .fl-builder-block").index(i),s=i.closest(".fl-col").attr("data-node")),i.closest(".fl-drop-target-last").length&&(r+=1),o.hasClass("fl-col-group")?(FLBuilder._newModuleParent=null,FLBuilder._newModulePosition=0):(FLBuilder._newModuleParent=o,FLBuilder._newModulePosition=r),FLBuilder._showNodeLoadingPlaceholder(o,r)}FLBuilder.ajax({action:a,template_id:i.attr("data-id"),template_type:i.attr("data-type"),parent_id:s,position:r},d),i.remove()},_editNodeTemplateClicked:function(t){t.preventDefault(),t.stopPropagation(),window.open(e(this).attr("href"))},_deleteNodeTemplateClicked:function(t){var l=e(t.target),i=l.closest(".fl-builder-blocks-section"),o=i.find(".fl-builder-blocks-section-content"),s=o.find(".fl-builder-block"),r=l.closest(".fl-builder-block"),n=r.hasClass("fl-builder-block-global"),a=n?FLBuilder._updateLayout:void 0,d=n?FLBuilderStrings.deleteGlobalTemplate:FLBuilderStrings.deleteTemplate;confirm(d)&&(r.remove(),1===s.length&&(r.hasClass("fl-builder-block-saved-row")?o.append('<span class="fl-builder-block-no-node-templates">'+FLBuilderStrings.noSavedRows+"</span>"):o.append('<span class="fl-builder-block-no-node-templates">'+FLBuilderStrings.noSavedModules+"</span>")),r.hasClass("fl-builder-block-global")&&FLBuilder.showAjaxLoader(),FLBuilder.ajax({action:"delete_node_template",template_id:r.attr("data-id")},a))},_initSettingsForms:function(){FLBuilder._initColorPickers(),FLBuilder._initSelectFields(),FLBuilder._initMultipleFields(),FLBuilder._initAutoSuggestFields(),FLBuilder._initLinkFields(),FLBuilder._initFontFields(),FLBuilder._initOrderingFields(),FLBuilder.triggerHook("settings-form-init")},_setSettingsFormContent:function(e){FLBuilder._setLightboxContent(e),FLBuilder._initSettingsForms()},_settingsTabClicked:function(t){var l=e(this),i=l.closest(".fl-builder-settings"),o=l.attr("href").split("#").pop();i.find(".fl-builder-settings-tab").removeClass("fl-active"),i.find("#"+o).addClass("fl-active"),i.find(".fl-builder-settings-tabs .fl-active").removeClass("fl-active"),e(this).addClass("fl-active"),t.preventDefault()},_settingsCancelClicked:function(t){var l=e(".fl-builder-lightbox[data-parent]"),i=e(".fl-builder-module-settings"),o=null,s=null,r=null,n=null;return l.length>0?void FLBuilder._closeNestedSettings():(i.length>0&&"undefined"!=typeof i.data("new-module")?(o=e(FLBuilder.preview.state.html),s=e(".fl-node-"+i.data("node")),r=s.closest(".fl-col"),n=o.find(".fl-node-"+r.data("node")),n.length>0?FLBuilder._deleteModule(s):FLBuilder._deleteCol(r)):FLBuilder.preview&&FLBuilder.preview.revert(),FLBuilder.preview=null,void FLLightbox.closeParent(this))},_initSettingsValidation:function(t,l){var i=e(".fl-builder-settings").last();i.validate({ignore:".fl-ignore-validation",rules:t,messages:l,errorPlacement:FLBuilder._settingsErrorPlacement})},_settingsErrorPlacement:function(e,t){e.appendTo(t.parent())},_toggleSettingsTabErrors:function(){for(var t=e(".fl-builder-settings:visible"),l=t.find(".fl-builder-settings-tab"),i=null,o=null,s=0;s<l.length;s++)i=l.eq(s),o=i.find("label.error"),tabLink=t.find(".fl-builder-settings-tabs a[href*="+i.attr("id")+"]"),tabLink.find(".fl-error-icon").remove(),tabLink.removeClass("error"),o.length>0&&(tabLink.append('<span class="fl-error-icon"></span>'),tabLink.addClass("error"))},_getSettings:function(t){FLBuilder._updateEditorFields();var l=t.serializeArray(),i=0,o=0,s="",r="",n="",a=[],d=[],u={};for(i=0;i<l.length;i++)if(s=l[i].value.replace(/\r/gm,""),!(l[i].name.indexOf("flrich")>-1))if(l[i].name.indexOf("[")>-1){for(r=l[i].name.replace(/\[(.*)\]/,""),n=l[i].name.replace(r,""),a=[],d=n.match(/\[[^\]]*\]/g),o=0;o<d.length;o++)"[]"!=d[o]&&a.push(d[o].replace(/\[|\]/g,""));n.match(/\[\]\[[^\]]*\]\[[^\]]+\]/)?("undefined"==typeof u[r]&&(u[r]={}),"undefined"==typeof u[r][a[0]]&&(u[r][a[0]]={}),"undefined"==typeof u[r][a[0]][a[1]]&&(u[r][a[0]][a[1]]={}),u[r][a[0]][a[1]]=s):n.match(/\[\]\[[^\]]*\]\[\]/)?("undefined"==typeof u[r]&&(u[r]={}),"undefined"==typeof u[r][a[0]]&&(u[r][a[0]]=[]),u[r][a[0]].push(s)):n.match(/\[\]\[[^\]]*\]/)?("undefined"==typeof u[r]&&(u[r]={}),u[r][a[0]]=s):n.match(/\[\]/)&&("undefined"==typeof u[r]&&(u[r]=[]),u[r].push(s))}else u[l[i].name]=s;for(n in u)if("undefined"!=typeof u["as_values_"+n]){u[n]=e.grep(u["as_values_"+n].split(","),function(e){return""!==e}).join(",");try{delete u["as_values_"+n]}catch(c){}}return u},_saveSettings:function(){var t=e(".fl-builder-settings-lightbox .fl-builder-settings"),l=t.attr("data-node"),i=FLBuilder._getSettings(t);FLBuilder._showNodeLoading(l),FLBuilder.ajax({action:"save_settings",node_id:l,settings:i},FLBuilder._saveSettingsComplete),FLBuilder._lightbox.close()},_saveSettingsComplete:function(e){FLBuilder._renderLayout(e,function(){FLBuilder.preview&&(FLBuilder.preview.clear(),FLBuilder.preview=null)})},_openNestedSettings:function(t){t=e.extend({className:"fl-builder-lightbox",destroyOnClose:!0},t);var l=e(".fl-lightbox-wrap:visible"),i=l.find(".fl-lightbox"),o=new FLLightbox(t),s=o._node,r=s.find(".fl-lightbox");return l.hide(),s.attr("data-parent",l.attr("data-instance-id")),o.open('<div class="fl-builder-lightbox-loading"></div>'),o.draggable({handle:".fl-lightbox-header"}),r.css({left:i.css("left"),top:i.css("top")}),o},_closeNestedSettings:function(){var t=e(".fl-builder-lightbox[data-parent]:visible"),l=t.find(".fl-lightbox"),i=t.attr("data-instance-id"),o=FLLightbox._instances[i],s=t.attr("data-parent"),r=e('[data-instance-id="'+s+'"]'),n=r.find(".fl-lightbox"),a=r.find("form");l.css("height","auto"),l.find(".fl-lightbox-content").html('<div class="fl-builder-lightbox-loading"></div>'),o.on("close",function(){r.show(),r.find("label.error").remove(),a.validate().hideErrors(),FLBuilder._toggleSettingsTabErrors(),n.css({left:l.css("left"),top:l.css("top")})}),setTimeout(function(){o.close()},250)},_showHelpTooltip:function(){e(this).siblings(".fl-help-tooltip-text").fadeIn()},_hideHelpTooltip:function(){e(this).siblings(".fl-help-tooltip-text").fadeOut()},_initAutoSuggestFields:function(){e(".fl-builder-settings:visible .fl-suggest-field").each(FLBuilder._initAutoSuggestField)},_initAutoSuggestField:function(){var t=e(this);t.autoSuggest(FLBuilder._ajaxUrl({fl_action:"fl_builder_autosuggest",fl_as_action:t.data("action"),fl_as_action_data:t.data("action-data"),_wpnonce:FLBuilderConfig.ajaxNonce}),e.extend({},{asHtmlID:t.attr("name"),selectedItemProp:"name",searchObjProps:"name",minChars:3,keyDelay:1e3,fadeOut:!1,usePlaceholder:!0,emptyText:FLBuilderStrings.noResultsFound,showResultListWhenNoMatch:!0,preFill:t.data("value"),queryParam:"fl_as_query",afterSelectionAdd:FLBuilder._updateAutoSuggestField,afterSelectionRemove:FLBuilder._updateAutoSuggestField,selectionLimit:t.data("limit")},t.data("args")))},_updateAutoSuggestField:function(t,l,i){e(this).siblings(".as-values").val(i.join(",")).trigger("change")},_initMultipleFields:function(){for(var t=e(".fl-builder-settings:visible .fl-builder-field-multiples"),l=null,i=null,o=0,s=FLBuilderConfig.isRtl?{left:10}:{right:10};o<t.length;o++)l=t.eq(o),i=l.find(".fl-builder-field-multiple"),1===i.length?i.eq(0).find(".fl-builder-field-actions").addClass("fl-builder-field-actions-single"):i.find(".fl-builder-field-actions").removeClass("fl-builder-field-actions-single");e(".fl-builder-field-multiples").sortable({items:".fl-builder-field-multiple",cursor:"move",cursorAt:s,distance:5,opacity:.5,helper:FLBuilder._fieldDragHelper,placeholder:"fl-builder-field-dd-zone",stop:FLBuilder._fieldDragStop,tolerance:"pointer"})},_addFieldClicked:function(){var t=e(this),l=t.attr("data-field"),i=t.closest("tr").siblings("tr[data-field="+l+"]").last(),o=i.clone(),s=parseInt(i.find("label span.fl-builder-field-index").html(),10)+1;o.find("th label span.fl-builder-field-index").html(s),o.find(".fl-form-field-preview-text").html(""),o.find("input, textarea, select").val(""),i.after(o),FLBuilder._initMultipleFields()},_copyFieldClicked:function(){var t=e(this),l=t.closest("tr"),i=l.clone(),o=parseInt(l.find("label span.fl-builder-field-index").html(),10)+1;i.find("th label span.fl-builder-field-index").html(o),l.after(i),FLBuilder._renumberFields(l.parent()),FLBuilder._initMultipleFields(),FLBuilder.preview.delayPreview()},_deleteFieldClicked:function(){var t=e(this).closest("tr"),l=t.parent(),i=confirm(FLBuilderStrings.deleteFieldMessage);i&&(t.remove(),FLBuilder._renumberFields(l),FLBuilder._initMultipleFields(),FLBuilder.preview.delayPreview())},_renumberFields:function(e){for(var t=e.find(".fl-builder-field-multiple"),l=0;l<t.length;l++)t.eq(l).find("th label span.fl-builder-field-index").html(l+1)},_fieldDragHelper:function(){return e('<div class="fl-builder-field-dd-helper"></div>')},_fieldDragStop:function(e,t){FLBuilder._renumberFields(t.item.parent()),FLBuilder.preview.delayPreview()},_initSelectFields:function(){e(".fl-builder-settings:visible").find(".fl-builder-settings-fields select").trigger("change")},_settingsSelectChanged:function(){var t=e(this),l=t.attr("data-toggle"),i=t.attr("data-hide"),o=t.attr("data-trigger"),s=t.val(),r=0;if("undefined"!=typeof l){l=JSON.parse(l);for(r in l)FLBuilder._settingsSelectToggle(l[r].fields,"hide","#fl-field-"),FLBuilder._settingsSelectToggle(l[r].sections,"hide","#fl-builder-settings-section-"),FLBuilder._settingsSelectToggle(l[r].tabs,"hide","a[href*=fl-builder-settings-tab-","]");"undefined"!=typeof l[s]&&(FLBuilder._settingsSelectToggle(l[s].fields,"show","#fl-field-"),FLBuilder._settingsSelectToggle(l[s].sections,"show","#fl-builder-settings-section-"),FLBuilder._settingsSelectToggle(l[s].tabs,"show","a[href*=fl-builder-settings-tab-","]"))}if("undefined"!=typeof i&&(i=JSON.parse(i),"undefined"!=typeof i[s]&&(FLBuilder._settingsSelectToggle(i[s].fields,"hide","#fl-field-"),FLBuilder._settingsSelectToggle(i[s].sections,"hide","#fl-builder-settings-section-"),FLBuilder._settingsSelectToggle(i[s].tabs,"hide","a[href*=fl-builder-settings-tab-","]"))),"undefined"!=typeof o&&(o=JSON.parse(o),"undefined"!=typeof o[s]&&"undefined"!=typeof o[s].fields))for(r=0;r<o[s].fields.length;r++)e("#fl-field-"+o[s].fields[r]).find("select").trigger("change")},_settingsSelectToggle:function(t,l,i,o){var s=0;if(o="undefined"==typeof o?"":o,"undefined"!=typeof t)for(;s<t.length;s++)e(".fl-builder-settings:visible").find(i+t[s]+o)[l](),e(i+t[s]+o).parent().find('.fl-field[data-type="code"]').each(function(){e(this).data("editor").resize()})},_initColorPickers:function(){var t=FLBuilderConfig.colorPresets?FLBuilderConfig.colorPresets:[];FLBuilder.colorPicker=new FLBuilderColorPicker({mode:"hsv",elements:".fl-color-picker .fl-color-picker-value",presets:t,labels:{colorPresets:FLBuilderStrings.colorPresets,colorPicker:FLBuilderStrings.colorPicker,placeholder:FLBuilderStrings.placeholder,removePresetConfirm:FLBuilderStrings.removePresetConfirm,noneColorSelected:FLBuilderStrings.noneColorSelected,alreadySaved:FLBuilderStrings.alreadySaved,noPresets:FLBuilderStrings.noPresets,presetAdded:FLBuilderStrings.presetAdded}}),e(FLBuilder.colorPicker).on("presetRemoved presetAdded",function(e,t){FLBuilder.ajax({action:"save_color_presets",presets:t.presets})})},_initSinglePhotoSelector:function(){null===FLBuilder._singlePhotoSelector&&(FLBuilder._singlePhotoSelector=wp.media({title:FLBuilderStrings.selectPhoto,button:{text:FLBuilderStrings.selectPhoto},library:{type:"image"},multiple:!1}))},_selectSinglePhoto:function(){FLBuilder._initSinglePhotoSelector(),FLBuilder._singlePhotoSelector.once("open",e.proxy(FLBuilder._singlePhotoOpened,this)),FLBuilder._singlePhotoSelector.once("select",e.proxy(FLBuilder._singlePhotoSelected,this)),FLBuilder._singlePhotoSelector.open()},_singlePhotoOpened:function(){var t=FLBuilder._singlePhotoSelector.state().get("selection"),l=e(this).closest(".fl-photo-field"),i=l.find("input[type=hidden]"),o=i.val(),s=null;e(this).hasClass("fl-photo-replace")?(t.reset(),l.addClass("fl-photo-empty"),i.val("")):""!==o?(s=wp.media.attachment(o),s.fetch(),t.add(s?[s]:[])):t.reset()},_singlePhotoSelected:function(){var t=FLBuilder._singlePhotoSelector.state().get("selection").first().toJSON(),l=e(this).closest(".fl-photo-field"),i=l.find("input[type=hidden]"),o=l.find(".fl-photo-preview img"),s=l.find("select");i.val(t.id),o.attr("src",FLBuilder._getPhotoSrc(t)),l.removeClass("fl-photo-empty"),l.find("label.error").remove(),s.show(),s.html(FLBuilder._getPhotoSizeOptions(t)),s.trigger("change")},_singlePhotoRemoved:function(){FLBuilder._initSinglePhotoSelector();var t=FLBuilder._singlePhotoSelector.state(),l="undefined"!=typeof t?t.get("selection"):null,i=e(this).closest(".fl-photo-field"),o=i.find("input[type=hidden]"),s=i.find("select");l&&l.reset(),i.addClass("fl-photo-empty"),o.val(""),s.html('<option value="" selected></option>'),s.trigger("change")},_getPhotoSrc:function(e){return"undefined"==typeof e.sizes?e.url:"undefined"!=typeof e.sizes.thumbnail?e.sizes.thumbnail.url:e.sizes.full.url},_getPhotoSizeOptions:function(e){var t="",l=null,i=null,o="",s={full:FLBuilderStrings.fullSize,large:FLBuilderStrings.large,medium:FLBuilderStrings.medium,thumbnail:FLBuilderStrings.thumbnail};if("undefined"==typeof e.sizes)t+='<option value="'+e.url+'">'+FLBuilderStrings.fullSize+"</option>";else for(l in e.sizes)o="undefined"!=typeof s[l]?s[l]+" - ":"undefined"!=typeof FLBuilderConfig.customImageSizeTitles[l]?FLBuilderConfig.customImageSizeTitles[l]+" - ":"",i="full"==l?' selected="selected"':"",t+='<option value="'+e.sizes[l].url+'"'+i+">"+o+e.sizes[l].width+" x "+e.sizes[l].height+"</option>";return t},_selectMultiplePhotos:function(){var t=e(this).closest(".fl-multiple-photos-field"),l=t.find("input[type=hidden]"),i=l.val(),o=""===i?"":JSON.parse(i),s=wp.media.gallery.defaults.id,r='[gallery ids="-1"]',n=null,a=null,d=null,u=null,c=[];if("object"==typeof o){for(u in o)c.push(o[u]);r='[gallery ids="'+c.join()+'"]'}n=wp.shortcode.next("gallery",r).shortcode,_.isUndefined(n.get("id"))&&!_.isUndefined(s)&&n.set("id",s),a=wp.media.gallery.attachments(n),d=new wp.media.model.Selection(a.models,{props:a.props.toJSON(),multiple:!0}),d.gallery=a.gallery,d.more().done(function(){d.length||FLBuilder._multiplePhotoSelector.setState("gallery-library"),d.props.set({query:!1}),d.unmirror(),d.props.unset("orderby")}),FLBuilder._multiplePhotoSelector&&FLBuilder._multiplePhotoSelector.dispose(),FLBuilder._multiplePhotoSelector=wp.media({frame:"post",state:e(this).hasClass("fl-multiple-photos-edit")?"gallery-edit":"gallery-library",title:wp.media.view.l10n.editGalleryTitle,editing:!0,multiple:!0,selection:d}).open(),e(FLBuilder._multiplePhotoSelector.views.view.el).addClass("fl-multiple-photos-lightbox"),FLBuilder._multiplePhotoSelector.once("update",e.proxy(FLBuilder._multiplePhotosSelected,this))},_multiplePhotosSelected:function(t){for(var l=e(this).closest(".fl-multiple-photos-field"),i=l.find("input[type=hidden]"),o=l.find(".fl-multiple-photos-count"),s=[],r=0;r<t.models.length;r++)s.push(t.models[r].id);1==s.length?o.html("1 "+FLBuilderStrings.photoSelected):o.html(s.length+" "+FLBuilderStrings.photosSelected),l.removeClass("fl-multiple-photos-empty"),l.find("label.error").remove(),i.val(JSON.stringify(s)).trigger("change")},_selectSingleVideo:function(){null===FLBuilder._singleVideoSelector&&(FLBuilder._singleVideoSelector=wp.media({title:FLBuilderStrings.selectVideo,button:{text:FLBuilderStrings.selectVideo},library:{type:"video"},multiple:!1})),FLBuilder._singleVideoSelector.once("select",e.proxy(FLBuilder._singleVideoSelected,this)),FLBuilder._singleVideoSelector.open()},_singleVideoSelected:function(){var t=FLBuilder._singleVideoSelector.state().get("selection").first().toJSON(),l=e(this).closest(".fl-video-field"),i=l.find(".fl-video-preview-img img"),o=l.find(".fl-video-preview-filename"),s=l.find("input[type=hidden]");i.attr("src",t.icon),o.html(t.filename),l.removeClass("fl-video-empty"),l.find("label.error").remove(),s.val(t.id).trigger("change")},_selectMultipleAudios:function(){var t=e(this).closest(".fl-multiple-audios-field"),l=t.find("input[type=hidden]"),i=l.val(),o=""==i?'[playlist ids="-1"]':'[playlist ids="'+JSON.parse(i).join()+'"]',s=wp.shortcode.next("playlist",o).shortcode,r=wp.media.playlist.defaults.id,n=null,a=null;_.isUndefined(s.get("id"))&&!_.isUndefined(r)&&s.set("id",r),n=wp.media.playlist.attachments(s),a=new wp.media.model.Selection(n.models,{props:n.props.toJSON(),multiple:!0}),a.playlist=n.playlist,a.more().done(function(){a.props.set({query:!1}),a.unmirror(),a.props.unset("orderby")}),FLBuilder._multipleAudiosSelector&&FLBuilder._multipleAudiosSelector.dispose(),FLBuilder._multipleAudiosSelector=wp.media({frame:"post",state:e(this).hasClass("fl-multiple-audios-edit")?"playlist-edit":"playlist-library",title:wp.media.view.l10n.editPlaylistTitle,editing:!0,multiple:!0,selection:a}).open(),FLBuilder._multipleAudiosSelector.content.get("view").sidebar.unset("playlist"),FLBuilder._multipleAudiosSelector.on("content:render:browse",function(e){e&&e.sidebar.on("ready",function(){e.sidebar.unset("playlist")})}),FLBuilder._multipleAudiosSelector.once("update",e.proxy(FLBuilder._multipleAudiosSelected,this))},_multipleAudiosSelected:function(t){for(var l=e(this).closest(".fl-multiple-audios-field"),i=l.find(".fl-multiple-audios-count"),o=l.find("input[type=hidden]"),s=[],r=0;r<t.models.length;r++)s.push(t.models[r].id);1==s.length?i.html("1 "+FLBuilderStrings.audioSelected):i.html(s.length+" "+FLBuilderStrings.audiosSelected),o.val(JSON.stringify(s)).trigger("change"),l.removeClass("fl-multiple-audios-empty"),l.find("label.error").remove()},_selectIcon:function(){var e=this;FLIconSelector.open(function(t){FLBuilder._iconSelected.apply(e,[t])})},_iconSelected:function(t){var l=e(this).closest(".fl-icon-field"),i=l.find("input[type=hidden]"),o=l.find("i"),s=o.attr("data-icon");i.val(t).trigger("change"),o.removeClass(s),o.addClass(t),o.attr("data-icon",t),l.removeClass("fl-icon-empty"),l.find("label.error").remove()},_removeIcon:function(){var t=e(this).closest(".fl-icon-field"),l=t.find("input[type=hidden]"),i=t.find("i");l.val("").trigger("change"),i.removeClass(),i.attr("data-icon",""),t.addClass("fl-icon-empty")},_formFieldClicked:function(){var t=e(this),l=t.closest(".fl-builder-settings"),i=t.attr("data-type"),o=t.siblings("input").val(),s=FLBuilder._moduleHelpers[i],r=FLBuilder._openNestedSettings({className:"fl-builder-lightbox fl-form-field-settings"});t.attr("id","fl-"+r._node.attr("data-instance-id")),FLBuilder.ajax({action:"render_settings_form",node_id:l.attr("data-node"),node_settings:FLBuilder._getSettings(l),type:i,settings:o.replace(/&#39;/g,"'")},function(e){var t=JSON.parse(e);r._node.find(".fl-lightbox-content").html(t.html),r._node.find("form.fl-builder-settings").attr("data-type",i),FLBuilder._initSettingsForms(),"undefined"!=typeof s&&(FLBuilder._initSettingsValidation(s.rules),s.init())})},_saveFormFieldClicked:function(){var t=e(this).closest(".fl-builder-settings"),l=e(this).closest(".fl-lightbox-wrap").attr("data-instance-id"),i=t.attr("data-type"),o=FLBuilder._getSettings(t),s={},r=FLBuilder._moduleHelpers[i],n=e(".fl-builder-settings #fl-"+l),a=n.parent().attr("data-preview-text"),d=o[a],u=e('select[name="'+a+'"]'),c=document.createElement("div"),f=!0;return u.length>0&&(d=u.find('option[value="'+o[a]+'"]').text()),"undefined"!=typeof r&&(t.find("label.error").remove(),t.validate().hideErrors(),f=t.validate().form(),f&&(f=r.submit())),f?("undefined"!=typeof a&&"undefined"!=typeof d&&(d.indexOf("fa fa-")>-1?d='<i class="'+d+'"></i>':d.length>35&&(c.innerHTML=d,d=(c.textContent||c.innerText||"").replace(/^(.{35}[^\s]*).*/,"$1")+"..."),n.siblings(".fl-form-field-preview-text").html(d)),s=n.siblings("input").val().replace(/&#39;/g,"'"),""!=s&&(o=e.extend(JSON.parse(s),o)),n.siblings("input").val(JSON.stringify(o)).trigger("change"),FLBuilder._closeNestedSettings(),!0):(FLBuilder._toggleSettingsTabErrors(),!1)},_layoutFieldClicked:function(){var t=e(this);t.siblings().removeClass("fl-layout-field-option-selected"),t.addClass("fl-layout-field-option-selected"),t.siblings("input").val(t.attr("data-value"))},_initLinkFields:function(){e(".fl-builder-settings:visible .fl-link-field").each(FLBuilder._initLinkField)},_initLinkField:function(){var t=e(this),l=t.find(".fl-link-field-search-input");l.autoSuggest(FLBuilder._ajaxUrl({fl_action:"fl_builder_autosuggest",fl_as_action:"fl_as_links",_wpnonce:FLBuilderConfig.ajaxNonce}),{asHtmlID:l.attr("name"),selectedItemProp:"name",searchObjProps:"name",minChars:3,keyDelay:1e3,fadeOut:!1,usePlaceholder:!0,emptyText:FLBuilderStrings.noResultsFound,showResultListWhenNoMatch:!0,queryParam:"fl_as_query",selectionLimit:1,afterSelectionAdd:FLBuilder._updateLinkField})},_updateLinkField:function(e,t,l){var i=e.closest(".fl-link-field"),o=i.find(".fl-link-field-search"),s=i.find(".fl-link-field-search-input"),r=i.find(".fl-link-field-input");r.val(t.value).trigger("keyup"),s.autoSuggest("remove",t.value),o.hide()},_linkFieldSelectClicked:function(){e(this).parent().find(".fl-link-field-search").show()},_linkFieldSelectCancelClicked:function(){e(this).parent().hide()},_initFontFields:function(){e(".fl-builder-settings:visible .fl-font-field").each(FLBuilder._initFontField)},_initFontField:function(){var t=e(this),l=t.find(".fl-font-field-font");l.on("change",function(){FLBuilder._getFontWeights(l)})},_getFontWeights:function(t){var l=t.next(".fl-font-field-weight"),i=t.val(),o={"default":"Default",regular:"Regular",100:"Thin 100",200:"Extra-Light 200",300:"Light 300",400:"Normal 400",500:"Medium 500",600:"Semi-Bold 600",700:"Bold 700",800:"Extra-Bold 800",900:"Ultra-Bold 900"},s={};l.html(""),s="undefined"!=typeof FLBuilderFontFamilies.system[i]?FLBuilderFontFamilies.system[i].weights:"undefined"!=typeof FLBuilderFontFamilies.google[i]?FLBuilderFontFamilies.google[i]:FLBuilderFontFamilies["default"][i],e.each(s,function(e,t){l.append('<option value="'+t+'">'+o[t]+"</option>")})},initEditorField:function(e){var t=tinyMCEPreInit.mceInit.flhiddeneditor;t.elements=e,tinyMCEPreInit.mceInit[e]=t},_updateEditorFields:function(){var t=e(".fl-builder-settings:visible textarea.wp-editor-area");t.each(FLBuilder._updateEditorField)},_updateEditorField:function(){var t=e(this),l=t.closest(".fl-editor-field"),i=(t.closest(".fl-builder-settings"),t.closest(".wp-editor-wrap")),o=t.attr("id"),s=l.attr("id"),r="undefined"!=typeof tinyMCE&&tinyMCE.get(o),n=t.siblings('textarea[name="'+s+'"]'),a=l.data("wpautop");0===n.length&&(n=e('<textarea name="'+s+'"></textarea>').hide(),t.after(n)),a?r&&i.hasClass("tmce-active")?n.val(r.getContent()):"undefined"!=typeof switchEditors?n.val(switchEditors.wpautop(t.val())):n.val(t.val()):(r&&i.hasClass("tmce-active")&&r.save(),n.val(t.val()))},_loopDataSourceChange:function(){var t=e(this).val();e(".fl-loop-data-source").hide(),e('.fl-loop-data-source[data-source="'+t+'"]').show()},_customQueryPostTypeChange:function(){var t=e(this).val();e(".fl-custom-query-filter").hide(),e(".fl-custom-query-"+t+"-filter").show()},_initOrderingFields:function(){e(".fl-builder-settings:visible .fl-ordering-field-options").each(FLBuilder._initOrderingField)},_initOrderingField:function(){e(this).sortable({items:".fl-ordering-field-option",containment:"parent",tolerance:"pointer",stop:FLBuilder._updateOrderingField})},_updateOrderingField:function(t){var l=e(t.target),i=l.siblings("input[type=hidden]"),o=[];l.find(".fl-ordering-field-option").each(function(){o.push(e(this).attr("data-key"))}),i.val(JSON.stringify(o)).trigger("change");
4
- },_textFieldAddValueSelectChange:function(){var t=e(this),l=e('input[name="'+t.data("target")+'"]'),i=l.val(),o=t.val(),s="";-1==i.indexOf(o)&&(s=(i.trim()+" "+o.trim()).trim(),l.val(s).trigger("change").trigger("keyup")),t.val("")},ajax:function(t,l){var i;for(i in t)"undefined"==typeof t[i]&&(t[i]=null);return t._wpnonce=FLBuilderConfig.ajaxNonce,t.post_id=FLBuilderConfig.postId,t.fl_builder=1,t.fl_action=t.action,"undefined"!=typeof t.settings&&(t.settings=FLBuilder._ajaxModSecFix(t.settings)),"undefined"!=typeof t.node_settings&&(t.node_settings=FLBuilder._ajaxModSecFix(t.node_settings)),t={fl_builder_data:t},e.post(FLBuilder._ajaxUrl(),t,function(e){FLBuilder._ajaxComplete(),"undefined"!=typeof l&&l.call(this,e)})},_ajaxComplete:function(){FLBuilder.hideAjaxLoader()},_ajaxUrl:function(e){var t=window.location.href.split("#").shift(),l=null;if("undefined"!=typeof e)for(l in e)t+=t.indexOf("?")>-1?"&":"?",t+=l+"="+e[l];return t},showAjaxLoader:function(){0===e(".fl-builder-lightbox-loading").length&&e(".fl-builder-loading").show()},hideAjaxLoader:function(){e(".fl-builder-loading").hide()},_showNodeLoading:function(t){var l=e('[data-node="'+t+'"]');l.addClass("fl-builder-node-loading")},_showNodeLoadingPlaceholder:function(t,l){var i=e('<div class="fl-builder-node-loading-placeholder"></div>');t.hasClass("fl-builder-content")?siblings=t.find(".fl-row"):t.hasClass("fl-row-content")?siblings=t.find(" > .fl-col-group"):t.hasClass("fl-col-group")?(t.addClass("fl-col-group-has-child-loading"),siblings=t.find(" > .fl-col")):siblings=t.find(" > .fl-col-group, > .fl-module"),0===siblings.length||siblings.length==l?t.append(i):siblings.eq(l).before(i)},_removeNodeLoadingPlaceholder:function(e){var t=e.prev(".fl-builder-node-loading-placeholder"),l=e.next(".fl-builder-node-loading-placeholder");t.length?t.remove():l.remove()},_ajaxModSecFix:function(e){var t;if(FLBuilderConfig.modSecFix&&"undefined"!=typeof btoa)if("string"==typeof e)e=btoa(e);else for(t in e)"string"==typeof e[t]?e[t]=btoa(e[t]):"object"==typeof e[t]&&(e[t]=FLBuilder._ajaxModSecFix(e[t]));return e},_showLightbox:function(e){e="undefined"==typeof e||e,FLBuilder._lightbox.open('<div class="fl-builder-lightbox-loading"></div>'),e?FLBuilder._lightbox.draggable({handle:".fl-lightbox-header"}):FLBuilder._lightbox.draggable(!1),FLBuilder._removeAllOverlays(),FLBuilder._initLightboxScrollbars()},_setLightboxContent:function(e){FLBuilder._lightbox.setContent(e)},_initLightboxScrollbars:function(){FLBuilder._initScrollbars(),FLBuilder._lightboxScrollbarTimeout=setTimeout(FLBuilder._initLightboxScrollbars,500)},_lightboxClosed:function(){FLBuilder.triggerHook("settings-lightbox-closed"),FLBuilder._lightbox.empty(),clearTimeout(FLBuilder._lightboxScrollbarTimeout)},_showActionsLightbox:function(e){var t=wp.template("fl-actions-lightbox");FLBuilder.triggerHook("actions-lightbox-settings",e),FLBuilder._actionsLightbox.open(t(e))},_resizeLightbox:function(){var t=e(this),l=t.hasClass("fa-expand")?"expand":"contract";FLBuilder._lightbox.renderResize(l),e(this).toggleClass("fa-expand").toggleClass("fa-compress")},alert:function(e){var t=new FLLightbox({className:"fl-builder-lightbox fl-builder-alert-lightbox",destroyOnClose:!0}),l=wp.template("fl-alert-lightbox");t.open(l({message:e}))},_alertClose:function(){FLLightbox.closeParent(this)},confirm:function(t){var l={message:"",ok:function(){},cancel:function(){},strings:{ok:FLBuilderStrings.ok,cancel:FLBuilderStrings.cancel}},i=e.extend({},l,"undefined"==typeof t?{}:t);lightbox=new FLLightbox({className:"fl-builder-lightbox fl-builder-confirm-lightbox fl-builder-alert-lightbox",destroyOnClose:!0}),template=wp.template("fl-confirm-lightbox"),lightbox.open(template(i)),lightbox._node.find(".fl-builder-confirm-ok").on("click",i.ok),lightbox._node.find(".fl-builder-confirm-cancel").on("click",i.cancel)},triggerHook:function(t,l){e("body").trigger("fl-builder."+t,l)},addHook:function(t,l){e("body").on("fl-builder."+t,l)},removeHook:function(t,l){e("body").off("fl-builder."+t,l)},log:function(e){"undefined"!=typeof window.console&&"undefined"!=typeof window.console.log&&console.log(e)},logError:function(e){var t=null;"undefined"!=typeof e&&("undefined"!=typeof e.stack?t=e.stack:"undefined"!=typeof e.message&&(t=e.message),t&&(FLBuilder.log("************************************************************************"),FLBuilder.log(FLBuilderStrings.errorMessage),FLBuilder.log(t),FLBuilder.log("************************************************************************")))},logGlobalError:function(e,t,l,i,o){FLBuilder.log("************************************************************************"),FLBuilder.log(FLBuilderStrings.errorMessage),FLBuilder.log(FLBuilderStrings.globalErrorMessage.replace("{message}",e).replace("{line}",l).replace("{file}",t)),"undefined"!=typeof o&&"undefined"!=typeof o.stack&&(FLBuilder.log(o.stack),FLBuilder.log("************************************************************************"))}},e(function(){FLBuilder._init()})}(jQuery),function(e){FLBuilderAJAXLayout=function(t,l){this._data=e.extend({},this._defaults,"string"==typeof t?JSON.parse(t):t),this._callback=l,this._post=FLBuilderConfig.postId,this._head=e("head").eq(0),this._body=e("body").eq(0),this._data.css&&(this._loader=e('<img src="'+this._data.css+'" />'),this._oldCss=e('link[href*="/cache/'+this._post+'"]'),this._newCss=e('<link rel="stylesheet" id="fl-builder-layout-'+this._post+'-css" href="'+this._data.css+'" />')),this._data.partial?(this._data.js&&(this._oldJs=e("#fl-builder-partial-refresh-js"),this._newJs=e('<script type="text/javascript" id="fl-builder-partial-refresh-js">'+this._data.js+"</script>")),this._data.nodeId&&(this._data.oldNodeId?(this._oldScriptsStyles=e('.fl-builder-node-scripts-styles[data-node="'+this._data.oldNodeId+'"]'),this._content=e(".fl-node-"+this._data.oldNodeId)):(this._oldScriptsStyles=e('.fl-builder-node-scripts-styles[data-node="'+this._data.nodeId+'"]'),this._content=e(".fl-node-"+this._data.nodeId).eq(0)))):(this._oldJs=e('script[src*="/cache/'+this._post+'"]'),this._newJs=e('<script src="'+this._data.js+'"></script>'),this._oldScriptsStyles=e(".fl-builder-layout-scripts-styles"),this._content=e(FLBuilder._contentClass)),this._init()},FLBuilderAJAXLayout.prototype={_defaults:{partial:!1,nodeId:null,nodeType:null,nodeParent:null,nodePosition:null,oldNodeId:null,html:null,scriptsStyles:null,css:null,js:null},_data:null,_callback:function(){},_post:null,_head:null,_body:null,_loader:null,_oldCss:null,_newCss:null,_oldJs:null,_newJs:null,_oldScriptsStyles:null,_content:null,_init:function(){this._body.height(this._body.height()),this._loader?(this._loader.on("error",e.proxy(this._loadNewCSSComplete,this)),this._body.append(this._loader)):this._finish()},_loadNewCSSComplete:function(){this._loader.remove(),this._oldCss.length>0?this._oldCss.after(this._newCss):this._head.append(this._newCss),setTimeout(e.proxy(this._finish,this),250)},_finish:function(){this._removeOldContentAndAssets(),this._cleanNewHTML(),this._cleanNewAssets(),this._addNewHTML(),this._addNewScriptsStyles(),this._addNewJS(),e(FLBuilder._contentClass).trigger("fl-builder.layout-rendered"),FLBuilder.hideAjaxLoader(),"undefined"!=typeof this._callback&&this._callback()},_removeOldContentAndAssets:function(){this._content&&this._content.empty(),this._oldCss&&this._oldCss.remove(),this._oldJs&&this._oldJs.remove(),this._oldScriptsStyles&&this._oldScriptsStyles.remove()},_cleanNewHTML:function(){if(this._data.scriptsStyles){var t=e("<div>"+this._data.html+"</div>"),l="fl-row",i=this._data.scriptsStyles,o="";this._data.partial&&(l="column-group"==this._data.nodeType?"fl-col-group":"column"==this._data.nodeType?"fl-col":"fl-"+this._data.nodeType),t.find("> *, script").each(function(){e(this).hasClass(l)||(o=e(this).remove(),i+=o[0].outerHTML)}),""!==i&&(i=this._data.partial?'<div class="fl-builder-node-scripts-styles" data-node="'+this._data.nodeId+'">'+i+"<div>":'<div class="fl-builder-node-scripts-styles">'+i+"<div>"),this._data.html=t.html(),this._data.scriptsStyles=i}},_addNewHTML:function(){var t;this._data.partial?this._data.nodeParent?(t=this._data.nodeParent.hasClass("fl-builder-content")?this._data.nodeParent.find(".fl-row"):this._data.nodeParent.hasClass("fl-row-content")?this._data.nodeParent.find(" > .fl-col-group"):this._data.nodeParent.find(" > .fl-col-group, > .fl-module"),t=t.filter(":not(.fl-builder-node-clone)"),0===t.length||t.length==this._data.nodePosition?this._data.nodeParent.append(this._data.html):t.eq(this._data.nodePosition).before(this._data.html),this._data.nodeId&&FLBuilder._removeNodeLoadingPlaceholder(e(".fl-node-"+this._data.nodeId))):(this._content.after(this._data.html),this._content.remove()):this._content.append(this._data.html)},_cleanNewAssets:function(){var t=this;this._data.html=this._removeDuplicateAssets(this._data.html),this._data.scriptsStyles&&""!==this._data.scriptsStyles&&(this._data.scriptsStyles=this._removeDuplicateAssets(this._data.scriptsStyles)),this._data.partial?e(".fl-builder-node-scripts-styles").each(function(){t._data.html.indexOf("fl-node-"+e(this).data("node"))>-1&&e(this).remove()}):(e("#fl-builder-partial-refresh-js").remove(),e(".fl-builder-node-scripts-styles").remove())},_removeDuplicateAssets:function(t){var l=e("<div>"+t+"</div>"),i="",o=null,s="",r=null,n=window.location,a=n.protocol+"//"+n.hostname+(n.port?":"+n.port:"");return l.find("script").each(function(){i=e(this).attr("src"),"undefined"!=typeof i&&(i=i.replace(a,""),o=e('script[src*="'+i+'"]'),o.length>0&&e(this).remove())}),l.find("link").each(function(){s=e(this).attr("href"),"undefined"!=typeof s&&(s=s.replace(a,""),r=e('link[href*="'+s+'"]'),r.length>0&&e(this).remove())}),l.html()},_addNewScriptsStyles:function(){this._data.scriptsStyles&&""!==this._data.scriptsStyles&&this._body.append(this._data.scriptsStyles)},_addNewJS:function(){setTimeout(e.proxy(function(){this._newJs&&this._head.append(this._newJs)},this),50)},_complete:function(){FLBuilder._setupEmptyLayout(),FLBuilder._highlightEmptyCols(),FLBuilder._initDropTargets(),FLBuilder._initSortables(),FLBuilder._resizeLayout(),FLBuilder._initMediaElements(),FLBuilderLayout.init(),FLBuilderResponsiveEditing.refreshPreview(),this._body.height("auto")}}}(jQuery),function(e){FLBuilderPreview=function(t){this.type=t.type,"undefined"!=t.state&&t.state?this.state=t.state:this._saveState(),"undefined"!=t.layout&&t.layout?FLBuilder._renderLayout(t.layout,e.proxy(this._init,this)):this._init()},FLBuilderPreview._fontsList={},FLBuilderPreview.prototype={type:"",nodeId:null,classes:{},elements:{},state:null,_savedSettings:null,_styleSheet:null,_styleSheetMedium:null,_styleSheetResponsive:null,_timeout:null,_loaderTimeout:null,_lastClassName:null,_xhr:null,_init:function(){switch(this.nodeId=e(".fl-builder-settings").data("node"),this._saveSettings(),this._initElementsAndClasses(),this._createSheets(),this._initResponsivePreviews(),this._initDefaultFieldPreviews(),this.type){case"row":this._initRow();break;case"col":this._initColumn();break;case"module":this._initModule()}},_saveSettings:function(){var t=e(".fl-builder-settings-lightbox .fl-builder-settings");this._savedSettings=FLBuilder._getSettings(t)},_settingsHaveChanged:function(){var t=e(".fl-builder-settings-lightbox .fl-builder-settings"),l=FLBuilder._getSettings(t);return JSON.stringify(this._savedSettings)!=JSON.stringify(l)},_initElementsAndClasses:function(){var t;t="row"==this.type?".fl-row-content-wrap":".fl-"+this.type+"-content",e.extend(this.classes,{settings:".fl-builder-"+this.type+"-settings",settingsHeader:".fl-builder-"+this.type+"-settings .fl-lightbox-header",node:FLBuilder._contentClass+" .fl-node-"+this.nodeId,content:FLBuilder._contentClass+" .fl-node-"+this.nodeId+" > "+t}),e.extend(this.elements,{settings:e(this.classes.settings),settingsHeader:e(this.classes.settingsHeader),node:e(this.classes.node),content:e(this.classes.content)})},_createSheets:function(){this._styleSheet||(this._styleSheet=new FLStyleSheet({id:"fl-builder-preview"})),this._styleSheetMedium||(this._styleSheetMedium=new FLStyleSheet({id:"fl-builder-preview-medium"})),this._styleSheetResponsive||(this._styleSheetResponsive=new FLStyleSheet({id:"fl-builder-preview-responsive"}))},_destroySheets:function(){this._styleSheet&&(this._styleSheet.destroy(),this._styleSheet=null),this._styleSheetMedium&&(this._styleSheetMedium.destroy(),this._styleSheetMedium=null),this._styleSheetResponsive&&(this._styleSheetResponsive.destroy(),this._styleSheetResponsive=null)},updateCSSRule:function(e,t,l){this._styleSheet.updateRule(e,t,l)},delay:function(e,t){this._cancelDelay(),this._timeout=setTimeout(t,e)},_cancelDelay:function(){null!==this._timeout&&clearTimeout(this._timeout)},hexToRgb:function(e){var t=parseInt(e,16),l=t>>16&255,i=t>>8&255,o=255&t;return[l,i,o]},parseFloat:function(e){return isNaN(parseFloat(e))?0:parseFloat(e)},_initResponsivePreviews:function(){FLBuilder.addHook("responsive-editing-switched",e.proxy(this._responsiveEditingSwitched,this))},_destroyResponsivePreviews:function(){FLBuilder.removeHook("responsive-editing-switched")},_responsiveEditingSwitched:function(e,t){"default"==t?(this._styleSheetMedium.disable(),this._styleSheetResponsive.disable()):"medium"==t?(this._styleSheetMedium.enable(),this._styleSheetResponsive.disable()):"responsive"==t&&(this._styleSheetMedium.disable(),this._styleSheetResponsive.enable())},updateResponsiveCSSRule:function(e,t,l){var i=FLBuilderResponsiveEditing._mode,o="default"==i?"":i.charAt(0).toUpperCase()+i.slice(1);this["_styleSheet"+o].updateRule(e,t,l)},_saveState:function(){var t=FLBuilderConfig.postId,l=e('link[href*="/cache/'+t+'"]').attr("href"),i=e('script[src*="/cache/'+t+'"]').attr("src"),o=e(FLBuilder._contentClass).html();this.state={css:l,js:i,html:o}},preview:function(){var t=e(".fl-builder-settings-lightbox .fl-builder-settings"),l=t.attr("data-node"),i=FLBuilder._getSettings(t);this._cancelPreview(),this._xhr=FLBuilder.ajax({action:"render_layout",node_id:l,node_preview:i},e.proxy(this._renderPreview,this))},delayPreview:function(t){var l="undefined"==typeof t?[]:e(t.target).closest("tr").find("th"),i=e(".fl-builder-widget-settings .fl-builder-settings-title"),o=e(".fl-builder-settings .fl-lightbox-header"),s=FLBuilderLayoutConfig.paths.pluginUrl+"img/ajax-loader-small.svg",r=e('<img class="fl-builder-preview-loader" src="'+s+'" />');this.delay(1e3,e.proxy(this.preview,this)),this._loaderTimeout=setTimeout(function(){e(".fl-builder-preview-loader").remove(),l.length>0?l.append(r):i.length>0?i.append(r):o.length>0&&o.append(r)},1500)},_cancelPreview:function(){this._xhr&&(this._xhr.abort(),this._xhr=null)},_renderPreview:function(t){this._xhr=null,FLBuilder._renderLayout(t,e.proxy(this._renderPreviewComplete,this))},_renderPreviewComplete:function(){this._destroySheets(),this._createSheets(),this._initElementsAndClasses(),null!==this._loaderTimeout&&clearTimeout(this._loaderTimeout),e(".fl-builder-preview-loader").remove(),e(FLBuilder._contentClass).trigger("fl-builder.preview-rendered")},revert:function(){this.clear(),FLBuilder._renderLayout(this.state)},clear:function(){this._cancelDelay(),this._cancelPreview(),this._destroySheets(),this._destroyResponsivePreviews()},_initNodeTextColor:function(){e.extend(this.elements,{textColor:e(this.classes.settings+" input[name=text_color]"),linkColor:e(this.classes.settings+" input[name=link_color]"),hoverColor:e(this.classes.settings+" input[name=hover_color]"),headingColor:e(this.classes.settings+" input[name=heading_color]")}),this.elements.textColor.on("change",e.proxy(this._textColorChange,this)),this.elements.linkColor.on("change",e.proxy(this._textColorChange,this)),this.elements.hoverColor.on("change",e.proxy(this._textColorChange,this)),this.elements.headingColor.on("change",e.proxy(this._textColorChange,this))},_textColorChange:function(t){var l=this.elements.textColor.val(),i=this.elements.linkColor.val(),o=this.elements.hoverColor.val(),s=this.elements.headingColor.val();i=""===i?l:i,o=""===o?l:o,s=""===s?l:s,this.delay(100,e.proxy(function(){""===l?this.updateCSSRule(this.classes.node,"color","inherit"):this.updateCSSRule(this.classes.node,"color","#"+l),""===i?this.updateCSSRule(this.classes.node+" a","color","inherit"):this.updateCSSRule(this.classes.node+" a","color","#"+i),""===o?this.updateCSSRule(this.classes.node+" a:hover","color","inherit"):this.updateCSSRule(this.classes.node+" a:hover","color","#"+o),""===s?(this.updateCSSRule(this.classes.node+" h1","color","inherit"),this.updateCSSRule(this.classes.node+" h2","color","inherit"),this.updateCSSRule(this.classes.node+" h3","color","inherit"),this.updateCSSRule(this.classes.node+" h4","color","inherit"),this.updateCSSRule(this.classes.node+" h5","color","inherit"),this.updateCSSRule(this.classes.node+" h6","color","inherit"),this.updateCSSRule(this.classes.node+" h1 a","color","inherit"),this.updateCSSRule(this.classes.node+" h2 a","color","inherit"),this.updateCSSRule(this.classes.node+" h3 a","color","inherit"),this.updateCSSRule(this.classes.node+" h4 a","color","inherit"),this.updateCSSRule(this.classes.node+" h5 a","color","inherit"),this.updateCSSRule(this.classes.node+" h6 a","color","inherit")):(this.updateCSSRule(this.classes.node+" h1","color","#"+s),this.updateCSSRule(this.classes.node+" h2","color","#"+s),this.updateCSSRule(this.classes.node+" h3","color","#"+s),this.updateCSSRule(this.classes.node+" h4","color","#"+s),this.updateCSSRule(this.classes.node+" h5","color","#"+s),this.updateCSSRule(this.classes.node+" h6","color","#"+s),this.updateCSSRule(this.classes.node+" h1 a","color","#"+s),this.updateCSSRule(this.classes.node+" h2 a","color","#"+s),this.updateCSSRule(this.classes.node+" h3 a","color","#"+s),this.updateCSSRule(this.classes.node+" h4 a","color","#"+s),this.updateCSSRule(this.classes.node+" h5 a","color","#"+s),this.updateCSSRule(this.classes.node+" h6 a","color","#"+s))},this))},_initNodeBg:function(){e.extend(this.elements,{bgType:e(this.classes.settings+" select[name=bg_type]"),bgColor:e(this.classes.settings+" input[name=bg_color]"),bgColorPicker:e(this.classes.settings+" .fl-picker-bg_color"),bgOpacity:e(this.classes.settings+" input[name=bg_opacity]"),bgImageSrc:e(this.classes.settings+" select[name=bg_image_src]"),bgRepeat:e(this.classes.settings+" select[name=bg_repeat]"),bgPosition:e(this.classes.settings+" select[name=bg_position]"),bgAttachment:e(this.classes.settings+" select[name=bg_attachment]"),bgSize:e(this.classes.settings+" select[name=bg_size]"),bgVideoSource:e(this.classes.settings+" select[name=bg_video_source]"),bgVideo:e(this.classes.settings+" input[name=bg_video]"),bgVideoServiceUrl:e(this.classes.settings+" input[name=bg_video_service_url]"),bgVideoFallbackSrc:e(this.classes.settings+" select[name=bg_video_fallback_src]"),bgSlideshowSource:e(this.classes.settings+" select[name=ss_source]"),bgSlideshowPhotos:e(this.classes.settings+" input[name=ss_photos]"),bgSlideshowFeedUrl:e(this.classes.settings+" input[name=ss_feed_url]"),bgSlideshowSpeed:e(this.classes.settings+" input[name=ss_speed]"),bgSlideshowTrans:e(this.classes.settings+" select[name=ss_transition]"),bgSlideshowTransSpeed:e(this.classes.settings+" input[name=ss_transitionDuration]"),bgParallaxImageSrc:e(this.classes.settings+" select[name=bg_parallax_image_src]"),bgOverlayColor:e(this.classes.settings+" input[name=bg_overlay_color]"),bgOverlayOpacity:e(this.classes.settings+" input[name=bg_overlay_opacity]")}),this.elements.bgType.on("change",e.proxy(this._bgTypeChange,this)),this.elements.bgColor.on("change",e.proxy(this._bgColorChange,this)),this.elements.bgOpacity.on("keyup",e.proxy(this._bgOpacityChange,this)),this.elements.bgImageSrc.on("change",e.proxy(this._bgPhotoChange,this)),this.elements.bgRepeat.on("change",e.proxy(this._bgPhotoChange,this)),this.elements.bgPosition.on("change",e.proxy(this._bgPhotoChange,this)),this.elements.bgAttachment.on("change",e.proxy(this._bgPhotoChange,this)),this.elements.bgSize.on("change",e.proxy(this._bgPhotoChange,this)),this.elements.bgVideoServiceUrl.on("change",e.proxy(this._bgVideoChange,this)),this.elements.bgSlideshowSource.on("change",e.proxy(this._bgSlideshowChange,this)),this.elements.bgSlideshowPhotos.on("change",e.proxy(this._bgSlideshowChange,this)),this.elements.bgSlideshowFeedUrl.on("keyup",e.proxy(this._bgSlideshowChange,this)),this.elements.bgSlideshowSpeed.on("keyup",e.proxy(this._bgSlideshowChange,this)),this.elements.bgSlideshowTrans.on("change",e.proxy(this._bgSlideshowChange,this)),this.elements.bgSlideshowTransSpeed.on("keyup",e.proxy(this._bgSlideshowChange,this)),this.elements.bgParallaxImageSrc.on("change",e.proxy(this._bgParallaxChange,this)),this.elements.bgOverlayColor.on("change",e.proxy(this._bgOverlayChange,this)),this.elements.bgOverlayOpacity.on("keyup",e.proxy(this._bgOverlayChange,this))},_bgTypeChange:function(e){var t=this.elements.bgType.val();this.elements.node.removeClass("fl-row-bg-video"),this.elements.node.removeClass("fl-row-bg-slideshow"),this.elements.node.removeClass("fl-row-bg-parallax"),this.elements.node.find(".fl-bg-video").remove(),this.elements.node.find(".fl-bg-slideshow").remove(),this.elements.content.css("background-image",""),this.updateCSSRule(this.classes.content,{"background-color":"transparent","background-image":"none"}),"none"==t?this._bgOverlayClear():"color"==t?(this.elements.bgColor.trigger("change"),this._bgOverlayClear()):"photo"==t?(this.elements.bgColor.trigger("change"),this.elements.bgImageSrc.trigger("change")):"video"==t?(this.elements.bgColor.trigger("change"),this._bgVideoChange()):"slideshow"==t?(this.elements.bgColor.trigger("change"),this._bgSlideshowChange()):"parallax"==t&&(this.elements.bgColor.trigger("change"),this.elements.bgParallaxImageSrc.trigger("change"))},_bgColorChange:function(t){var l,i,o;""===this.elements.bgColor.val()||isNaN(this.elements.bgOpacity.val())?this.updateCSSRule(this.classes.content,"background-color","transparent"):(l=this.hexToRgb(this.elements.bgColor.val()),i=this.parseFloat(this.elements.bgOpacity.val())/100,o="rgba("+l.join()+", "+i+")",this.delay(100,e.proxy(function(){this.updateCSSRule(this.classes.content,"background-color",o)},this)))},_bgOpacityChange:function(e){this.elements.bgColor.trigger("change")},_bgPhotoChange:function(e){this.elements.bgImageSrc.val()?this.updateCSSRule(this.classes.content,{"background-image":"url("+this.elements.bgImageSrc.val()+")","background-repeat":this.elements.bgRepeat.val(),"background-position":this.elements.bgPosition.val(),"background-attachment":this.elements.bgAttachment.val(),"background-size":this.elements.bgSize.val()}):this.updateCSSRule(this.classes.content,{"background-image":"none"})},_bgVideoChange:function(t){var l=this.elements,i=l.bgVideoSource.val(),o=l.bgVideo.val(),s=l.bgVideoServiceUrl.val(),r="https://www.youtube.com/iframe_api",n="https://player.vimeo.com/api/player.js",a=e("<script>");"video_service"==i&&""!=s?(/^(?:(?:(?:https?:)?\/\/)?(?:www.)?(?:youtu(?:be.com|.be))\/(?:watch\?v\=|v\/|embed\/)?([\w\-]+))/i.test(s)&&e('script[src*="youtube.com"').length<1?a.attr("src",r):/^(http\:\/\/|https\:\/\/)?(www\.)?(vimeo\.com\/)([0-9]+)$/.test(s)&&e('script[src*="vimeo.com"').length<1&&a.attr("src",n),a.attr("type","text/javascript").appendTo("head"),this.delay(500,e.proxy(this.preview,this))):""!=o&&this.preview()},_bgSlideshowChange:function(t){var l=this.elements,i=l.bgSlideshowSource.val(),o=l.bgSlideshowPhotos.val(),s=l.bgSlideshowFeedUrl.val(),r=l.bgSlideshowSpeed.val(),n=l.bgSlideshowTransSpeed.val();"wordpress"==i&&""===o||"smugmug"==i&&""===s||isNaN(parseInt(r))||isNaN(parseInt(n))||this.delay(500,e.proxy(this.preview,this))},_bgParallaxChange:function(e){this.elements.bgParallaxImageSrc.val()&&this.updateCSSRule(this.classes.content,{"background-image":"url("+this.elements.bgParallaxImageSrc.val()+")","background-repeat":"no-repeat","background-position":"center center","background-attachment":"fixed","background-size":"cover"})},_bgOverlayChange:function(t){var l,i,o;""===this.elements.bgOverlayColor.val()||isNaN(this.elements.bgOverlayOpacity.val())?(this.elements.node.removeClass("fl-row-bg-overlay"),this.elements.node.removeClass("fl-col-bg-overlay"),this.updateCSSRule(this.classes.content+":after","background-color","transparent")):(l=this.hexToRgb(this.elements.bgOverlayColor.val()),i=this.parseFloat(this.elements.bgOverlayOpacity.val())/100,o="rgba("+l.join()+", "+i+")",this.delay(100,e.proxy(function(){this.elements.node.hasClass("fl-col")?this.elements.node.addClass("fl-col-bg-overlay"):this.elements.node.addClass("fl-row-bg-overlay"),this.updateCSSRule(this.classes.content+":after","background-color",o)},this)))},_bgOverlayClear:function(e){this.elements.bgOverlayColor.prev(".fl-color-picker-clear").trigger("click")},_initNodeBorder:function(){e.extend(this.elements,{borderType:e(this.classes.settings+" select[name=border_type]"),borderColor:e(this.classes.settings+" input[name=border_color]"),borderColorPicker:e(this.classes.settings+" .fl-picker-border_color"),borderOpacity:e(this.classes.settings+" input[name=border_opacity]")}),this.elements.borderType.on("change",e.proxy(this._borderTypeChange,this)),this.elements.borderColor.on("change",e.proxy(this._borderColorChange,this)),this.elements.borderOpacity.on("keyup",e.proxy(this._borderOpacityChange,this))},_borderTypeChange:function(e){var t=this.elements.borderType.val();this.updateCSSRule(this.classes.content,{"border-style":""===t?"none":t}),this.elements.borderColor.trigger("change"),this.elements.borderTop.trigger("keyup")},_borderColorChange:function(t){var l,i,o;""===this.elements.borderColor.val()||isNaN(this.elements.borderOpacity.val())?this.updateCSSRule(this.classes.content,"border-color","transparent"):(l=this.hexToRgb(this.elements.borderColor.val()),i=parseInt(this.elements.borderOpacity.val())/100,o="rgba("+l.join()+", "+i+")",this.delay(100,e.proxy(function(){this.updateCSSRule(this.classes.content,"border-color",o)},this)))},_borderOpacityChange:function(e){this.elements.borderColor.trigger("change")},_initNodeClassName:function(){e.extend(this.elements,{className:e(this.classes.settings+" input[name=class]")}),this.elements.className.on("keyup",e.proxy(this._classNameChange,this)),this._lastClassName=this.elements.className.val()},_classNameChange:function(e){var t=this.elements.className.val();null!==this._lastClassName&&this.elements.node.removeClass(this._lastClassName),this.elements.node.addClass(t),this._lastClassName=t},_initResponsiveDimensions:function(t){var l={},i=["Top","Bottom","Left","Right"],o=["","Medium","Responsive"],s=this.classes.settings,r="",n="",a=null,d=null;for(a=0;a<i.length;a++)for(d=0;d<o.length;d++)r=t+i[a]+o[d],n=t+"_"+i[a].toLowerCase(),""!=o[d]&&(n+="_"+o[d].toLowerCase()),l[r]=e(s+" input[name="+n+"]"),l[r].on("keyup",e.proxy(this._responsiveDimensionChange,this,t));e.extend(this.elements,l)},_getDimensions:function(e){for(var t=FLBuilderResponsiveEditing._mode,l=["Top","Bottom","Left","Right"],i="default"==t?"":t.charAt(0).toUpperCase()+t.slice(1),o={},s=0;s<l.length;s++)o[l[s].toLowerCase()]=this.elements[e+l[s]+i].val();return this._normalizeDimensionValues(o,e)},_responsiveDimensionChange:function(t){var l=this._getDimensions(t),i={},o="border"==t;e.each(l,function(e,l){i[t+"-"+e+(o?"-width":"")]=l}),this.updateResponsiveCSSRule(this.classes.content,i),this._positionAbsoluteBgs()},_normalizeDimensionValues:function(t,l){var i=this,o=FLBuilderResponsiveEditing._mode,s="default"==o?"":o.charAt(0).toUpperCase()+o.slice(1),l=l.split("-");return"undefined"==typeof l[1]?l[1]="":l[1]=l[1].charAt(0).toUpperCase()+l[1].slice(1),e.map(t,function(e,o){if(e=e.toLowerCase().replace(/[^a-z0-9%.\-]/g,""),""===e){var r=l[0]+o.charAt(0).toUpperCase()+o.slice(1)+l[1]+s,n=i.elements[r].attr("placeholder");n&&(e=n)}null===e||""===e||isNaN(e)||(e=parseFloat(e)+"px"),t[o]=e}),t},_positionAbsoluteBgs:function(){var t=this.elements.node.find(".fl-bg-slideshow"),l=this.elements.node.find(".fl-bg-video"),i=null,o=null,s={top:0,bottom:0,left:0,right:0};(t.length>0||l.length>0)&&(i=this._getDimensions("margin"),o=this._getDimensions("border"),e.map(s,function(e,t){i[t]&&o[t]?s[t]="calc("+i[t]+"+"+o[t]+")":i[t]?s[t]=i[t]:o[t]&&(s[t]=o[t])}),t.length>0&&(this.updateCSSRule(this.classes.node+" .fl-bg-slideshow",s),FLBuilder._resizeLayout()),l.length>0&&this.updateCSSRule(this.classes.node+" .fl-bg-video",s))},_initRow:function(){e.extend(this.elements,{width:e(this.classes.settings+" select[name=width]"),contentWidth:e(this.classes.settings+" select[name=content_width]"),height:e(this.classes.settings+" select[name=full_height]"),align:e(this.classes.settings+" select[name=content_alignment]")}),this.elements.width.on("change",e.proxy(this._rowWidthChange,this)),this.elements.contentWidth.on("change",e.proxy(this._rowContentWidthChange,this)),this.elements.height.on("change",e.proxy(this._rowHeightChange,this)),this.elements.align.on("change",e.proxy(this._rowHeightChange,this)),this._initNodeTextColor(),this._initNodeBg(),this._initNodeClassName(),this._initNodeBorder(),this._initResponsiveDimensions("border"),this._initResponsiveDimensions("margin"),this._initResponsiveDimensions("padding")},_rowWidthChange:function(e){var t=this.elements.node;"full"==this.elements.width.val()?(t.removeClass("fl-row-fixed-width"),t.addClass("fl-row-full-width")):(t.removeClass("fl-row-full-width"),t.addClass("fl-row-fixed-width"))},_rowHeightChange:function(e){var t=this.elements.node;t.removeClass("fl-row-align-top"),t.removeClass("fl-row-align-center"),t.removeClass("fl-row-align-bottom"),"full"==this.elements.height.val()?(t.addClass("fl-row-full-height"),t.addClass("fl-row-align-"+this.elements.align.val())):t.removeClass("fl-row-full-height")},_rowContentWidthChange:function(e){var t=this.elements.content.find(".fl-row-content");"full"==this.elements.contentWidth.val()?(t.removeClass("fl-row-fixed-width"),t.addClass("fl-row-full-width")):(t.removeClass("fl-row-full-width"),t.addClass("fl-row-fixed-width"))},_initColumn:function(){e.extend(this.elements,{size:e(this.classes.settings+" input[name=size]"),columnHeight:e(this.classes.settings+" select[name=equal_height]"),columnAlign:e(this.classes.settings+" select[name=content_alignment]"),responsiveOrder:e(this.classes.settings+" select[name=responsive_order]")}),this.elements.size.on("keyup",e.proxy(this._colSizeChange,this)),this.elements.columnHeight.on("change",e.proxy(this._colHeightChange,this)),this.elements.columnAlign.on("change",e.proxy(this._colHeightChange,this)),this.elements.responsiveOrder.on("change",e.proxy(this._colResponsiveOrder,this)),this._initNodeTextColor(),this._initNodeBg(),this._initNodeClassName(),this._initNodeBorder(),this._initResponsiveDimensions("border"),this._initResponsiveDimensions("margin"),this._initResponsiveDimensions("padding")},_colSizeChange:function(){var t=8,l=100-t,i=parseFloat(this.elements.size.val()),o=this.elements.node.prev(".fl-col"),s=this.elements.node.next(".fl-col"),r=0===s.length?o:s,n=this.elements.node.siblings(".fl-col"),a=0;0===n.length||isNaN(i)||(n.each(function(){e(this).data("node")!=r.data("node")&&(l-=parseFloat(e(this)[0].style.width),a+=parseFloat(e(this)[0].style.width))}),i<t&&(i=t),i>l&&(i=l),r.css("width",100-a-i+"%"),this.elements.node.css("width",i+"%"))},_colHeightChange:function(){var e=this.elements.node.parent(".fl-col-group");e.removeClass("fl-col-group-align-top"),e.removeClass("fl-col-group-align-center"),e.removeClass("fl-col-group-align-bottom"),"yes"==this.elements.columnHeight.val()?(e.addClass("fl-col-group-equal-height"),e.addClass("fl-col-group-align-"+this.elements.columnAlign.val())):e.removeClass("fl-col-group-equal-height")},_colResponsiveOrder:function(){var e=this.elements.node.parent(".fl-col-group");"reversed"==this.elements.responsiveOrder.val()?e.addClass("fl-col-group-responsive-reversed"):e.removeClass("fl-col-group-responsive-reversed");
5
- },_initModule:function(){this._initNodeClassName(),this._initResponsiveDimensions("margin")},_initDefaultFieldPreviews:function(){for(var e=this.elements.settings.find(".fl-field"),t=null,l=null,i=0;i<e.length;i++)t=e.eq(i),l=t.data("preview"),"refresh"==l.type&&this._initFieldRefreshPreview(t),"text"==l.type&&this._initFieldTextPreview(t),"css"==l.type&&this._initFieldCSSPreview(t),"widget"==l.type&&this._initFieldWidgetPreview(t),"font"==l.type&&this._initFieldFontPreview(t)},_initFieldRefreshPreview:function(t){var l=t.data("type"),i=t.data("preview"),o=e.proxy(this.delayPreview,this);switch(l){case"text":t.find("input[type=text]").on("keyup",o);break;case"textarea":t.find("textarea").on("keyup",o);break;case"select":t.find("select").on("change",o);break;case"color":t.find(".fl-color-picker-value").on("change",o);break;case"photo":t.find("select").on("change",o);break;case"multiple-photos":t.find("input").on("change",o);break;case"photo-sizes":t.find("select").on("change",o);break;case"video":t.find("input").on("change",o);break;case"multiple-audios":t.find("input").on("change",o);break;case"icon":t.find("input").on("change",o);break;case"form":t.delegate("input","change",o);break;case"editor":this._addTextEditorCallback(t,i);break;case"code":t.find("textarea").on("change",o);break;case"post-type":t.find("select").on("change",o);break;case"suggest":t.find(".as-values").on("change",o),t.find("select").on("change",o);break;case"unit":t.find("input[type=number]").on("keyup",o);break;case"ordering":t.find("input[type=hidden]").on("change",o)}},_initFieldTextPreview:function(t){var l=t.data("type"),i=t.data("preview"),o=e.proxy(this._previewText,this,i);switch(l){case"text":t.find("input[type=text]").on("keyup",o);break;case"unit":t.find("input[type=number]").on("keyup",o);break;case"textarea":t.find("textarea").on("keyup",o);break;case"code":t.find("textarea").on("change",o);break;case"editor":this._addTextEditorCallback(t,i)}},_previewText:function(t,l){var i=this.elements.node.find(t.selector),o=e("<div>"+e(l.target).val()+"</div>");i.length>0&&(o.find("script").remove(),i.html(o.html()))},_previewTextEditor:function(t,l,i){var o=this.elements.node.find(t.selector),s="undefined"!=typeof tinyMCE?tinyMCE.get(l):null,r=e("#"+l),n="";o.length>0&&(n=e(s&&"none"==r.css("display")?"<div>"+s.getContent()+"</div>":"undefined"==typeof switchEditors||"undefined"==typeof switchEditors.wpautop?"<div>"+r.val()+"</div>":"<div>"+switchEditors.wpautop(r.val())+"</div>"),n.find("script").remove(),o.html(n.html()))},_addTextEditorCallback:function(t,l){var i=t.find("textarea.wp-editor-area").attr("id"),o=null;if("refresh"==l.type)o=e.proxy(this.delayPreview,this);else{if("text"!=l.type)return;o=e.proxy(this._previewTextEditor,this,l,i)}e("#"+i).on("keyup",o),"undefined"!=typeof tinyMCE&&(editor=tinyMCE.get(i),editor.on("change",o),editor.on("keyup",o))},_initFieldFontPreview:function(t){var l=t.data("type"),i=t.data("preview");i.id=t.attr("id");var o=e.proxy(this._previewFont,this,i);"font"==l&&t.find(".fl-font-field").on("change","select",o)},_previewFont:function(t,l){var i=e(l.delegateTarget),o=i.find(".fl-font-field-font"),s=e(o).find(":selected"),r=s.parent().attr("label"),n=i.find(".fl-font-field-weight"),a=t.id+"-"+this.nodeId,d=this._getPreviewSelector(this.classes.node,t.selector);"Google"==r&&this._buildFontStylesheet(a,o.val(),n.val()),"Default"==o.val()?(this.updateCSSRule(d,"font-family",""),this.updateCSSRule(d,"font-weight","")):(this.updateCSSRule(d,"font-family",o.val()),this.updateCSSRule(d,"font-weight",n.val()))},_buildFontStylesheet:function(t,l,i){var o=FLBuilderConfig.googleFontsUrl,s="",r={},n={};r[l]=[i],FLBuilderPreview._fontsList[t]=r,Object.keys(FLBuilderPreview._fontsList).forEach(function(e){var t=FLBuilderPreview._fontsList[e];Object.keys(t).forEach(function(e){var l=t[e];n[e]=n[e]||[],l=l.filter(function(t){return n[e].indexOf(t)<0}),n[e]=n[e].concat(l)})}),e.each(n,function(e,t){s+=e+":"+t.join()+"|"}),s=o+s.slice(0,-1).replace(" ","+"),e("#fl-builder-google-fonts-preview").length<1?e("<link>").attr("id","fl-builder-google-fonts-preview").attr("type","text/css").attr("rel","stylesheet").attr("href",s).appendTo("head"):e("#fl-builder-google-fonts-preview").attr("href",s)},_initFieldCSSPreview:function(e){var t=e.data("preview"),l=null;if("undefined"!=typeof t.rules)for(l in t.rules)this._initFieldCSSPreviewCallback(e,t.rules[l]);else this._initFieldCSSPreviewCallback(e,t)},_initFieldCSSPreviewCallback:function(t,l){switch(t.data("type")){case"text":t.find("input[type=text]").on("keyup",e.proxy(this._previewCSS,this,l));break;case"unit":t.find("input[type=number]").on("keyup",e.proxy(this._previewCSS,this,l));break;case"select":t.find("select").on("change",e.proxy(this._previewCSS,this,l));break;case"color":t.find(".fl-color-picker-value").on("change",e.proxy(this._previewColor,this,l))}},_previewCSS:function(t,l){var i=this._getPreviewSelector(this.classes.node,t.selector),o=t.property,s="undefined"==typeof t.unit?"":t.unit,r=e(l.target),n=r.val();"%"==s?n=parseInt(n)/100:""!==n&&(n+=s),r.closest(".fl-field-responsive-setting").length?this.updateResponsiveCSSRule(i,o,n):this.updateCSSRule(i,o,n)},_previewColor:function(t,l){var i=this._getPreviewSelector(this.classes.node,t.selector),o=e(l.target),s=o.val(),r=""===s?"inherit":"#"+s;/^rgb/.test(s.replace(/\s+/g,""))&&(r=s),o.closest(".fl-field-responsive-setting").length?this.updateResponsiveCSSRule(i,t.property,r):this.updateCSSRule(i,t.property,r)},_initFieldWidgetPreview:function(t){var l=e.proxy(this.delayPreview,this);t.find("input").on("keyup",l),t.find("input[type=checkbox]").on("click",l),t.find("textarea").on("keyup",l),t.find("select").on("change",l)},_getPreviewSelector:function(e,t){for(var l="",i=t.split(","),o=0;o<i.length;o++)l+=e+" "+i[o],o!=i.length-1&&(l+=", ");return l}}}(jQuery),function(e){var t={ignored:[],reparsed:[],width:null,callback:null,sheets:{},styles:[],queue:[],emPxValue:null,regex:{media:/@media[^\{]+\{([^\{\}]*\{[^\}\{]*\})+[^\}]+\}/gi,keyframes:/@(?:\-(?:o|moz|webkit)\-)?keyframes[^\{]+\{(?:[^\{\}]*\{[^\}\{]*\})+[^\}]*\}/gi,comments:/\/\*[^*]*\*+([^\/][^*]*\*+)*\//gi,urls:/(url\()['"]?([^\/\)'"][^:\)'"]+)['"]?(\))/g,findStyles:/@media *([^\{]+)\{([\S\s]+?)\}$/,only:/(only\s+)?([a-zA-Z]+)\s?/,minw:/\(\s*min\-width\s*:\s*(\s*[0-9\.]+)(px|em)\s*\)/,maxw:/\(\s*max\-width\s*:\s*(\s*[0-9\.]+)(px|em)\s*\)/,minmaxwh:/\(\s*m(in|ax)\-(height|width)\s*:\s*(\s*[0-9\.]+)(px|em)\s*\)/gi,other:/\([^\)]*\)/g},ignore:function(e){Array.prototype.push.apply(this.ignored,e)},reparse:function(e){Array.prototype.push.apply(this.reparsed,e)},update:function(e,t){this.width=void 0===e?null:e,this.callback=void 0===t?null:t,l.update(),this.queueSheets()?this.runQueue():this.applyStyles()},queueSheets:function(){for(var t=e("head"),l=t.find("link"),i=null,o=null,s=null,r=null,n=!1,a=0,d=0;a<l.length;a++)if(i=l[a],o=i.href,s=i.media,r=i.rel&&"stylesheet"===i.rel.toLowerCase(),n=!1,o&&r){for(d=0;d<this.ignored.length;d++)if(o.indexOf(this.ignored[d])>-1){n=!0;break}if(n)continue;for(d=0;d<this.reparsed.length;d++)if(o.indexOf(this.reparsed[d])>-1){this.sheets[o]=null;break}void 0!==this.sheets[o]&&this.sheets[o]||this.queue.push({link:l.eq(a),href:o,media:s})}return this.queue.length},runQueue:function(){var t;this.queue.length?(t=this.queue.shift(),e.get(t.href,e.proxy(function(e){this.parse(e,t),this.runQueue()},this))):this.applyStyles()},parse:function(e,t){var l=this.regex,i=e.replace(l.comments,"").replace(l.keyframes,"").match(l.media),o=i&&i.length||0,s=!o&&t.media,r=null,n=null,a=null,d="",u=0,c=0;for(i?d=e.replace(l.media,""):s&&"all"!=t.media?o=1:d=e,this.sheets[t.href]={link:t.link,href:t.href,link:t.link,all:d,queries:[]},u=0;u<o;u++)for(s?(r=t.media,e=this.convertURLs(e,t.href)):(r=i[u].match(l.findStyles)&&RegExp.$1,e=RegExp.$2&&this.convertURLs(RegExp.$2,t.href)),n=r.split(","),c=0;c<n.length;c++)r=n[c],a=r.split("(")[0].match(l.only)&&RegExp.$2,"print"!=a&&(r.replace(l.minmaxwh,"").match(l.other)||this.sheets[t.href].queries.push({minw:r.match(l.minw)&&parseFloat(RegExp.$1)+(RegExp.$2||""),maxw:r.match(l.maxw)&&parseFloat(RegExp.$1)+(RegExp.$2||""),styles:e}))},applyStyles:function(){var t=e("head"),l=null,i=null,o=null,s=null,r=null,n=null,a=null,d=null,u=!1;this.clearStyles();for(s in this.sheets)if(l="",i=e("<style></style>"),o=this.sheets[s],o.queries.length&&this.width){for(l+=o.all,n=0;n<o.queries.length;n++)r=o.queries[n],a=r.minw,d=r.maxw,u=!1,a&&(a=parseFloat(a)*(a.indexOf("em")>-1?this.getEmPxValue():1),this.width>=a&&(l+=r.styles,u=!0)),d&&!u&&(d=parseFloat(d)*(d.indexOf("em")>-1?this.getEmPxValue():1),this.width<=d&&(l+=r.styles));this.styles.push(i),t.append(i),i.html(l),o.link.remove()}},clearStyles:function(){var t=e("head"),l=null,i=this.styles.slice(0);this.styles=[];for(l in this.sheets)this.sheets[l].link.parent().length||t.append(this.sheets[l].link);setTimeout(function(){for(var e=0;e<i.length;e++)i[e].empty(),i[e].remove()},50)},convertURLs:function(e,t){return t=t.substring(0,t.lastIndexOf("/")),t.length&&(t+="/"),e.replace(this.regex.urls,"$1"+t+"$2$3")},getEmPxValue:function(){if(this.emPxValue)return this.emPxValue;var e=null,t=window.document,l=t.documentElement,i=t.body,o=t.createElement("div"),s=l.style.fontSize,r=i&&i.style.fontSize,n=!1;return o.style.cssText="position:absolute;font-size:1em;width:1em",i||(i=n=t.createElement("body"),i.style.background="none"),l.style.fontSize="100%",i.style.fontSize="100%",i.appendChild(o),n&&l.insertBefore(i,l.firstChild),e=parseFloat(o.offsetWidth),n?l.removeChild(i):i.removeChild(o),l.style.fontSize=s,r?i.style.fontSize=r:i.style.fontSize="",this.emPxValue=e,e}},l={_functions:null,update:function(){var e;if(!this._functions){this._functions={};for(e in i)this._functions[e]=jQuery.fn[e]}if(t.width)for(e in i)jQuery.fn[e]=i[e];else for(e in this._functions)jQuery.fn[e]=this._functions[e]}},i={width:function(i){return void 0!=i?l._functions.width.call(this,i):e.isWindow(this[0])?t.width:l._functions.width.call(this)}};FLBuilderSimulateMediaQuery={ignore:function(e){t.ignore(e)},reparse:function(e){t.reparse(e)},update:function(e,l){t.update(e,l)}}}(jQuery),function(e){FLBuilderResponsiveEditing={_mode:"default",refreshPreview:function(){var t;e(".fl-responsive-preview").length&&"default"!=this._mode&&("responsive"==this._mode?(t=FLBuilderConfig.global.responsive_breakpoint>=320?320:FLBuilderConfig.global.responsive_breakpoint,FLBuilderSimulateMediaQuery.update(t)):"medium"==this._mode&&(t=FLBuilderConfig.global.medium_breakpoint>=769?769:FLBuilderConfig.global.medium_breakpoint,FLBuilderSimulateMediaQuery.update(t)),FLBuilder._resizeLayout())},_init:function(){this._bind(),this._initMediaQueries()},_bind:function(){FLBuilder.addHook("responsive-editing-switched",this._previewSpacingFields),FLBuilder.addHook("settings-form-init",this._initSettingsForms),FLBuilder.addHook("settings-lightbox-closed",this._clearPreview),e("body").delegate(".fl-field-responsive-toggle","click",this._settingToggleClicked)},_initMediaQueries:function(){FLBuilderSimulateMediaQuery.ignore([FLBuilderConfig.pluginUrl,"fl-theme-builder","/wp-includes/","/wp-admin/"]),FLBuilderSimulateMediaQuery.reparse([FLBuilderConfig.postId+"-layout-draft.css?",FLBuilderConfig.postId+"-layout-draft-partial.css?",FLBuilderConfig.postId+"-layout-preview.css?",FLBuilderConfig.postId+"-layout-preview-partial.css?"])},_switchTo:function(t,l){var i=e("body"),o=e(FLBuilder._contentClass),s=e(".fl-responsive-preview"),r=e(".fl-responsive-preview-mask"),n=e(".fl-content-placeholder"),a=null;if(FLBuilderResponsiveEditing._mode=t,"default"==t){if(0===n.length)return;n.after(o),n.remove(),s.remove(),r.remove()}else 0===s.length?(o.after('<div class="fl-content-placeholder"></div>'),i.prepend(wp.template("fl-responsive-preview")()),e(".fl-responsive-preview").addClass("fl-preview-"+t),e(".fl-responsive-preview-content").append(o)):(s.removeClass("fl-preview-responsive fl-preview-medium"),s.addClass("fl-preview-"+t));"responsive"==t?(a=FLBuilderConfig.global.responsive_breakpoint>=320?320:FLBuilderConfig.global.responsive_breakpoint,o.width(a),FLBuilderSimulateMediaQuery.update(a,l)):"medium"==t?(a=FLBuilderConfig.global.medium_breakpoint>=769?769:FLBuilderConfig.global.medium_breakpoint,o.width(a),FLBuilderSimulateMediaQuery.update(a,l)):(o.width(""),FLBuilderSimulateMediaQuery.update(null,l)),this._setContentBackgroundColor(),FLBuilder._resizeLayout(),FLBuilder.triggerHook("responsive-editing-switched",t)},_setContentBackgroundColor:function(){var t=e(FLBuilder._contentClass),l=e(".fl-responsive-preview"),i=e(".fl-content-placeholder"),o=i.parents(),s="#fff",r=0;if(0===l.length)t.css("background-color","");else{for(;r<o.length&&(s=o.eq(r).css("background-color"),"rgba(0, 0, 0, 0)"==s);r++);t.css("background-color",s)}},_switchToAndScroll:function(t){var l=e(".fl-builder-settings").data("node"),i=void 0===l?void 0:e(".fl-node-"+l);FLBuilderResponsiveEditing._switchTo(t,function(){void 0!==i&&i&&setTimeout(function(){var t=e(window),l=e(".fl-responsive-preview-content");!l.length||t.height()<l.height()?e("html, body").animate({scrollTop:i.offset().top-100},250):scrollTo(0,0)},250)})},_clearPreview:function(){FLBuilderResponsiveEditing._switchToAndScroll("default")},_settingToggleClicked:function(){var t=e(this),l=t.data("mode");l="default"==l?"medium":"medium"==l?"responsive":"default",FLBuilderResponsiveEditing._switchAllSettingsTo(l),t.siblings(".fl-field-responsive-setting:visible").find("input").focus()},_switchAllSettingsTo:function(t){var l="dashicons-desktop dashicons-tablet dashicons-smartphone";e(".fl-field-responsive-toggle").removeClass(l),e(".fl-field-responsive-setting").hide(),l="default"==t?"dashicons-desktop":"medium"==t?"dashicons-tablet":"dashicons-smartphone",e(".fl-field-responsive-toggle").addClass(l).data("mode",t),e(".fl-field-responsive-setting-"+t).css("display","inline-block"),FLBuilderResponsiveEditing._switchToAndScroll(t)},_initSettingsForms:function(){var e=FLBuilderResponsiveEditing;Number(FLBuilderConfig.global.responsive_enabled)&&(e._initFields("unit","input","keyup",e._spacingFieldKeyup,["margin_top","margin_bottom","margin_left","margin_right","padding_top","padding_bottom","padding_left","padding_right"]),e._initFields("unit","input","keyup",e._textFieldKeyup)),e._switchAllSettingsTo(e._mode)},_initFields:function(t,l,i,o,s){for(var r=e(".fl-builder-settings"),n=r.find(".fl-field").has(".fl-field-responsive-setting"),a=null,d=null,u=0;u<n.length;u++)a=n.eq(u),d=a.attr("id").replace("fl-field-",""),"object"==typeof s&&e.inArray(d,s)<0||t==a.attr("data-type")&&void 0===a.attr("data-responsive-init")&&(a.find(".fl-field-responsive-setting-default "+l).on(i,o),a.find(".fl-field-responsive-setting-medium "+l).on(i,o),a.find(".fl-field-responsive-setting-responsive "+l).on(i,o),a.find(".fl-field-responsive-setting-default "+l).trigger(i),a.attr("data-responsive-init",1))},_getFields:function(t,l){var i=e(t).closest(".fl-field");return{"default":i.find(".fl-field-responsive-setting-default "+l),medium:i.find(".fl-field-responsive-setting-medium "+l),responsive:i.find(".fl-field-responsive-setting-responsive "+l)}},_textFieldKeyup:function(){var e=FLBuilderResponsiveEditing._getFields(this,"input"),t=e["default"].attr("placeholder"),l=e["default"].val(),i=e.medium.val();""==l?e.medium.attr("placeholder",void 0===t?"":t):e.medium.attr("placeholder",l),""==i?e.responsive.attr("placeholder",e.medium.attr("placeholder")):e.responsive.attr("placeholder",i)},_spacingFieldKeyup:function(){var t=e(".fl-builder-settings"),l="row",i=e(this).closest(".fl-field").attr("id").replace("fl-field-","").split("_"),o=i[0],s=i[1],r=FLBuilderResponsiveEditing._getFields(this,"input"),n=FLBuilderConfig.global,a=null,d=r["default"].val(),u=null,c=r.medium.val(),f=null,h=(r.responsive.val(),null),p=null,g=null;t.hasClass("fl-builder-row-settings")?l="row":t.hasClass("fl-builder-col-settings")?l="col":t.hasClass("fl-builder-module-settings")&&(l="module"),e.extend(n,{col_margins:0,col_margins_medium:"",col_margins_responsive:"",col_padding:0,col_padding_medium:"",col_padding_responsive:""}),a=l+"_"+o+("margin"==o?"s":""),u=n[a],f=n[a+"_medium"],h=n[a+"_responsive"],""==f&&(""!=d?r.medium.attr("placeholder",d):""!=u&&r.medium.attr("placeholder",u)),""==h&&("module"==l&&Number(n.auto_spacing)?(p=""==f?Number(u):f,g=""==c?Number(d):c,""!=g&&(g>p||g<0)?r.responsive.attr("placeholder",p):""!=g?r.responsive.attr("placeholder",g):r.responsive.attr("placeholder",p)):(!Number(n.auto_spacing)||"padding"==o&&"top|bottom".indexOf(s)>-1)&&(""!=c?r.responsive.attr("placeholder",c):""!=f?r.responsive.attr("placeholder",f):""!=d?r.responsive.attr("placeholder",d):""!=u&&r.responsive.attr("placeholder",u)))},_previewSpacingFields:function(){var t=FLBuilderResponsiveEditing._mode,l=e(".fl-builder-settings");0!==l.length&&void 0!==l.attr("data-node")&&l.find(".fl-field").has(".fl-field-responsive-setting").each(function(){var e=FLBuilderResponsiveEditing._getFields(this,"input"),l=e.responsive.closest(".fl-field").data("preview");"refresh"!=l.type&&e[t].trigger("keyup")})}},e(function(){FLBuilderResponsiveEditing._init()})}(jQuery),function(e){var t={init:function(){var t=e("body");t.delegate(".fl-builder-service-select","change",this._serviceChange),t.delegate(".fl-builder-service-connect-button","click",this._connectClicked),t.delegate(".fl-builder-service-account-select","change",this._accountChange),t.delegate(".fl-builder-service-account-delete","click",this._accountDeleteClicked),t.delegate(".fl-builder-campaign-monitor-client-select","change",this._campaignMonitorClientChange),t.delegate(".fl-builder-mailchimp-list-select","change",this._mailChimpListChange),t.delegate(".fl-builder-activecampaign-list_type-select","change",this._activeCampaignChange)},_startSettingsLoading:function(t){var l=e(".fl-builder-settings"),i=t.closest(".fl-builder-service-settings"),o=e(".fl-builder-service-error");l.append('<div class="fl-builder-loading"></div>'),i.addClass("fl-builder-service-settings-loading"),o.remove()},_finishSettingsLoading:function(){var t=e(".fl-builder-settings"),l=e(".fl-builder-service-settings-loading");t.find(".fl-builder-loading").remove(),l.removeClass("fl-builder-service-settings-loading")},_serviceChange:function(){var l=e(".fl-builder-settings").data("node"),i=e(this),o=i.closest("tr"),s=i.val();o.siblings("tr.fl-builder-service-account-row").remove(),o.siblings("tr.fl-builder-service-connect-row").remove(),o.siblings("tr.fl-builder-service-field-row").remove(),e(".fl-builder-service-error").remove(),""!==s&&(t._startSettingsLoading(i),FLBuilder.ajax({action:"render_service_settings",node_id:l,service:s},t._serviceChangeComplete))},_serviceChangeComplete:function(l){var i=JSON.parse(l),o=e(".fl-builder-service-settings-loading"),s=o.find(".fl-builder-service-select-row");s.after(i.html),t._addAccountDelete(o),t._finishSettingsLoading()},_connectClicked:function(){for(var l=e(".fl-builder-settings").data("node"),i=e(this).closest(".fl-builder-service-settings"),o=i.find(".fl-builder-service-select"),s=i.find(".fl-builder-service-connect-row"),r=i.find(".fl-builder-service-connect-input"),n=null,a=null,d=0,u={action:"connect_service",node_id:l,service:o.val(),fields:{}};d<r.length;d++)n=r.eq(d),a=n.attr("name"),u.fields[a]=n.val();s.hide(),t._startSettingsLoading(o),FLBuilder.ajax(u,t._connectComplete)},_connectComplete:function(l){var i=JSON.parse(l),o=e(".fl-builder-service-settings-loading"),s=o.find(".fl-builder-service-select-row"),r=o.find(".fl-builder-service-select"),n=o.find(".fl-builder-service-account-row"),a=o.find(".fl-builder-service-account-select"),d=o.find(".fl-builder-service-connect-row");i.error?(d.show(),0===a.length?r.after('<div class="fl-builder-service-error">'+i.error+"</div>"):a.after('<div class="fl-builder-service-error">'+i.error+"</div>")):(d.remove(),n.remove(),s.after(i.html)),t._addAccountDelete(o),t._finishSettingsLoading()},_accountChange:function(){var l=e(".fl-builder-settings").data("node"),i=e(this).closest(".fl-builder-service-settings"),o=i.find(".fl-builder-service-select"),s=i.find(".fl-builder-service-account-select"),r=i.find(".fl-builder-service-connect-row"),n=i.find("tr.fl-builder-service-field-row"),a=e(".fl-builder-service-error"),d=s.val(),u=null;r.remove(),n.remove(),a.remove(),"add_new_account"==d?u={action:"render_service_settings",node_id:l,service:o.val(),add_new:!0}:""!==d&&(u={action:"render_service_fields",node_id:l,service:o.val(),account:d}),u&&(t._startSettingsLoading(o),FLBuilder.ajax(u,t._accountChangeComplete)),t._addAccountDelete(i)},_accountChangeComplete:function(l){var i=JSON.parse(l),o=e(".fl-builder-service-settings-loading"),s=o.find(".fl-builder-service-account-row");s.after(i.html),t._finishSettingsLoading()},_addAccountDelete:function(e){var t=e.find(".fl-builder-service-account-select");t.length>0&&(e.find(".fl-builder-service-account-delete").remove(),""!==t.val()&&"add_new_account"!=t.val()&&t.after('<a href="javascript:void(0);" class="fl-builder-service-account-delete">'+FLBuilderStrings.deleteAccount+"</a>"))},_accountDeleteClicked:function(){var l=e(this).closest(".fl-builder-service-settings"),i=l.find(".fl-builder-service-select"),o=l.find(".fl-builder-service-account-select");confirm(FLBuilderStrings.deleteAccountWarning)&&(FLBuilder.ajax({action:"delete_service_account",service:i.val(),account:o.val()},t._accountDeleteComplete),t._startSettingsLoading(o))},_accountDeleteComplete:function(){var l=e(".fl-builder-service-settings-loading"),i=l.find(".fl-builder-service-select");t._finishSettingsLoading(),i.trigger("change")},_campaignMonitorClientChange:function(){var l=e(".fl-builder-settings").data("node"),i=e(this).closest(".fl-builder-service-settings"),o=i.find(".fl-builder-service-select"),s=i.find(".fl-builder-service-account-select"),r=e(this),n=i.find(".fl-builder-service-list-select"),a=r.val();0!==n.length&&n.closest("tr").remove(),""!==a&&(t._startSettingsLoading(o),FLBuilder.ajax({action:"render_service_fields",node_id:l,service:o.val(),account:s.val(),client:a},t._campaignMonitorClientChangeComplete))},_campaignMonitorClientChangeComplete:function(l){var i=JSON.parse(l),o=e(".fl-builder-service-settings-loading"),s=o.find(".fl-builder-campaign-monitor-client-select");s.closest("tr").after(i.html),t._finishSettingsLoading()},_mailChimpListChange:function(){var l=e(".fl-builder-settings").data("node"),i=e(this).closest(".fl-builder-service-settings"),o=i.find(".fl-builder-service-select"),s=i.find(".fl-builder-service-account-select"),r=i.find(".fl-builder-service-list-select");e(".fl-builder-mailchimp-group-select").closest("tr").remove(),""!==r.val()&&(t._startSettingsLoading(o),FLBuilder.ajax({action:"render_service_fields",node_id:l,service:o.val(),account:s.val(),list_id:r.val()},t._mailChimpListChangeComplete))},_mailChimpListChangeComplete:function(l){var i=JSON.parse(l),o=e(".fl-builder-service-settings-loading"),s=o.find(".fl-builder-service-list-select");s.closest("tr").after(i.html),t._finishSettingsLoading()},_activeCampaignChange:function(){var l=e(".fl-builder-settings").data("node"),i=e(this).closest(".fl-builder-service-settings"),o=i.find(".fl-builder-service-select"),s=i.find(".fl-builder-service-account-select"),r=i.find(".fl-builder-service-list-select");list_type=i.find('select[name="list_type"]'),0!==r.length&&r.closest("tr").remove(),""!==list_type.val()&&(t._startSettingsLoading(o),FLBuilder.ajax({action:"render_service_fields",node_id:l,service:o.val(),account:s.val(),list_type:list_type.val()},t._activeCampaignTypeChangeComplete))},_activeCampaignTypeChangeComplete:function(l){var i=JSON.parse(l),o=e(".fl-builder-service-settings-loading"),s=o.find(".fl-builder-service-field-row");s.after(i.html),t._finishSettingsLoading()}};e(function(){t.init()})}(jQuery),function(e){FLBuilderTour={_tour:null,start:function(){FLBuilderTour._tour?FLBuilderTour._tour.restart():(FLBuilderTour._tour=new Tour(FLBuilderTour._config()),FLBuilderTour._tour.init()),FLBuilderTour._tour.start()},_config:function(){var t={storage:!1,onStart:FLBuilderTour._onStart,onPrev:FLBuilderTour._onPrev,onNext:FLBuilderTour._onNext,onEnd:FLBuilderTour._onEnd,template:'<div class="popover" role="tooltip"> <i class="fa fa-times" data-role="end"></i> <div class="arrow"></div> <h3 class="popover-title"></h3> <div class="popover-content"></div> <div class="popover-navigation clearfix"> <button class="fl-builder-button fl-builder-button-primary fl-builder-tour-next" data-role="next">'+FLBuilderStrings.tourNext+"</button> </div> </div>",steps:[{animation:!1,element:".fl-builder-bar",placement:"bottom",title:FLBuilderStrings.tourTemplatesTitle,content:FLBuilderStrings.tourTemplates,onShown:function(){0===e(".fl-template-selector").length?(e(".popover[class*=tour-]").css("visibility","hidden"),FLBuilder._showTemplateSelector()):FLBuilderTour._templateSelectorLoaded()}},{animation:!1,element:"#fl-builder-blocks-rows .fl-builder-blocks-section-title",placement:"left",title:FLBuilderStrings.tourAddRowsTitle,content:FLBuilderStrings.tourAddRows,onShow:function(){FLBuilderTour._dimSection("body"),FLBuilderTour._dimSection(".fl-builder-bar"),FLBuilder._showPanel(),e(".fl-template-selector .fl-builder-settings-cancel").trigger("click"),e("#fl-builder-blocks-rows .fl-builder-blocks-section-title").trigger("click")}},{animation:!1,element:"#fl-builder-blocks-basic .fl-builder-blocks-section-title",placement:"left",title:FLBuilderStrings.tourAddContentTitle,content:FLBuilderStrings.tourAddContent,onShow:function(){FLBuilderTour._dimSection("body"),FLBuilderTour._dimSection(".fl-builder-bar"),FLBuilder._showPanel(),e("#fl-builder-blocks-basic .fl-builder-blocks-section-title").trigger("click"),e(".fl-row").eq(0).trigger("mouseleave"),e(".fl-module").eq(0).trigger("mouseleave")}},{animation:!1,element:".fl-row:first-of-type",placement:"top",title:FLBuilderStrings.tourEditContentTitle,content:FLBuilderStrings.tourEditContent,onShow:function(){FLBuilderTour._dimSection(".fl-builder-bar"),FLBuilder._closePanel(),e(".fl-row").eq(0).trigger("mouseenter"),e(".fl-module").eq(0).trigger("mouseenter")}},{animation:!1,element:".fl-row:first-of-type .fl-module-overlay .fl-block-overlay-actions",placement:"top",title:FLBuilderStrings.tourEditContentTitle,content:FLBuilderStrings.tourEditContent2,onShow:function(){FLBuilderTour._dimSection(".fl-builder-bar"),FLBuilder._closePanel(),e(".fl-row").eq(0).trigger("mouseenter"),e(".fl-module").eq(0).trigger("mouseenter")}},{animation:!1,element:".fl-builder-add-content-button",placement:"bottom",title:FLBuilderStrings.tourAddContentButtonTitle,content:FLBuilderStrings.tourAddContentButton,onShow:function(){FLBuilderTour._dimSection("body"),e(".fl-row").eq(0).trigger("mouseleave"),e(".fl-module").eq(0).trigger("mouseleave")}},{animation:!1,element:".fl-builder-templates-button",placement:"bottom",title:FLBuilderStrings.tourTemplatesButtonTitle,content:FLBuilderStrings.tourTemplatesButton,onShow:function(){FLBuilderTour._dimSection("body")}},{animation:!1,element:".fl-builder-tools-button",placement:"bottom",title:FLBuilderStrings.tourToolsButtonTitle,content:FLBuilderStrings.tourToolsButton,onShow:function(){FLBuilderTour._dimSection("body")}},{animation:!1,element:".fl-builder-done-button",placement:"bottom",title:FLBuilderStrings.tourDoneButtonTitle,content:FLBuilderStrings.tourDoneButton,onShow:function(){FLBuilderTour._dimSection("body")}},{animation:!1,orphan:!0,backdrop:!0,title:FLBuilderStrings.tourFinishedTitle,content:FLBuilderStrings.tourFinished,template:'<div class="popover" role="tooltip"> <div class="arrow"></div> <i class="fa fa-times" data-role="end"></i> <h3 class="popover-title"></h3> <div class="popover-content"></div> <div class="popover-navigation clearfix"> <button class="fl-builder-button fl-builder-button-primary fl-builder-tour-next" data-role="end">'+FLBuilderStrings.tourEnd+"</button> </div> </div>"}]};return FLBuilderConfig.lite?t.steps.shift():"disabled"==FLBuilderConfig.enabledTemplates?t.steps.shift():"fl-builder-template"==FLBuilderConfig.postType&&t.steps.shift(),t},_onStart:function(){var t=e("body");t.append('<div class="fl-builder-tour-mask"></div>'),t.on("fl-builder.template-selector-loaded",FLBuilderTour._templateSelectorLoaded),0===e(".fl-row").length&&"module"!=FLBuilderConfig.userTemplateType&&(e(".fl-builder-content").append('<div class="fl-builder-tour-demo-content fl-row fl-row-fixed-width fl-row-bg-none"> <div class="fl-row-content-wrap"> <div class="fl-row-content fl-row-fixed-width fl-node-content"> <div class="fl-col-group"> <div class="fl-col" style="width:100%"> <div class="fl-col-content fl-node-content"> <div class="fl-module fl-module-rich-text" data-type="rich-text" data-name="Text Editor"> <div class="fl-module-content fl-node-content"> <div class="fl-rich-text"> <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus pellentesque ut lorem non cursus. Sed mauris nunc, porttitor iaculis lorem a, sollicitudin lacinia sapien. Proin euismod orci lacus, et sollicitudin leo posuere ac. In hac habitasse platea dictumst. Maecenas elit magna, consequat in turpis suscipit, ultrices rhoncus arcu. Phasellus finibus sapien nec elit tempus venenatis. Maecenas tincidunt sapien non libero maximus, in aliquam felis tincidunt. Mauris mollis ultricies facilisis. Duis condimentum dignissim tortor sit amet facilisis. Aenean gravida lacus eu risus molestie egestas. Donec ut dolor dictum, fringilla metus malesuada, viverra nunc. Maecenas ut purus ac justo aliquet lacinia. Cras vestibulum elementum tincidunt. Maecenas mattis tortor neque, consectetur dignissim neque tempor nec.</p></div> </div> </div> </div> </div> </div> </div> </div> </div>'),FLBuilder._setupEmptyLayout(),FLBuilder._highlightEmptyCols())},_onPrev:function(){e(".fl-builder-tour-dimmed").remove()},_onNext:function(){e(".fl-builder-tour-dimmed").remove()},_onEnd:function(){e("body").off("fl-builder.template-selector-loaded"),e(".fl-builder-tour-mask").remove(),e(".fl-builder-tour-dimmed").remove(),e(".fl-builder-tour-demo-content").remove(),FLBuilder._setupEmptyLayout(),FLBuilder._highlightEmptyCols(),FLBuilder._showPanel(),FLBuilder._initTemplateSelector()},_dimSection:function(t){e(t).find(".fl-builder-tour-dimmed").remove(),e(t).append('<div class="fl-builder-tour-dimmed"></div>')},_templateSelectorLoaded:function(){var t=e(".fl-builder-settings-lightbox .fl-lightbox-header"),l=t.height(),i=t.offset().top+75;e(".popover[class*=tour-]").css({top:i+l+"px",visibility:"visible"})}}}(jQuery);var FLBuilderColorPicker;!function(e,t){function l(){var t,l,i="backgroundImage";f?h="filter":(t=e('<div id="iris-gradtest" />'),l="linear-gradient(top,#fff,#000)",e.each(p,function(e,o){if(t.css(i,o+l),t.css(i).match("gradient"))return h=e,!1}),h===!1&&(t.css("background","-webkit-gradient(linear,0% 0%,0% 100%,from(#fff),to(#000))"),t.css(this.bgImageString).match("gradient")&&(h="webkit")),t.remove())}function i(t,l){return t="top"===t?"top":"left",l=e.isArray(l)?l:Array.prototype.slice.call(arguments,1),"webkit"===h?s(t,l):p[h]+"linear-gradient("+t+", "+l.join(", ")+")"}function o(t,l){var i,o,s,n,a,d,u,c,f;t="top"===t?"top":"left",l=e.isArray(l)?l:Array.prototype.slice.call(arguments,1),i="top"===t?0:1,o=e(this),s=l.length-1,n="filter",a=1===i?"left":"top",d=1===i?"right":"bottom",u=1===i?"height":"width",c='<div class="iris-ie-gradient-shim" style="position:absolute;'+u+":100%;"+a+":%start%;"+d+":%end%;"+n+':%filter%;" data-color:"%color%"></div>',f="","static"===o.css("position")&&o.css({position:"relative"}),l=r(l),e.each(l,function(e,t){var o,r,n;return e!==s&&(o=l[e+1],void(t.stop!==o.stop&&(r=100-parseFloat(o.stop)+"%",t.octoHex=new Color(t.color).toIEOctoHex(),o.octoHex=new Color(o.color).toIEOctoHex(),n="progid:DXImageTransform.Microsoft.Gradient(GradientType="+i+", StartColorStr='"+t.octoHex+"', EndColorStr='"+o.octoHex+"')",
6
- f+=c.replace("%start%",t.stop).replace("%end%",r).replace("%filter%",n))))}),o.find(".iris-ie-gradient-shim").remove(),e(f).prependTo(o)}function s(t,l){var i=[];return t="top"===t?"0% 0%,0% 100%,":"0% 100%,100% 100%,",l=r(l),e.each(l,function(e,t){i.push("color-stop("+parseFloat(t.stop)/100+", "+t.color+")")}),"-webkit-gradient(linear,"+t+i.join(",")+")"}function r(t){var l=[],i=[],o=[],s=t.length-1;return e.each(t,function(e,t){var o=t,s=!1,r=t.match(/1?[0-9]{1,2}%$/);r&&(o=t.replace(/\s?1?[0-9]{1,2}%$/,""),s=r.shift()),l.push(o),i.push(s)}),i[0]===!1&&(i[0]="0%"),i[s]===!1&&(i[s]="100%"),i=n(i),e.each(i,function(e){o[e]={color:l[e],stop:i[e]}}),o}function n(t){var l,i,o,s,r=0,a=t.length-1,d=0,u=!1;if(t.length<=2||e.inArray(!1,t)<0)return t;for(;d<t.length-1;)u||t[d]!==!1?u&&t[d]!==!1&&(a=d,d=t.length):(r=d-1,u=!0),d++;for(i=a-r,s=parseInt(t[r].replace("%"),10),l=(parseFloat(t[a].replace("%"))-s)/i,d=r+1,o=1;d<a;)t[d]=s+o*l+"%",o++,d++;return n(t)}var a=[],d=navigator.userAgent.toLowerCase(),u="Microsoft Internet Explorer"===navigator.appName,c=u?parseFloat(d.match(/msie ([0-9]{1,}[\.0-9]{0,})/)[1]):0,f=u&&c<10,h=!1,p=["-moz-","-webkit-","-o-","-ms-"];flBuilderParseColorValue=function(e){var t=e.replace(/\s+/g,""),l=t.indexOf("rgba")!==-1?parseFloat(100*t.replace(/^.*,(.+)\)/,"$1")):100,i=l<100;return{value:t,alpha:l,rgba:i}},e.fn.flBuilderColorPickerGradient=function(){var t=arguments;return this.each(function(){f?o.apply(this,t):e(this).css("backgroundImage",i.apply(this,t))})},e.fn.flBuilderColorPickerRaninbowGradient=function(t,l){var i,o,s,r;for(t=t||"top",i=e.extend({},{s:100,l:50},l),o="hsl(%h%,"+i.s+"%,"+i.l+"%)",s=0,r=[];s<=360;)r.push(o.replace("%h%",s)),s+=30;return this.each(function(){e(this).flBuilderColorPickerGradient(t,r)})},FLBuilderColorPicker=function(t){this._html='<div class="fl-color-picker-ui"><div class="iris-picker"><div class="iris-picker-inner"><div class="iris-square"><a class="iris-square-value" href="#"><span class="iris-square-handle ui-slider-handle"></span></a><div class="iris-square-inner iris-square-horiz"></div><div class="iris-square-inner iris-square-vert"></div></div><div class="iris-slider iris-strip"><div class="iris-slider-offset"></div></div></div></div></div>';var l={elements:null,color:"",mode:"hsl",controls:{horiz:"s",vert:"l",strip:"h"},target:!1,width:200,presets:[],labels:{colorPresets:"Color Presets",colorPicker:"Color Picker",placeholder:"Paste color here...",removePresetConfirm:"Are you sure?",noneColorSelected:"None color selected.",alreadySaved:"%s is already a saved preset.",noPresets:"Add a color preset first.",presetAdded:"%s added to presets!"}};this.options=e.extend({},l,t),(f===!1||f===!0&&c>7)&&this._init()},FLBuilderColorPicker.prototype={_html:"",_color:"",_currentElement:"",_inited:!1,_defaultHSLControls:{horiz:"s",vert:"l",strip:"h"},_defaultHSVControls:{horiz:"h",vert:"v",strip:"s"},_scale:{h:360,s:100,l:100,v:100},_init:function(){var t=this;e(t.options.elements);this._color=new Color("#ff0000").setHSpace(t.options.mode),a=this.options.presets,h===!1&&l(),e("html").hasClass("fl-color-picker-init")?t.picker=e(".fl-color-picker-ui"):t.picker=e(this._html).appendTo("body"),u?9===c?t.picker.addClass("iris-ie-9"):c<=8&&t.picker.addClass("iris-ie-lt9"):d.indexOf("compatible")<0&&d.indexOf("khtml")<0&&d.match(/mozilla/)&&t.picker.addClass("iris-mozilla"),t.controls={square:t.picker.find(".iris-square"),squareDrag:t.picker.find(".iris-square-value"),horiz:t.picker.find(".iris-square-horiz"),vert:t.picker.find(".iris-square-vert"),strip:t.picker.find(".iris-strip"),stripSlider:t.picker.find(".iris-strip .iris-slider-offset")},"hsv"===t.options.mode&&t._has("l",t.options.controls)?t.options.controls=t._defaultHSVControls:"hsl"===t.options.mode&&t._has("v",t.options.controls)&&(t.options.controls=t._defaultHSLControls),t.hue=t._color.h(),this._setTemplates(),this._ui=e(".fl-color-picker-ui"),this._iris=e(".iris-picker"),this._wrapper=e("body"),e("html").hasClass("fl-color-picker-init")||this._ui.prepend(this._hexHtml).append(this._presetsHtml),t.element=this._ui.find(".fl-color-picker-input"),t._initControls(),t.active="external",t._change(),t._addInputListeners(t.element),this._buildUI(),this._prepareColorFields(),this._pickerControls(),this._presetsControls(),this._buildAlphaUI(),e("html").addClass("fl-color-picker-init")},_prepareColorFields:function(){var t=this;e(".fl-color-picker-value").each(function(){var l=e(this),i=l.val(),o=l.parent().find(".fl-color-picker-color"),s=flBuilderParseColorValue(i),r="";if(i){if(o.hasClass("fl-color-picker-alpha-enabled")&&s.rgba)r=l.val().toString();else if(!o.hasClass("fl-color-picker-alpha-enabled")&&s.rgba){var n=i.replace("rgba","rgb");n=n.substr(0,n.lastIndexOf(","))+")",t._color._alpha=1,r=n,l.val(n)}else r="#"+l.val().toString();o.css({backgroundColor:r})}})},_setTemplates:function(){this._alphaHtml='<div class="fl-alpha-wrap"><div class="fl-alpha-slider"></div><div class="fl-alpha-slider-offset"></div><div class="fl-alpha-text"></div></div>',this._presetsHtml='<div class="fl-color-picker-presets"><div class="fl-color-picker-presets-toggle"><div class="fl-color-picker-presets-open-label fl-color-picker-active">'+this.options.labels.colorPresets+' <span class="fl-color-picker-icon-arrow-up"></span></div><div class="fl-color-picker-presets-close-label">'+this.options.labels.colorPicker+' <span class="fl-color-picker-icon-arrow-down"></span></div></div><ul class="fl-color-picker-presets-list"></ul></div>',this._hexHtml='<input type="text" class="fl-color-picker-input" maxlength="7" placeholder="'+this.options.labels.placeholder+'"><div class="fl-color-picker-preset-add"></div>',this._presetsTpl='<li class="fl-color-picker-preset"><span class="fl-color-picker-preset-color"></span> <span class="fl-color-picker-preset-label"></span> <span class="fl-color-picker-preset-remove fl-color-picker-icon-remove"></span></li>',this._noPresetsTpl='<li class="fl-color-picker-no-preset"><span class="fl-color-picker-preset-label">'+this.options.labels.noPresets+"</span></li>"},_has:function(t,l){var i=!1;return e.each(l,function(e,l){if(t===l)return i=!0,!1}),i},_buildUI:function(){var t=this;t._presetsList=this._ui.find(".fl-color-picker-presets-list"),t._presetsList.html(""),this.options.presets.length>0?e.each(this.options.presets,function(e,l){t._addPresetView(l)}):t._presetsList.append(this._noPresetsTpl)},_addPresetView:function(t){var l=this._presetsList.find(".fl-color-picker-no-preset");l.length>0&&l.remove();var i=e(this._presetsTpl),o=Color(t);i.attr("data-color",t).find(".fl-color-picker-preset-color").css({backgroundColor:o.toString()}).end().find(".fl-color-picker-preset-label").html(o.toString()),this._presetsList.append(i)},_addPresetFeedback:function(){this._ui.append('<div class="fl-color-picker-added"><div class="fl-color-picker-added-text"><div class="fl-color-picker-icon-check"></div> "'+this.options.labels.presetAdded.replace("%s",this._color.toString())+'"</div></div>'),this._ui.find(".fl-color-picker-added").hide().fadeIn(200).delay(2e3).fadeOut(200,function(){e(this).remove()})},_pickerControls:function(){var t=this;this._wrapper.on("click",".fl-color-picker-color",function(){var l=e(this);t._currentElement=l.parent().find(".fl-color-picker-value"),t._ui.position({my:"left top",at:"left bottom",of:l,collision:"flipfit",using:function(e,l){t._togglePicker(e)}})}).on("click",".fl-color-picker-clear",function(){var l=e(this);t._currentElement=l.parent().find(".fl-color-picker-value"),l.prev(".fl-color-picker-color").css({backgroundColor:"transparent"}).addClass("fl-color-picker-empty"),t._setColor(""),t.element.val(""),t._currentElement.val("").trigger("change")}),e(document).on("mousedown",function(t){0===e(t.target).closest(".fl-color-picker-ui").length&&e(".fl-color-picker-ui.fl-color-picker-active").removeClass("fl-color-picker-active")})},_presetsControls:function(){var t=this,l=t._ui.find(".fl-color-picker-preset-add"),i=t._ui.find(".fl-color-picker-presets"),o=i.find(".fl-color-picker-presets-open-label"),s=i.find(".fl-color-picker-presets-close-label"),r=i.find(".fl-color-picker-presets-list");l.off("click").on("click",function(){t._addPreset(t.element.val())}),r.css({height:t.element.innerHeight()+t._iris.innerHeight()+14+"px"}).hide(),i.off("click").on("click",".fl-color-picker-presets-toggle",function(){o.toggleClass("fl-color-picker-active"),s.toggleClass("fl-color-picker-active"),r.slideToggle(500)}).on("click",".fl-color-picker-preset",function(l){var i=new Color(e(this).data("color").toString());t._setColor(i),t._currentElement.parent().find(".fl-color-picker-color").css({backgroundColor:i.toString()}).removeClass("fl-color-picker-empty"),o.toggleClass("fl-color-picker-active"),s.toggleClass("fl-color-picker-active"),r.slideToggle(500)}).on("click",".fl-color-picker-preset-remove",function(l){l.stopPropagation(),t._removePreset(e(this).parent().data("color"))})},_removePreset:function(t){if(confirm(this.options.labels.removePresetConfirm)){var l=t.toString(),i=a.indexOf(l);i>-1&&(a.splice(i,1),this.options.presets=a,this._presetsList.find('.fl-color-picker-preset[data-color="'+l+'"]').slideUp(function(){e(this).remove()})),a.length<1&&this._presetsList.append(this._noPresetsTpl),e(this).trigger("presetRemoved",{presets:a})}},_addPreset:function(t){var l=t.toString().replace(/^#/,"");""===l?alert(this.options.labels.noneColorSelected):a.indexOf(l)>-1?alert(this.options.labels.alreadySaved.replace("%s","#"+l)):(this._addPresetView(l),this._addPresetFeedback(),a.push(l),this.options.presets=a,e(this).trigger("presetAdded",{presets:a}))},_togglePicker:function(e){var t=this;this._ui.hasClass("fl-color-picker-active")?(this._ui.removeClass("fl-color-picker-active"),e&&setTimeout(function(){t._ui.css(e),t._ui.addClass("fl-color-picker-active"),t._setColor(t._currentElement.val())},200)):(e&&t._ui.css(e),setTimeout(function(){t._ui.addClass("fl-color-picker-active"),t._setColor(t._currentElement.val())},200))},_paint:function(){var e=this;e._paintDimension("right","strip"),e._paintDimension("top","vert"),e._paintDimension("left","horiz")},_paintDimension:function(e,t){var l,i=this,o=i._color,s=i.options.mode,r=i._getHSpaceColor(),n=i.controls[t],a=i.options.controls;if(t!==i.active&&("square"!==i.active||"strip"===t))switch(a[t]){case"h":if("hsv"===s){switch(r=o.clone(),t){case"horiz":r[a.vert](100);break;case"vert":r[a.horiz](100);break;case"strip":r.setHSpace("hsl")}l=r.toHsl()}else l="strip"===t?{s:r.s,l:r.l}:{s:100,l:r.l};n.flBuilderColorPickerRaninbowGradient(e,l);break;case"s":"hsv"===s?"vert"===t?l=[o.clone().a(0).s(0).toCSS("rgba"),o.clone().a(1).s(0).toCSS("rgba")]:"strip"===t?l=[o.clone().s(100).toCSS("hsl"),o.clone().s(0).toCSS("hsl")]:"horiz"===t&&(l=["#fff","hsl("+r.h+",100%,50%)"]):l="vert"===t&&"h"===i.options.controls.horiz?["hsla(0, 0%, "+r.l+"%, 0)","hsla(0, 0%, "+r.l+"%, 1)"]:["hsl("+r.h+",0%,50%)","hsl("+r.h+",100%,50%)"],n.flBuilderColorPickerGradient(e,l);break;case"l":l="strip"===t?["hsl("+r.h+",100%,100%)","hsl("+r.h+", "+r.s+"%,50%)","hsl("+r.h+",100%,0%)"]:["#fff","rgba(255,255,255,0) 50%","rgba(0,0,0,0) 50%","rgba(0,0,0,1)"],n.flBuilderColorPickerGradient(e,l);break;case"v":l="strip"===t?[o.clone().v(100).toCSS(),o.clone().v(0).toCSS()]:["rgba(0,0,0,0)","#000"],n.flBuilderColorPickerGradient(e,l)}},_getHSpaceColor:function(){return"hsv"===this.options.mode?this._color.toHsv():this._color.toHsl()},_dimensions:function(e){var t,l=this,i=l.options,o=l.controls,s=o.square,r=l.picker.find(".iris-strip"),n="77.5%",a="12%",d=20,u=i.border?i.width-d:i.width;if(e&&(s.css("width",""),r.css("width",""),l.picker.css({width:"",height:""})),n=u*(parseFloat(n)/100),a=u*(parseFloat(a)/100),t=i.border?n+d:n,s.width(n).height(n),r.height(n).width(a),l.picker.css({width:i.width,height:t}),!i.palettes)return l.picker.css("paddingBottom","")},_addInputListeners:function(e){var t=this,l=100,i=function(l){var i=new Color(e.val()),o=e.val().replace(/^#/,"");if(e.removeClass("iris-error"),i.error)""!==o&&e.addClass("iris-error");else if(i.toString()!==t._color.toString())if("keyup"===l.type){if(o.match(/^[0-9a-fA-F]{3}$/))return;t._setColor(o),t._currentElement.parent().find(".fl-color-picker-color").css({backgroundColor:Color(o).toString()}).removeClass("fl-color-picker-empty"),t._currentElement.val(o).trigger("change")}else if("paste"===l.type)return o=l.originalEvent.clipboardData.getData("text").replace(/^#/,""),hex=Color(o).toString(),t._setColor(o),e.val(hex),t._currentElement.parent().find(".fl-color-picker-color").css({backgroundColor:hex}).removeClass("fl-color-picker-empty"),t._currentElement.val(o).trigger("change"),!1};e.on("change",i).on("keyup",t._debounce(i,l))},_initControls:function(){var t=this,l=t.controls,i=l.square,o=t.options.controls,s=t._scale[o.strip];l.stripSlider.slider({orientation:"horizontal",max:s,slide:function(e,l){t.active="strip","h"===o.strip&&(l.value=s-l.value),t._color[o.strip](l.value),t._change.apply(t,arguments)}}),l.squareDrag.draggable({containment:l.square.find(".iris-square-inner"),zIndex:1e3,cursor:"move",drag:function(e,l){t._squareDrag(e,l)},start:function(){i.addClass("iris-dragging"),e(this).addClass("ui-state-focus")},stop:function(){i.removeClass("iris-dragging"),e(this).removeClass("ui-state-focus")}}).on("mousedown mouseup",function(l){var i="ui-state-focus";l.preventDefault(),"mousedown"===l.type?(t.picker.find("."+i).removeClass(i).blur(),e(this).addClass(i).focus()):e(this).removeClass(i)}).on("keydown",function(e){var i=l.square,o=l.squareDrag,s=o.position(),r=2;switch(e.altKey&&(r*=10),e.keyCode){case 37:s.left-=r;break;case 38:s.top-=r;break;case 39:s.left+=r;break;case 40:s.top+=r;break;default:return!0}s.left=Math.max(0,Math.min(s.left,i.width())),s.top=Math.max(0,Math.min(s.top,i.height())),o.css(s),t._squareDrag(e,{position:s}),e.preventDefault()}),i.mousedown(function(l){var i,o;1===l.which&&e(l.target).is("div")&&(i=t.controls.square.offset(),o={top:l.pageY-i.top,left:l.pageX-i.left},l.preventDefault(),t._squareDrag(l,{position:o}),l.target=t.controls.squareDrag.get(0),t.controls.squareDrag.css(o).trigger(l))})},_squareDrag:function(e,t){var l=this,i=l.options.controls,o=l._squareDimensions(),s=Math.round((o.h-t.position.top)/o.h*l._scale[i.vert]),r=l._scale[i.horiz]-Math.round((o.w-t.position.left)/o.w*l._scale[i.horiz]);l._color[i.horiz](r)[i.vert](s),l.active="square",l._change.apply(l,arguments)},_setColor:function(e){var t,l,i=this,o=i.options.color;i.options.color=e,e=""+e,t=e.replace(/^#/,""),l=new Color(e).setHSpace(i.options.mode),l.error?i.options.color=o:(i._color=l,i.options.color=i._color.toString(),i.active="external",i._change())},_squareDimensions:function(e){var l,i,o=this.controls.square;return e!==t&&o.data("dimensions")?o.data("dimensions"):(i=this.controls.squareDrag,l={w:o.width(),h:o.height()},o.data("dimensions",l),l)},_isNonHueControl:function(e,t){return"square"===e&&"h"===this.options.controls.strip||"external"!==t&&("h"!==t||"strip"!==e)},_change:function(){var t=this,l=t.controls,i=t._getHSpaceColor(),o=["square","strip"],s=t.options.controls,r=s[t.active]||"external",n=t.hue;"strip"===t.active?o=[]:"external"!==t.active&&o.pop(),e.each(o,function(e,o){var r,n,a;if(o!==t.active)switch(o){case"strip":r="h"===s.strip?t._scale[s.strip]-i[s.strip]:i[s.strip],l.stripSlider.slider("value",r);break;case"square":n=t._squareDimensions(),a={left:i[s.horiz]/t._scale[s.horiz]*n.w,top:n.h-i[s.vert]/t._scale[s.vert]*n.h},t.controls.squareDrag.css(a)}}),i.h!==n&&t._isNonHueControl(t.active,r)&&t._color.h(n),t.hue=t._color.h(),t.options.color=t._color.toString(),t.element.is(":input")&&!t._color.error&&(t.element.removeClass("iris-error"),t.element.val()!==t._color.toString()&&(t.element.val(t._color.toString()),this._currentElement&&(this._currentElement.val(t._color.toString().replace(/^#/,"")).parent().find(".fl-color-picker-color").css({backgroundColor:t._color.toString()}).removeClass("fl-color-picker-empty"),t._wrapper.find(".fl-alpha-slider-offset").css("background-color",t._color.toString()),this._currentElement.trigger("change")))),t._paint(),t._inited=!0,t.active=!1},_debounce:function(e,t,l){var i,o;return function(){var s,r,n=this,a=arguments;return s=function(){i=null,l||(o=e.apply(n,a))},r=l&&!i,clearTimeout(i),i=setTimeout(s,t),r&&(o=e.apply(n,a)),o}},_buildAlphaUI:function(){var t=this;t._wrapper.on("click",".fl-color-picker-color",function(){var l=e(this);t._currentElement.val();l.hasClass("fl-color-picker-alpha-enabled")?(t._ui.find(".fl-alpha-wrap").length<=0&&e(t._alphaHtml).insertAfter(t._iris),t.picker.addClass("fl-color-alpha-enabled"),t._pickerAlphaControls()):t._ui.find(".fl-alpha-wrap").remove()})},_pickerAlphaControls:function(){var e=this,t=e._currentElement,l=flBuilderParseColorValue(t.val()),i=parseFloat(l.alpha/100),o=e._wrapper,s=e._ui,r=s.find(".fl-alpha-wrap"),n=r.find(".fl-alpha-slider"),a=r.find(".fl-alpha-text"),d=r.find(".fl-alpha-slider-offset");alphaHandle=r.find(".ui-slider-handle"),a.text(i<1?i:""),n.slider({orientation:"vertical",slide:function(t,l){var i=parseFloat(l.value/100);e._color._alpha=i,a.text(i<1?i:""),e._change.apply(e,arguments)},create:function(){d.css({backgroundColor:l.value}),o.on("click",".fl-color-picker-clear",function(){e._color._alpha=1,a.text(""),n.slider("value",100).trigger("slide")})},value:l.alpha,step:1,min:1,max:100})}}}(jQuery),function(e,t){var l=function(e,t){return this instanceof l?this._init(e,t):new l(e,t)};l.fn=l.prototype={_color:0,_alpha:1,error:!1,_hsl:{h:0,s:0,l:0},_hsv:{h:0,s:0,v:0},_hSpace:"hsl",_init:function(e){var l="noop";switch(typeof e){case"object":return e.a!==t&&this.a(e.a),l=e.r!==t?"fromRgb":e.l!==t?"fromHsl":e.v!==t?"fromHsv":l,this[l](e);case"string":return this.fromCSS(e);case"number":return this.fromInt(parseInt(e,10))}return this},_error:function(){return this.error=!0,this},clone:function(){for(var e=new l(this.toInt()),t=["_alpha","_hSpace","_hsl","_hsv","error"],i=t.length-1;i>=0;i--)e[t[i]]=this[t[i]];return e},setHSpace:function(e){return this._hSpace="hsv"===e?e:"hsl",this},noop:function(){return this},fromCSS:function(e){var t,l=/^(rgb|hs(l|v))a?\(/;if(this.error=!1,e=e.replace(/^\s+/,"").replace(/\s+$/,"").replace(/;$/,""),e.match(l)&&e.match(/\)$/)){if(t=e.replace(/(\s|%)/g,"").replace(l,"").replace(/,?\);?$/,"").split(","),t.length<3)return this._error();if(4===t.length&&(this.a(parseFloat(t.pop())),this.error))return this;for(var i=t.length-1;i>=0;i--)if(t[i]=parseInt(t[i],10),isNaN(t[i]))return this._error();return e.match(/^rgb/)?this.fromRgb({r:t[0],g:t[1],b:t[2]}):e.match(/^hsv/)?this.fromHsv({h:t[0],s:t[1],v:t[2]}):this.fromHsl({h:t[0],s:t[1],l:t[2]})}return this.fromHex(e)},fromRgb:function(e,l){return"object"!=typeof e||e.r===t||e.g===t||e.b===t?this._error():(this.error=!1,this.fromInt(parseInt((e.r<<16)+(e.g<<8)+e.b,10),l))},fromHex:function(e){return e=e.replace(/^#/,"").replace(/^0x/,""),3===e.length&&(e=e[0]+e[0]+e[1]+e[1]+e[2]+e[2]),this.error=!/^[0-9A-F]{6}$/i.test(e),this.fromInt(parseInt(e,16))},fromHsl:function(e){var l,i,o,s,r,n,a,d;return"object"!=typeof e||e.h===t||e.s===t||e.l===t?this._error():(this._hsl=e,this._hSpace="hsl",n=e.h/360,a=e.s/100,d=e.l/100,0===a?l=i=o=d:(s=d<.5?d*(1+a):d+a-d*a,r=2*d-s,l=this.hue2rgb(r,s,n+1/3),i=this.hue2rgb(r,s,n),o=this.hue2rgb(r,s,n-1/3)),this.fromRgb({r:255*l,g:255*i,b:255*o},!0))},fromHsv:function(e){var l,i,o,s,r,n,a,d,u,c,f;if("object"!=typeof e||e.h===t||e.s===t||e.v===t)return this._error();switch(this._hsv=e,this._hSpace="hsv",l=e.h/360,i=e.s/100,o=e.v/100,a=Math.floor(6*l),d=6*l-a,u=o*(1-i),c=o*(1-d*i),f=o*(1-(1-d)*i),a%6){case 0:s=o,r=f,n=u;break;case 1:s=c,r=o,n=u;break;case 2:s=u,r=o,n=f;break;case 3:s=u,r=c,n=o;break;case 4:s=f,r=u,n=o;break;case 5:s=o,r=u,n=c}return this.fromRgb({r:255*s,g:255*r,b:255*n},!0)},fromInt:function(e,l){return this._color=parseInt(e,10),isNaN(this._color)&&(this._color=0),this._color>16777215?this._color=16777215:this._color<0&&(this._color=0),l===t&&(this._hsv.h=this._hsv.s=this._hsl.h=this._hsl.s=0),this},hue2rgb:function(e,t,l){return l<0&&(l+=1),l>1&&(l-=1),l<1/6?e+6*(t-e)*l:l<.5?t:l<2/3?e+(t-e)*(2/3-l)*6:e},toString:function(){if(this._alpha<1)return this.toCSS("rgba",this._alpha).replace(/\s+/g,"");var e=parseInt(this._color,10).toString(16);if(this.error)return"";if(e.length<6)for(var t=6-e.length-1;t>=0;t--)e="0"+e;return"#"+e},toCSS:function(e,t){switch(e=e||"hex",t=parseFloat(t||this._alpha),e){case"rgb":case"rgba":var l=this.toRgb();return t<1?"rgba( "+l.r+", "+l.g+", "+l.b+", "+t+" )":"rgb( "+l.r+", "+l.g+", "+l.b+" )";case"hsl":case"hsla":var i=this.toHsl();return t<1?"hsla( "+i.h+", "+i.s+"%, "+i.l+"%, "+t+" )":"hsl( "+i.h+", "+i.s+"%, "+i.l+"% )";default:return this.toString()}},toRgb:function(){return{r:255&this._color>>16,g:255&this._color>>8,b:255&this._color}},toHsl:function(){var e,t,l=this.toRgb(),i=l.r/255,o=l.g/255,s=l.b/255,r=Math.max(i,o,s),n=Math.min(i,o,s),a=(r+n)/2;if(r===n)e=t=0;else{var d=r-n;switch(t=a>.5?d/(2-r-n):d/(r+n),r){case i:e=(o-s)/d+(o<s?6:0);break;case o:e=(s-i)/d+2;break;case s:e=(i-o)/d+4}e/=6}return e=Math.round(360*e),0===e&&this._hsl.h!==e&&(e=this._hsl.h),t=Math.round(100*t),0===t&&this._hsl.s&&(t=this._hsl.s),{h:e,s:t,l:Math.round(100*a)}},toHsv:function(){var e,t,l=this.toRgb(),i=l.r/255,o=l.g/255,s=l.b/255,r=Math.max(i,o,s),n=Math.min(i,o,s),a=r,d=r-n;if(t=0===r?0:d/r,r===n)e=t=0;else{switch(r){case i:e=(o-s)/d+(o<s?6:0);break;case o:e=(s-i)/d+2;break;case s:e=(i-o)/d+4}e/=6}return e=Math.round(360*e),0===e&&this._hsv.h!==e&&(e=this._hsv.h),t=Math.round(100*t),0===t&&this._hsv.s&&(t=this._hsv.s),{h:e,s:t,v:Math.round(100*a)}},toInt:function(){return this._color},toIEOctoHex:function(){var e=this.toString(),t=parseInt(255*this._alpha,10).toString(16);return 1===t.length&&(t="0"+t),"#"+t+e.replace(/^#/,"")},toLuminosity:function(){var e=this.toRgb();return.2126*Math.pow(e.r/255,2.2)+.7152*Math.pow(e.g/255,2.2)+.0722*Math.pow(e.b/255,2.2)},getDistanceLuminosityFrom:function(e){if(!(e instanceof l))throw"getDistanceLuminosityFrom requires a Color object";var t=this.toLuminosity(),i=e.toLuminosity();return t>i?(t+.05)/(i+.05):(i+.05)/(t+.05)},getMaxContrastColor:function(){var e=this.toLuminosity(),t=e>=.5?"000000":"ffffff";return new l(t)},getReadableContrastingColor:function(e,i){if(!(e instanceof l))return this;var o=i===t?5:i,s=e.getDistanceLuminosityFrom(this),r=e.getMaxContrastColor(),n=r.getDistanceLuminosityFrom(e);if(n<=o)return r;if(s>=o)return this;for(var a=0===r.toInt()?-1:1;s<o&&(this.l(a,!0),s=this.getDistanceLuminosityFrom(e),0!==this._color&&16777215!==this._color););return this},a:function(e){if(e===t)return this._alpha;var l=parseFloat(e);return isNaN(l)?this._error():(this._alpha=l,this)},darken:function(e){return e=e||5,this.l(-e,!0)},lighten:function(e){return e=e||5,this.l(e,!0)},saturate:function(e){return e=e||15,this.s(e,!0)},desaturate:function(e){return e=e||15,this.s(-e,!0)},toGrayscale:function(){return this.setHSpace("hsl").s(0)},getComplement:function(){return this.h(180,!0)},getSplitComplement:function(e){e=e||1;var t=180+30*e;return this.h(t,!0)},getAnalog:function(e){e=e||1;var t=30*e;return this.h(t,!0)},getTetrad:function(e){e=e||1;var t=60*e;return this.h(t,!0)},getTriad:function(e){e=e||1;var t=120*e;return this.h(t,!0)},_partial:function(e){var l=i[e];return function(i,o){var s=this._spaceFunc("to",l.space);return i===t?s[e]:(o===!0&&(i=s[e]+i),l.mod&&(i%=l.mod),l.range&&(i=i<l.range[0]?l.range[0]:i>l.range[1]?l.range[1]:i),s[e]=i,this._spaceFunc("from",l.space,s))}},_spaceFunc:function(e,t,l){var i=t||this._hSpace,o=e+i.charAt(0).toUpperCase()+i.substr(1);return this[o](l)}};var i={h:{mod:360},s:{range:[0,100]},l:{space:"hsl",range:[0,100]},v:{space:"hsv",range:[0,100]},r:{space:"rgb",range:[0,255]},g:{space:"rgb",range:[0,255]},b:{space:"rgb",range:[0,255]}};for(var o in i)i.hasOwnProperty(o)&&(l.fn[o]=l.fn._partial(o));"object"==typeof exports?module.exports=l:e.Color=l}(this),function(e){FLIconSelector={_content:null,_lightbox:null,_rendered:!1,_filterText:"",open:function(e){FLIconSelector._rendered||FLIconSelector._render(),null===FLIconSelector._content?(FLIconSelector._lightbox.open('<div class="fl-builder-lightbox-loading"></div>'),FLBuilder.ajax({action:"render_icon_selector"},FLIconSelector._getContentComplete)):FLIconSelector._lightbox.open(),FLIconSelector._lightbox.on("icon-selected",function(t,l){FLIconSelector._lightbox.off("icon-selected"),FLIconSelector._lightbox.close(),e(l)})},_render:function(){FLIconSelector._lightbox=new FLLightbox({className:"fl-icon-selector"}),FLIconSelector._rendered=!0},_getContentComplete:function(t){var l=JSON.parse(t);FLIconSelector._content=l.html,FLIconSelector._lightbox.setContent(l.html),e(".fl-icons-filter-select").on("change",FLIconSelector._filter),e(".fl-icons-filter-text").on("keyup",FLIconSelector._filter),e(".fl-icons-list i").on("click",FLIconSelector._select),e(".fl-icon-selector-cancel").on("click",e.proxy(FLIconSelector._lightbox.close,FLIconSelector._lightbox))},_filter:function(){var t=e(".fl-icons-filter-select").val(),l=e(".fl-icons-filter-text").val();"all"==t?e(".fl-icons-section").show():(e(".fl-icons-section").hide(),e(".fl-"+t).show()),FLIconSelector._filterText=l,""!==l?e(".fl-icons-list i").each(FLIconSelector._filterIcon):e(".fl-icons-list i").show()},_filterIcon:function(){var t=e(this);-1==t.attr("class").indexOf(FLIconSelector._filterText)?t.hide():t.show()},_select:function(){var t=e(this).attr("class");FLIconSelector._lightbox.trigger("icon-selected",t)}}}(jQuery),function(e){FLStyleSheet=function(t){"object"==typeof t&&e.extend(this,t),this._createSheet()},FLStyleSheet.prototype={id:null,_sheet:null,_sheetElement:null,updateRule:function(e,t,l){for(var i=this._sheet.cssRules?this._sheet.cssRules:this._sheet.rules,o=null,s=0;s<i.length;s++)i[s].selectorText.toLowerCase()==e.toLowerCase()&&(o=i[s]);if(o)if("object"==typeof t)for(s in t)o.style[this._toCamelCase(s)]=t[s];else o.style[this._toCamelCase(t)]=l;else this.addRule(e,t,l)},addRule:function(e,t,l){var i="",o="";if("object"==typeof t)for(o in t)i+=o+":"+t[o]+";";else i=t+":"+l+";";this._sheet.insertRule?this._sheet.insertRule(e+" { "+i+" }",this._sheet.cssRules.length):this._sheet.addRule(e,i)},destroy:function(){this._sheetElement&&(this._sheetElement.remove(),this._sheetElement=null),this._sheet&&(this._sheet=null)},disable:function(){this._sheet.disabled=!0},enable:function(){this._sheet.disabled=!1},_createSheet:function(){var t=this.id?' id="'+this.id+'"':"";this._sheet||(this._sheetElement=e('<style type="text/css"'+t+"></style>"),e("body").append(this._sheetElement),this._sheet=this._sheetElement[0].sheet)},_toCamelCase:function(e){return e.toLowerCase().replace(/-(.)/g,function(e,t){return t.toUpperCase()})}}}(jQuery);
1
+ !function(e){FLLightbox=function(e){this._init(e),this._render(),this._bind()},FLLightbox.closeParent=function(t){var l=e(t).closest(".fl-lightbox-wrap").attr("data-instance-id");FLLightbox._instances[l].close()},FLLightbox._instances={},FLLightbox.prototype={_id:null,_node:null,_visible:!1,_resizeTimer:null,_draggable:!1,_defaults:{className:"",destroyOnClose:!1},open:function(e){this._node.find(".fl-lightbox").attr("style",""),this._node.show(),this._visible=!0,"undefined"!=typeof e?this.setContent(e):this._resize(),this.trigger